<?php

namespace App\Service\Pdf;

use App\Entity\Contrats;
use Fpdf\Fpdf;
use Symfony\Component\HttpKernel\KernelInterface;

class FacturePdfService extends Fpdf
{
    private Contrats $contrat;
    private string $logo;
    private bool $isExtraPage = false;

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

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

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

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

    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->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('contact@ludikevent.fr | 06 14 17 24 47'), 0, 1, 'L');

            $this->SetY(40);
            $this->SetFont('Arial', 'B', 18);
            $this->SetTextColor(37, 99, 235);
            // On utilise le numéro de réservation comme base de numéro de facture
            $this->Cell(0, 10, $this->clean('FACTURE N° F' . $this->contrat->getNumReservation()), 0, 1, 'L');

            $this->SetFont('Arial', '', 10);
            $this->SetTextColor(0, 0, 0);
            $this->Cell(0, 5, $this->clean('Date de facturation : ' . date('d/m/Y')), 0, 1, 'L');
            $this->Cell(0, 5, $this->clean('Référence commande : #' . $this->contrat->getNumReservation()), 0, 1, 'L');

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

    public function generate(): string
    {
        $this->AddPage();
        $this->renderCustomerBlock();
        $this->renderInvoiceTable();
        $this->renderPaymentsHistory();
        $this->renderFooterMentions();
        return $this->Output('S');
    }

    private function renderCustomerBlock(): void
    {
        $this->SetY(65);
        $this->SetFont('Arial', 'B', 10);
        $this->SetFillColor(245, 245, 245);
        $this->Cell(95, 7, $this->clean(" FACTURÉ À"), 0, 0, 'L', true);
        $this->Cell(5, 7, "", 0, 0);
        $this->Cell(95, 7, $this->clean(" DÉTAILS ÉVÉNEMENT"), 0, 1, 'L', true);

        $this->Ln(2);
        $startY = $this->GetY();
        $this->SetFont('Arial', '', 10);

        // Client
        $this->SetX(10);
        $customer = $this->contrat->getCustomer();
        $this->MultiCell(95, 5, $this->clean(
            $customer->getSurname() . ' ' . $customer->getName() . "\n" .
            $this->contrat->getAddressEvent() . "\n" .
            $this->contrat->getZipCodeEvent() . " " . $this->contrat->getTownEvent()
        ), 0, 'L');

        // Event
        $this->SetXY(110, $startY);
        $this->MultiCell(95, 5, $this->clean(
            "Date début : " . $this->contrat->getDateAt()->format('d/m/Y') . "\n" .
            "Date fin : " . $this->contrat->getEndAt()->format('d/m/Y') . "\n" .
            "Lieu : " . $this->contrat->getTownEvent()
        ), 0, 'L');

        $this->Ln(10);
    }

    private function renderInvoiceTable(): void
    {
        $tvaEnabled = isset($_ENV['TVA_ENABLED']) && $_ENV['TVA_ENABLED'] === "true";
        $tvaRate = $tvaEnabled ? 0.20 : 0;

        $this->SetFont('Arial', 'B', 9);
        $this->SetFillColor(37, 99, 235);
        $this->SetTextColor(255, 255, 255);
        $this->Cell(110, 8, $this->clean("Désignation"), 1, 0, 'L', true);
        $this->Cell(40, 8, $this->clean("Quantité / Durée"), 1, 0, 'C', true);
        $this->Cell(40, 8, $this->clean("Total HT"), 1, 1, 'C', true);

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

        $totalHt = 0;
        $devis = $this->contrat->getDevis();
        $formule = $devis?->getFormule();
        $interval = $this->contrat->getDateAt()->diff($this->contrat->getEndAt());
        $nbJours = $interval->days + 1;

        // Logique Formule ou Lignes standards
        if ($formule) {
            $fPrice = $formule->getPrice1j() ?? 0;
            if ($nbJours >= 2 && $formule->getPrice2j()) $fPrice = $formule->getPrice2j();
            if ($nbJours >= 5 && $formule->getPrice5j()) $fPrice = $formule->getPrice5j();

            $this->Cell(110, 7, $this->clean("Location Formule : " . $formule->getName()), 1, 0, 'L');
            $this->Cell(40, 7, $nbJours . " jour(s)", 1, 0, 'C');
            $this->Cell(40, 7, number_format($fPrice, 2, ',', ' ') . $this->euro(), 1, 1, 'R');
            $totalHt += $fPrice;
        }

        foreach ($this->contrat->getContratsLines() as $line) {
            if (!$formule) {
                $price = $line->getPrice1DayHt() + ($line->getPriceSupDayHt() * ($nbJours - 1));
                $this->Cell(110, 7, $this->clean($line->getName()), 1, 0, 'L');
                $this->Cell(40, 7, $nbJours . " jour(s)", 1, 0, 'C');
                $this->Cell(40, 7, number_format($price, 2, ',', ' ') . $this->euro(), 1, 1, 'R');
                $totalHt += $price;
            } else {
                // Si formule, les lignes sont listées à 0 pour info
                $this->SetTextColor(100, 100, 100);
                $this->Cell(110, 6, $this->clean(" - " . $line->getName()), 1, 0, 'L');
                $this->Cell(40, 6, "Inclus", 1, 0, 'C');
                $this->Cell(40, 6, "0,00" . $this->euro(), 1, 1, 'R');
                $this->SetTextColor(0, 0, 0);
            }
        }

        foreach ($this->contrat->getContratsOptions() as $opt) {
            $priceOpt = ($formule && stripos($opt->getName(), 'livraison') === false) ? 0 : $opt->getPrice();
            $this->Cell(110, 7, $this->clean("Option : " . $opt->getName()), 1, 0, 'L');
            $this->Cell(40, 7, "Forfait", 1, 0, 'C');
            $this->Cell(40, 7, number_format($priceOpt, 2, ',', ' ') . $this->euro(), 1, 1, 'R');
            $totalHt += $priceOpt;
        }

        // Remises
        $promotion = $devis?->getOrderSession()?->getPromotion();
        if ($promotion) {
            $discount = $totalHt * (($promotion['percentage'] ?? 0) / 100);
            $this->SetTextColor(37, 99, 235);
            $this->Cell(150, 7, $this->clean("Remise : " . $promotion['name'] . " (-" . $promotion['percentage'] . "%)"), 1, 0, 'L');
            $this->Cell(40, 7, "-" . number_format($discount, 2, ',', ' ') . $this->euro(), 1, 1, 'R');
            $totalHt -= $discount;
            $this->SetTextColor(0, 0, 0);
        }

        // Totaux
        $this->Ln(5);
        $this->SetX(120);
        $this->SetFont('Arial', 'B', 10);
        $this->Cell(40, 8, $this->clean("TOTAL HT"), 0, 0, 'L');
        $this->Cell(30, 8, number_format($totalHt, 2, ',', ' ') . $this->euro(), 0, 1, 'R');

        if ($tvaEnabled) {
            $tvaVal = $totalHt * $tvaRate;
            $this->SetX(120);
            $this->SetFont('Arial', '', 10);
            $this->Cell(40, 8, $this->clean("TVA (20%)"), 0, 0, 'L');
            $this->Cell(30, 8, number_format($tvaVal, 2, ',', ' ') . $this->euro(), 0, 1, 'R');
            $totalTtc = $totalHt + $tvaVal;
        } else {
            $totalTtc = $totalHt;
        }

        $this->SetX(120);
        $this->SetFont('Arial', 'B', 12);
        $this->SetFillColor(37, 99, 235); $this->SetTextColor(255, 255, 255);
        $this->Cell(40, 10, $this->clean(" TOTAL TTC"), 0, 0, 'L', true);
        $this->Cell(30, 10, number_format($totalTtc, 2, ',', ' ') . $this->euro(), 0, 1, 'R', true);
        $this->SetTextColor(0, 0, 0);
    }

    private function renderPaymentsHistory(): void
    {
        $this->Ln(10);
        $this->SetFont('Arial', 'B', 10);
        $this->Cell(0, 7, $this->clean("RÈGLEMENTS REÇUS"), 'B', 1, 'L');
        $this->Ln(2);

        $this->SetFont('Arial', '', 9);
        $totalPaid = 0;
        foreach ($this->contrat->getContratsPayments() as $payment) {
            if ($payment->getType() !== 'caution' && str_contains(strtolower($payment->getState()), 'complete')) {
                $this->Cell(50, 6, $payment->getPaymentAt()->format('d/m/Y'), 0, 0, 'L');
                $this->Cell(100, 6, $this->clean("Paiement " . $payment->getType()), 0, 0, 'L');
                $this->Cell(40, 6, number_format($payment->getAmount(), 2, ',', ' ') . $this->euro(), 0, 1, 'R');
                $totalPaid += $payment->getAmount();
            }
        }

        $this->Ln(2);
        $this->SetFont('Arial', 'B', 11);
        $solde = $this->getTotalTtc() - $totalPaid;

        $this->Cell(150, 8, $this->clean("SOLDE À PAYER"), 0, 0, 'R');
        if($solde <=0.05){
            $this->SetTextColor(16,185,129);
        } else {
            $this->SetTextColor(200,38,38);
        }
        $this->Cell(40, 8, number_format(max(0, $solde), 2, ',', ' ') . $this->euro(), 0, 1, 'R');
        $this->SetTextColor(0, 0, 0);
    }

    private function getTotalTtc(): float
    {
        $totalHt = 0;
        $nbJours = $this->contrat->getDateAt()->diff($this->contrat->getEndAt())->days + 1;
        $devis = $this->contrat->getDevis();
        $formule = $devis?->getFormule();

        if ($formule) {
            $fPrice = $formule->getPrice1j() ?? 0;
            if ($nbJours >= 2 && $formule->getPrice2j()) $fPrice = $formule->getPrice2j();
            if ($nbJours >= 5 && $formule->getPrice5j()) $fPrice = $formule->getPrice5j();
            $totalHt += $fPrice;
        }

        foreach ($this->contrat->getContratsLines() as $line) {
            if (!$formule) $totalHt += $line->getPrice1DayHt() + ($line->getPriceSupDayHt() * ($nbJours - 1));
        }

        foreach ($this->contrat->getContratsOptions() as $opt) {
            $totalHt += ($formule && stripos($opt->getName(), 'livraison') === false) ? 0 : $opt->getPrice();
        }

        if ($devis && $devis->getOrderSession() && $devis->getOrderSession()->getPromotion()) {
            $totalHt -= $totalHt * (($devis->getOrderSession()->getPromotion()['percentage'] ?? 0) / 100);
        }

        $tvaEnabled = isset($_ENV['TVA_ENABLED']) && $_ENV['TVA_ENABLED'] === "true";
        return $tvaEnabled ? $totalHt * 1.20 : $totalHt;
    }

    private function renderFooterMentions(): void
    {
        $this->SetY(-40);
        $this->SetFont('Arial', 'I', 8);
        $this->SetTextColor(100, 100, 100);

        if (!(isset($_ENV['TVA_ENABLED']) && $_ENV['TVA_ENABLED'] === "true")) {
            $this->Cell(0, 4, $this->clean("TVA non applicable, art. 293 B du CGI"), 0, 1, 'C');
        }

        $this->Cell(0, 4, $this->clean("En votre aimable règlement. Cordialement,"), 0, 1, 'C');
        $this->SetFont('Arial', 'B', 8);
        $this->Cell(0, 4, $this->clean("Ludikevent - Lilian SEGARD"), 0, 1, 'C');
    }

    public function Footer()
    {
        $this->SetY(-15);
        $this->SetFont('Arial', 'I', 7);
        $this->SetTextColor(150, 150, 150);
        $this->Cell(0, 10, $this->clean('Facture F' . $this->contrat->getNumReservation() . ' - Page ' . $this->PageNo() . '/{nb}'), 0, 0, 'C');
    }
}
