<?php

namespace App\Service\Pdf;

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

if (!\defined('EURO')) {
    \define('EURO', \chr(128)); // @codeCoverageIgnore
}

class ContratMigrationSiteconseilPdf extends Fpdi
{
    public function __construct(
        private readonly KernelInterface $kernel,
        private readonly Contrat $contrat,
    ) {
        parent::__construct();
        $this->SetTitle($this->enc('Contrat de Service '.$this->contrat->getReference().' - '.$this->contrat->getRaisonSociale()));
        $this->SetAuthor($this->enc('Association E-Cosplay'));
    }

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

        $this->writeHeader();
        $this->writePreambule();
        $this->writeServicesTable();
        $this->writeArticles();
        $this->writeSignatures();
    }

    /** @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', 14);
        $this->SetXY(60, 10);
        $this->Cell(0, 7, $this->enc('CONTRAT DE SERVICE'), 0, 1, 'L');

        $this->SetFont('Arial', 'B', 10);
        $this->SetXY(60, 17);
        $this->SetTextColor(253, 140, 4);
        $this->Cell(0, 5, $this->enc('Migration SARL SITECONSEIL'), 0, 1, 'L');
        $this->SetTextColor(0, 0, 0);

        $this->SetFont('Arial', '', 9);
        $this->SetXY(60, 23);
        $this->SetTextColor(150, 150, 150);
        $this->Cell(0, 5, $this->enc('Ref. : '.$this->contrat->getReference()), 0, 1, 'L');
        $this->SetTextColor(0, 0, 0);

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

        $this->SetFont('Arial', '', 10);
        $this->SetXY(60, 29);
        $this->Cell(0, 5, $this->enc('Emis a Beautor, le '.$formatter->format($this->contrat->getCreatedAt())), 0, 1, 'L');

        // Parties
        $this->SetY(42);

        // Partie 1 : Association
        $this->SetFont('Arial', 'B', 9);
        $this->Cell(0, 5, $this->enc('ENTRE LES SOUSSIGNES :'), 0, 1, 'L');
        $this->Ln(2);

        // Bloc info association (meme style ComptaPdf)
        $this->SetDrawColor(200, 200, 200);
        $this->Cell(0, 0.5, '', 'T', 1, 'L');
        $this->Ln(2);

        $labelW = 45;

        $this->SetFont('Arial', '', 9);
        $this->Cell($labelW, 5, $this->enc('Association :'), 0, 0, 'L');
        $this->SetFont('Arial', 'B', 9);
        $this->Cell(0, 5, $this->enc('E-Cosplay Association loi 1901 - RNA N W022006988'), 0, 1, 'L');

        $this->SetFont('Arial', '', 9);
        $this->Cell($labelW, 5, $this->enc('Siege social :'), 0, 0, 'L');
        $this->Cell(0, 5, $this->enc('42 rue de Saint-Quentin 02800 Beautor'), 0, 1, 'L');

        $this->Cell($labelW, 5, 'SIRET :', 0, 0, 'L');
        $this->Cell(0, 5, '943 121 517 00011', 0, 1, 'L');

        $this->Cell($labelW, 5, 'Code APE :', 0, 0, 'L');
        $this->Cell(0, 5, '9329Z', 0, 1, 'L');

        $this->Cell($labelW, 5, $this->enc('President :'), 0, 0, 'L');
        $this->SetFont('Arial', 'B', 9);
        $this->Cell(0, 5, $this->enc('Shoko Cosplay - Serreau Jovann'), 0, 1, 'L');

        $this->SetFont('Arial', '', 9);
        $this->Cell($labelW, 5, 'Email :', 0, 0, 'L');
        $this->Cell(0, 5, 'client@e-cosplay.fr', 0, 1, 'L');

        $this->Cell($labelW, 5, $this->enc('Telephone :'), 0, 0, 'L');
        $this->Cell(0, 5, '07 66 95 70 06', 0, 1, 'L');

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

        $this->SetFont('Arial', 'I', 9);
        $this->Cell(0, 5, $this->enc('Ci-apres denommee "le Prestataire",'), 0, 1, 'L');
        $this->Ln(3);

        // Partie 2 : Client
        $this->SetFont('Arial', 'B', 9);
        $this->Cell(0, 5, $this->enc('ET :'), 0, 1, 'L');
        $this->Ln(2);

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

        $this->SetFont('Arial', '', 9);
        $this->Cell($labelW, 5, $this->enc('Raison sociale :'), 0, 0, 'L');
        $this->SetFont('Arial', 'B', 9);
        $this->Cell(0, 5, '{{RaisonSociale;type=text;role=First Party}}', 0, 1, 'L');

        $this->SetFont('Arial', '', 9);
        $this->Cell($labelW, 5, 'SIRET :', 0, 0, 'L');
        $this->Cell(0, 5, '{{SIRET;type=text;role=First Party}}', 0, 1, 'L');

        $this->Cell($labelW, 5, $this->enc('Adresse :'), 0, 0, 'L');
        $this->Cell(0, 5, '{{Adresse;type=text;role=First Party}}', 0, 1, 'L');

        $this->Cell($labelW, 5, 'Email :', 0, 0, 'L');
        $this->Cell(0, 5, '{{Email;type=text;role=First Party}}', 0, 1, 'L');

        $this->Cell($labelW, 5, $this->enc('Telephone :'), 0, 0, 'L');
        $this->Cell(0, 5, '{{Telephone;type=text;role=First Party}}', 0, 1, 'L');

        $this->Cell($labelW, 5, $this->enc('Representant :'), 0, 0, 'L');
        $this->Cell(0, 5, '{{Representant;type=text;role=First Party}}', 0, 1, 'L');

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

        $this->SetFont('Arial', 'I', 9);
        $this->Cell(0, 5, $this->enc('Ci-apres denomme(e) "le Client",'), 0, 1, 'L');
        $this->Ln(5);
    }

    /** @codeCoverageIgnore */
    private function writePreambule(): void
    {
        $this->SetFont('Arial', 'B', 11);
        $this->SetFillColor(250, 191, 4);
        $this->Cell(0, 8, $this->enc('  PREAMBULE'), 0, 1, 'L', true);
        $this->Ln(4);

        $this->SetFont('Arial', '', 9);
        $paragraphs = [
            'Dans le cadre de la cessation d\'activite de la SARL SITECONSEIL, l\'Association E-Cosplay '
            .'assure depuis plusieurs mois la gestion de l\'infrastructure technique et des services '
            .'precedemment operes par la SARL SITECONSEIL, dans un objectif de continuite de service '
            .'pour l\'ensemble des clients concernes.',

            'La SARL SITECONSEIL a decide de transmettre la gestion de vos services a l\'Association '
            .'E-Cosplay. Cette transmission necessite la signature d\'un nouveau contrat de prestation '
            .'entre vous et l\'Association E-Cosplay.',

            'Le present contrat definit les conditions dans lesquelles l\'Association E-Cosplay '
            .'poursuivra la fourniture des services dont vous beneficiez jusqu\'a present.',
        ];

        foreach ($paragraphs as $p) {
            $this->MultiCell(0, 5, $this->enc($p), 0, 'J');
            $this->Ln(2);
        }

        // Avertissement important
        $this->Ln(2);
        $this->SetFillColor(255, 247, 237);
        $this->SetDrawColor(234, 88, 12);
        $this->Rect($this->GetX(), $this->GetY(), 180, 18, 'DF');

        $this->SetFont('Arial', 'B', 9);
        $this->SetTextColor(154, 52, 18);
        $this->SetX(15);
        $this->Cell(0, 6, $this->enc('ATTENTION :'), 0, 1, 'L');
        $this->SetFont('Arial', '', 8);
        $this->SetX(15);
        $this->MultiCell(170, 4, $this->enc(
            'L\'Association E-Cosplay ne prendra pas en compte votre anciennete avec la SARL SITECONSEIL, '
            .'ni les accords ou conditions particulieres que vous auriez pu conclure avec cette derniere. '
            .'Le present contrat constitue un engagement nouveau et independant.'
        ), 0, 'J');
        $this->SetTextColor(0, 0, 0);
        $this->SetDrawColor(200, 200, 200);
        $this->Ln(5);
    }

    /** @codeCoverageIgnore */
    private function writeServicesTable(): void
    {
        $services = $this->contrat->getServices();
        if ([] === $services) {
            return;
        }

        if ($this->GetY() + 30 > $this->GetPageHeight() - 25) {
            $this->AddPage();
        }

        $this->SetFont('Arial', 'B', 11);
        $this->SetFillColor(250, 191, 4);
        $this->Cell(0, 8, $this->enc('  SERVICES INCLUS DANS LE CONTRAT'), 0, 1, 'L', true);
        $this->Ln(4);

        // Header tableau
        $this->SetFont('Arial', 'B', 9);
        $this->SetFillColor(35, 35, 35);
        $this->SetTextColor(255, 255, 255);
        $this->Cell(80, 7, $this->enc(' Service'), 1, 0, 'L', true);
        $this->Cell(20, 7, $this->enc('Qte'), 1, 0, 'C', true);
        $this->Cell(40, 7, $this->enc('Prix unitaire HT'), 1, 0, 'R', true);
        $this->Cell(40, 7, $this->enc('Sous-total HT'), 1, 1, 'R', true);
        $this->SetTextColor(0, 0, 0);

        $this->SetFont('Arial', '', 9);
        $fill = false;
        $catalog = \App\Entity\Contrat::SERVICE_CATALOG;

        foreach ($services as $s) {
            $this->SetFillColor(245, 245, 240);
            $label = $catalog[$s['service']]['label'] ?? $s['service'];
            $unit = $catalog[$s['service']]['unit'] ?? '';
            $qty = $s['quantity'];
            $price = (float) $s['priceHt'];
            $subtotal = $price * $qty;

            $this->Cell(80, 6, $this->enc(' '.$label), 'B', 0, 'L', $fill);
            $this->Cell(20, 6, (string) $qty, 'B', 0, 'C', $fill);
            $this->Cell(40, 6, number_format($price, 2, ',', ' ').' '.EURO.' '.$unit, 'B', 0, 'R', $fill);
            $this->Cell(40, 6, number_format($subtotal, 2, ',', ' ').' '.EURO, 'B', 1, 'R', $fill);

            $fill = !$fill;
        }

        // Total
        $this->SetFont('Arial', 'B', 10);
        $this->Cell(140, 8, $this->enc('TOTAL HT'), 0, 0, 'R');
        $this->Cell(40, 8, number_format($this->contrat->getTotalHt(), 2, ',', ' ').' '.EURO, 0, 1, 'R');

        $this->Ln(5);
    }

    /** @codeCoverageIgnore */
    private function writeArticles(): void
    {
        $articles = [
            'OBJET DU CONTRAT' => [
                'Le present contrat a pour objet de definir les conditions dans lesquelles l\'Association '
                .'E-Cosplay fournira au Client les services informatiques precedemment assures par la '
                .'SARL SITECONSEIL, incluant sans s\'y limiter : l\'hebergement web, la gestion des noms '
                .'de domaine, la messagerie electronique, et tout autre service technique associe.',
            ],
            'TRANSFERT DES SERVICES' => [
                'Le Client reconnait que les services qui lui etaient fournis par la SARL SITECONSEIL '
                .'sont desormais operes par l\'Association E-Cosplay.',
                'Le Client accepte que le transfert de ses services soit effectue dans les conditions '
                .'du present contrat, sans garantie de reprise des conditions anterieures.',
            ],
            'CONDITIONS TARIFAIRES' => [
                'Les tarifs applicables seront ceux en vigueur au sein de l\'Association E-Cosplay '
                .'au moment de la signature du present contrat.',
                'Les tarifs precedemment appliques par la SARL SITECONSEIL ne sont pas opposables '
                .'a l\'Association E-Cosplay.',
                'Les devis et factures seront emis par l\'Association E-Cosplay selon sa propre grille tarifaire.',
            ],
            'DUREE ET RESILIATION' => [
                'Le present contrat prend effet a la date de sa signature et est conclu pour une duree indeterminee.',
                'Chacune des parties peut resilier le contrat a tout moment, sous reserve d\'un preavis '
                .'de 30 jours, notifie par email avec accuse de reception.',
            ],
            'ANCIENNETE ET DROITS ANTERIEURS' => [
                'Le Client reconnait expressement que l\'Association E-Cosplay ne reprend aucun '
                .'engagement, garantie, condition particuliere ou anciennete lies aux relations '
                .'commerciales entre le Client et la SARL SITECONSEIL.',
                'Tout litige relatif aux prestations anterieures de la SARL SITECONSEIL devra etre '
                .'dirige exclusivement vers cette derniere.',
            ],
            'RESPONSABILITE' => [
                'L\'Association E-Cosplay s\'engage a assurer la continuite des services dans la mesure '
                .'du possible. Elle ne saurait etre tenue responsable des interruptions de service '
                .'liees a la transition depuis la SARL SITECONSEIL.',
            ],
            'DONNEES PERSONNELLES' => [
                'L\'Association E-Cosplay s\'engage a traiter les donnees personnelles du Client '
                .'conformement au Reglement General sur la Protection des Donnees (RGPD) et a la '
                .'loi Informatique et Libertes.',
            ],
            'DROIT APPLICABLE ET JURIDICTION' => [
                'Le present contrat est soumis au droit francais. En cas de litige, les parties '
                .'s\'engagent a rechercher une solution amiable. A defaut, les tribunaux competents '
                .'de Laon seront seuls competents.',
            ],
        ];

        $articleNum = 1;
        foreach ($articles as $title => $contents) {
            if ($this->GetY() + 25 > $this->GetPageHeight() - 25) {
                $this->AddPage();
            }

            $this->SetFont('Arial', 'B', 10);
            $this->Cell(0, 6, $this->enc('Article '.$articleNum.' - '.$title), 0, 1, 'L');
            $this->Ln(1);

            $this->SetFont('Arial', '', 9);
            foreach ($contents as $content) {
                $this->MultiCell(0, 4, $this->enc($content), 0, 'J');
                $this->Ln(2);
            }

            $this->Ln(2);
            ++$articleNum;
        }
    }

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

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

        $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()).', en deux exemplaires.'), 0, 1, 'L');
        $this->Ln(5);

        $colWidth = 85;

        // Labels
        $this->SetFont('Arial', 'B', 9);
        $this->Cell($colWidth, 5, $this->enc('Pour l\'Association E-Cosplay :'), 0, 0, 'L');
        $this->Cell(10, 5, '', 0, 0);
        $this->Cell($colWidth, 5, $this->enc('Le Client ('.$this->contrat->getRaisonSociale().') :'), 0, 1, 'L');
        $this->Ln(2);

        // Signatures DocuSeal
        $this->SetFont('Arial', '', 10);
        $this->Cell($colWidth, 20, '{{Sign;type=signature;role=Company}}', 0, 0, 'L');
        $this->Cell(10, 20, '', 0, 0);
        $this->Cell($colWidth, 20, '{{SignClient;type=signature;role=First Party}}', 0, 1, 'L');

        $this->Ln(5);
        $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');
    }
}
