<?php
/**
 * Upload Manager
 * Handles temporary file uploads
 */

class UploadManager {
    private $tempDir;
    private $maxFileSize = 5242880; // 5MB
    private $allowedTypes = [
        'image/jpeg', 'image/png', 'image/gif',
        'application/pdf',
        'application/msword',
        'application/vnd.openxmlformats-officedocument.wordprocessingml.document'
    ];
    
    public function __construct($tempDir = null) {
        $this->tempDir = $tempDir ?: __DIR__ . '/../tmp/uploads/';
        $this->ensureDirectory();
    }
    
    /**
     * Ensure upload directory exists
     */
    private function ensureDirectory() {
        if (!is_dir($this->tempDir)) {
            mkdir($this->tempDir, 0755, true);
        }
    }
    
    /**
     * Upload temporary file
     * @param array $file $_FILES array element
     * @return array
     */
    public function upload($file) {
        if ($file['error'] !== UPLOAD_ERR_OK) {
            return [
                'success' => false,
                'error' => $this->getUploadErrorMessage($file['error'])
            ];
        }
        
        // Check file size
        if ($file['size'] > $this->maxFileSize) {
            return [
                'success' => false,
                'error' => 'File too large. Maximum size: ' . ($this->maxFileSize / 1024 / 1024) . 'MB'
            ];
        }
        
        // Check file type
        $finfo = finfo_open(FILEINFO_MIME_TYPE);
        $mimeType = finfo_file($finfo, $file['tmp_name']);
        finfo_close($finfo);
        
        if (!in_array($mimeType, $this->allowedTypes)) {
            return [
                'success' => false,
                'error' => 'Invalid file type. Allowed: ' . implode(', ', $this->allowedTypes)
            ];
        }
        
        // Generate unique filename
        $extension = pathinfo($file['name'], PATHINFO_EXTENSION);
        $filename = time() . '_' . bin2hex(random_bytes(8)) . '.' . $extension;
        $filepath = $this->tempDir . $filename;
        
        if (move_uploaded_file($file['tmp_name'], $filepath)) {
            return [
                'success' => true,
                'filename' => $filename,
                'original_name' => $file['name'],
                'size' => $file['size'],
                'mime_type' => $mimeType,
                'path' => $filepath
            ];
        }
        
        return [
            'success' => false,
            'error' => 'Failed to save uploaded file'
        ];
    }
    
    /**
     * Get temporary file
     * @param string $filename
     * @return string|null
     */
    public function get($filename) {
        $filepath = $this->tempDir . basename($filename);
        if (file_exists($filepath)) {
            return $filepath;
        }
        return null;
    }
    
    /**
     * Delete temporary file
     * @param string $filename
     * @return bool
     */
    public function delete($filename) {
        $filepath = $this->tempDir . basename($filename);
        if (file_exists($filepath)) {
            return unlink($filepath);
        }
        return true;
    }
    
    /**
     * Clean old temporary files
     * @param int $maxAge Maximum age in seconds
     * @return int Number of files deleted
     */
    public function clean($maxAge = 86400) { // 24 hours default
        $count = 0;
        $files = glob($this->tempDir . '*');
        $now = time();
        
        foreach ($files as $file) {
            if (is_file($file) && $now - filemtime($file) > $maxAge) {
                if (unlink($file)) {
                    $count++;
                }
            }
        }
        
        return $count;
    }
    
    /**
     * Get upload error message
     * @param int $errorCode
     * @return string
     */
    private function getUploadErrorMessage($errorCode) {
        switch ($errorCode) {
            case UPLOAD_ERR_INI_SIZE:
                return 'File exceeds upload_max_filesize directive';
            case UPLOAD_ERR_FORM_SIZE:
                return 'File exceeds MAX_FILE_SIZE directive';
            case UPLOAD_ERR_PARTIAL:
                return 'File was only partially uploaded';
            case UPLOAD_ERR_NO_FILE:
                return 'No file was uploaded';
            case UPLOAD_ERR_NO_TMP_DIR:
                return 'Missing temporary folder';
            case UPLOAD_ERR_CANT_WRITE:
                return 'Failed to write file to disk';
            case UPLOAD_ERR_EXTENSION:
                return 'File upload stopped by extension';
            default:
                return 'Unknown upload error';
        }
    }
    
    /**
     * Get upload statistics
     * @return array
     */
    public function getStats() {
        $files = glob($this->tempDir . '*');
        $totalSize = 0;
        
        foreach ($files as $file) {
            if (is_file($file)) {
                $totalSize += filesize($file);
            }
        }
        
        return [
            'total_files' => count($files),
            'total_size' => $totalSize,
            'total_size_formatted' => $this->formatSize($totalSize),
            'max_file_size' => $this->maxFileSize,
            'temp_directory' => $this->tempDir
        ];
    }
    
    /**
     * Format file size
     * @param int $bytes
     * @return string
     */
    private function formatSize($bytes) {
        if ($bytes >= 1073741824) {
            return round($bytes / 1073741824, 2) . ' GB';
        } elseif ($bytes >= 1048576) {
            return round($bytes / 1048576, 2) . ' MB';
        } elseif ($bytes >= 1024) {
            return round($bytes / 1024, 2) . ' KB';
        }
        return $bytes . ' B';
    }
}

// Global upload manager
$uploadManager = null;

function getUploadManager() {
    global $uploadManager;
    if ($uploadManager === null) {
        $uploadManager = new UploadManager();
    }
    return $uploadManager;
}