<?php

declare(strict_types=1);

namespace App\Services;

class GravureService
{
    private const MAX_LENGTH = 120;
    private const FORBIDDEN_CHARS = ['<', '>', '"', '&'];
    private const FORBIDDEN_REPLACEMENTS = ['(', ')', "'", 'et'];

    public function genererTexte(string $typeCommande, array $data): string
    {
        $texte = match ($typeCommande) {
            'medaille_complete' => $this->medailleComplete($data),
            'gravure_seule'     => $this->gravureSeule($data),
            'b2b_vierge'        => $this->b2bVierge($data),
            'test_interne'      => $this->testInterne($data),
            default             => throw new \InvalidArgumentException("Type commande inconnu: {$typeCommande}")
        };

        $texte = $this->sanitize($texte);

        if (mb_strlen($texte) > self::MAX_LENGTH) {
            error_log('[GravureService] Texte trop long (' . mb_strlen($texte) . ' chars): ' . $texte);
        }

        return $texte;
    }

    private function medailleComplete(array $data): string
    {
        $prenom  = strtoupper(trim($data['prenom'] ?? ''));
        $nom     = strtoupper(trim($data['nom'] ?? ''));
        $parcours = strtoupper(trim($data['parcours_nom'] ?? ''));
        $date    = $this->formatDate($data['date_debut'] ?? '');
        $duree   = $this->formatDuree((int)($data['duree'] ?? 0));

        if (!$prenom || !$nom) {
            throw new \Exception('Prénom/nom manquant pour générer le texte de gravure');
        }

        return "{$prenom} {$nom} / {$parcours} / {$date} / {$duree}";
    }

    private function gravureSeule(array $data): string
    {
        $prenom  = strtoupper(trim($data['prenom'] ?? $data['Prénom'] ?? ''));
        $nom     = strtoupper(trim($data['nom'] ?? $data['Nom'] ?? ''));
        $parcours = strtoupper(trim($data['parcours'] ?? $data['Parcours'] ?? ''));
        $date    = $data['date'] ?? $data['Date de l\'exploit'] ?? '';
        $temps   = $data['temps'] ?? $data['Temps réalisé'] ?? '';

        // Normaliser la date
        if ($date && !preg_match('/^\d{2}\.\d{2}\.\d{4}$/', $date)) {
            $ts = strtotime($date);
            $date = $ts ? date('d.m.Y', $ts) : $date;
        }

        // Normaliser le temps (accepte HH:MM:SS ou H'MM"SS)
        if ($temps && !preg_match("/^\d+'\d{2}\"\d{2}$/", $temps)) {
            $temps = $this->normaliserTemps($temps);
        }

        return "{$prenom} {$nom} / {$parcours} / {$date} / {$temps}";
    }

    private function b2bVierge(array $data): string
    {
        $orgNom  = strtoupper(trim($data['b2b_client_nom'] ?? $data['Nom org.'] ?? 'CLIENT B2B'));
        $parcours = strtoupper(trim($data['parcours_nom'] ?? ''));
        return "{$orgNom} / {$parcours}";
    }

    private function testInterne(array $data): string
    {
        $parcours = strtoupper(trim($data['parcours_nom'] ?? 'PARCOURS'));
        $date = date('d.m.Y');
        return "TEST / {$parcours} / {$date}";
    }

    public function formatDuree(int $secondes): string
    {
        if ($secondes <= 0) return '';
        $h  = intdiv($secondes, 3600);
        $m  = intdiv($secondes % 3600, 60);
        $s  = $secondes % 60;

        if ($h > 0) {
            return sprintf("%d'%02d\"%02d", $h, $m, $s);
        }
        return sprintf("%d'%02d", $m, $s);
    }

    public function formatDate(string $datetime): string
    {
        $ts = strtotime($datetime);
        return $ts ? date('d.m.Y', $ts) : $datetime;
    }

    private function normaliserTemps(string $temps): string
    {
        // HH:MM:SS → H'MM"SS
        if (preg_match('/^(\d+):(\d{2}):(\d{2})$/', $temps, $m)) {
            return "{$m[1]}'{$m[2]}\"{$m[3]}";
        }
        return $temps;
    }

    private function sanitize(string $texte): string
    {
        return str_replace(self::FORBIDDEN_CHARS, self::FORBIDDEN_REPLACEMENTS, $texte);
    }

    public function formaterDureeAffichage(int $secondes): string
    {
        $h = intdiv($secondes, 3600);
        $m = intdiv($secondes % 3600, 60);
        $s = $secondes % 60;

        if ($h > 0) {
            return sprintf("%dh %02d'%02d\"", $h, $m, $s);
        }
        return sprintf("%d'%02d\"", $m, $s);
    }
}
