<?php

declare(strict_types=1);

namespace App\Domain\Manga\Infrastructure\Service;

use App\Domain\Manga\Domain\Contract\Service\FilenameAnalyzerInterface;
use App\Domain\Manga\Domain\Model\AnalyzedFilename;
use App\Domain\Manga\Domain\Model\ValueObject\ChapterNumber;
use App\Domain\Manga\Domain\Model\ValueObject\MangaTitle;
use App\Domain\Manga\Domain\Model\ValueObject\VolumeNumber;

readonly class FilenameAnalyzer implements FilenameAnalyzerInterface
{
    public function analyze(string $filename): AnalyzedFilename
    {
        // Enlever l'extension
        $nameWithoutExtension = preg_replace('/\.(cbz|cbr)$/i', '', $filename);

        // Extraire les informations en utilisant la logique du CbzService
        $titleStr = $this->extractTitle($nameWithoutExtension);
        $volumeNumber = $this->extractVolume($nameWithoutExtension);
        $chapterNumber = $this->extractChapter($nameWithoutExtension);

        $cleanedTitle = $this->cleanTitle($titleStr);

        return new AnalyzedFilename(
            title: new MangaTitle($cleanedTitle),
            chapterNumber: $chapterNumber !== null ? new ChapterNumber($chapterNumber) : null,
            volumeNumber: $volumeNumber !== null ? new VolumeNumber((float) $volumeNumber) : null
        );
    }

    private function extractTitle(string $fileName): string
    {
        // Pattern avec tirets complets : titre-volume-42-chapter-100 ou titre-chapitre-100-volume-42
        $fullDashCombinedPattern = '/^(?P<title>.*?)-(?:volume|chapter|chapitre)-\d+-(?:volume|chapter|chapitre)-\d+/i';
        if (preg_match($fullDashCombinedPattern, $fileName, $matches)) {
            return trim($matches['title']);
        }

        // Pattern avec tirets complets : titre-volume-42 ou titre-chapter-100 ou titre-chapitre-100
        $fullDashPattern = '/^(?P<title>.*?)-(?:volume|chapter|chapitre)-\d+/i';
        if (preg_match($fullDashPattern, $fileName, $matches)) {
            return trim($matches['title']);
        }

        // Pattern principal : titre suivi de volume/chapitre (inspiré du CbzService)
        // Supporte: vol, volume, tome, t, ch, chap, chapter, chapitre
        $titlePattern = '/^(?P<title>.+?)(?:\s*-\s*|\s+)?(?:(?:[Tt]ome|[Vv]ol(?:ume)?\.?|[Cc]h(?:ap(?:itre|ter)?)?|[Tt])\s*\d+)/';
        if (preg_match($titlePattern, $fileName, $matches)) {
            return trim($matches['title']);
        }

        // Pattern underscore : titre_vol123 ou titre_ch456 ou titre_chapter_1094
        $underscorePattern = '/^(?P<title>.*?)_(?:vol|tome|t|ch|chap|chapter|chapitre)[\s_-]*\d+/i';
        if (preg_match($underscorePattern, $fileName, $matches)) {
            return trim($matches['title']);
        }

        // Pattern avec tiret : titre-vol123 ou titre-ch456 ou titre-tome-50
        $dashPattern = '/^(?P<title>.*?)-(?:vol|tome|t|ch|chap|chapter|chapitre)[\s_-]*\d+/i';
        if (preg_match($dashPattern, $fileName, $matches)) {
            return trim($matches['title']);
        }

        // Pattern underscore simple : titre_123
        $newFormatPattern = '/^(?P<title>.*?)_\d+/';
        if (preg_match($newFormatPattern, $fileName, $matches)) {
            return trim($matches['title']);
        }

        // Si aucun pattern ne matche, retourner le nom sans extension
        return $fileName;
    }

    private function extractVolume(string $fileName): ?int
    {
        // Pattern pour volume : vol123, volume123, tome123, t123, v123
        $volumePattern = '/(?:[Tt]ome|[Vv]ol(?:ume)?\.?|[Tt]|[Vv])[\s\-_]*(?P<volume>\d+)/i';
        if (preg_match($volumePattern, $fileName, $matches)) {
            return (int) $matches['volume'];
        }

        // Pattern avec tirets complets pour volume : volume-42
        $fullDashVolumePattern = '/volume-(?P<volume>\d+)/i';
        if (preg_match($fullDashVolumePattern, $fileName, $matches)) {
            return (int) $matches['volume'];
        }

        return null;
    }

    private function extractChapter(string $fileName): ?float
    {
        // Pattern pour chapitre : ch123, chap123, chapter123, chapitre123
        $chapterPattern = '/[Cc]h(?:ap(?:itre|ter)?)?[\s\-_]*(?P<chapter>\d+(?:\.\d+)?)/i';
        if (preg_match($chapterPattern, $fileName, $matches)) {
            return (float) $matches['chapter'];
        }

        // Pattern avec tirets complets pour chapitre : chapter-100 ou chapitre-100
        $fullDashChapterPattern = '/(?:chapter|chapitre)-(?P<chapter>\d+(?:\.\d+)?)/i';
        if (preg_match($fullDashChapterPattern, $fileName, $matches)) {
            return (float) $matches['chapter'];
        }

        // Pattern underscore à la fin : _123.cbz
        $newFormatPattern = '/_ch(?P<chapter>\d+(?:\.\d+)?)(?:\.\w+)?$/i';
        if (preg_match($newFormatPattern, $fileName, $matches)) {
            return (float) $matches['chapter'];
        }

        return null;
    }

    private function cleanTitle(string $title): string
    {
        // Enlever les patterns communs (avec séparateurs possibles)
        $cleanTitle = preg_replace('/[\s\-_]?(?:scan|raw|fr|en|jp|hq|lq)[\s\-_]?/i', ' ', $title);

        // Enlever les caractères spéciaux en début/fin
        $cleanTitle = trim($cleanTitle, ' -_.');

        // Normaliser les espaces multiples
        $cleanTitle = preg_replace('/\s+/', ' ', $cleanTitle);

        return trim($cleanTitle);
    }
}
