<?php
// app/Core/Upload.php - SMOOTH BLUR BACKGROUND (No Pixelation)

class Upload {
    
    // Image processing configuration
    const TARGET_SIZE = 1000;
    const QUALITY_JPEG = 85;
    const QUALITY_PNG = 8;
    const QUALITY_WEBP = 85;
    const MAX_WIDTH = 1920;
    
    /**
     * Upload single file
     */
    public static function file($file, $folder = 'general', $allowed_types = null, $max_size = null) {
        $allowed_types = $allowed_types ?: ALLOWED_IMAGE_TYPES;
        $validation = Security::validateFile($file, $allowed_types, $max_size);
        
        if (!$validation['success']) {
            return ['success' => false, 'message' => $validation['message']];
        }
        
        $upload_dir = UPLOAD_PATH . '/' . $folder;
        if (!is_dir($upload_dir)) {
            mkdir($upload_dir, 0755, true);
        }
        
        // Generate filename with date prefix: YYMMDDHHMMSS_hash.ext
        $date_prefix = date('ymdHis'); // 260203162013
        $hash = md5(uniqid(mt_rand(), true));
        $extension = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION));
        $filename = $date_prefix . '_' . $hash . '.' . $extension;
        
        $destination = $upload_dir . '/' . $filename;
        
        if (move_uploaded_file($file['tmp_name'], $destination)) {
            $relative_path = $folder . '/' . $filename;
            error_log("File uploaded successfully: {$relative_path}");
            
            return [
                'success' => true,
                'filename' => $filename,
                'path' => $relative_path,
                'full_path' => $destination
            ];
        }
        
        error_log("File upload failed: " . $file['name'] . " - move_uploaded_file returned false");
        error_log("Source: " . $file['tmp_name'] . " -> Destination: " . $destination);
        error_log("Upload directory writable: " . (is_writable($upload_dir) ? 'YES' : 'NO'));
        
        return ['success' => false, 'message' => 'Failed to upload file. Check directory permissions.'];
    }
    
    /**
     * Upload image with blur background square processing
     */
    public static function image($file, $folder = 'images', $max_size = null, $make_square = true) {
        $allowed_types = explode(',', ALLOWED_IMAGE_TYPES);
        $result = self::file($file, $folder, implode(',', $allowed_types), $max_size);
        
        if ($result['success']) {
            if ($make_square) {
                self::smoothBlurSquare($result['full_path']);
            } else {
                self::compressImage($result['full_path']);
            }
        }
        
        return $result;
    }

    /**
     * Upload image (alias)
     */
    public static function uploadImage($file, $folder = 'images', $max_size = null) {
        return self::image($file, $folder, $max_size, true);
    }
    
    /**
     * SMOOTH BLUR BACKGROUND - NO PIXELATION
     * Uses moderate downscale (500px) to avoid artifacts
     */
    private static function smoothBlurSquare($file_path) {
        $start_time = microtime(true);
        
        $image_info = getimagesize($file_path);
        if (!$image_info) return false;
        
        list($width, $height, $type) = $image_info;
        
        $source = self::createImageResource($file_path, $type);
        if (!$source) return false;
        
        $target = self::TARGET_SIZE;
        
        // Check if already square (within 5%)
        $ratio = $width / $height;
        $ratio_diff = abs(1 - $ratio);
        
        if ($ratio_diff <= 0.05) {
            // Nearly square - just resize
            $new_image = imagecreatetruecolor($target, $target);
            self::preserveTransparency($new_image, $type);
            imagecopyresampled($new_image, $source, 0, 0, 0, 0, $target, $target, $width, $height);
            self::saveImage($new_image, $file_path, $type);
            imagedestroy($new_image);
            imagedestroy($source);
            
            $processing_time = round((microtime(true) - $start_time) * 1000, 2);
            error_log("Image: {$width}x{$height} → Simple Resize in {$processing_time}ms");
            return true;
        }
        
        // Step 1: Resize main image to fit within 1000px
        if ($width > $height) {
            $new_width = $target;
            $new_height = intval(($height / $width) * $target);
        } else {
            $new_height = $target;
            $new_width = intval(($width / $height) * $target);
        }
        
        // Create sharp main image
        $resized = imagecreatetruecolor($new_width, $new_height);
        self::preserveTransparency($resized, $type);
        imagecopyresampled($resized, $source, 0, 0, 0, 0, $new_width, $new_height, $width, $height);
        
        // Step 2: Create blurred background at HALF resolution (500px)
        // This avoids pixelation while still being fast
        $blur_size = 500; // Half size = 4x faster, but smooth
        $medium_blur = imagecreatetruecolor($blur_size, $blur_size);
        
        // Downscale source to medium size
        imagecopyresampled($medium_blur, $source, 0, 0, 0, 0, $blur_size, $blur_size, $width, $height);
        
        // Apply strong blur on medium image
        for ($i = 0; $i < 25; $i++) {
            imagefilter($medium_blur, IMG_FILTER_GAUSSIAN_BLUR);
        }
        
        // Darken for better contrast
        imagefilter($medium_blur, IMG_FILTER_BRIGHTNESS, -35);
        
        // Step 3: Scale blurred image to full 1000x1000
        $blur_bg = imagecreatetruecolor($target, $target);
        imagecopyresampled($blur_bg, $medium_blur, 0, 0, 0, 0, $target, $target, $blur_size, $blur_size);
        
        imagedestroy($medium_blur);
        
        // Apply final light blur to ensure smoothness (CRITICAL!)
        for ($i = 0; $i < 5; $i++) {
            imagefilter($blur_bg, IMG_FILTER_GAUSSIAN_BLUR);
        }
        
        // Step 4: Center the sharp image on blurred background
        $offset_x = intval(($target - $new_width) / 2);
        $offset_y = intval(($target - $new_height) / 2);
        
        imagecopy($blur_bg, $resized, $offset_x, $offset_y, 0, 0, $new_width, $new_height);
        
        // Save final image
        self::saveImage($blur_bg, $file_path, $type);
        
        // Clean up
        imagedestroy($source);
        imagedestroy($resized);
        imagedestroy($blur_bg);
        
        $processing_time = round((microtime(true) - $start_time) * 1000, 2);
        error_log("Image: {$width}x{$height} → Smooth Blur in {$processing_time}ms");
        
        return true;
    }
    
    /**
     * Create image resource
     */
    private static function createImageResource($file_path, $type) {
        switch ($type) {
            case IMAGETYPE_JPEG:
                return imagecreatefromjpeg($file_path);
            case IMAGETYPE_PNG:
                return imagecreatefrompng($file_path);
            case IMAGETYPE_GIF:
                return imagecreatefromgif($file_path);
            case IMAGETYPE_WEBP:
                return imagecreatefromwebp($file_path);
            default:
                return false;
        }
    }
    
    /**
     * Preserve transparency
     */
    private static function preserveTransparency($image, $type) {
        if ($type == IMAGETYPE_PNG || $type == IMAGETYPE_GIF || $type == IMAGETYPE_WEBP) {
            imagealphablending($image, false);
            imagesavealpha($image, true);
            $transparent = imagecolorallocatealpha($image, 255, 255, 255, 127);
            imagefilledrectangle($image, 0, 0, imagesx($image), imagesy($image), $transparent);
        }
    }
    
    /**
     * Save image with optimal compression
     */
    private static function saveImage($image, $file_path, $type) {
        switch ($type) {
            case IMAGETYPE_JPEG:
                imagejpeg($image, $file_path, self::QUALITY_JPEG);
                break;
            case IMAGETYPE_PNG:
                imagepng($image, $file_path, self::QUALITY_PNG);
                break;
            case IMAGETYPE_GIF:
                imagegif($image, $file_path);
                break;
            case IMAGETYPE_WEBP:
                imagewebp($image, $file_path, self::QUALITY_WEBP);
                break;
        }
    }
    
    /**
     * Compress image (for non-square images like profiles)
     */
    private static function compressImage($file_path, $max_width = 1920, $quality = 85) {
        $image_info = getimagesize($file_path);
        if (!$image_info) return false;
        
        list($width, $height, $type) = $image_info;
        
        $source = self::createImageResource($file_path, $type);
        if (!$source) return false;
        
        if ($width > $max_width) {
            $new_width = $max_width;
            $new_height = floor($height * ($max_width / $width));
        } else {
            $new_width = $width;
            $new_height = $height;
        }
        
        $new_image = imagecreatetruecolor($new_width, $new_height);
        self::preserveTransparency($new_image, $type);
        imagecopyresampled($new_image, $source, 0, 0, 0, 0, $new_width, $new_height, $width, $height);
        
        self::saveImage($new_image, $file_path, $type);
        
        imagedestroy($source);
        imagedestroy($new_image);
        
        return true;
    }
    
    /**
     * Upload document
     */
    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 = [];
        
        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 with blur background
     */
    public static function itemImages($files, $item_id) {
        $uploaded_files = [];
        $errors = [];
        
        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::image($file, 'items', null, true);
                
                if ($result['success']) {
                    $uploaded_files[] = $result;
                    
                    $db = Database::getInstance();
                    $sql = "INSERT INTO item_images (item_id, image_path, display_order) 
                            VALUES (?, ?, ?)";
                    $db->execute($sql, [$item_id, $result['path'], $i]);
                } else {
                    $errors[] = $result['message'];
                }
            }
        }
        
        return [
            'success' => count($uploaded_files) > 0,
            'uploaded' => $uploaded_files,
            'errors' => $errors,
            'total' => count($uploaded_files)
        ];
    }
    
    /**
     * Upload profile picture (no square processing)
     */
    public static function profilePicture($file, $user_id) {
        $result = self::image($file, 'profiles', 2097152, false);
        
        if ($result['success']) {
            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);
        
        if ($result['success']) {
            $db = Database::getInstance();
            
            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;
    }

    public static function deleteFile($file_path) {
        return self::delete($file_path);
    }
    
    public static function deleteMultiple($file_paths) {
        $deleted = 0;
        foreach ($file_paths as $path) {
            if (self::delete($path)) $deleted++;
        }
        return $deleted;
    }
    
    private static function deleteOldProfilePicture($user_id) {
        $db = Database::getInstance();
        $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']);
        }
    }
    
    public static function getExtension($filename) {
        return strtolower(pathinfo($filename, PATHINFO_EXTENSION));
    }
    
    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));
    }
    
    public static function exists($file_path) {
        $full_path = UPLOAD_PATH . '/' . ltrim($file_path, '/');
        return file_exists($full_path);
    }
    
    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;
        
        $source = self::createImageResource($full_path, $type);
        if (!$source) return false;
        
        $ratio = min($width / $orig_width, $height / $orig_height);
        $thumb_width = $orig_width * $ratio;
        $thumb_height = $orig_height * $ratio;
        
        $thumbnail = imagecreatetruecolor($thumb_width, $thumb_height);
        self::preserveTransparency($thumbnail, $type);
        imagecopyresampled($thumbnail, $source, 0, 0, 0, 0, $thumb_width, $thumb_height, $orig_width, $orig_height);
        
        $path_info = pathinfo($full_path);
        $thumb_path = $path_info['dirname'] . '/thumb_' . $path_info['basename'];
        
        self::saveImage($thumbnail, $thumb_path, $type);
        
        imagedestroy($source);
        imagedestroy($thumbnail);
        
        return str_replace(UPLOAD_PATH . '/', '', $thumb_path);
    }
}