<?php

namespace App\Service\Pdf;

use App\Entity\Customer;
use setasign\Fpdi\Fpdi;
use Symfony\Component\HttpKernel\KernelInterface;

class ClientWarningPdf extends Fpdi
{
    private const REASON_LABELS = [
        'impayes' => 'Impayes et/ou rejets de prelevement',
        'irrespect' => 'Manque de respect et/ou insultes envers notre equipe',
        'hors_horaires' => 'Appels repetes hors des heures d\'ouverture avec refus de payer le service hors horaire',
        'gratuit' => 'Exigence de services gratuits non prevus dans votre contrat',
    ];

    private const LEVEL_LABELS = [
        '1st' => '1er avertissement',
        '2nd' => '2eme avertissement - Procedure de suspension engagee',
        'last' => 'Dernier avertissement avant suspension',
    ];

    /**
     * @param list<string> $reasons
     */
    public function __construct(
        private readonly KernelInterface $kernel,
        private readonly Customer $customer,
        private readonly string $level,
        private readonly array $reasons = [],
    ) {
        parent::__construct();
        $this->SetTitle($this->enc('Avertissement - '.$this->customer->getFullName()));
        $this->SetAuthor($this->enc('Association E-Cosplay'));
    }

    public function generate(): void
    {
        $this->AliasNbPages();
        $this->AddPage();

        $this->writeHeader();
        $this->writeLevelBanner();
        $this->writeReasons();
        $this->writeContent();
        $this->writeLegalFooter();
        $this->writeSignature();
    }

    /** @codeCoverageIgnore */
    public function Header(): void
    {
    }

    /** @codeCoverageIgnore */
    public function Footer(): void
    {
        $this->SetY(-22);
        $this->SetDrawColor(253, 140, 4);
        $this->Line(15, $this->GetY(), 195, $this->GetY());
        $this->Ln(3);
        $this->SetFont('Arial', '', 7);
        $this->SetTextColor(0, 0, 0);
        $this->Cell(190, 3, $this->enc('42 rue de Saint-Quentin - 02800 BEAUTOR - Tel: 07 66 95 70 06 - client@e-cosplay.fr'), 0, 1, 'C');
        $this->Cell(190, 3, $this->enc('Association E-Cosplay - N SIRET 943 121 517 00011 - CODE APE 9329Z - RNA W022006988'), 0, 1, 'C');
        $this->SetFont('Arial', 'I', 7);
        $this->SetTextColor(150, 150, 150);
        $this->Cell(190, 3, $this->enc('Page ').$this->PageNo().' / {nb}', 0, 0, 'C');
    }

    /** @codeCoverageIgnore */
    private function writeHeader(): void
    {
        $logo = $this->kernel->getProjectDir().'/public/logo.jpg';
        if (file_exists($logo)) {
            $this->Image($logo, 10, 8, 45);
        }

        $this->SetFont('Arial', 'B', 16);
        $this->SetXY(60, 10);
        $this->Cell(0, 8, $this->enc('AVERTISSEMENT'), 0, 1, 'L');

        $formatter = new \IntlDateFormatter(
            'fr_FR',
            \IntlDateFormatter::FULL,
            \IntlDateFormatter::NONE,
            'Europe/Paris',
            \IntlDateFormatter::GREGORIAN
        );

        $this->SetFont('Arial', '', 10);
        $this->SetXY(60, 19);
        $this->Cell(0, 5, $this->enc('Emis a Beautor, le '.$formatter->format(new \DateTime())), 0, 1, 'L');

        // Destinataire
        $y = 32;
        $this->SetFont('Arial', 'B', 11);
        $this->SetXY(120, $y);
        $name = $this->customer->getRaisonSociale() ?: $this->customer->getFullName();
        $this->Cell(0, 5, $this->enc($name), 0, 1, 'L');

        if ($address = $this->customer->getAddress()) {
            $y += 5;
            $this->SetXY(120, $y);
            $this->SetFont('Arial', '', 10);
            $this->Cell(0, 5, $this->enc($address), 0, 1, 'L');
        }

        $y += 5;
        $this->SetXY(120, $y);
        $this->SetFont('Arial', '', 10);
        $cityLine = ($this->customer->getZipCode() ?? '').' '.($this->customer->getCity() ?? '');
        $this->Cell(0, 5, $this->enc(trim($cityLine)), 0, 1, 'L');

        if ($this->customer->getEmail()) {
            $y += 5;
            $this->SetXY(120, $y);
            $this->Cell(0, 5, $this->enc($this->customer->getEmail()), 0, 1, 'L');
        }

        $this->Ln(10);
    }

    /** @codeCoverageIgnore */
    private function writeLevelBanner(): void
    {
        $this->SetY(60);

        $label = self::LEVEL_LABELS[$this->level] ?? $this->level;

        if ('last' === $this->level) {
            $this->SetFillColor(220, 38, 38);
        } elseif ('2nd' === $this->level) {
            $this->SetFillColor(234, 88, 12);
        } else {
            $this->SetFillColor(245, 158, 11);
        }

        $this->SetTextColor(255, 255, 255);
        $this->SetFont('Arial', 'B', 12);
        $this->Cell(0, 10, $this->enc('  '.mb_strtoupper($label)), 0, 1, 'L', true);
        $this->SetTextColor(0, 0, 0);
        $this->Ln(5);

        // Texte introductif
        $greeting = $this->customer->getRaisonSociale()
            ? 'Chez '.$this->customer->getRaisonSociale()
            : $this->customer->getFirstName() ?? $this->customer->getFullName();

        $this->SetFont('Arial', '', 10);
        $this->MultiCell(0, 5, $this->enc($greeting.','), 0, 'L');
        $this->Ln(3);

        if ('1st' === $this->level) {
            $this->MultiCell(0, 5, $this->enc('Nous constatons des manquements sur votre compte. Nous vous invitons a regulariser votre situation dans les meilleurs delais.'), 0, 'L');
            $this->Ln(2);
            $this->SetFont('Arial', 'B', 10);
            $this->MultiCell(0, 5, $this->enc('En cas de repetition, un 2eme avertissement sera decide et pourra entrainer la suspension de vos services.'), 0, 'L');
        } elseif ('2nd' === $this->level) {
            $this->MultiCell(0, 5, $this->enc('Malgre notre precedent avertissement, nous constatons que votre situation n\'a pas ete regularisee. La procedure de suspension a ete preparee :'), 0, 'L');
            $this->Ln(2);
            $this->SetFont('Arial', '', 10);
            $this->Cell(5, 5, '', 0, 0);
            $this->Cell(0, 5, $this->enc('- La resiliation de vos services (sites internet, emails, noms de domaine) a ete preparee'), 0, 1, 'L');
            $this->Cell(5, 5, '', 0, 0);
            $this->Cell(0, 5, $this->enc('- La fermeture de votre compte a ete programmee'), 0, 1, 'L');
            $this->Cell(5, 5, '', 0, 0);
            $this->Cell(0, 5, $this->enc('- Ces mesures seront effectives au prochain avertissement en l\'absence de regularisation'), 0, 1, 'L');
        } else {
            $this->SetFont('Arial', 'B', 10);
            $this->SetTextColor(220, 38, 38);
            $this->MultiCell(0, 5, $this->enc('Malgre nos precedents avertissements, votre situation n\'a toujours pas ete regularisee. Ceci est votre dernier avertissement. Sans regularisation sous 48 heures, nous procederons a la suspension immediate de votre compte et de l\'ensemble de vos services.'), 0, 'L');
            $this->SetTextColor(0, 0, 0);
        }

        $this->SetFont('Arial', '', 10);
        $this->Ln(5);
    }

    /** @codeCoverageIgnore */
    private function writeReasons(): void
    {
        if ([] === $this->reasons) {
            return;
        }

        $this->SetDrawColor(200, 200, 200);
        $this->Cell(0, 0.5, '', 'T', 1, 'L');
        $this->Ln(3);

        $this->SetFont('Arial', 'B', 11);
        $this->Cell(0, 6, $this->enc('MOTIFS CONSTATES'), 0, 1, 'L');
        $this->Ln(2);

        $this->SetFont('Arial', '', 10);
        foreach ($this->reasons as $reason) {
            $label = self::REASON_LABELS[$reason] ?? $reason;
            $this->Cell(5, 5, '', 0, 0);
            $this->Cell(0, 5, $this->enc('- '.$label), 0, 1, 'L');
        }

        $this->Ln(5);
    }

    /** @codeCoverageIgnore */
    private function writeContent(): void
    {
        $this->SetDrawColor(200, 200, 200);
        $this->Cell(0, 0.5, '', 'T', 1, 'L');
        $this->Ln(3);

        $this->SetFont('Arial', '', 10);
        $this->MultiCell(0, 5, $this->enc('Nous vous invitons a regulariser votre situation dans les meilleurs delais ou a contacter notre service pour trouver une solution.'), 0, 'L');
        $this->Ln(3);

        $this->SetFont('Arial', '', 10);
        $this->Cell(0, 5, $this->enc('Contact : client@e-cosplay.fr'), 0, 1, 'L');
        $this->Ln(5);
    }

    /** @codeCoverageIgnore */
    private function writeLegalFooter(): void
    {
        $this->SetDrawColor(200, 200, 200);
        $this->Cell(0, 0.5, '', 'T', 1, 'L');
        $this->Ln(3);

        $this->SetFont('Arial', 'I', 8);
        $this->SetTextColor(150, 150, 150);
        $this->MultiCell(0, 4, $this->enc(
            'Le present document constitue un avertissement officiel de l\'Association E-Cosplay. Il fait foi en cas de litige. '
            .'Toutes les decisions relatives aux avertissements sont prises par le bureau de l\'association a huis clos. '
            .'Toute contestation devra etre adressee a direction@e-cosplay.fr'
        ), 0, 'L');
        $this->SetTextColor(0, 0, 0);
        $this->Ln(5);
    }

    /** @codeCoverageIgnore */
    private function writeSignature(): void
    {
        if ($this->GetY() + 35 > $this->GetPageHeight() - 25) {
            $this->AddPage();
        }

        $formatter = new \IntlDateFormatter(
            'fr_FR',
            \IntlDateFormatter::LONG,
            \IntlDateFormatter::NONE,
            'Europe/Paris',
            \IntlDateFormatter::GREGORIAN
        );

        $this->SetFont('Arial', '', 9);
        $this->Cell(0, 5, $this->enc('Fait a Beautor, le '.$formatter->format(new \DateTime())), 0, 1, 'L');
        $this->Ln(3);

        $this->SetFont('Arial', 'B', 9);
        $this->Cell(0, 5, $this->enc('Pour le bureau de l\'Association E-Cosplay :'), 0, 1, 'L');
        $this->Ln(2);
        $this->SetFont('Arial', '', 10);
        $this->Cell(85, 20, '{{Sign;type=signature;role=First Party}}', 0, 1, 'L');

        $this->Ln(3);
        $this->SetFont('Arial', 'I', 8);
        $this->SetTextColor(150, 150, 150);
        $this->Cell(0, 4, $this->enc('Signature electronique via DocuSeal - Valeur juridique (reglement eIDAS, art. 1367 Code civil)'), 0, 1, 'C');
        $this->SetTextColor(0, 0, 0);
    }

    private function enc(string $text): string
    {
        return mb_convert_encoding($text, 'Windows-1252', 'UTF-8');
    }
}
