<?php
namespace App\Services;

class ImageService {
    
    private string $uploadDir;
    private int $maxWidth;
    private int $maxHeight;
    private int $quality;

    public function __construct(string $subDir = 'products', int $maxWidth = 1200, int $maxHeight = 1200, int $quality = 80) {
        $this->uploadDir = __DIR__ . '/../../public/uploads/' . $subDir . '/';
        $this->maxWidth = $maxWidth;
        $this->maxHeight = $maxHeight;
        $this->quality = $quality;
        
        if (!is_dir($this->uploadDir)) {
            mkdir($this->uploadDir, 0777, true);
        }
    }

    /**
     * Handle multiple file uploads from $_FILES array
     */
    public function uploadMultiple(array $fileArray): array {
        $savedImages = [];
        
        if (!isset($fileArray['name']) || !is_array($fileArray['name'])) {
            return $savedImages;
        }

        $count = count($fileArray['name']);
        for ($i = 0; $i < $count; $i++) {
            if ($fileArray['error'][$i] === UPLOAD_ERR_OK) {
                $tmpName = $fileArray['tmp_name'][$i];
                $originalName = $fileArray['name'][$i];
                
                $result = $this->processAndSaveWebp($tmpName, $originalName);
                if ($result) {
                    $savedImages[$originalName] = $result;
                }
            }
        }
        
        return $savedImages;
    }

    /**
     * Fetch images from a list of URLs
     */
    public function fetchFromUrls(string $urlText): array {
        $savedImages = [];
        $urls = explode("\n", str_replace("\r", "", $urlText));
        
        foreach ($urls as $url) {
            $url = trim($url);
            if (empty($url) || !filter_var($url, FILTER_VALIDATE_URL)) {
                continue;
            }

            $tmpFile = tempnam(sys_get_temp_dir(), 'img_');
            
            // Set a user agent to avoid being blocked by some servers
            $options = [
                'http' => [
                    'method' => 'GET',
                    'header' => "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36\r\n"
                ]
            ];
            $context = stream_context_create($options);
            $imageContent = @file_get_contents($url, false, $context);
            
            if ($imageContent !== false) {
                file_put_contents($tmpFile, $imageContent);
                $originalName = basename(parse_url($url, PHP_URL_PATH));
                if (empty($originalName) || strpos($originalName, '.') === false) {
                    $originalName = 'downloaded_image.jpg';
                }
                
                $result = $this->processAndSaveWebp($tmpFile, $originalName);
                if ($result) {
                    $savedImages[] = $result;
                }
            }
            @unlink($tmpFile);
        }
        
        return $savedImages;
    }

    private function processAndSaveWebp(string $sourcePath, string $originalName): ?string {
        $info = @getimagesize($sourcePath);
        if (!$info) {
            return null;
        }

        $mime = $info['mime'];
        $width = $info[0];
        $height = $info[1];

        if (!extension_loaded('gd') || !function_exists('imagecreatefromjpeg')) {
            // Fallback: Just copy the file if GD is not available
            $ext = pathinfo($originalName, PATHINFO_EXTENSION);
            if (empty($ext)) {
                $ext = 'jpg';
            }
            $filenameWithoutExt = pathinfo($originalName, PATHINFO_FILENAME);
            $cleanName = preg_replace('/[^a-z0-9]+/', '-', strtolower($filenameWithoutExt));
            $cleanName = trim($cleanName, '-');
            if (empty($cleanName)) $cleanName = 'image';
            
            $uniqueName = $cleanName . '-' . uniqid() . '.' . strtolower($ext);
            $destinationPath = $this->uploadDir . $uniqueName;
            
            if (copy($sourcePath, $destinationPath)) {
                $subDir = basename(dirname($destinationPath));
                return '/uploads/' . $subDir . '/' . $uniqueName;
            }
            return null;
        }

        switch ($mime) {
            case 'image/jpeg':
                $image = @imagecreatefromjpeg($sourcePath);
                break;
            case 'image/png':
                $image = @imagecreatefrompng($sourcePath);
                break;
            case 'image/gif':
                $image = @imagecreatefromgif($sourcePath);
                break;
            case 'image/webp':
                $image = @imagecreatefromwebp($sourcePath);
                break;
            default:
                return null;
        }

        if (!$image) {
            return null;
        }

        $newWidth = $width;
        $newHeight = $height;
        if ($width > $this->maxWidth || $height > $this->maxHeight) {
            $ratio = min($this->maxWidth / $width, $this->maxHeight / $height);
            $newWidth = (int)($width * $ratio);
            $newHeight = (int)($height * $ratio);
        }

        $newImage = imagecreatetruecolor($newWidth, $newHeight);

        if ($mime === 'image/png' || $mime === 'image/gif' || $mime === 'image/webp') {
            imagealphablending($newImage, false);
            imagesavealpha($newImage, true);
            $transparent = imagecolorallocatealpha($newImage, 255, 255, 255, 127);
            imagefilledrectangle($newImage, 0, 0, $newWidth, $newHeight, $transparent);
        }

        imagecopyresampled($newImage, $image, 0, 0, 0, 0, $newWidth, $newHeight, $width, $height);

        $filenameWithoutExt = pathinfo($originalName, PATHINFO_FILENAME);
        $cleanName = preg_replace('/[^a-z0-9]+/', '-', strtolower($filenameWithoutExt));
        $cleanName = trim($cleanName, '-');
        if (empty($cleanName)) $cleanName = 'image';
        
        $uniqueName = $cleanName . '-' . uniqid() . '.webp';
        $destinationPath = $this->uploadDir . $uniqueName;

        $success = imagewebp($newImage, $destinationPath, $this->quality);

        imagedestroy($image);
        imagedestroy($newImage);

        if ($success) {
            $subDir = basename(dirname($destinationPath));
            return '/uploads/' . $subDir . '/' . $uniqueName;
        }

        return null;
    }
}
