<?php

declare(strict_types=1);

namespace App\DataFixtures;

use App\Module\Absence\Domain\Entity\AbsenceBalance;
use App\Module\Absence\Domain\Entity\AbsencePolicy;
use App\Module\Absence\Domain\Entity\AbsenceRequest;
use App\Module\Absence\Domain\Enum\AbsenceStatus;
use App\Module\Absence\Domain\Enum\AbsenceType;
use App\Module\Core\Application\Rbac\RbacSeeder;
use App\Module\Core\Domain\Entity\User;
use App\Module\Core\Domain\Enum\ContractType;
use App\Module\Directory\Domain\Entity\Address;
use App\Module\Directory\Domain\Entity\Client;
use App\Module\Directory\Domain\Entity\Prospect;
use App\Module\Directory\Domain\Enum\ProspectStatus;
use App\Module\Integration\Domain\Entity\ZimbraConfiguration;
use App\Module\Mail\Domain\Entity\MailConfiguration;
use App\Module\ProjectManagement\Domain\Entity\Project;
use App\Module\ProjectManagement\Domain\Entity\Task;
use App\Module\ProjectManagement\Domain\Entity\TaskEffort;
use App\Module\ProjectManagement\Domain\Entity\TaskGroup;
use App\Module\ProjectManagement\Domain\Entity\TaskPriority;
use App\Module\ProjectManagement\Domain\Entity\TaskRecurrence;
use App\Module\ProjectManagement\Domain\Entity\TaskStatus;
use App\Module\ProjectManagement\Domain\Entity\TaskTag;
use App\Module\ProjectManagement\Domain\Entity\Workflow;
use App\Module\ProjectManagement\Domain\Enum\RecurrenceType;
use App\Module\ProjectManagement\Domain\Enum\StatusCategory;
use App\Module\TimeTracking\Domain\Entity\TimeEntry;
use DateTimeImmutable;
use DateTimeZone;
use Doctrine\Bundle\FixturesBundle\Fixture;
use Doctrine\Persistence\ObjectManager;
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;

class AppFixtures extends Fixture
{
    public function __construct(
        private readonly UserPasswordHasherInterface $passwordHasher,
        private readonly RbacSeeder $rbacSeeder,
    ) {}

    public function load(ObjectManager $manager): void
    {
        // Users
        $admin = new User();
        $admin->setUsername('admin');
        $admin->setFirstName('Alex');
        $admin->setLastName('Martin');
        $admin->setRoles(['ROLE_ADMIN']);
        $admin->setPassword($this->passwordHasher->hashPassword($admin, 'admin'));
        $admin->setApiToken('dev-mcp-token-for-testing-only-do-not-use-in-production');
        $manager->persist($admin);

        $userAlice = new User();
        $userAlice->setUsername('alice');
        $userAlice->setFirstName('Alice');
        $userAlice->setLastName('Dupont');
        $userAlice->setRoles(['ROLE_USER']);
        $userAlice->setPassword($this->passwordHasher->hashPassword($userAlice, 'alice'));
        $manager->persist($userAlice);

        $userBob = new User();
        $userBob->setUsername('bob');
        $userBob->setFirstName('Bob');
        $userBob->setLastName('Leroy');
        $userBob->setRoles(['ROLE_USER']);
        $userBob->setPassword($this->passwordHasher->hashPassword($userBob, 'bob'));
        $manager->persist($userBob);

        $userCharlie = new User();
        $userCharlie->setUsername('charlie');
        $userCharlie->setFirstName('Charlie');
        $userCharlie->setLastName('Moreau');
        $userCharlie->setRoles(['ROLE_USER']);
        $userCharlie->setPassword($this->passwordHasher->hashPassword($userCharlie, 'charlie'));
        $manager->persist($userCharlie);

        // Clients
        $clientLiot = new Client();
        $clientLiot->setName('LIOT');
        $clientLiot->setEmail('contact@liot.fr');
        $clientLiot->setPhone('05 50 50 50 50');
        $manager->persist($clientLiot);

        $addressLiot = new Address();
        $addressLiot->setLabel('Principale');
        $addressLiot->setStreet('14 allée d\'argenson');
        $addressLiot->setCity('Poitiers');
        $addressLiot->setPostalCode('86100');
        $addressLiot->setCountry('FR');
        $addressLiot->setClient($clientLiot);
        $manager->persist($addressLiot);

        $clientAcme = new Client();
        $clientAcme->setName('ACME Corp');
        $clientAcme->setEmail('contact@acme.com');
        $clientAcme->setPhone('01 23 45 67 89');
        $manager->persist($clientAcme);

        $addressAcme = new Address();
        $addressAcme->setLabel('Principale');
        $addressAcme->setStreet('10 rue de la Paix');
        $addressAcme->setCity('Paris');
        $addressAcme->setPostalCode('75002');
        $addressAcme->setCountry('FR');
        $addressAcme->setClient($clientAcme);
        $manager->persist($addressAcme);

        $clientNova = new Client();
        $clientNova->setName('Nova Tech');
        $clientNova->setEmail('info@novatech.io');
        $clientNova->setPhone('04 56 78 90 12');
        $manager->persist($clientNova);

        $addressNova = new Address();
        $addressNova->setLabel('Principale');
        $addressNova->setStreet('5 avenue Jean Jaurès');
        $addressNova->setCity('Lyon');
        $addressNova->setPostalCode('69007');
        $addressNova->setCountry('FR');
        $addressNova->setClient($clientNova);
        $manager->persist($addressNova);

        // Prospects
        $prospectLead = new Prospect();
        $prospectLead->setCompany('Atelier Dupont');
        $prospectLead->setEmail('marie@atelier-dupont.fr');
        $prospectLead->setPhone('06 11 22 33 44');
        $prospectLead->setStatus(ProspectStatus::New);
        $prospectLead->setSource('Site web');
        $prospectLead->setNotes('Demande de devis via le formulaire de contact.');
        $manager->persist($prospectLead);

        $addressLead = new Address();
        $addressLead->setLabel('Principale');
        $addressLead->setCity('Nantes');
        $addressLead->setPostalCode('44000');
        $addressLead->setCountry('FR');
        $addressLead->setProspect($prospectLead);
        $manager->persist($addressLead);

        $prospectQualified = new Prospect();
        $prospectQualified->setCompany('Martin & Fils');
        $prospectQualified->setEmail('contact@martin-fils.fr');
        $prospectQualified->setPhone('07 55 66 77 88');
        $prospectQualified->setStatus(ProspectStatus::Qualified);
        $prospectQualified->setSource('Salon professionnel');
        $manager->persist($prospectQualified);

        $addressQualified = new Address();
        $addressQualified->setLabel('Principale');
        $addressQualified->setStreet('22 rue du Commerce');
        $addressQualified->setCity('Bordeaux');
        $addressQualified->setPostalCode('33000');
        $addressQualified->setCountry('FR');
        $addressQualified->setProspect($prospectQualified);
        $manager->persist($addressQualified);

        $prospectWon = new Prospect();
        $prospectWon->setCompany('ACME Corp');
        $prospectWon->setEmail('contact@acme.com');
        $prospectWon->setPhone('01 23 45 67 89');
        $prospectWon->setStatus(ProspectStatus::Won);
        $prospectWon->setSource('Recommandation');
        $prospectWon->setConvertedClient($clientAcme);
        $manager->persist($prospectWon);

        $addressWon = new Address();
        $addressWon->setLabel('Principale');
        $addressWon->setCity('Paris');
        $addressWon->setPostalCode('75002');
        $addressWon->setCountry('FR');
        $addressWon->setProspect($prospectWon);
        $manager->persist($addressWon);

        // Workflow par défaut
        $standardWorkflow = new Workflow();
        $standardWorkflow->setName('Standard');
        $standardWorkflow->setIsDefault(true);
        $standardWorkflow->setPosition(0);
        $manager->persist($standardWorkflow);

        // Task Statuses (rattachés au workflow Standard)
        $defaultStatuses = [
            ['A faire', '#222783', 0, StatusCategory::Todo, false],
            ['En cours', '#4A90D9', 1, StatusCategory::InProgress, false],
            ['Bloqué', '#C62828', 2, StatusCategory::Blocked, false],
            ['En attente de validation', '#FF8F00', 3, StatusCategory::Review, false],
            ['Terminé', '#26A69A', 4, StatusCategory::Done, true],
        ];

        $statusObjects = [];
        foreach ($defaultStatuses as [$label, $color, $position, $category, $isFinal]) {
            $status = new TaskStatus();
            $status->setLabel($label);
            $status->setColor($color);
            $status->setPosition($position);
            $status->setCategory($category);
            $status->setIsFinal($isFinal);
            $standardWorkflow->addStatus($status);
            $manager->persist($status);
            $statusObjects[$label] = $status;
        }

        $statusTodo       = $statusObjects['A faire'];
        $statusInProgress = $statusObjects['En cours'];
        $statusBlocked    = $statusObjects['Bloqué'];
        $statusReview     = $statusObjects['En attente de validation'];
        $statusDone       = $statusObjects['Terminé'];

        // Projets
        $projectSirh = new Project();
        $projectSirh->setCode('SIRH');
        $projectSirh->setName('SIRH');
        $projectSirh->setDescription('Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer ac blandit turpis.');
        $projectSirh->setColor('#222783');
        $projectSirh->setClient($clientLiot);
        $projectSirh->setWorkflow($standardWorkflow);
        $manager->persist($projectSirh);

        $projectCrm = new Project();
        $projectCrm->setCode('CRM');
        $projectCrm->setName('CRM');
        $projectCrm->setDescription('Gestion de la relation client et suivi commercial.');
        $projectCrm->setColor('#E91E63');
        $projectCrm->setClient($clientAcme);
        $projectCrm->setWorkflow($standardWorkflow);
        $manager->persist($projectCrm);

        $projectErp = new Project();
        $projectErp->setCode('ERP');
        $projectErp->setName('ERP');
        $projectErp->setDescription('Planification des ressources et gestion des stocks.');
        $projectErp->setColor('#4A90D9');
        $projectErp->setClient($clientNova);
        $projectErp->setWorkflow($standardWorkflow);
        $manager->persist($projectErp);

        $projectInterne = new Project();
        $projectInterne->setCode('SITE');
        $projectInterne->setName('Site vitrine');
        $projectInterne->setDescription('Refonte du site web corporate.');
        $projectInterne->setColor('#26A69A');
        $projectInterne->setClient(null);
        $projectInterne->setWorkflow($standardWorkflow);
        $manager->persist($projectInterne);

        // Task Efforts
        $effortS = new TaskEffort();
        $effortS->setLabel('S');
        $manager->persist($effortS);

        $effortM = new TaskEffort();
        $effortM->setLabel('M');
        $manager->persist($effortM);

        $effortL = new TaskEffort();
        $effortL->setLabel('L');
        $manager->persist($effortL);

        $effortXL = new TaskEffort();
        $effortXL->setLabel('XL');
        $manager->persist($effortXL);

        $effortXXL = new TaskEffort();
        $effortXXL->setLabel('XXL');
        $manager->persist($effortXXL);

        // Task Priorities
        $priorityLow = new TaskPriority();
        $priorityLow->setLabel('Basse');
        $priorityLow->setColor('#222783');
        $manager->persist($priorityLow);

        $priorityMedium = new TaskPriority();
        $priorityMedium->setLabel('Moyen');
        $priorityMedium->setColor('#FF8F00');
        $manager->persist($priorityMedium);

        $priorityHigh = new TaskPriority();
        $priorityHigh->setLabel('Haute');
        $priorityHigh->setColor('#C62828');
        $manager->persist($priorityHigh);

        // Task Tags
        $tagPassword = new TaskTag();
        $tagPassword->setLabel('Gestion mdp');
        $tagPassword->setColor('#C62828');
        $manager->persist($tagPassword);

        $tagAuth = new TaskTag();
        $tagAuth->setLabel('Connexion');
        $tagAuth->setColor('#FF8F00');
        $manager->persist($tagAuth);

        $tagCalendar = new TaskTag();
        $tagCalendar->setLabel('Calendrier');
        $tagCalendar->setColor('#222783');
        $manager->persist($tagCalendar);

        // Task Groups — SIRH
        $groupFrontend = new TaskGroup();
        $groupFrontend->setTitle('Frontend');
        $groupFrontend->setColor('#4A90D9');
        $groupFrontend->setProject($projectSirh);
        $manager->persist($groupFrontend);

        $groupBackend = new TaskGroup();
        $groupBackend->setTitle('Backend');
        $groupBackend->setColor('#26A69A');
        $groupBackend->setProject($projectSirh);
        $manager->persist($groupBackend);

        // Task Groups — CRM
        $groupCrmUi = new TaskGroup();
        $groupCrmUi->setTitle('Interface');
        $groupCrmUi->setColor('#E91E63');
        $groupCrmUi->setProject($projectCrm);
        $manager->persist($groupCrmUi);

        $groupCrmApi = new TaskGroup();
        $groupCrmApi->setTitle('API');
        $groupCrmApi->setColor('#9C27B0');
        $groupCrmApi->setProject($projectCrm);
        $manager->persist($groupCrmApi);

        // Task Groups — ERP
        $groupErpStock = new TaskGroup();
        $groupErpStock->setTitle('Stocks');
        $groupErpStock->setColor('#4A90D9');
        $groupErpStock->setProject($projectErp);
        $manager->persist($groupErpStock);

        $groupErpFacturation = new TaskGroup();
        $groupErpFacturation->setTitle('Facturation');
        $groupErpFacturation->setColor('#FF8F00');
        $groupErpFacturation->setProject($projectErp);
        $manager->persist($groupErpFacturation);

        // Task Groups — Site vitrine
        $groupSiteDesign = new TaskGroup();
        $groupSiteDesign->setTitle('Design');
        $groupSiteDesign->setColor('#26A69A');
        $groupSiteDesign->setProject($projectInterne);
        $manager->persist($groupSiteDesign);

        $groupSiteContenu = new TaskGroup();
        $groupSiteContenu->setTitle('Contenu');
        $groupSiteContenu->setColor('#795548');
        $groupSiteContenu->setProject($projectInterne);
        $manager->persist($groupSiteContenu);

        // =============================================
        // Tasks — SIRH
        // =============================================
        $task1 = new Task();
        $task1->setNumber(1);
        $task1->setTitle('Création d\'une page de login');
        $task1->setStatus($statusTodo);
        $task1->setEffort($effortXXL);
        $task1->setPriority($priorityLow);
        $task1->setAssignee($admin);
        $task1->setGroup($groupFrontend);
        $task1->setProject($projectSirh);
        $task1->addTag($tagPassword);
        $manager->persist($task1);

        $task2 = new Task();
        $task2->setNumber(2);
        $task2->setTitle('Intégration SSO');
        $task2->setStatus($statusTodo);
        $task2->setEffort($effortL);
        $task2->setPriority($priorityHigh);
        $task2->setAssignee($userAlice);
        $task2->setGroup($groupFrontend);
        $task2->setProject($projectSirh);
        $task2->addTag($tagAuth);
        $task2->setScheduledStart(new DateTimeImmutable('next monday 09:00'));
        $task2->setScheduledEnd(new DateTimeImmutable('next monday 17:00'));
        $task2->setSyncToCalendar(false);
        $manager->persist($task2);

        $task3 = new Task();
        $task3->setNumber(3);
        $task3->setTitle('API d\'authentification');
        $task3->setStatus($statusInProgress);
        $task3->setEffort($effortXXL);
        $task3->setPriority($priorityLow);
        $task3->setAssignee($admin);
        $task3->setGroup($groupBackend);
        $task3->setProject($projectSirh);
        $task3->addTag($tagPassword);
        $manager->persist($task3);

        $task4 = new Task();
        $task4->setNumber(4);
        $task4->setTitle('Gestion des tokens JWT');
        $task4->setStatus($statusBlocked);
        $task4->setEffort($effortXXL);
        $task4->setPriority($priorityLow);
        $task4->setAssignee($userBob);
        $task4->setProject($projectSirh);
        $task4->addTag($tagPassword);
        $manager->persist($task4);

        $task5 = new Task();
        $task5->setNumber(5);
        $task5->setTitle('Calendrier des congés');
        $task5->setStatus($statusReview);
        $task5->setEffort($effortXXL);
        $task5->setPriority($priorityMedium);
        $task5->setAssignee($userCharlie);
        $task5->setProject($projectSirh);
        $task5->addTag($tagCalendar);
        $task5->setDeadline(new DateTimeImmutable('+2 weeks'));
        $task5->setSyncToCalendar(false);
        $manager->persist($task5);

        $task6 = new Task();
        $task6->setNumber(6);
        $task6->setTitle('Page de réinitialisation mdp');
        $task6->setStatus($statusDone);
        $task6->setEffort($effortXXL);
        $task6->setPriority($priorityHigh);
        $task6->setAssignee($admin);
        $task6->setProject($projectSirh);
        $task6->addTag($tagAuth);
        $manager->persist($task6);

        // =============================================
        // Tasks — CRM
        // =============================================
        $taskCrm1 = new Task();
        $taskCrm1->setNumber(1);
        $taskCrm1->setTitle('Liste des contacts');
        $taskCrm1->setStatus($statusDone);
        $taskCrm1->setEffort($effortL);
        $taskCrm1->setPriority($priorityHigh);
        $taskCrm1->setAssignee($admin);
        $taskCrm1->setGroup($groupCrmUi);
        $taskCrm1->setProject($projectCrm);
        $manager->persist($taskCrm1);

        $taskCrm2 = new Task();
        $taskCrm2->setNumber(2);
        $taskCrm2->setTitle('Fiche contact détaillée');
        $taskCrm2->setStatus($statusInProgress);
        $taskCrm2->setEffort($effortM);
        $taskCrm2->setPriority($priorityMedium);
        $taskCrm2->setAssignee($userAlice);
        $taskCrm2->setGroup($groupCrmUi);
        $taskCrm2->setProject($projectCrm);
        $manager->persist($taskCrm2);

        $taskCrm3 = new Task();
        $taskCrm3->setNumber(3);
        $taskCrm3->setTitle('Import CSV contacts');
        $taskCrm3->setStatus($statusTodo);
        $taskCrm3->setEffort($effortXL);
        $taskCrm3->setPriority($priorityLow);
        $taskCrm3->setAssignee($admin);
        $taskCrm3->setGroup($groupCrmApi);
        $taskCrm3->setProject($projectCrm);
        $manager->persist($taskCrm3);

        $taskCrm4 = new Task();
        $taskCrm4->setNumber(4);
        $taskCrm4->setTitle('Pipeline de vente');
        $taskCrm4->setStatus($statusInProgress);
        $taskCrm4->setEffort($effortXXL);
        $taskCrm4->setPriority($priorityHigh);
        $taskCrm4->setAssignee($userBob);
        $taskCrm4->setGroup($groupCrmUi);
        $taskCrm4->setProject($projectCrm);
        $taskCrm4->addTag($tagCalendar);
        $manager->persist($taskCrm4);

        $taskCrm5 = new Task();
        $taskCrm5->setNumber(5);
        $taskCrm5->setTitle('API recherche contacts');
        $taskCrm5->setStatus($statusReview);
        $taskCrm5->setEffort($effortM);
        $taskCrm5->setPriority($priorityMedium);
        $taskCrm5->setAssignee($admin);
        $taskCrm5->setGroup($groupCrmApi);
        $taskCrm5->setProject($projectCrm);
        $manager->persist($taskCrm5);

        // =============================================
        // Tasks — ERP
        // =============================================
        $taskErp1 = new Task();
        $taskErp1->setNumber(1);
        $taskErp1->setTitle('Tableau de bord stocks');
        $taskErp1->setStatus($statusDone);
        $taskErp1->setEffort($effortL);
        $taskErp1->setPriority($priorityHigh);
        $taskErp1->setAssignee($admin);
        $taskErp1->setGroup($groupErpStock);
        $taskErp1->setProject($projectErp);
        $manager->persist($taskErp1);

        $taskErp2 = new Task();
        $taskErp2->setNumber(2);
        $taskErp2->setTitle('Alertes stock bas');
        $taskErp2->setStatus($statusInProgress);
        $taskErp2->setEffort($effortM);
        $taskErp2->setPriority($priorityHigh);
        $taskErp2->setAssignee($userCharlie);
        $taskErp2->setGroup($groupErpStock);
        $taskErp2->setProject($projectErp);
        $manager->persist($taskErp2);

        $taskErp3 = new Task();
        $taskErp3->setNumber(3);
        $taskErp3->setTitle('Génération factures PDF');
        $taskErp3->setStatus($statusTodo);
        $taskErp3->setEffort($effortXXL);
        $taskErp3->setPriority($priorityMedium);
        $taskErp3->setAssignee($admin);
        $taskErp3->setGroup($groupErpFacturation);
        $taskErp3->setProject($projectErp);
        $taskErp3->setDeadline(new DateTimeImmutable('+1 month'));
        $taskErp3->setSyncToCalendar(false);
        $manager->persist($taskErp3);

        $taskErp4 = new Task();
        $taskErp4->setNumber(4);
        $taskErp4->setTitle('Historique mouvements stock');
        $taskErp4->setStatus($statusReview);
        $taskErp4->setEffort($effortL);
        $taskErp4->setPriority($priorityLow);
        $taskErp4->setAssignee($admin);
        $taskErp4->setGroup($groupErpStock);
        $taskErp4->setProject($projectErp);
        $manager->persist($taskErp4);

        $taskErp5 = new Task();
        $taskErp5->setNumber(5);
        $taskErp5->setTitle('Export comptable');
        $taskErp5->setStatus($statusBlocked);
        $taskErp5->setEffort($effortXL);
        $taskErp5->setPriority($priorityHigh);
        $taskErp5->setAssignee($admin);
        $taskErp5->setGroup($groupErpFacturation);
        $taskErp5->setProject($projectErp);
        $manager->persist($taskErp5);

        $taskErp6 = new Task();
        $taskErp6->setNumber(6);
        $taskErp6->setTitle('Inventaire annuel');
        $taskErp6->setStatus($statusTodo);
        $taskErp6->setEffort($effortS);
        $taskErp6->setPriority($priorityLow);
        $taskErp6->setAssignee($admin);
        $taskErp6->setGroup($groupErpStock);
        $taskErp6->setProject($projectErp);
        $taskErp6->addTag($tagCalendar);
        $manager->persist($taskErp6);

        // =============================================
        // Tasks — Site vitrine
        // =============================================
        $taskSite1 = new Task();
        $taskSite1->setNumber(1);
        $taskSite1->setTitle('Maquette page d\'accueil');
        $taskSite1->setStatus($statusDone);
        $taskSite1->setEffort($effortM);
        $taskSite1->setPriority($priorityHigh);
        $taskSite1->setAssignee($admin);
        $taskSite1->setGroup($groupSiteDesign);
        $taskSite1->setProject($projectInterne);
        $manager->persist($taskSite1);

        $taskSite2 = new Task();
        $taskSite2->setNumber(2);
        $taskSite2->setTitle('Intégration responsive');
        $taskSite2->setStatus($statusInProgress);
        $taskSite2->setEffort($effortL);
        $taskSite2->setPriority($priorityMedium);
        $taskSite2->setAssignee($userAlice);
        $taskSite2->setGroup($groupSiteDesign);
        $taskSite2->setProject($projectInterne);
        $manager->persist($taskSite2);

        $taskSite3 = new Task();
        $taskSite3->setNumber(3);
        $taskSite3->setTitle('Rédaction page "À propos"');
        $taskSite3->setStatus($statusTodo);
        $taskSite3->setEffort($effortS);
        $taskSite3->setPriority($priorityLow);
        $taskSite3->setAssignee($admin);
        $taskSite3->setGroup($groupSiteContenu);
        $taskSite3->setProject($projectInterne);
        $manager->persist($taskSite3);

        $taskSite4 = new Task();
        $taskSite4->setNumber(4);
        $taskSite4->setTitle('Formulaire de contact');
        $taskSite4->setStatus($statusReview);
        $taskSite4->setEffort($effortM);
        $taskSite4->setPriority($priorityMedium);
        $taskSite4->setAssignee($admin);
        $taskSite4->setGroup($groupSiteDesign);
        $taskSite4->setProject($projectInterne);
        $taskSite4->addTag($tagAuth);
        $manager->persist($taskSite4);

        $taskSite5 = new Task();
        $taskSite5->setNumber(5);
        $taskSite5->setTitle('SEO et métadonnées');
        $taskSite5->setStatus($statusTodo);
        $taskSite5->setEffort($effortS);
        $taskSite5->setPriority($priorityHigh);
        $taskSite5->setAssignee($admin);
        $taskSite5->setGroup($groupSiteContenu);
        $taskSite5->setProject($projectInterne);
        $manager->persist($taskSite5);

        // =============================================
        // Time Entries — tous les projets
        // =============================================
        $timeEntryData = [
            // SIRH — lundi à vendredi
            ['title' => 'Réunion', 'project' => $projectSirh, 'tag' => $tagAuth, 'start' => '09:00', 'stop' => '09:45', 'day' => 1],
            ['title' => 'Page accueil', 'project' => $projectSirh, 'tag' => $tagPassword, 'start' => '10:00', 'stop' => '12:00', 'day' => 0],
            ['title' => 'Design admin', 'project' => $projectSirh, 'tag' => $tagAuth, 'start' => '09:30', 'stop' => '11:00', 'day' => 2],
            ['title' => 'Page accueil', 'project' => $projectSirh, 'tag' => $tagPassword, 'start' => '10:30', 'stop' => '12:15', 'day' => 1],
            ['title' => 'System os', 'project' => $projectSirh, 'tag' => $tagCalendar, 'start' => '13:00', 'stop' => '15:30', 'day' => 0],
            ['title' => 'Login', 'project' => $projectSirh, 'tag' => $tagPassword, 'start' => '13:00', 'stop' => '15:00', 'day' => 1],
            ['title' => 'Script vault', 'project' => $projectSirh, 'tag' => $tagCalendar, 'start' => '10:00', 'stop' => '12:00', 'day' => 3],
            ['title' => 'Script backup BDD', 'project' => $projectSirh, 'tag' => $tagAuth, 'start' => '13:30', 'stop' => '15:00', 'day' => 3],
            ['title' => 'Maquette', 'project' => $projectSirh, 'tag' => null, 'start' => '09:00', 'stop' => '11:00', 'day' => 4],
            ['title' => 'PC compta', 'project' => $projectSirh, 'tag' => null, 'start' => '13:30', 'stop' => '15:30', 'day' => 4],
            // CRM — lundi à vendredi
            ['title' => 'Liste contacts UI', 'project' => $projectCrm, 'tag' => null, 'start' => '08:30', 'stop' => '10:00', 'day' => 0],
            ['title' => 'Fiche contact', 'project' => $projectCrm, 'tag' => null, 'start' => '15:30', 'stop' => '17:00', 'day' => 0],
            ['title' => 'Pipeline vente', 'project' => $projectCrm, 'tag' => $tagCalendar, 'start' => '08:30', 'stop' => '09:30', 'day' => 1],
            ['title' => 'Import CSV', 'project' => $projectCrm, 'tag' => null, 'start' => '15:30', 'stop' => '17:30', 'day' => 2],
            ['title' => 'API recherche', 'project' => $projectCrm, 'tag' => null, 'start' => '08:30', 'stop' => '10:00', 'day' => 3],
            ['title' => 'Tests unitaires CRM', 'project' => $projectCrm, 'tag' => null, 'start' => '15:30', 'stop' => '17:00', 'day' => 3],
            ['title' => 'Revue pipeline', 'project' => $projectCrm, 'tag' => $tagCalendar, 'start' => '08:00', 'stop' => '09:00', 'day' => 4],
            // ERP — lundi à vendredi
            ['title' => 'Dashboard stocks', 'project' => $projectErp, 'tag' => null, 'start' => '16:00', 'stop' => '17:30', 'day' => 1],
            ['title' => 'Alertes stock bas', 'project' => $projectErp, 'tag' => null, 'start' => '11:30', 'stop' => '12:30', 'day' => 2],
            ['title' => 'Factures PDF', 'project' => $projectErp, 'tag' => null, 'start' => '15:30', 'stop' => '17:30', 'day' => 4],
            ['title' => 'Mouvement stock', 'project' => $projectErp, 'tag' => null, 'start' => '09:00', 'stop' => '10:30', 'day' => 0],
            ['title' => 'Export comptable', 'project' => $projectErp, 'tag' => $tagCalendar, 'start' => '13:00', 'stop' => '14:30', 'day' => 2],
            ['title' => 'Inventaire', 'project' => $projectErp, 'tag' => null, 'start' => '13:30', 'stop' => '15:00', 'day' => 4],
            // Site vitrine — lundi à jeudi
            ['title' => 'Maquette accueil', 'project' => $projectInterne, 'tag' => null, 'start' => '16:00', 'stop' => '17:30', 'day' => 0],
            ['title' => 'Responsive mobile', 'project' => $projectInterne, 'tag' => null, 'start' => '16:00', 'stop' => '17:30', 'day' => 2],
            ['title' => 'Rédaction contenu', 'project' => $projectInterne, 'tag' => null, 'start' => '15:30', 'stop' => '17:00', 'day' => 1],
            ['title' => 'Formulaire contact', 'project' => $projectInterne, 'tag' => $tagAuth, 'start' => '16:00', 'stop' => '17:30', 'day' => 3],
            ['title' => 'SEO meta tags', 'project' => $projectInterne, 'tag' => null, 'start' => '11:00', 'stop' => '12:00', 'day' => 4],
        ];

        $monday = new DateTimeImmutable('monday this week', new DateTimeZone('UTC'));

        foreach ($timeEntryData as $data) {
            $entry = new TimeEntry();
            $entry->setTitle($data['title']);
            $entry->setUser($admin);
            $entry->setProject($data['project']);
            $entry->setStartedAt($monday->modify("+{$data['day']} days")->modify($data['start']));
            $entry->setStoppedAt($monday->modify("+{$data['day']} days")->modify($data['stop']));
            if ($data['tag']) {
                $entry->addTag($data['tag']);
            }
            $manager->persist($entry);
        }

        // =============================================
        // Zimbra Configuration
        // =============================================
        $zimbraConfig = new ZimbraConfiguration();
        $zimbraConfig->setServerUrl('https://mail.ovh.com');
        $zimbraConfig->setUsername('lesstime@ovh.fr');
        $zimbraConfig->setCalendarPath('/dav/lesstime@ovh.fr/Calendar/');
        $zimbraConfig->setEnabled(false);
        $manager->persist($zimbraConfig);

        // =============================================
        // Task Recurrence — exemple hebdomadaire
        // =============================================
        $recurrence = new TaskRecurrence();
        $recurrence->setType(RecurrenceType::Weekly);
        $recurrence->setInterval(1);
        $recurrence->setDaysOfWeek(['monday', 'wednesday', 'friday']);
        $manager->persist($recurrence);

        $taskRecurring = new Task();
        $taskRecurring->setNumber(7);
        $taskRecurring->setTitle('Réunion de suivi hebdomadaire');
        $taskRecurring->setStatus($statusTodo);
        $taskRecurring->setEffort($effortS);
        $taskRecurring->setPriority($priorityMedium);
        $taskRecurring->setAssignee($admin);
        $taskRecurring->setProject($projectSirh);
        $taskRecurring->setScheduledStart(new DateTimeImmutable('next monday 10:00'));
        $taskRecurring->setScheduledEnd(new DateTimeImmutable('next monday 10:30'));
        $taskRecurring->setSyncToCalendar(false);
        $taskRecurring->setRecurrence($recurrence);
        $manager->persist($taskRecurring);

        // =============================================
        // Mail Configuration
        // =============================================
        $mailConfig = new MailConfiguration();
        $mailConfig->setImapHost('ssl0.ovh.net');
        $mailConfig->setImapPort(993);
        $mailConfig->setImapEncryption('ssl');
        $mailConfig->setSmtpHost('ssl0.ovh.net');
        $mailConfig->setSmtpPort(465);
        $mailConfig->setSmtpEncryption('ssl');
        $mailConfig->setUsername('lesstime@ovh.fr');
        $mailConfig->setSentFolderPath('Sent');
        $mailConfig->setEnabled(false);
        $manager->persist($mailConfig);

        // =============================================
        // Absence management — policies, employees, balances, requests
        // =============================================

        // Default policies for the absence types (legal defaults, editable by admin)
        $policyData = [
            // [type, daysPerYear, daysPerEvent, justifRequired, noticeDays, workingDaysOnly]
            [AbsenceType::PaidLeave, 25.0, null, false, 30, true],
            [AbsenceType::MarriagePacs, null, 4.0, true, 0, true],
            [AbsenceType::Birth, null, 3.0, true, 0, true],
            // Bereavement: no fixed entitlement — depends on the relationship to
            // the deceased (legal minimums recalled in the help), reason required.
            [AbsenceType::Bereavement, null, null, true, 0, true],
            [AbsenceType::ParentalLeave, null, null, true, 30, true],
            [AbsenceType::SickLeave, null, null, true, 0, true],
        ];

        foreach ($policyData as [$type, $daysPerYear, $daysPerEvent, $justif, $notice, $workingDaysOnly]) {
            $policy = new AbsencePolicy();
            $policy->setType($type);
            $policy->setDaysPerYear($daysPerYear);
            $policy->setDaysPerEvent($daysPerEvent);
            $policy->setJustificationRequired($justif);
            $policy->setNoticeDays($notice);
            $policy->setCountWorkingDaysOnly($workingDaysOnly);
            $policy->setActive(true);
            $manager->persist($policy);
        }

        // Mark internal users as employees
        $admin->setIsEmployee(true);
        $admin->setHireDate(new DateTimeImmutable('2020-01-15'));
        $admin->setContractType(ContractType::Cdi);

        $userAlice->setIsEmployee(true);
        $userAlice->setHireDate(new DateTimeImmutable('2022-09-01'));
        $userAlice->setContractType(ContractType::Cdi);

        $userBob->setIsEmployee(true);
        $userBob->setHireDate(new DateTimeImmutable('2023-03-10'));
        $userBob->setContractType(ContractType::Cdd);
        $userBob->setWorkTimeRatio(0.8);

        // Paid-leave balances for the current reference period (June 1st → May 31st)
        $cpPeriod    = '2025-2026';
        $balanceData = [
            // [user, acquired (N-1), acquiring (N, en cours), taken, pending]
            // Alice's `pending` matches her pending CP request below (same 2025-2026 period).
            [$admin, 10.0, 22.5, 5.0, 0.0],
            [$userAlice, 8.0, 18.0, 2.0, 4.0],
            [$userBob, 0.0, 14.0, 0.0, 0.0],
        ];

        foreach ($balanceData as [$bUser, $acquired, $acquiring, $taken, $pending]) {
            $balance = new AbsenceBalance();
            $balance->setUser($bUser);
            $balance->setType(AbsenceType::PaidLeave);
            $balance->setPeriod($cpPeriod);
            $balance->setAcquired($acquired);
            $balance->setAcquiring($acquiring);
            $balance->setTaken($taken);
            $balance->setPending($pending);
            $manager->persist($balance);
        }

        // Demo requests
        $approvedCp = new AbsenceRequest();
        $approvedCp->setUser($admin);
        $approvedCp->setType(AbsenceType::PaidLeave);
        $approvedCp->setStartDate(new DateTimeImmutable('2026-04-13'));
        $approvedCp->setEndDate(new DateTimeImmutable('2026-04-17'));
        $approvedCp->setCountedDays(5.0);
        $approvedCp->setReason('Vacances de printemps');
        $approvedCp->setStatus(AbsenceStatus::Approved);
        $approvedCp->setCreatedAt(new DateTimeImmutable('2026-03-10'));
        $approvedCp->setReviewedAt(new DateTimeImmutable('2026-03-11'));
        $approvedCp->setReviewedBy($admin);
        $manager->persist($approvedCp);

        // Pending CP within Alice's current reference period (2025-2026), so the
        // reserved days line up with her balance's `pending` bucket above.
        // Tue 26 → Fri 29 May 2026 = 4 working days (Pentecost Mon 25/05 excluded).
        $pendingCp = new AbsenceRequest();
        $pendingCp->setUser($userAlice);
        $pendingCp->setType(AbsenceType::PaidLeave);
        $pendingCp->setStartDate(new DateTimeImmutable('2026-05-26'));
        $pendingCp->setEndDate(new DateTimeImmutable('2026-05-29'));
        $pendingCp->setCountedDays(4.0);
        $pendingCp->setStatus(AbsenceStatus::Pending);
        $pendingCp->setCreatedAt(new DateTimeImmutable('-2 days'));
        $manager->persist($pendingCp);

        $pendingMarriage = new AbsenceRequest();
        $pendingMarriage->setUser($userBob);
        $pendingMarriage->setType(AbsenceType::MarriagePacs);
        $pendingMarriage->setStartDate(new DateTimeImmutable('2026-07-06'));
        $pendingMarriage->setEndDate(new DateTimeImmutable('2026-07-09'));
        $pendingMarriage->setCountedDays(4.0);
        $pendingMarriage->setReason('Mariage');
        $pendingMarriage->setStatus(AbsenceStatus::Pending);
        $pendingMarriage->setCreatedAt(new DateTimeImmutable('-1 day'));
        $manager->persist($pendingMarriage);

        $manager->flush();

        // Seed des rôles système RBAC (admin, user). Idempotent ; aucune matrice
        // métier attachée (cf. Décision 4 : les modules métier arrivent en 2.x).
        $this->rbacSeeder->ensureSystemRoles();
    }
}
