<?php

declare(strict_types=1);

namespace App\DataFixtures;

use App\Entity\AnneeScolaire;
use App\Entity\Classe;
use App\Entity\Ecole;
use App\Entity\Niveau;
use App\Entity\Section;
use Doctrine\Bundle\FixturesBundle\Fixture;
use Doctrine\Common\DataFixtures\DependentFixtureInterface;
use Doctrine\Persistence\ObjectManager;

final class AcademicFixtures extends Fixture implements DependentFixtureInterface
{
    public function load(ObjectManager $manager): void
    {
        $ecoleRepository = $manager->getRepository(Ecole::class);

        $qamar = $ecoleRepository->findOneBy(['slug' => 'qamar']);
        if ($qamar instanceof Ecole) {
            $this->syncQamar($manager, $qamar);
        }

        $daroulIlm = $ecoleRepository->findOneBy(['slug' => 'daroul-ilm']);
        if ($daroulIlm instanceof Ecole) {
            $this->syncDaroulIlm($manager, $daroulIlm);
        }

        $sahaba = $ecoleRepository->findOneBy(['slug' => 'sahaba']);
        if ($sahaba instanceof Ecole) {
            $this->syncSahaba($manager, $sahaba);
        }

        $manager->flush();
    }

    public function getDependencies(): array
    {
        return [AppFixtures::class];
    }

    private function syncQamar(ObjectManager $manager, Ecole $ecole): void
    {
        $section = $this->syncSection($manager, $ecole, [
            'nom' => 'Section femmes en ligne',
            'slug' => 'section-femmes-en-ligne',
            'description' => 'Cours en ligne dédiés aux femmes pour l’apprentissage progressif de la Qaida Nouraniyya, la lecture du Qur’an et la mémorisation.',
            'type' => 'EN_LIGNE',
            'publicCible' => 'Femmes',
            'ordre' => 1,
            'active' => true,
            'legacySlugs' => [],
        ]);

        $annee = $this->syncAnnee($manager, $ecole, [
            'libelle' => 'Année 2026',
            'dateDebut' => '2026-05-02',
            'dateFin' => '2027-04-30',
            'statut' => 'ACTIVE',
            'active' => true,
            'section' => null,
        ]);

        $niveaux = [
            'qaida-nouraniyya' => $this->syncNiveau($manager, $ecole, $section, [
                'nom' => 'Qaida Nouraniyya',
                'slug' => 'qaida-nouraniyya',
                'description' => 'Apprentissage du décodage et des bases de lecture à travers la méthode Qaida Nouraniyya.',
                'ordre' => 1,
                'active' => true,
                'legacySlugs' => [],
            ]),
            'amelioration-lecture-quran' => $this->syncNiveau($manager, $ecole, $section, [
                'nom' => 'Amélioration Lecture du Qur’an',
                'slug' => 'amelioration-lecture-quran',
                'description' => 'Renforcement de la fluidité, de la correction et de la qualité de lecture du Noble Qur’an.',
                'ordre' => 2,
                'active' => true,
                'legacySlugs' => ['amelioration-lecture'],
            ]),
            'memorisation' => $this->syncNiveau($manager, $ecole, $section, [
                'nom' => 'Mémorisation',
                'slug' => 'memorisation',
                'description' => 'Programme progressif de mémorisation avec suivi et révision.',
                'ordre' => 3,
                'active' => true,
                'legacySlugs' => [],
            ]),
        ];

        foreach ([
            [
                'nom' => 'Qaida Nouraniyya - Groupe A',
                'slug' => 'qaida-nouraniyya-groupe-a',
                'niveau' => $niveaux['qaida-nouraniyya'],
                'langue' => 'FRANCAIS',
                'sexe' => 'FEMME',
                'mode' => 'EN_LIGNE',
                'capacite' => 30,
                'joursCours' => 'Mardi, Jeudi',
                'heureDebut' => '20:00',
                'heureFin' => '21:30',
                'tarifDefaut' => '10000',
                'active' => true,
                'legacySlugs' => ['qaida-groupe-a'],
            ],
            [
                'nom' => 'Lecture Qur’an - Groupe A',
                'slug' => 'lecture-quran-groupe-a',
                'niveau' => $niveaux['amelioration-lecture-quran'],
                'langue' => 'FRANCAIS',
                'sexe' => 'FEMME',
                'mode' => 'EN_LIGNE',
                'capacite' => 30,
                'joursCours' => 'Lundi, Mercredi',
                'heureDebut' => '20:00',
                'heureFin' => '21:30',
                'tarifDefaut' => '10000',
                'active' => true,
                'legacySlugs' => ['lecture-groupe-a'],
            ],
            [
                'nom' => 'Mémorisation - Groupe A',
                'slug' => 'memorisation-groupe-a',
                'niveau' => $niveaux['memorisation'],
                'langue' => 'FRANCAIS',
                'sexe' => 'FEMME',
                'mode' => 'EN_LIGNE',
                'capacite' => 25,
                'joursCours' => 'Samedi, Dimanche',
                'heureDebut' => '07:00',
                'heureFin' => '08:30',
                'tarifDefaut' => '10000',
                'active' => true,
                'legacySlugs' => [],
            ],
        ] as $classeData) {
            $this->syncClasse($manager, $ecole, $section, $annee, $classeData);
        }
    }

    private function syncDaroulIlm(ObjectManager $manager, Ecole $ecole): void
    {
        $whatsapp = $this->syncSection($manager, $ecole, [
            'nom' => 'Cours en ligne WhatsApp',
            'slug' => 'cours-en-ligne-whatsapp',
            'description' => 'Cours accessibles via WhatsApp pour hommes et femmes, en français, haoussa et foulfouldé, autour des sciences islamiques essentielles.',
            'type' => 'WHATSAPP',
            'publicCible' => 'Hommes et femmes',
            'ordre' => 1,
            'active' => true,
            'legacySlugs' => [],
        ]);

        $presentiel = $this->syncSection($manager, $ecole, [
            'nom' => 'Présentiel et accompagnement personnalisé',
            'slug' => 'presentiel-accompagnement-personnalise',
            'description' => 'Accompagnement personnalisé à Etoudi pour les nouveaux convertis, les adultes débutants et les personnes souhaitant améliorer la lecture du Qur’an.',
            'type' => 'PERSONNALISE',
            'publicCible' => 'Adultes débutants, nouveaux convertis et apprenants souhaitant un suivi personnalisé',
            'ordre' => 2,
            'active' => true,
            'legacySlugs' => ['presentiel-personnalise'],
        ]);

        $annee = $this->syncAnnee($manager, $ecole, [
            'libelle' => 'Session 2026',
            'dateDebut' => '2026-05-02',
            'dateFin' => '2027-04-30',
            'statut' => 'ACTIVE',
            'active' => true,
            'section' => null,
        ]);

        $niveaux = [
            'sciences-islamiques-essentielles' => $this->syncNiveau($manager, $ecole, $whatsapp, [
                'nom' => 'Sciences islamiques essentielles',
                'slug' => 'sciences-islamiques-essentielles',
                'description' => 'Programme regroupant Tawhid, Fiqh, Aadab, éducation des enfants et mariage.',
                'ordre' => 1,
                'active' => true,
                'legacySlugs' => ['sciences-islamiques'],
            ]),
            'debutant-decodage' => $this->syncNiveau($manager, $ecole, $presentiel, [
                'nom' => 'Débutant - Décodage',
                'slug' => 'debutant-decodage',
                'description' => 'Apprentissage du décodage avec la Qaida Nouraniyya pour les adultes débutants.',
                'ordre' => 2,
                'active' => true,
                'legacySlugs' => ['debutant'],
            ]),
            'tajwid-lecture-quran' => $this->syncNiveau($manager, $ecole, $presentiel, [
                'nom' => 'Tajwid et lecture du Qur’an',
                'slug' => 'tajwid-lecture-quran',
                'description' => 'Amélioration de la lecture, correction des erreurs et apprentissage des règles de tajwid.',
                'ordre' => 3,
                'active' => true,
                'legacySlugs' => [],
            ]),
            'memorisation' => $this->syncNiveau($manager, $ecole, $presentiel, [
                'nom' => 'Mémorisation',
                'slug' => 'memorisation',
                'description' => 'Parcours de mémorisation et de révision selon le niveau de l’apprenant.',
                'ordre' => 4,
                'active' => true,
                'legacySlugs' => [],
            ]),
        ];

        foreach ([
            ['nom' => 'Femmes Français - WhatsApp', 'slug' => 'femmes-francais-whatsapp', 'section' => $whatsapp, 'niveau' => $niveaux['sciences-islamiques-essentielles'], 'langue' => 'FRANCAIS', 'sexe' => 'FEMME', 'mode' => 'WHATSAPP', 'capacite' => 50, 'joursCours' => 'Samedi, Dimanche', 'heureDebut' => '20:00', 'heureFin' => '21:00', 'tarifDefaut' => '2000', 'active' => true, 'legacySlugs' => []],
            ['nom' => 'Hommes Français - WhatsApp', 'slug' => 'hommes-francais-whatsapp', 'section' => $whatsapp, 'niveau' => $niveaux['sciences-islamiques-essentielles'], 'langue' => 'FRANCAIS', 'sexe' => 'HOMME', 'mode' => 'WHATSAPP', 'capacite' => 50, 'joursCours' => 'Samedi, Dimanche', 'heureDebut' => '20:00', 'heureFin' => '21:00', 'tarifDefaut' => '2000', 'active' => true, 'legacySlugs' => []],
            ['nom' => 'Femmes Haoussa - WhatsApp', 'slug' => 'femmes-haoussa-whatsapp', 'section' => $whatsapp, 'niveau' => $niveaux['sciences-islamiques-essentielles'], 'langue' => 'HAOUSSA', 'sexe' => 'FEMME', 'mode' => 'WHATSAPP', 'capacite' => 50, 'joursCours' => 'Samedi, Dimanche', 'heureDebut' => '20:00', 'heureFin' => '21:00', 'tarifDefaut' => '2000', 'active' => true, 'legacySlugs' => []],
            ['nom' => 'Hommes Haoussa - WhatsApp', 'slug' => 'hommes-haoussa-whatsapp', 'section' => $whatsapp, 'niveau' => $niveaux['sciences-islamiques-essentielles'], 'langue' => 'HAOUSSA', 'sexe' => 'HOMME', 'mode' => 'WHATSAPP', 'capacite' => 50, 'joursCours' => 'Samedi, Dimanche', 'heureDebut' => '20:00', 'heureFin' => '21:00', 'tarifDefaut' => '2000', 'active' => true, 'legacySlugs' => []],
            ['nom' => 'Femmes Foulfouldé - WhatsApp', 'slug' => 'femmes-foulfoulde-whatsapp', 'section' => $whatsapp, 'niveau' => $niveaux['sciences-islamiques-essentielles'], 'langue' => 'FOULFOULDE', 'sexe' => 'FEMME', 'mode' => 'WHATSAPP', 'capacite' => 50, 'joursCours' => 'Samedi, Dimanche', 'heureDebut' => '20:00', 'heureFin' => '21:00', 'tarifDefaut' => '2000', 'active' => true, 'legacySlugs' => []],
            ['nom' => 'Hommes Foulfouldé - WhatsApp', 'slug' => 'hommes-foulfoulde-whatsapp', 'section' => $whatsapp, 'niveau' => $niveaux['sciences-islamiques-essentielles'], 'langue' => 'FOULFOULDE', 'sexe' => 'HOMME', 'mode' => 'WHATSAPP', 'capacite' => 50, 'joursCours' => 'Samedi, Dimanche', 'heureDebut' => '20:00', 'heureFin' => '21:00', 'tarifDefaut' => '2000', 'active' => true, 'legacySlugs' => []],
            ['nom' => 'Présentiel débutants - Etoudi', 'slug' => 'presentiel-debutants-etoudi', 'section' => $presentiel, 'niveau' => $niveaux['debutant-decodage'], 'langue' => 'FRANCAIS', 'sexe' => 'MIXTE', 'mode' => 'PRESENTIEL', 'capacite' => 20, 'joursCours' => 'À définir', 'heureDebut' => null, 'heureFin' => null, 'tarifDefaut' => null, 'active' => true, 'legacySlugs' => []],
            ['nom' => 'Tajwid personnalisé - Etoudi', 'slug' => 'tajwid-personnalise-etoudi', 'section' => $presentiel, 'niveau' => $niveaux['tajwid-lecture-quran'], 'langue' => 'FRANCAIS', 'sexe' => 'MIXTE', 'mode' => 'PERSONNALISE', 'capacite' => 15, 'joursCours' => 'Selon disponibilité', 'heureDebut' => null, 'heureFin' => null, 'tarifDefaut' => null, 'active' => true, 'legacySlugs' => []],
        ] as $classeData) {
            $section = $classeData['section'];
            unset($classeData['section']);
            $this->syncClasse($manager, $ecole, $section, $annee, $classeData);
        }
    }

    private function syncSahaba(ObjectManager $manager, Ecole $ecole): void
    {
        $section = $this->syncSection($manager, $ecole, [
            'nom' => 'Programme Qur’an et Mutun',
            'slug' => 'programme-quran-mutun',
            'description' => 'Programme de lecture du Qur’an, mémorisation, perfectionnement du tajwid et apprentissage des textes religieux Mutun Talibil Ilm.',
            'type' => 'PRESENTIEL',
            'publicCible' => 'Apprenants souhaitant progresser dans la lecture, la mémorisation et les textes religieux',
            'ordre' => 1,
            'active' => true,
            'legacySlugs' => [],
        ]);

        $annee = $this->syncAnnee($manager, $ecole, [
            'libelle' => '1447-1448 / 2026-2027',
            'dateDebut' => '2026-06-13',
            'dateFin' => '2027-06-30',
            'statut' => 'ACTIVE',
            'active' => true,
            'section' => null,
        ]);

        $niveaux = [
            'n1-initiation' => $this->syncNiveau($manager, $ecole, $section, [
                'nom' => 'N1 - Initiation',
                'slug' => 'n1-initiation',
                'description' => 'Initiation à la lecture, mémorisation des courtes sourates et apprentissage de quelques azkar.',
                'ordre' => 1,
                'active' => true,
                'legacySlugs' => [],
            ]),
            'n2-lecture-tajwid' => $this->syncNiveau($manager, $ecole, $section, [
                'nom' => 'N2 - Lecture et tajwid',
                'slug' => 'n2-lecture-tajwid',
                'description' => 'Lecture de 15 hizb ou du Qur’an entier avec perfectionnement du tajwid, et mémorisation des textes religieux des Mutun Talibil Ilm.',
                'ordre' => 2,
                'active' => true,
                'legacySlugs' => [],
            ]),
            'n3-memorisation' => $this->syncNiveau($manager, $ecole, $section, [
                'nom' => 'N3 - Mémorisation',
                'slug' => 'n3-memorisation',
                'description' => 'Mémorisation du Qur’an et des textes religieux des Mutun Talibil Ilm.',
                'ordre' => 3,
                'active' => true,
                'legacySlugs' => [],
            ]),
        ];

        foreach ([
            [
                'nom' => 'N1 - Groupe principal',
                'slug' => 'n1-groupe-principal',
                'niveau' => $niveaux['n1-initiation'],
                'langue' => 'FRANCAIS',
                'sexe' => 'MIXTE',
                'mode' => 'PRESENTIEL',
                'capacite' => 40,
                'joursCours' => 'Samedi, Dimanche',
                'heureDebut' => null,
                'heureFin' => null,
                'tarifDefaut' => '25000',
                'active' => true,
                'legacySlugs' => [],
            ],
            [
                'nom' => 'N2 - Groupe principal',
                'slug' => 'n2-groupe-principal',
                'niveau' => $niveaux['n2-lecture-tajwid'],
                'langue' => 'FRANCAIS',
                'sexe' => 'MIXTE',
                'mode' => 'PRESENTIEL',
                'capacite' => 40,
                'joursCours' => 'Samedi, Dimanche',
                'heureDebut' => null,
                'heureFin' => null,
                'tarifDefaut' => '25000',
                'active' => true,
                'legacySlugs' => [],
            ],
            [
                'nom' => 'N3 - Groupe principal',
                'slug' => 'n3-groupe-principal',
                'niveau' => $niveaux['n3-memorisation'],
                'langue' => 'FRANCAIS',
                'sexe' => 'MIXTE',
                'mode' => 'PRESENTIEL',
                'capacite' => 40,
                'joursCours' => 'Samedi, Dimanche',
                'heureDebut' => null,
                'heureFin' => null,
                'tarifDefaut' => '25000',
                'active' => true,
                'legacySlugs' => [],
            ],
        ] as $classeData) {
            $this->syncClasse($manager, $ecole, $section, $annee, $classeData);
        }
    }

    /**
     * @param array{nom: string, slug: string, description: string, type: string, publicCible: string, ordre: int, active: bool, legacySlugs: list<string>} $data
     */
    private function syncSection(ObjectManager $manager, Ecole $ecole, array $data): Section
    {
        $section = $this->findExistingBySlug($manager, Section::class, $ecole, $data['slug'], $data['legacySlugs']);
        $section = $section instanceof Section ? $section : new Section();
        $section
            ->setEcole($ecole)
            ->setNom($data['nom'])
            ->setSlug($data['slug'])
            ->setDescription($data['description'])
            ->setType($data['type'])
            ->setPublicCible($data['publicCible'])
            ->setOrdre($data['ordre'])
            ->setActive($data['active']);

        $manager->persist($section);

        return $section;
    }

    /**
     * @param array{libelle: string, dateDebut: string, dateFin: string, statut: string, active: bool, section: ?Section} $data
     */
    private function syncAnnee(ObjectManager $manager, Ecole $ecole, array $data): AnneeScolaire
    {
        $annee = $manager->getRepository(AnneeScolaire::class)->findOneBy(['ecole' => $ecole, 'libelle' => $data['libelle']]) ?? new AnneeScolaire();
        $annee
            ->setEcole($ecole)
            ->setSection($data['section'])
            ->setLibelle($data['libelle'])
            ->setDateDebut(new \DateTime($data['dateDebut']))
            ->setDateFin(new \DateTime($data['dateFin']))
            ->setStatut($data['statut'])
            ->setActive($data['active']);

        $manager->persist($annee);

        return $annee;
    }

    /**
     * @param array{nom: string, slug: string, description: string, ordre: int, active: bool, legacySlugs: list<string>} $data
     */
    private function syncNiveau(ObjectManager $manager, Ecole $ecole, Section $section, array $data): Niveau
    {
        $niveau = $this->findExistingBySlug($manager, Niveau::class, $ecole, $data['slug'], $data['legacySlugs']);
        $niveau = $niveau instanceof Niveau ? $niveau : new Niveau();
        $niveau
            ->setEcole($ecole)
            ->setSection($section)
            ->setNom($data['nom'])
            ->setSlug($data['slug'])
            ->setDescription($data['description'])
            ->setOrdre($data['ordre'])
            ->setActive($data['active']);

        $manager->persist($niveau);

        return $niveau;
    }

    /**
     * @param array{nom: string, slug: string, niveau: Niveau, langue: string, sexe: string, mode: string, capacite: int, joursCours: string, heureDebut: ?string, heureFin: ?string, tarifDefaut: ?string, active: bool, legacySlugs: list<string>} $data
     */
    private function syncClasse(ObjectManager $manager, Ecole $ecole, Section $section, AnneeScolaire $annee, array $data): Classe
    {
        $classe = $this->findExistingBySlug($manager, Classe::class, $ecole, $data['slug'], $data['legacySlugs']);
        $classe = $classe instanceof Classe ? $classe : new Classe();
        $classe
            ->setEcole($ecole)
            ->setSection($section)
            ->setNiveau($data['niveau'])
            ->setAnneeScolaire($annee)
            ->setNom($data['nom'])
            ->setSlug($data['slug'])
            ->setLangue($data['langue'])
            ->setSexe($data['sexe'])
            ->setMode($data['mode'])
            ->setCapacite($data['capacite'])
            ->setJoursCours($data['joursCours'])
            ->setHeureDebut($this->timeOrNull($data['heureDebut']))
            ->setHeureFin($this->timeOrNull($data['heureFin']))
            ->setTarifDefaut($data['tarifDefaut'])
            ->setActive($data['active']);

        $manager->persist($classe);

        return $classe;
    }

    private function timeOrNull(?string $time): ?\DateTimeInterface
    {
        if ($time === null) {
            return null;
        }

        $dateTime = \DateTime::createFromFormat('H:i', $time);

        return $dateTime instanceof \DateTimeInterface ? $dateTime : null;
    }

    /**
     * @param class-string $entityClass
     * @param list<string> $legacySlugs
     */
    private function findExistingBySlug(ObjectManager $manager, string $entityClass, Ecole $ecole, string $slug, array $legacySlugs): ?object
    {
        $repository = $manager->getRepository($entityClass);
        $entity = $repository->findOneBy(['ecole' => $ecole, 'slug' => $slug]);
        if ($entity !== null) {
            return $entity;
        }

        foreach ($legacySlugs as $legacySlug) {
            $entity = $repository->findOneBy(['ecole' => $ecole, 'slug' => $legacySlug]);
            if ($entity !== null) {
                return $entity;
            }
        }

        return null;
    }
}
