<?php

namespace App\Support;

use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;

class ImageOptimizer
{
    private const PRESETS = [
        'cover'      => ['w' => 600,  'h' => 900,  'quality' => 92],
        'banner'     => ['w' => 1920, 'h' => 1080, 'quality' => 90],
        'thumbnail'  => ['w' => 854,  'h' => 480,  'quality' => 88],
        'site_banner'=> ['w' => 1920, 'h' => 600,  'quality' => 90],
        'avatar'     => ['w' => 400,  'h' => 400,  'quality' => 92],
        'default'    => ['w' => 1920, 'h' => 1920, 'quality' => 92],
    ];

    public static function store(UploadedFile $file, string $folder, string $preset = 'default'): string
    {
        if (!extension_loaded('gd')) {
            return $file->store($folder, 'public');
        }

        try {
            $cfg  = self::PRESETS[$preset] ?? self::PRESETS['default'];
            $path = $file->getRealPath();
            $mime = mime_content_type($path);

            $src = match (true) {
                str_contains($mime, 'jpeg'), str_contains($mime, 'jpg') => @imagecreatefromjpeg($path),
                str_contains($mime, 'png')  => @imagecreatefrompng($path),
                str_contains($mime, 'webp') => @imagecreatefromwebp($path),
                str_contains($mime, 'gif')  => @imagecreatefromgif($path),
                default                     => false,
            };

            if (!$src) {
                return $file->store($folder, 'public');
            }

            [$origW, $origH] = [imagesx($src), imagesy($src)];

            // Scale down only — never upscale
            $ratio   = min(1.0, $cfg['w'] / $origW, $cfg['h'] / $origH);
            $newW    = (int) round($origW * $ratio);
            $newH    = (int) round($origH * $ratio);

            $dst = imagecreatetruecolor($newW, $newH);

            // Preserve transparency for PNG
            if (str_contains($mime, 'png')) {
                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);

            // Output as WebP if supported, else JPEG
            $ext      = function_exists('imagewebp') ? 'webp' : 'jpg';
            $filename = $folder . '/' . Str::uuid() . '.' . $ext;

            ob_start();
            if ($ext === 'webp') {
                imagewebp($dst, null, $cfg['quality']);
            } else {
                imagejpeg($dst, null, $cfg['quality']);
            }
            $bytes = ob_get_clean();
            imagedestroy($dst);

            Storage::disk('public')->put($filename, $bytes);

            return $filename;
        } catch (\Throwable) {
            return $file->store($folder, 'public');
        }
    }

    public static function delete(?string $path): void
    {
        if ($path && !MediaUrl::isExternal($path)) {
            Storage::disk('public')->delete($path);
        }
    }
}
