<?php

namespace App\Domain\Manga\Infrastructure\Service;

use App\Domain\Manga\Domain\Contract\Service\ImageProcessorInterface;
use Intervention\Image\Drivers\Gd\Driver;
use Intervention\Image\ImageManager;
use GuzzleHttp\Client;
use Ramsey\Uuid\Uuid;
use Symfony\Component\HttpFoundation\File\Exception\FileException;

class ImageProcessor implements ImageProcessorInterface
{
    private const string BASE_PATH = '/images';
    private const string FULL_IMAGES_DIR = self::BASE_PATH . '/full';
    private const string THUMBNAILS_DIR = self::BASE_PATH . '/thumbnails';
    private const int THUMBNAIL_WIDTH = 300;
    private const int THUMBNAIL_HEIGHT = 440;
    private const int FULL_IMAGE_QUALITY = 90;
    private const int THUMBNAIL_QUALITY = 85;

    private ImageManager $imageManager;

    public function __construct(
        private readonly string $publicDir,
        private readonly Client $httpClient
    ) {
        $this->imageManager = new ImageManager(new Driver());
        $this->ensureDirectoriesExist();
    }

    public function downloadImage(string $imageUrl): string
    {
        try {
            $response = $this->httpClient->get($imageUrl);

            if ($response->getStatusCode() !== 200) {
                throw new \RuntimeException('Échec du téléchargement de l\'image');
            }

            $uuid = Uuid::uuid4()->toString();
            $extension = pathinfo($imageUrl, PATHINFO_EXTENSION) ?: 'jpg';
            $filename = sprintf('%s.%s', $uuid, $extension);
            $fullPath = $this->publicDir . self::FULL_IMAGES_DIR . '/' . $filename;

            $image = $this->imageManager->read($response->getBody()->getContents());
            $image->save($fullPath, quality: self::FULL_IMAGE_QUALITY);

            return self::FULL_IMAGES_DIR . '/' . $filename;
        } catch (\Exception $e) {
            throw new \RuntimeException('Erreur lors du téléchargement de l\'image : ' . $e->getMessage());
        }
    }

    public function createThumbnail(string $originalImagePath): string
    {
        try {
            $fullPath = $this->publicDir . $originalImagePath;
            if (!file_exists($fullPath)) {
                throw new \RuntimeException('Image originale non trouvée');
            }

            $filename = pathinfo($originalImagePath, PATHINFO_BASENAME);
            $thumbnailPath = $this->publicDir . self::THUMBNAILS_DIR . '/' . $filename;

            $thumbnail = $this->imageManager->read($fullPath);
            $thumbnail->cover(self::THUMBNAIL_WIDTH, self::THUMBNAIL_HEIGHT);
            $thumbnail->save($thumbnailPath, quality: self::THUMBNAIL_QUALITY);

            return self::THUMBNAILS_DIR . '/' . $filename;
        } catch (\Exception $e) {
            throw new \RuntimeException('Erreur lors de la création de la miniature : ' . $e->getMessage());
        }
    }

    private function ensureDirectoriesExist(): void
    {
        $directories = [
            $this->publicDir . self::FULL_IMAGES_DIR,
            $this->publicDir . self::THUMBNAILS_DIR,
        ];

        foreach ($directories as $directory) {
            if (!is_dir($directory)) {
                if (!mkdir($directory, 0755, true) && !is_dir($directory)) {
                    throw new \RuntimeException(sprintf('Le répertoire "%s" n\'a pas pu être créé', $directory));
                }
            }
        }
    }
}
