<?php

namespace App\Service\Pdf;

use App\Entity\Ag\Main;
use App\Entity\Ag\MainMember;
use App\Entity\Members;
use Doctrine\ORM\EntityManagerInterface;
use Fpdf\Fpdf;
use Symfony\Component\HttpKernel\KernelInterface;

class AgGenerator extends Fpdf
{
    private Main $main;
    private KernelInterface $kernel;
    private EntityManagerInterface $em;
    private array $burreauMembers; // Ajout de l'initialisation de la propriété

    private int $nbVote = 0;
    private int $nbVoteVoix = 0;
    public function __construct($orientation = 'P', $unit = 'mm', $size = 'A4')
    {
        parent::__construct($orientation, $unit, $size);
    }

    public function setData(Main $main, KernelInterface $kernel,EntityManagerInterface $em)
    {
        $this->main = $main;
        $this->kernel = $kernel;
        $this->em = $em;

        $this->burreauMembers = [];
        foreach ($main->getMainMembers() as $member) {
            if($member->getMember()->getRole() == "President")
                $this->burreauMembers[] = $member;
            if($member->getMember()->getRole() == "Tresorier")
                $this->burreauMembers[] = $member;
            if($member->getMember()->getRole() == "Secretaire")
                $this->burreauMembers[] = $member;
            if($member->getMember()->getRole() == "VicePresident")
                $this->burreauMembers[] = $member;
            if($member->getMember()->getRole() == "TresorierAdjoint")
                $this->burreauMembers[] = $member;
            if($member->getMember()->getRole() == "SecretaireAdjoint")
                $this->burreauMembers[] = $member;
        }
    }

    /**
     * Définit l'en-tête de chaque page du document PDF.
     */
    public function Header()
    {
        // --- 1. Définition des constantes de position ---
        $yPos = 10; // Marge haute par défaut
        $xPos = 10; // Marge gauche par défaut
        $logoWidth = 20; // Nouvelle valeur
        $logoHeight = 10; // Nouvelle valeur

        // --- 2. Titre et Date (Top Centré) ---
        $this->SetY($yPos);

        $agDate = $this->main->getAgDateAt() ? $this->main->getAgDateAt()->format('d/m/Y') : 'Date non spécifiée';

        $titleLine1 = "PROCES-VERBAL DE L'ASSEMBLÉE GÉNÉRALE";
        $titleLine2 = "Séance du : " . $agDate;

        // Titre Principal
        $this->SetFont('Arial', 'B', 14);
        $this->SetTextColor(0, 0, 0);
        $this->Cell(0, 7, utf8_decode($titleLine1), 0, 1, 'C');

        // Date
        $this->SetFont('Arial', '', 11);
        $this->Cell(0, 6, utf8_decode($titleLine2), 0, 1, 'C');

        // Sauvegarde la position Y après le titre/date
        $yAfterTitle = $this->GetY();

        // --- 3. Logo (Fixé Haut Gauche) ---
        $logoPath = $this->kernel->getProjectDir() . '/public/assets/images/logo.jpg';
        $this->Image($logoPath, $xPos, $yPos, $logoWidth, $logoHeight);

        // --- 4. Bloc d'informations légales (Uniquement sur la première page) ---
        if ($this->PageNo() == 1) {
            $this->writeAgContextBlock();
        } else {
            // --- 5. Définir la position finale Y pour les pages suivantes ---
            $finalY = max($yAfterTitle, $yPos + $logoHeight);
            $this->SetY($finalY + 5);
        }
    }

    /**
     * Définit le pied de page (généralement le numéro de page).
     */
    public function Footer()
    {
        // Positionnement à 15 mm du bas
        $this->SetY(-15);
        // Police Arial italique 8
        $this->SetFont('Arial', 'I', 8);
        // Numéro de page
        $this->Cell(0, 10, 'Page ' . $this->PageNo() . '/{nb}', 0, 0, 'C');
    }

    /**
     * Écrit le bloc d'informations légales et contextuelles de l'AG.
     */
    public function writeAgContextBlock()
    {
        // Récupération des données nécessaires
        $agDate = $this->main->getAgDateAt() ? $this->main->getAgDateAt()->format('d/m/Y') : 'Date non spécifiée';
        $agTime = $this->main->getAgDateAt() ? $this->main->getAgDateAt()->format('H\hi') : 'Heure non spécifiée';

        // Utilisez une petite police pour les détails légaux
        $this->SetFont('Arial', '', 10);
        $this->SetTextColor(0, 0, 0);

        // Largeur de la cellule de données (pour aligner les données)
        $dataCellWidth = 100;
        $labelCellWidth = 60;

        // Ajout du cadre
        $this->Cell(0, 1, '', 'T', 1, 'L', false); // Ligne supérieure légère
        $this->Ln(2); // Petite marge après la ligne

        $this->SetFont('Arial', 'B', 10);
        $this->Cell(0, 5, utf8_decode('INFORMATIONS LÉGALES ET CONTEXTUELLES'), 0, 1, 'C');
        $this->Ln(1);

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

        // Ligne 1: Association / RNA
        $this->Cell($labelCellWidth, 5, utf8_decode('Association :'), 0, 0, 'L');
        $this->SetFont('Arial', 'B', 10);
        $this->Cell($dataCellWidth, 5, utf8_decode('E-Cosplay Association loi 1901 – RNA N°W022006988'), 0, 1, 'L');
        $this->SetFont('Arial', '', 10);

        // Ligne 2: Siège social
        $this->Cell($labelCellWidth, 5, utf8_decode('Siège social :'), 0, 0, 'L');
        $this->Cell($dataCellWidth, 5, utf8_decode('42 rue de saint-quentin 02800 Beautor'), 0, 1, 'L');

        // Ligne 3: Date de déclaration
        $this->Cell($labelCellWidth, 5, utf8_decode('Date de déclaration :'), 0, 0, 'L');
        $this->Cell($dataCellWidth, 5, utf8_decode($agDate), 0, 1, 'L');

        // Ligne 4: Date de l'AG
        $this->Cell($labelCellWidth, 5, utf8_decode("Date de l'Assemblée Générale :"), 0, 0, 'L');
        $this->Cell($dataCellWidth, 5, utf8_decode($agDate), 0, 1, 'L');

        // Ligne 5: Heure de début
        $this->Cell($labelCellWidth, 5, utf8_decode('Heure de début de la séance :'), 0, 0, 'L');
        $this->Cell($dataCellWidth, 5, utf8_decode($agTime), 0, 1, 'L');

        // Ligne 6: Lieu (Dynamique)
        $this->Cell($labelCellWidth, 5, utf8_decode('Lieu :'), 0, 0, 'L');
        $this->Cell($dataCellWidth, 5, utf8_decode($this->main->getLocate() . " " . $this->main->getLocateZipcode() . " " . $this->main->getLocateCity()), 0, 1, 'L');

        // Ligne 7: Nature de l'AG (Dynamique)
        $this->Cell($labelCellWidth, 5, utf8_decode("Nature de l'AG :"), 0, 0, 'L');
        $this->Cell($dataCellWidth, 5, utf8_decode($this->main->getType()), 0, 1, 'L');

        // Fin de la mise en forme du bloc
        $this->Ln(2); // Petite marge avant la ligne
        $this->Cell(0, 1, '', 'T', 1, 'L', false); // Ligne inférieure légère
        $this->Ln(5); // Espacement final avant le corps du texte
    }

    /**
     * Écrit la sous-section 1.2 : Présidence et Secrétariat de Séance.
     */
    public function writePresidenceAndSecretariat()
    {
        $this->SetFont('Arial', 'B', 12);
        $this->Cell(0, 7, utf8_decode('1.2. Présidence et Secrétariat de Séance'), 0, 1, 'L');
        $this->SetFont('Arial', '', 10);
        $this->Ln(3);

        $text = utf8_decode("Conformément aux statuts de l'Association, la séance est présidée par le Président".(($this->main->getPresident()->getCiv() == "Mme")?"e":"")." en exercice, ".$this->main->getPresident()->getCiv()." ".$this->main->getPresident()->getName()." ".$this->main->getPresident()->getSurname().", et la fonction de Secrétair".(($this->main->getSecretaire()->getCiv() == "Mme")?"e":"")." de Séance est assurée par ".$this->main->getSecretaire()->getCiv()." ".$this->main->getSecretaire()->getName()." ".$this->main->getSecretaire()->getSurname()." désigné par l'Assemblée, après vote à main levée, ou par le Secrétaire de l'Association.");

        $this->MultiCell(0, 5, $text);

        $this->Ln(5);

        // Cadre pour les noms à compléter manuellement ou via un autre champ
        $this->SetFont('Arial', 'B', 10);
        $this->Cell(60, 6, utf8_decode('Président de Séance :'), 0, 0, 'L');
        $this->Cell(0, 6, utf8_decode($this->main->getPresident()->getCiv()." ".$this->main->getPresident()->getName()." ".$this->main->getPresident()->getSurname()), 'B', 1, 'L');

        $this->Cell(60, 6, utf8_decode('Secrétaire de Séance :'), 0, 0, 'L');
        $this->Cell(0, 6, utf8_decode($this->main->getSecretaire()->getCiv()." ".$this->main->getSecretaire()->getName()." ".$this->main->getSecretaire()->getSurname()), 'B', 1, 'L');

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

    /**
     * Écrit la sous-section 1.3 : Ouverture de la Séance.
     */
    public function writeOuvertureSeance()
    {
        $agTime = $this->main->getAgDateAt() ? $this->main->getAgDateAt()->format('H\hi') : 'Heure non spécifiée';
        $presidentCiv = $this->main->getPresident()->getCiv();
        $presidentTitle = ($presidentCiv === 'Mme') ? 'Présidente' : 'Président';

        $this->SetFont('Arial', 'B', 12);
        $this->Cell(0, 7, utf8_decode('1.3. Ouverture de la séance'), 0, 1, 'L');
        $this->SetFont('Arial', '', 10);
        $this->Ln(3);

        $text = utf8_decode("Le $presidentTitle de séance déclare l'Assemblée Générale ouverte à $agTime et rappelle l'ordre du jour, qui a été porté à la connaissance des membres lors de la convocation.");

        $this->MultiCell(0, 5, $text);

        $this->Ln(5);
    }

    /**
     * Écrit la liste spécifique des points de l'ordre du jour et les délibérations.
     */
    public function writeSpecificAgendaItems()
    {
        // Récupération dynamique des points d'ordre du jour
        $agendaOrders = $this->main->getOrders();

        $this->SetFont('Arial', 'B', 12);
        $this->Cell(0, 7, utf8_decode('2.1. Points de l\'Ordre du Jour et Délibérations'), 0, 1, 'L');
        $this->SetFont('Arial', '', 10);
        $this->Ln(3);

        $i = 1;
        foreach ($agendaOrders as $order) {

            // Titre du point
            $this->SetFont('Arial', 'B', 10);
            $this->Cell(0, 6, utf8_decode("Point $i : " . $order->getTitle()), 0, 1, 'L');
            $this->SetFont('Arial', '', 10);

            // Contenu de la délibération (Description du point de l'ordre du jour)
            $this->SetX(15); // Décalage pour l'indentation
            // Utilisation de la méthode MultiCell pour gérer les sauts de ligne si besoin
            $this->MultiCell(0, 5, utf8_decode($order->getDescription()));

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


    /**
     * Écrit la section 2 complète : Ordre du Jour et Délibérations.
     */
    public function writeAgendaAndDeliberations()
    {
        // 1. Titre de la section principale
        $this->SetFont('Arial', 'B', 14);
        $this->Ln(5);
        $this->Cell(0, 8, utf8_decode('2. ORDRE DU JOUR ET DÉLIBÉRATIONS'), 0, 1, 'L');
        $this->Ln(3);

        // 2. Appel des sous-sections (le nouvel ordre du jour)
        $this->writeSpecificAgendaItems();
    }


    /**
     * Écrit la section 3 complète : Renouvellement du Bureau et Clôture.
     */
    public function writeBureauRenewalAndClosure()
    {
        $agTime = $this->main->getAgDateAt() ? $this->main->getAgDateAt()->format('H\hi') : 'Heure non spécifiée';
        $presidentCiv = $this->main->getPresident()->getCiv();
        $presidentTitle = ($presidentCiv === 'Mme') ? 'Présidente' : 'Président';
        $secretaireCiv = $this->main->getSecretaire()->getCiv();
        $secretaireTitle = ($secretaireCiv === 'Mme') ? 'Secrétaire' : 'Secrétaire';

        // 1. Titre de la section principale
        $this->SetFont('Arial', 'B', 14);
        $this->Ln(5);
        $this->Cell(0, 8, utf8_decode('3. RENOUVELLEMENT DU BUREAU ET CLÔTURE DE SÉANCE'), 0, 1, 'L');
        $this->Ln(3);

        // --- 3.1. Renouvellement des membres du Bureau ---
        $this->SetFont('Arial', 'B', 12);
        $this->Cell(0, 7, utf8_decode('3.1. Renouvellement des membres du Bureau'), 0, 1, 'L');
        $this->SetFont('Arial', '', 10);
        $this->Ln(3);

        // Rappel statutaire / Anciens membres
        $this->SetFont('Arial', 'B', 10);
        $this->Cell(0, 5, utf8_decode('Rappel Statutaire (Ancien Bureau) :'), 0, 1, 'L');
        $this->SetFont('Arial', '', 10);
        foreach ($this->burreauMembers as $member) {
            $this->SetX(15);
            $this->Cell(0, 5, utf8_decode($member->getMember()->getRole().' : '.(($member->getMember()->getCiv() == "M")?"M":"Mme").' '.$member->getMember()->getName()." ".$member->getMember()->getSurname()), 0, 1, 'L');
        }
        $this->Ln(5);

        // Modalités de vote
        $this->SetFont('Arial', 'B', 10);
        $this->Cell(0, 5, utf8_decode('Modalités de vote :'), 0, 1, 'L');
        $this->SetFont('Arial', '', 10);
        $this->SetX(15);
        $this->MultiCell(0, 5, utf8_decode("Il est procédé au vote à main levée pour le renouvellement des membres du Bureau."));
        $this->SetX(10);
        $this->Ln(3);

        // Résultats et Validité
        $this->SetFont('Arial', 'B', 10);
        $this->Cell(0, 5, utf8_decode('Résultats du Vote :'), 0, 1, 'L');
        $this->SetFont('Arial', '', 10);
        $this->SetX(15);
        $this->Cell(0, 5, utf8_decode(' Nombre de votants éligibles : '.$this->nbVote), 0, 1, 'L');
        $this->SetX(15);
        $this->Cell(0, 5, utf8_decode(' Majorité absolue requise pour élection : '.$this->nbVoteVoix.' voix'), 0, 1, 'L');
        $this->SetX(10);
        $this->Ln(3);

        // Résolution: Nouveaux membres du Bureau
        $this->SetFont('Arial', 'B', 10);
        $this->Cell(0, 5, utf8_decode('Résolution : Sont élus/réélus, en tant que membres du Bureau :'), 0, 1, 'L');
        $this->SetFont('Arial', '', 10);
        foreach ($this->main->getMainVote() as $vote) {
            $this->SetX(15);
            $this->Cell(0, 5, utf8_decode('o Président'.(($vote->getMember()->getCiv() == "Mme")?"e":"").' : '.$vote->getMember()->getCiv().' '.$vote->getMember()->getName().' '.$vote->getMember()->getSurname().' ('.$vote->getPour().' Pour, '.$vote->getContre().' Contre, 0 Abstention)'), 0, 1, 'L');
        }

        $this->SetX(10);
        $this->Ln(3);

        // Acceptance
        $acceptanceText = utf8_decode("Les membres nouvellement élus (selon les résultats de l'élection du Bureau qui sera reporté ci-dessous) acceptent leurs fonctions pour une durée de 1 an.");
        $this->MultiCell(0, 5, $acceptanceText);
        $this->Ln(10);


        // --- 3.2. Clôture de la Séance et Signatures ---
        $this->SetFont('Arial', 'B', 12);
        $this->Cell(0, 7, utf8_decode('3.2. Clôture de la Séance'), 0, 1, 'L');
        $this->SetFont('Arial', '', 10);
        $this->Ln(3);

        // Mise à jour de l'heure de clôture à 16h00
        $this->MultiCell(0, 5, utf8_decode("L'ordre du jour étant épuisé et plus personne ne demandant la parole, le $presidentTitle de séance remercie l'Assemblée de sa participation et prononce la clôture de l'Assemblée Générale à ".$this->main->getClosedAt()->format('H:i')));

        $this->Ln(10);

        // Ajout de la mention "Fait à..."
        $this->SetFont('Arial', '', 10);
        $this->Cell(0, 5, utf8_decode('Fait à Beautor Le '.$this->main->getAgDateAt()->format('d M  Y')), 0, 1, 'L');
        $this->Ln(5); // Espace après la date et avant les titres

        // Signatures
        $this->SetFont('Arial', 'B', 10);
        // Utiliser Cell avec une largeur définie (95mm pour chaque signature sur A4)
        $this->Cell(95, 5, utf8_decode("Le $presidentTitle de Séance"), 0, 0, 'C');
        $this->Cell(95, 5, utf8_decode(""), 0, 1, 'C');

        $this->Ln(5);

        $this->SetFont('Arial', '', 10);
        $this->Cell(95, 5, utf8_decode("{{Signature;width=250;height=25;type=signature}}"), 0, 0, 'C');
        $this->Cell(95, 5, utf8_decode(""), 0, 1, 'C');
        $this->Ln(5);
        $this->Cell(95, 5, utf8_decode($this->main->getPresident()->getName()." ".$this->main->getPresident()->getSurname()), 0, 0, 'C');

        $this->Ln(5);
    }


    /**
     * Écrit la section 1 complète : Constitution et Membres, y compris le quorum.
     */
    public function writeConstitutionAndMembers()
    {
        // 1. Titre de la section principale
        $this->SetFont('Arial', 'B', 14);
        $this->Ln(5); // Plus d'espace pour la nouvelle section
        $this->Cell(0, 8, utf8_decode('1. CONSTITUTION ET OUVERTURE DE SÉANCE'), 0, 1, 'L');
        $this->Ln(3);

        // 2. Début de la sous-section 1.1
        $this->SetFont('Arial', 'B', 12);
        $this->Cell(0, 7, utf8_decode('1.1. Membres présents et absents'), 0, 1, 'L');
        $this->SetFont('Arial', '', 10);
        $this->Ln(3);

        // 3. Initialisation des listes et compteurs pour les listes
        $listPresent = [];
        $listAbsent = [];
        $countPresent = 0;
        $countAbsent = 0;

        // Compteurs pour le Quorum et la Majorité
        $totalMembers = 0; // Tous les membres de l'association
        $totalVoters = 0;  // Membres ayant le droit de vote (Présents ou Représentés)

        // Récupérer tous les membres de l'association
        $allMembers = $this->em->getRepository(Members::class)->findAll();
        $totalMembers = count($allMembers);

        // 4. Traitement et classification des membres
        foreach ($allMembers as $member) {
            /** @var MainMember $mainMemberStatus */
            $mainMemberStatus = $this->main->getMainMembers()->filter(function (MainMember $mainMember) use ($member) {
                // Correspondance de l'entité Members avec son statut MainMember pour cette AG
                return $member->getId() == $mainMember->getMember()->getId();
            })->first();

            if($mainMemberStatus instanceof MainMember && $mainMemberStatus->isVotedAllow()) {
                // Membre ayant le droit de vote (Présent ou Représenté)
                // Liste des votants (présents/représentés) par pseudo
                $listPresent[] = $member->getPseudo();
                $countPresent++;
                $totalVoters++;
            } else {
                // Membre n'ayant pas le droit de vote (Absent ou non éligible)
                // Liste des absents ou non votants par nom complet (Civilité Nom Prénom)
                $listAbsent[] = $member->getCiv()." ".$member->getName()." ".$member->getSurname();
                $countAbsent++;
            }
        }

        // 5. Affichage de la liste des Membres Présents / Votants
        $this->SetFont('Arial', 'B', 10);
        $this->Cell(0, 5, utf8_decode("Membres ayant le droit de vote (Présents ou Représentés) ($countPresent) :"), 0, 1, 'L');
        $this->SetFont('Arial', '', 10);

        if ($countPresent > 0) {
            $this->SetX(20);
            $this->MultiCell(0, 5, utf8_decode(implode(" / ", $listPresent)));
        } else {
            $this->SetX(20);
            $this->Cell(0, 5, utf8_decode("Aucun membre ayant le droit de vote (absence de quorum ou de procuration)."), 0, 1, 'L');
        }
        $this->SetX(10);

        $this->Ln(5);

        // 6. Affichage de la liste des Membres Absents
        $this->SetFont('Arial', 'B', 10);
        $this->Cell(0, 5, utf8_decode("Membres absents ou n'ayant pas le droit de vote ($countAbsent) :"), 0, 1, 'L');
        $this->SetFont('Arial', '', 10);

        if ($countAbsent > 0) {
            $this->SetX(20);
            $this->MultiCell(0, 5, utf8_decode(implode(" / ", $listAbsent)));
        } else {
            $this->SetX(20);
            $this->Cell(0, 5, utf8_decode("Aucun membre absent."), 0, 1, 'L');
        }
        $this->SetX(10);

        $this->Ln(10);

        // 7. Calcul et Affichage du Quorum et de la Majorité

        // Hypothèses standards pour le Quorum et la Majorité (à ajuster selon les statuts)
        // Quorum : 1/3 des membres totaux pour une 1ère convocation d'AG ordinaire (exemple)
        $quorumRequired = (int) ceil($totalMembers / 3);

        // Majorité requise pour une résolution (Majorité simple > 50% des votes exprimés)
        $majorityRequired = (int) floor($totalVoters / 2) + 1;
        $this->nbVote = $totalVoters;
        $this->nbVoteVoix = $majorityRequired;
        // Affichage des résultats
        $this->SetFont('Arial', 'B', 10);
        $this->Cell(0, 5, utf8_decode("Synthèse du Quorum et du Vote :"), 0, 1, 'L');
        $this->SetFont('Arial', '', 10);

        // Ligne 1: Total des membres
        $this->Cell(80, 5, utf8_decode("Total des membres de l'association :"), 0, 0, 'L');
        $this->Cell(20, 5, $totalMembers, 0, 1, 'R');

        // Ligne 2: Nombre de votants
        $this->Cell(80, 5, utf8_decode("Nombre de votants (Présents ou Représentés) :"), 0, 0, 'L');
        $this->Cell(20, 5, $totalVoters, 0, 1, 'R');

        // Ligne 3: Majorité
        $this->Cell(80, 5, utf8_decode("Nombre de voix requis pour la majorité simple :"), 0, 0, 'L');
        $this->Cell(20, 5, $majorityRequired, 0, 1, 'R');

        $this->Ln(2);

        // Ligne 4: Quorum Statut
        $this->SetFont('Arial', 'B', 10);
        $quorumStatus = ($totalVoters >= $quorumRequired)
            ? utf8_decode("QUORUM ATTEINT (requis : $quorumRequired votants)")
            : utf8_decode("QUORUM NON ATTEINT (requis : $quorumRequired votants)");

        $this->SetFillColor(220, 220, 220);
        $this->Cell(0, 7, $quorumStatus, 1, 1, 'C', true);

        $this->SetFont('Arial', '', 10);
        $this->Ln(5); // Espace avant la section 1.2

        // 8. Appel de la sous-section 1.2
        $this->writePresidenceAndSecretariat();

        // 9. Appel de la nouvelle sous-section 1.3
        $this->writeOuvertureSeance();
    }
}
