<?php

namespace App\Services;

use Illuminate\Support\Facades\Storage;

class UploadedImageOptimizer
{
    public const MAX_DIMENSION = 2560;

    public const JPEG_QUALITY = 85;

    public const WEBP_QUALITY = 82;

    /**
     * Redimensionne et recompresse une image déjà stockée sur le disque (même extension).
     */
    public function optimizeStoredFile(string $path, string $disk = 'public'): void
    {
        if (! Storage::disk($disk)->exists($path)) {
            return;
        }

        $fullPath = Storage::disk($disk)->path($path);
        $info = @getimagesize($fullPath);
        if ($info === false) {
            return;
        }

        [$width, $height, $type] = $info;
        if ($width < 1 || $height < 1) {
            return;
        }

        if ($type === IMAGETYPE_GIF) {
            return;
        }

        $src = $this->createImageResource($fullPath, $type);
        if ($src === null) {
            return;
        }

        $targetW = $width;
        $targetH = $height;
        if ($width > self::MAX_DIMENSION || $height > self::MAX_DIMENSION) {
            if ($width >= $height) {
                $targetW = self::MAX_DIMENSION;
                $targetH = (int) round($height * (self::MAX_DIMENSION / $width));
            } else {
                $targetH = self::MAX_DIMENSION;
                $targetW = (int) round($width * (self::MAX_DIMENSION / $height));
            }
        }

        $work = $src;
        if ($targetW !== $width || $targetH !== $height) {
            $resized = imagecreatetruecolor($targetW, $targetH);
            if ($resized === false) {
                imagedestroy($src);

                return;
            }
            imagealphablending($resized, false);
            imagesavealpha($resized, true);
            $transparent = imagecolorallocatealpha($resized, 0, 0, 0, 127);
            imagefilledrectangle($resized, 0, 0, $targetW, $targetH, $transparent);
            imagealphablending($resized, true);
            imagecopyresampled($resized, $src, 0, 0, 0, 0, $targetW, $targetH, $width, $height);
            imagedestroy($src);
            $work = $resized;
        }

        $ext = strtolower(pathinfo($fullPath, PATHINFO_EXTENSION) ?: '');

        if ($ext === 'png' || $type === IMAGETYPE_PNG) {
            imagesavealpha($work, true);
            imagepng($work, $fullPath, 6);
        } elseif ($ext === 'webp' && function_exists('imagewebp')) {
            imagewebp($work, $fullPath, self::WEBP_QUALITY);
        } elseif (in_array($ext, ['jpg', 'jpeg', 'jpe'], true) || $type === IMAGETYPE_JPEG) {
            imagejpeg($work, $fullPath, self::JPEG_QUALITY);
        }

        imagedestroy($work);
        clearstatcache(true, $fullPath);
    }

    private function createImageResource(string $fullPath, int $type): ?\GdImage
    {
        return match ($type) {
            IMAGETYPE_JPEG => @imagecreatefromjpeg($fullPath) ?: null,
            IMAGETYPE_PNG => @imagecreatefrompng($fullPath) ?: null,
            IMAGETYPE_WEBP => (function_exists('imagecreatefromwebp') ? @imagecreatefromwebp($fullPath) : null) ?: null,
            default => null,
        };
    }
}
