<?php

namespace App\Service\Pdf;

use App\Entity\Contrats;
use Endroid\QrCode\Builder\Builder;
use Endroid\QrCode\Encoding\Encoding;
use Endroid\QrCode\ErrorCorrectionLevel;
use Endroid\QrCode\RoundBlockSizeMode;
use Endroid\QrCode\Writer\PngWriter;
use Fpdf\Fpdf;
use Symfony\Component\HttpKernel\KernelInterface;

class EtatLieuxPdfService extends Fpdf
{
    private Contrats $contrats;
    private string $logo;
    private bool $isExtraPage = false;

    public function __construct(KernelInterface $kernel, Contrats $contrats, $orientation = 'P', $unit = 'mm', $size = 'A4')
    {
        parent::__construct($orientation, $unit, $size);
        $this->contrats = $contrats;
        $this->logo = $kernel->getProjectDir()."/public/provider/images/favicon.png";

        $this->AliasNbPages();
        $this->SetAutoPageBreak(true, 35);
    }

    public function generate(): string
    {
        $this->AddPage();
        $this->renderEtatLieuxEntrant();

        $this->renderSignaturePage();

        return $this->Output('S');
    }

    private function renderSignaturePage(): void
    {
        $this->AddPage();

        $this->SetFont('Arial', 'B', 14);
        $this->SetTextColor(37, 99, 235);
        $this->Cell(0, 10, $this->clean("SIGNATURES"), 0, 1, 'C');
        $this->Ln(10);

        $this->SetFont('Arial', '', 10);
        $this->SetTextColor(0, 0, 0);
        if($this->contrats->getEtatLieux()->getStatus() == "edl_return_done"){
            $this->MultiCell(0, 5, $this->clean("En signant ce document, les parties valident l'état de retour ci-dessus."), 0, 'C');
        } else {
            $this->MultiCell(0, 5, $this->clean("En signant ce document, les parties valident l'état des lieux d'installation ci-dessus."), 0, 'C');
        }
        $this->Ln(20);

        // --- SIGNATURES ---
        $ySign = $this->GetY();

        $this->SetFont('Arial', 'B', 10);
        $this->Cell(95, 8, $this->clean("Le Prestataire"), 0, 0, 'C');
        $this->Cell(95, 8, $this->clean("Le Client (Bon pour accord)"), 0, 1, 'C');

        $this->Ln(8);
        $this->Cell(95, 40, "", 1, 0);
        $this->Cell(95, 40, "", 1, 1);

        // DocuSeal tags
        $this->SetXY(20, $ySign + 35);
        $this->SetFont('Arial', '', 8);
        $this->SetTextColor(255, 255, 255);
        $this->Cell(50, 5, '{{Sign;type=signature;role=Ludikevent}}', 0, 0);

        $this->SetXY(115, $ySign + 35);
        $this->Cell(50, 5, '{{Sign;type=signature;role=Client}}', 0, 0);

        $this->SetTextColor(0, 0, 0);
    }

    private function renderEtatLieuxEntrant(): void
    {
        $this->SetY(50);

        // Titre
        $this->SetFont('Arial', 'B', 14);
        $this->SetTextColor(37, 99, 235);
        if($this->contrats->getEtatLieux()->getStatus() == "edl_return_done"){
            $this->Cell(0, 10, $this->clean("ÉTAT DES RETOUR"), 0, 1, 'C');
        } else {
            $this->Cell(0, 10, $this->clean("ÉTAT DES LIEUX D'INSTALLATION (ENTRANT)"), 0, 1, 'C');
        }


        $this->SetFont('Arial', 'B', 10);
        $this->SetTextColor(0, 0, 0);
        $this->Cell(0, 7, $this->clean("Contrat N° " . $this->contrats->getNumReservation()), 0, 1, 'C');
        $this->Ln(5);

        $this->SetFont('Arial', '', 10);
        $this->MultiCell(0, 5, $this->clean("Le locataire reconnaît avoir lue et accepter  l'état des retours."), 0, 'C');
        $this->Ln(5);

        // --- INFO PARTIES (2 BLOCS SÉPARÉS) ---

        // Detect Delivery/Installation
        $hasDelivery = false;
        foreach ($this->contrats->getContratsLines() as $line) {
            if (stripos($line->getName(), 'livraison') !== false || stripos($line->getName(), 'installation') !== false) {
                $hasDelivery = true; break;
            }
        }
        if (!$hasDelivery) {
            foreach ($this->contrats->getContratsOptions() as $opt) {
                if (stripos($opt->getName(), 'livraison') !== false || stripos($opt->getName(), 'installation') !== false) {
                    $hasDelivery = true; break;
                }
            }
        }

        $prestataireTitle = " PRESTATAIRE";
        if ($hasDelivery) {
            $prestataireTitle .= " (Livreur / Installateur)";
        }

        $colWidth = 90;
        $gap = 10;
        $xStart = 10;

        $this->SetFillColor(245, 245, 245);
        $this->SetFont('Arial', 'B', 9);

        // Header Block 1
        $this->Cell($colWidth, 6, $this->clean($prestataireTitle), 1, 0, 'L', true);

        // Header Block 2
        $this->SetX($xStart + $colWidth + $gap);
        $this->Cell($colWidth, 6, $this->clean(" CLIENT / LIEU"), 1, 1, 'L', true);

        $this->SetFont('Arial', '', 8);
        $yContent = $this->GetY();

        // Content Block 1 (Prestataire)
        $this->SetXY($xStart, $yContent);
        $prestataire = $this->contrats->getPrestataire();
        $prestataireTxt = $prestataire ? ($prestataire->getName() . "\n" . $prestataire->getEmail()) : "Ludikevent (Admin)\ncontact@ludikevent.fr";
        $this->MultiCell($colWidth, 5, $this->clean($prestataireTxt), 'LRB', 'L');
        $h1 = $this->GetY() - $yContent;

        // Content Block 2 (Client)
        $this->SetXY($xStart + $colWidth + $gap, $yContent);
        $customer = $this->contrats->getCustomer();
        $clientTxt = $customer->getName() . " " . $customer->getSurname() . "\n" .
                     $customer->getEmail() . "\n" .
                     $customer->getPhone() . "\n" .
                     "Lieu: " . $this->contrats->getAddressEvent() . " " . $this->contrats->getZipCodeEvent() . " " . $this->contrats->getTownEvent();
        $this->MultiCell($colWidth, 5, $this->clean($clientTxt), 'LRB', 'L');
        $h2 = $this->GetY() - $yContent;

        // Reset Y to max height
        $this->SetY($yContent + max($h1, $h2) + 5);

        // --- LISTE DU MATÉRIEL ---
        $this->SetFont('Arial', 'B', 10);
        $this->SetFillColor(240, 240, 240);
        // Header simplifié : Désignation sur toute la largeur (190)
        $this->Cell(190, 8, $this->clean(" DÉSIGNATION DU MATÉRIEL"), 1, 1, 'L', true);

        $this->SetFont('Arial', '', 9);

        foreach ($this->contrats->getContratsLines() as $line) {
            // Skip livraison
            if (stripos($line->getName(), 'livraison') !== false) {
                continue;
            }

            // Affichage simple avec case à cocher
            $this->MultiCell(190, 8, $this->clean($line->getName()), 1, 'L');
        }

        foreach ($this->contrats->getContratsOptions() as $opt) {
             // Skip livraison options if any
            if (stripos($opt->getName(), 'livraison') !== false) {
                continue;
            }

            $this->MultiCell(190, 8, $this->clean("[Option] " . $opt->getName()), 1, 'L');
        }

        $this->Ln(5);

        // --- POINTS DE CONTRÔLE ---
        $etatLieux = $this->contrats->getEtatLieux();
        if ($etatLieux) {
            $this->SetFont('Arial', 'B', 10);
            $this->SetFillColor(240, 240, 240);
            $this->Cell(190, 8, $this->clean(" POINTS DE CONTRÔLE"), 1, 1, 'L', true);
            $this->Ln(3);

            foreach ($this->contrats->getProductReserves() as $reserve) {
                $product = $reserve->getProduct();
                if ($product && count($product->getProductPointControlls()) > 0) {

                    $this->SetFillColor(230, 240, 255);
                    $this->SetFont('Arial', 'B', 9);
                    $this->Cell(190, 6, $this->clean(" " . $product->getName()), 1, 1, 'L', true);

                    $this->SetFillColor(250, 250, 250);
                    $this->SetFont('Arial', 'B', 8);
                    $this->Cell(95, 5, $this->clean(" Nom du contrôle"), 1, 0, 'L', true);
                    $this->Cell(95, 5, $this->clean(" Commentaire / État"), 1, 1, 'L', true);

                    $this->SetFont('Arial', '', 8);
                    foreach ($product->getProductPointControlls() as $pPoint) {
                        $details = '';
                        foreach ($etatLieux->getPointControls() as $ep) {
                            if ($ep->getName() === $pPoint->getName()) {
                                $details = $ep->getDetails();
                                break;
                            }
                        }

                        $y = $this->GetY();
                        $x = $this->GetX();

                        $this->MultiCell(95, 5, $this->clean($pPoint->getName()), 1, 'L');
                        $h1 = $this->GetY() - $y;

                        $this->SetXY($x + 95, $y);
                        $this->MultiCell(95, 5, $this->clean($details), 1, 'L');
                        $h2 = $this->GetY() - $y;

                        $this->SetY($y + max($h1, $h2));
                        $this->SetX(10);
                    }
                    $this->Ln(3);
                }
            }
            $this->Ln(3);
        }

        $this->Ln(5);

        // --- COMMENTAIRES ---
        $this->SetFont('Arial', 'B', 10);
        $this->Cell(0, 8, $this->clean("COMMENTAIRES & MÉDIAS :"), 0, 1, 'L');

        $currentY = $this->GetY();
        $etatLieux = $this->contrats->getEtatLieux();

        if ($etatLieux) {
            // Comments
            $comments = $etatLieux->getComments();
            if ($comments->count() > 0) {
                $this->SetFont('Arial', '', 9);
                foreach ($comments as $comment) {
                    $date = $comment->getCreatedAt()->format('d/m H:i');
                    $this->MultiCell(0, 5, $this->clean("- [$date] " . $comment->getContent()), 0, 'L');
                }
                $this->Ln(2);
            }

            // Files
            $filesCount = $etatLieux->getFiles()->count();
            if ($filesCount > 0) {
                $this->SetFont('Arial', 'I', 9);
                $this->Cell(0, 6, $this->clean(">> Nombre de photos/vidéos jointes au dossier numérique : " . $filesCount), 0, 1, 'L');
            }
        }

        $endY = $this->GetY();
        // Box removed as requested
        $this->Ln(30);
    }

    // --- HELPER METHODS DUPLICATED FROM ContratPdfService ---

    public function Header()
    {
        if ($this->page > 0 && !$this->isExtraPage) {
            $this->SetY(10);
            if (file_exists($this->logo)) {
                $this->Image($this->logo, 10, 10, 12);
                $this->SetX(25);
            }

            $this->SetFont('Arial', 'B', 14);
            $this->SetTextColor(0, 0, 0);
            $this->Cell(0, 7, $this->clean('Lilian SEGARD - Ludikevent'), 0, 1, 'L');

            $this->SetX(25);
            $this->SetFont('Arial', '', 8);
            $this->SetTextColor(80, 80, 80);
            $this->Cell(0, 4, $this->clean('SIRET : 930 488 408 00012 | RCS : 930 488 408'), 0, 1, 'L');
            $this->SetX(25);
            $this->Cell(0, 4, $this->clean('6 Rue du Château – 02800 Danizy – France'), 0, 1, 'L');
            $this->SetX(25);
            $this->Cell(0, 4, $this->clean('Tél. : 06 14 17 24 47'), 0, 1, 'L');
            $this->SetX(25);
            $this->Cell(0, 4, $this->clean('contact@ludikevent.fr | www.ludikevent.fr'), 0, 1, 'L');

            $this->SetY(40);
            $this->SetFont('Arial', 'B', 16);
            $this->SetTextColor(37, 99, 235);
            $this->Cell(0, 10, $this->clean('Contrat de location N° ' . $this->contrats->getNumReservation()), 0, 1, 'L');

            $this->insertQRCode(175, 10, $this->contrats->getNumReservation(), 22);

            $this->Ln(10);

            $this->SetDrawColor(37, 99, 235);
            $this->SetLineWidth(0.5);
            $this->Line(10, $this->GetY(), 200, $this->GetY());
        }
    }

    public function Footer(): void
    {
        $this->SetY(-15);
        $this->SetFont('Arial', 'I', 7);
        $this->SetTextColor(150, 150, 150);
        $this->Cell(0, 10, $this->clean('Etat des Lieux Entrant N° '.$this->contrats->getNumReservation().' - Ludikevent - Page ' . $this->PageNo() . '/{nb}'), 0, 0, 'C');
    }

    private function insertQRCode(float $x, float $y, string $data, int $size = 22): void
    {
        $builder = new Builder(
            writer: new PngWriter(),
            writerOptions: [],
            validateResult: false,
            data: $data,
            encoding: new Encoding('UTF-8'),
            errorCorrectionLevel: ErrorCorrectionLevel::High,
            size: 300,
            margin: 0,
            roundBlockSizeMode: RoundBlockSizeMode::Margin,
        );

        $result = $builder->build();
        $tmpFile = tempnam(sys_get_temp_dir(), 'qr_');
        $result->saveToFile($tmpFile);

        $this->Image($tmpFile, $x, $y, $size, $size, 'PNG');

        if (file_exists($tmpFile)) {
            unlink($tmpFile);
        }
    }

    private function clean(?string $text): string
    {
        if (!$text) return '';
        $text = iconv('UTF-8', 'windows-1252//TRANSLIT//IGNORE', $text);
        return str_replace('€', chr(128), $text);
    }

    private function euro(): string
    {
        return ' ' . chr(128);
    }
}
