<?php

namespace App\Services;

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

class ImageOptimizer
{
    /**
     * Configuracion por carpeta. Una unica fuente de verdad — usada por el
     * comando optimize:images y por los uploads de los controllers admin.
     */
    public const FOLDERS = [
        'carousel' => ['maxWidth' => 1600, 'quality' => 82],
        'noticias' => ['maxWidth' => 1200, 'quality' => 82],
        'promos'   => ['maxWidth' => 1200, 'quality' => 82],
        'clubes'   => ['maxWidth' => 512,  'quality' => 85],
        'sponsors' => ['maxWidth' => 600,  'quality' => 85],
        'qr'       => ['maxWidth' => 800,  'quality' => 85],
    ];

    private const MIN_RECOMPRESS_BYTES = 100 * 1024;

    /**
     * Sube el archivo al disk 'public' y lo optimiza in-place.
     * Retorna el path relativo (ej: "carousel/abc123.jpg").
     */
    public function storeAndOptimize(UploadedFile $file, string $folder): string
    {
        $path = $file->store($folder, 'public');

        if (!extension_loaded('gd')) {
            return $path;
        }

        $cfg = self::FOLDERS[$folder] ?? null;
        if (!$cfg) {
            return $path;
        }

        $abs = Storage::disk('public')->path($path);
        $this->optimizeFile($abs, $cfg['maxWidth'], $cfg['quality']);

        return $path;
    }

    /**
     * Optimiza un archivo en disco (resize + recompress).
     * Devuelve [origSize, newSize, newW, newH] o null si no se modifico.
     */
    public function optimizeFile(string $file, int $maxWidth, int $quality): ?array
    {
        if (!file_exists($file)) return null;

        $origSize = filesize($file);
        $info = @getimagesize($file);
        if (!$info) return null;

        [$w, $h] = $info;
        $needsResize = $w > $maxWidth;
        $needsRecomp = $origSize > self::MIN_RECOMPRESS_BYTES;
        if (!$needsResize && !$needsRecomp) return null;

        $ext = strtolower(pathinfo($file, PATHINFO_EXTENSION));
        $img = match ($ext) {
            'jpg', 'jpeg' => @imagecreatefromjpeg($file),
            'png'         => @imagecreatefrompng($file),
            'webp'        => @imagecreatefromwebp($file),
            default       => null,
        };
        if (!$img) return null;

        $newW = $w; $newH = $h;
        if ($w > $maxWidth) {
            $newW = $maxWidth;
            $newH = (int) round($h * ($maxWidth / $w));
            $resized = imagecreatetruecolor($newW, $newH);

            if (in_array($ext, ['png', 'webp'])) {
                imagealphablending($resized, false);
                imagesavealpha($resized, true);
                $transparent = imagecolorallocatealpha($resized, 0, 0, 0, 127);
                imagefilledrectangle($resized, 0, 0, $newW, $newH, $transparent);
            }

            imagecopyresampled($resized, $img, 0, 0, 0, 0, $newW, $newH, $w, $h);
            $img = $resized;
        }

        ob_start();
        match ($ext) {
            'jpg', 'jpeg' => imagejpeg($img, null, $quality),
            'png'         => imagepng($img, null, 9),
            'webp'        => imagewebp($img, null, $quality),
        };
        $bytes = ob_get_clean();

        if (strlen($bytes) >= $origSize) {
            return null;
        }

        file_put_contents($file, $bytes);
        return [$origSize, strlen($bytes), $newW, $newH];
    }
}
