<?php
namespace App\Services;

class UploadService {
    
    protected $uploadPath;
    protected $maxSize;
    protected $allowedTypes;
    
    public function __construct() {
        $this->uploadPath = BASE_PATH . UPLOAD_PATH;
        $this->maxSize = MAX_UPLOAD_SIZE;
        $this->allowedTypes = ALLOWED_FILE_TYPES;
    }
    
    /**
     * Upload file
     */
    public function upload($file, $subdirectory = 'documents') {
        if ($file['error'] !== UPLOAD_ERR_OK) {
            throw new \Exception($this->getUploadErrorMessage($file['error']));
        }
        
        // Check file size
        if ($file['size'] > $this->maxSize) {
            throw new \Exception('File size exceeds limit of ' . ($this->maxSize / 1048576) . '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)) {
            throw new \Exception('File type not allowed. Allowed types: ' . implode(', ', $this->allowedTypes));
        }
        
        // Create directory if not exists
        $targetDir = $this->uploadPath . '/' . $subdirectory;
        if (!is_dir($targetDir)) {
            mkdir($targetDir, 0755, true);
        }
        
        // Generate secure filename
        $extension = pathinfo($file['name'], PATHINFO_EXTENSION);
        $filename = uniqid() . '_' . bin2hex(random_bytes(8)) . '.' . $extension;
        $filepath = $targetDir . '/' . $filename;
        
        // Move file
        if (!move_uploaded_file($file['tmp_name'], $filepath)) {
            throw new \Exception('Failed to upload file');
        }
        
        // Return relative path
        $relativePath = str_replace(BASE_PATH, '', $filepath);
        
        return [
            'original_name' => $file['name'],
            'filename' => $filename,
            'filepath' => $relativePath,
            'size' => $file['size'],
            'mime_type' => $mimeType
        ];
    }
    
    /**
     * Upload multiple files
     */
    public function uploadMultiple($files, $subdirectory = 'documents') {
        $uploaded = [];
        
        foreach ($files['name'] as $key => $name) {
            if ($files['error'][$key] === UPLOAD_ERR_OK) {
                $file = [
                    'name' => $name,
                    'type' => $files['type'][$key],
                    'tmp_name' => $files['tmp_name'][$key],
                    'error' => $files['error'][$key],
                    'size' => $files['size'][$key]
                ];
                
                try {
                    $uploaded[] = $this->upload($file, $subdirectory);
                } catch (\Exception $e) {
                    error_log("Upload failed for file $name: " . $e->getMessage());
                }
            }
        }
        
        return $uploaded;
    }
    
    /**
     * Upload base64 image
     */
    public function uploadBase64($base64Data, $subdirectory = 'biometrics') {
        // Extract image data
        if (preg_match('/^data:image\/(\w+);base64,/', $base64Data, $matches)) {
            $imageType = $matches[1];
            $base64Data = substr($base64Data, strpos($base64Data, ',') + 1);
            $base64Data = base64_decode($base64Data);
        } else {
            throw new \Exception('Invalid base64 image data');
        }
        
        // Validate image size (approx 5MB)
        if (strlen($base64Data) > $this->maxSize) {
            throw new \Exception('Image size exceeds limit');
        }
        
        // Create directory
        $targetDir = $this->uploadPath . '/' . $subdirectory;
        if (!is_dir($targetDir)) {
            mkdir($targetDir, 0755, true);
        }
        
        // Save file
        $filename = uniqid() . '_' . bin2hex(random_bytes(8)) . '.' . $imageType;
        $filepath = $targetDir . '/' . $filename;
        
        if (file_put_contents($filepath, $base64Data) === false) {
            throw new \Exception('Failed to save image');
        }
        
        $relativePath = str_replace(BASE_PATH, '', $filepath);
        
        return [
            'filename' => $filename,
            'filepath' => $relativePath,
            'size' => strlen($base64Data),
            'mime_type' => 'image/' . $imageType
        ];
    }
    
    /**
     * Delete file
     */
    public function delete($filepath) {
        $fullPath = BASE_PATH . $filepath;
        if (file_exists($fullPath) && is_file($fullPath)) {
            return unlink($fullPath);
        }
        return false;
    }
    
    /**
     * Get upload error message
     */
    protected function getUploadErrorMessage($error) {
        switch ($error) {
            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';
        }
    }
}