<?php
// app/Core/Upload.php - File Upload Handler with Image Compression

class Upload {
    
    /**
     * Upload single file
     */
    public static function file($file, $folder = 'general', $allowed_types = null, $max_size = null) {
        // Validate file
        $allowed_types = $allowed_types ?: ALLOWED_IMAGE_TYPES;
        $validation = Security::validateFile($file, $allowed_types, $max_size);
        
        if (!$validation['success']) {
            return ['success' => false, 'message' => $validation['message']];
        }
        
        // Create upload directory if it doesn't exist
        $upload_dir = UPLOAD_PATH . '/' . $folder;
        if (!is_dir($upload_dir)) {
            mkdir($upload_dir, 0755, true);
        }
        
        // Generate secure filename
        $filename = Security::generateSecureFilename($file['name']);
        $destination = $upload_dir . '/' . $filename;
        
        // Move uploaded file
        if (move_uploaded_file($file['tmp_name'], $destination)) {
            // Return relative path
            $relative_path = $folder . '/' . $filename;
            
            log_message("File uploaded successfully: {$relative_path}", 'info');
            
            return [
                'success' => true,
                'filename' => $filename,
                'path' => $relative_path,
                'full_path' => $destination
            ];
        }
        
        log_message("File upload failed: " . $file['name'], 'error');
        return ['success' => false, 'message' => 'Failed to upload file'];
    }
    
    /**
     * Upload image file with compression
     */
    public static function image($file, $folder = 'images', $max_size = null) {
        $allowed_types = explode(',', ALLOWED_IMAGE_TYPES);
        $result = self::file($file, $folder, implode(',', $allowed_types), $max_size);
        
        if ($result['success']) {
            // Compress and optimize image
            self::compressImage($result['full_path']);
        }
        
        return $result;
    }

    /**
     * Upload image (alias for image method)
     */
    public static function uploadImage($file, $folder = 'images', $max_size = null) {
        return self::image($file, $folder, $max_size);
    }
    
    /**
     * Compress image while maintaining quality
     */
    private static function compressImage($file_path, $max_width = 1920, $quality = 85) {
        // Get image info
        $image_info = getimagesize($file_path);
        
        if (!$image_info) {
            return false;
        }
        
        list($width, $height, $type) = $image_info;
        
        // Create image resource based on type
        switch ($type) {
            case IMAGETYPE_JPEG:
                $source = imagecreatefromjpeg($file_path);
                break;
            case IMAGETYPE_PNG:
                $source = imagecreatefrompng($file_path);
                break;
            case IMAGETYPE_GIF:
                $source = imagecreatefromgif($file_path);
                break;
            case IMAGETYPE_WEBP:
                $source = imagecreatefromwebp($file_path);
                break;
            default:
                return false;
        }
        
        if (!$source) {
            return false;
        }
        
        // Calculate new dimensions if image is larger than max_width
        if ($width > $max_width) {
            $new_width = $max_width;
            $new_height = floor($height * ($max_width / $width));
        } else {
            $new_width = $width;
            $new_height = $height;
        }
        
        // Create new image with new dimensions
        $new_image = imagecreatetruecolor($new_width, $new_height);
        
        // Preserve transparency for PNG and GIF
        if ($type == IMAGETYPE_PNG || $type == IMAGETYPE_GIF || $type == IMAGETYPE_WEBP) {
            imagealphablending($new_image, false);
            imagesavealpha($new_image, true);
            $transparent = imagecolorallocatealpha($new_image, 255, 255, 255, 127);
            imagefilledrectangle($new_image, 0, 0, $new_width, $new_height, $transparent);
        }
        
        // Resize image
        imagecopyresampled($new_image, $source, 0, 0, 0, 0, $new_width, $new_height, $width, $height);
        
        // Save compressed image
        switch ($type) {
            case IMAGETYPE_JPEG:
                imagejpeg($new_image, $file_path, $quality);
                break;
            case IMAGETYPE_PNG:
                // PNG quality is 0-9, convert from percentage
                $png_quality = floor((100 - $quality) / 10);
                imagepng($new_image, $file_path, $png_quality);
                break;
            case IMAGETYPE_GIF:
                imagegif($new_image, $file_path);
                break;
            case IMAGETYPE_WEBP:
                imagewebp($new_image, $file_path, $quality);
                break;
        }
        
        // Free memory
        imagedestroy($source);
        imagedestroy($new_image);
        
        return true;
    }
    
    /**
     * Upload document file
     */
    public static function document($file, $folder = 'documents', $max_size = null) {
        $allowed_types = explode(',', ALLOWED_DOCUMENT_TYPES);
        return self::file($file, $folder, implode(',', $allowed_types), $max_size);
    }
    
    /**
     * Upload multiple files
     */
    public static function multiple($files, $folder = 'general', $allowed_types = null, $max_size = null) {
        $uploaded_files = [];
        $errors = [];
        
        // Handle multiple file array structure
        if (isset($files['name']) && is_array($files['name'])) {
            $file_count = count($files['name']);
            
            for ($i = 0; $i < $file_count; $i++) {
                $file = [
                    'name' => $files['name'][$i],
                    'type' => $files['type'][$i],
                    'tmp_name' => $files['tmp_name'][$i],
                    'error' => $files['error'][$i],
                    'size' => $files['size'][$i]
                ];
                
                $result = self::file($file, $folder, $allowed_types, $max_size);
                
                if ($result['success']) {
                    $uploaded_files[] = $result;
                } else {
                    $errors[] = $result['message'];
                }
            }
        }
        
        return [
            'success' => count($uploaded_files) > 0,
            'uploaded' => $uploaded_files,
            'errors' => $errors,
            'total' => count($uploaded_files)
        ];
    }
    
    /**
     * Upload item images
     */
    public static function itemImages($files, $item_id) {
        $result = self::multiple($files, 'items');
        
        if ($result['success']) {
            $db = Database::getInstance();
            
            foreach ($result['uploaded'] as $index => $file) {
                $sql = "INSERT INTO item_images (item_id, image_path, display_order) 
                        VALUES (?, ?, ?)";
                $db->execute($sql, [$item_id, $file['path'], $index]);
            }
        }
        
        return $result;
    }
    
    /**
     * Upload profile picture
     */
    public static function profilePicture($file, $user_id) {
        $result = self::image($file, 'profiles', 2097152); // 2MB max
        
        if ($result['success']) {
            // Delete old profile picture
            self::deleteOldProfilePicture($user_id);
        }
        
        return $result;
    }
    
    /**
     * Upload vendor documents
     */
    public static function vendorDocument($file, $vendor_id, $document_type) {
        $folder = 'documents/vendors/' . $vendor_id;
        $result = self::document($file, $folder, 5242880); // 5MB max
        
        if ($result['success']) {
            $db = Database::getInstance();
            
            // Update vendor document path
            if ($document_type === 'business') {
                $sql = "UPDATE vendors SET business_document = ? WHERE id = ?";
            } else {
                $sql = "UPDATE vendors SET id_document = ? WHERE id = ?";
            }
            
            $db->execute($sql, [$result['path'], $vendor_id]);
        }
        
        return $result;
    }
    
    /**
     * Delete file
     */
    public static function delete($file_path) {
        $full_path = UPLOAD_PATH . '/' . ltrim($file_path, '/');
        
        if (file_exists($full_path)) {
            if (unlink($full_path)) {
                log_message("File deleted: {$file_path}", 'info');
                return true;
            }
        }
        
        log_message("File deletion failed: {$file_path}", 'error');
        return false;
    }

    /**
     * Delete file (alias for delete method)
     */
    public static function deleteFile($file_path) {
        return self::delete($file_path);
    }
    
    /**
     * Delete multiple files
     */
    public static function deleteMultiple($file_paths) {
        $deleted = 0;
        
        foreach ($file_paths as $path) {
            if (self::delete($path)) {
                $deleted++;
            }
        }
        
        return $deleted;
    }
    
    /**
     * Delete old profile picture
     */
    private static function deleteOldProfilePicture($user_id) {
        $db = Database::getInstance();
        
        // Check user type and get old picture
        $user_sql = "SELECT user_type FROM users WHERE id = ?";
        $user = $db->fetch($user_sql, [$user_id]);
        
        if (!$user) return;
        
        if ($user['user_type'] === 'vendor') {
            $sql = "SELECT logo FROM vendors WHERE user_id = ?";
            $profile = $db->fetch($sql, [$user_id]);
            
            if ($profile && $profile['logo']) {
                self::delete($profile['logo']);
            }
        } elseif ($user['user_type'] === 'customer') {
            $sql = "SELECT profile_picture FROM customers WHERE user_id = ?";
            $profile = $db->fetch($sql, [$user_id]);
            
            if ($profile && $profile['profile_picture']) {
                self::delete($profile['profile_picture']);
            }
        }
    }
    
    /**
     * Get file extension from filename
     */
    public static function getExtension($filename) {
        return strtolower(pathinfo($filename, PATHINFO_EXTENSION));
    }
    
    /**
     * Get file size in human readable format
     */
    public static function getFileSize($file_path) {
        $full_path = UPLOAD_PATH . '/' . ltrim($file_path, '/');
        
        if (!file_exists($full_path)) {
            return 'N/A';
        }
        
        return format_filesize(filesize($full_path));
    }
    
    /**
     * Check if file exists
     */
    public static function exists($file_path) {
        $full_path = UPLOAD_PATH . '/' . ltrim($file_path, '/');
        return file_exists($full_path);
    }
    
    /**
     * Create thumbnail
     */
    public static function createThumbnail($file_path, $width = 300, $height = 300) {
        $full_path = UPLOAD_PATH . '/' . ltrim($file_path, '/');
        
        if (!file_exists($full_path)) {
            return false;
        }
        
        $info = getimagesize($full_path);
        if (!$info) return false;
        
        list($orig_width, $orig_height, $type) = $info;
        
        // Create image resource
        switch ($type) {
            case IMAGETYPE_JPEG:
                $source = imagecreatefromjpeg($full_path);
                break;
            case IMAGETYPE_PNG:
                $source = imagecreatefrompng($full_path);
                break;
            case IMAGETYPE_GIF:
                $source = imagecreatefromgif($full_path);
                break;
            case IMAGETYPE_WEBP:
                $source = imagecreatefromwebp($full_path);
                break;
            default:
                return false;
        }
        
        // Calculate thumbnail dimensions
        $ratio = min($width / $orig_width, $height / $orig_height);
        $thumb_width = $orig_width * $ratio;
        $thumb_height = $orig_height * $ratio;
        
        // Create thumbnail
        $thumbnail = imagecreatetruecolor($thumb_width, $thumb_height);
        
        // Preserve transparency
        if ($type == IMAGETYPE_PNG || $type == IMAGETYPE_GIF || $type == IMAGETYPE_WEBP) {
            imagealphablending($thumbnail, false);
            imagesavealpha($thumbnail, true);
            $transparent = imagecolorallocatealpha($thumbnail, 255, 255, 255, 127);
            imagefilledrectangle($thumbnail, 0, 0, $thumb_width, $thumb_height, $transparent);
        }
        
        imagecopyresampled($thumbnail, $source, 0, 0, 0, 0, $thumb_width, $thumb_height, $orig_width, $orig_height);
        
        // Save thumbnail
        $path_info = pathinfo($full_path);
        $thumb_path = $path_info['dirname'] . '/thumb_' . $path_info['basename'];
        
        switch ($type) {
            case IMAGETYPE_JPEG:
                imagejpeg($thumbnail, $thumb_path, 85);
                break;
            case IMAGETYPE_PNG:
                imagepng($thumbnail, $thumb_path, 8);
                break;
            case IMAGETYPE_GIF:
                imagegif($thumbnail, $thumb_path);
                break;
            case IMAGETYPE_WEBP:
                imagewebp($thumbnail, $thumb_path, 85);
                break;
        }
        
        imagedestroy($source);
        imagedestroy($thumbnail);
        
        // Return relative path
        return str_replace(UPLOAD_PATH . '/', '', $thumb_path);
    }
}