<?php
// app/Helpers/ImageUploader.php
// Handles image upload, resize, and WebP conversion for performance

class ImageUploader {

    // Max thumbnail dimensions
    const THUMB_W = 480;
    const THUMB_H = 360;
    const QUALITY = 82; // WebP quality (0-100). 82 = excellent balance

    /**
     * Process an uploaded product image.
     * - Validates type & size
     * - Resizes to max THUMB_W × THUMB_H (preserving aspect ratio)
     * - Converts to WebP
     * - Saves under public/uploads/products/{restaurant_id}/
     *
     * Returns: relative web path  (e.g. "uploads/products/3/abc123.webp")
     *          or throws RuntimeException on failure.
     */
    public static function saveProductImage(array $file, int $restaurantId): string {
        // ── Validate ───────────────────────────────────────────
        if ($file['error'] !== UPLOAD_ERR_OK) {
            throw new \RuntimeException('Upload error code: ' . $file['error']);
        }

        $maxBytes = 8 * 1024 * 1024; // 8 MB raw upload limit
        if ($file['size'] > $maxBytes) {
            throw new \RuntimeException('Image must be smaller than 8 MB.');
        }

        $mime = mime_content_type($file['tmp_name']);
        $allowed = ['image/jpeg', 'image/png', 'image/gif', 'image/webp', 'image/bmp'];
        if (!in_array($mime, $allowed)) {
            throw new \RuntimeException('Only JPEG, PNG, GIF, or WebP images are allowed.');
        }

        $dir = __DIR__ . '/../../public/uploads/products/' . $restaurantId;
        if (!is_dir($dir)) mkdir($dir, 0755, true);

        // ── GD available → resize + convert to WebP ───────────
        if (function_exists('imagecreatefromjpeg') && function_exists('imagewebp')) {

            $src = match($mime) {
                'image/jpeg' => imagecreatefromjpeg($file['tmp_name']),
                'image/png'  => imagecreatefrompng($file['tmp_name']),
                'image/gif'  => imagecreatefromgif($file['tmp_name']),
                'image/webp' => imagecreatefromwebp($file['tmp_name']),
                'image/bmp'  => function_exists('imagecreatefrombmp') ? imagecreatefrombmp($file['tmp_name']) : false,
                default      => false,
            };

            if (!$src) throw new \RuntimeException('GD could not decode this image.');

            // Resize (never upscale)
            [$origW, $origH] = [imagesx($src), imagesy($src)];
            $ratio = min(self::THUMB_W / $origW, self::THUMB_H / $origH, 1.0);
            $newW  = (int)round($origW * $ratio);
            $newH  = (int)round($origH * $ratio);

            $dst = imagecreatetruecolor($newW, $newH);
            imagealphablending($dst, false);
            imagesavealpha($dst, true);
            $transparent = imagecolorallocatealpha($dst, 0, 0, 0, 127);
            imagefilledrectangle($dst, 0, 0, $newW, $newH, $transparent);
            imagecopyresampled($dst, $src, 0, 0, 0, 0, $newW, $newH, $origW, $origH);
            imagedestroy($src);

            $filename = bin2hex(random_bytes(10)) . '.webp';
            $fullPath = $dir . '/' . $filename;

            if (!imagewebp($dst, $fullPath, self::QUALITY)) {
                imagedestroy($dst);
                throw new \RuntimeException('GD could not write WebP. Check GD was compiled with WebP support.');
            }
            imagedestroy($dst);

        } else {
            // ── Fallback: GD not loaded → store original file ─
            $ext      = match($mime) {
                'image/jpeg' => 'jpg', 'image/png' => 'png',
                'image/gif'  => 'gif', 'image/webp' => 'webp',
                default      => 'jpg',
            };
            $filename = bin2hex(random_bytes(10)) . '.' . $ext;
            $fullPath = $dir . '/' . $filename;

            if (!move_uploaded_file($file['tmp_name'], $fullPath)) {
                throw new \RuntimeException('Could not save image file.');
            }
        }

        return 'uploads/products/' . $restaurantId . '/' . $filename;
    }

    /**
     * Delete an existing product image file safely.
     */
    public static function delete(?string $relPath): void {
        if (!$relPath) return;
        $full = __DIR__ . '/../../public/' . $relPath;
        if (file_exists($full)) @unlink($full);
    }

    /**
     * Return <img> tag for a product image with lazy loading.
     * Falls back to an SVG placeholder if no image.
     */
    public static function img(?string $relPath, string $alt = '', string $class = '', string $style = ''): string {
        if ($relPath) {
            $src = '/public/' . htmlspecialchars($relPath);
            return "<img src=\"{$src}\" alt=\"" . htmlspecialchars($alt) . "\" class=\"{$class}\" style=\"{$style}\" loading=\"lazy\">";
        }
        // SVG placeholder — zero network request
        return '<div class="' . $class . '" style="' . $style . ' display:flex;align-items:center;justify-content:center;background:rgba(255,255,255,0.04);">
                    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1" style="width:40%;height:40%;opacity:0.2;color:#94a3b8">
                        <rect x="3" y="3" width="18" height="18" rx="2"/><circle cx="8.5" cy="8.5" r="1.5"/>
                        <polyline points="21 15 16 10 5 21"/>
                    </svg>
                </div>';
    }

    /**
     * Process an uploaded restaurant logo.
     * - Validates type & size (max 4MB)
     * - Resizes to max 300x300 pixels
     * - Converts to WebP
     * - Saves under public/uploads/logos/
     *
     * Returns: relative web path (e.g. "public/uploads/logos/logo_3_abc123.webp")
     */
    public static function saveLogoImage(array $file, int $restaurantId): string {
        if ($file['error'] !== UPLOAD_ERR_OK) {
            throw new \RuntimeException('Upload error: ' . $file['error']);
        }
        $maxBytes = 4 * 1024 * 1024; // 4MB
        if ($file['size'] > $maxBytes) {
            throw new \RuntimeException('Logo must be smaller than 4 MB.');
        }
        $mime = mime_content_type($file['tmp_name']);
        $allowed = ['image/jpeg', 'image/png', 'image/gif', 'image/webp'];
        if (!in_array($mime, $allowed)) {
            throw new \RuntimeException('Only JPEG, PNG, GIF, or WebP images are allowed.');
        }
        $dir = __DIR__ . '/../../public/uploads/logos';
        if (!is_dir($dir)) mkdir($dir, 0755, true);

        $filename = 'logo_' . $restaurantId . '_' . bin2hex(random_bytes(5)) . '.webp';
        $fullPath = $dir . '/' . $filename;

        if (function_exists('imagecreatefromjpeg') && function_exists('imagewebp')) {
            $src = match($mime) {
                'image/jpeg' => imagecreatefromjpeg($file['tmp_name']),
                'image/png'  => imagecreatefrompng($file['tmp_name']),
                'image/gif'  => imagecreatefromgif($file['tmp_name']),
                'image/webp' => imagecreatefromwebp($file['tmp_name']),
                default      => false,
            };
            if (!$src) throw new \RuntimeException('Could not decode image.');

            [$origW, $origH] = [imagesx($src), imagesy($src)];
            $maxDim = 300;
            $ratio = min($maxDim / $origW, $maxDim / $origH, 1.0);
            $newW = (int)round($origW * $ratio);
            $newH = (int)round($origH * $ratio);

            $dst = imagecreatetruecolor($newW, $newH);
            imagealphablending($dst, false);
            imagesavealpha($dst, true);
            $transparent = imagecolorallocatealpha($dst, 0, 0, 0, 127);
            imagefilledrectangle($dst, 0, 0, $newW, $newH, $transparent);
            imagecopyresampled($dst, $src, 0, 0, 0, 0, $newW, $newH, $origW, $origH);
            imagedestroy($src);

            if (!imagewebp($dst, $fullPath, self::QUALITY)) {
                imagedestroy($dst);
                throw new \RuntimeException('Could not save WebP logo.');
            }
            imagedestroy($dst);
        } else {
            // fallback
            $filename = 'logo_' . $restaurantId . '_' . bin2hex(random_bytes(5)) . '.png';
            $fullPath = $dir . '/' . $filename;
            if (!move_uploaded_file($file['tmp_name'], $fullPath)) {
                throw new \RuntimeException('Could not save logo file.');
            }
        }
        return 'public/uploads/logos/' . $filename;
    }
}
