<?php

namespace App\Tests\Fixture;

use App\Entity\Access\Access;
use App\Entity\Billing\AccessBilling;
use App\Entity\Billing\BillingSetting;
use App\Entity\Billing\ResidenceArea;
use App\Entity\Booking\Event;
use App\Entity\Core\ContactPoint;
use App\Entity\Education\Cycle;
use App\Entity\Education\CycleByEducation;
use App\Entity\Education\Education;
use App\Entity\Education\EducationCategory;
use App\Entity\Education\EducationComplement;
use App\Entity\Education\EducationCurriculum;
use App\Entity\Education\EducationStudent;
use App\Entity\Education\EducationTiming;
use App\Entity\Network\Network;
use App\Entity\Organization\Organization;
use App\Entity\Organization\Parameters;
use App\Entity\Organization\Settings;
use App\Entity\Organization\Subdomain;
use App\Entity\Person\Person;
use App\Enum\Booking\VisibilityEnum;
use App\Enum\Core\ContactPointTypeEnum;
use App\Enum\Core\TimeZoneEnum;
use App\Enum\Education\AdvancedEducationNotationTypeEnum;
use App\Enum\Education\CycleEnum;
use App\Enum\Education\PeriodicityEnum;
use App\Enum\Organization\BulletinCriteriaSortEnum;
use App\Enum\Organization\BulletinOutputEnum;
use App\Enum\Organization\BulletinPeriodEnum;
use App\Enum\Organization\LegalEnum;
use App\Enum\Organization\PrincipalTypeEnum;
use App\Enum\Organization\SendToBulletinEnum;
use App\Enum\Organization\SettingsProductEnum;
use App\Service\Utils\Uuid;
use Doctrine\Bundle\FixturesBundle\Fixture;
use Doctrine\DBAL\Connection;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\Persistence\ObjectManager;

class OrganizationFixtures extends Fixture
{
    protected EntityManagerInterface $em;
    private Connection $connection;

    public function __construct(EntityManagerInterface $em, Connection $connection)
    {
        $this->em = $em;
        $this->connection = $connection;
    }

    public static function getGroups(): array
    {
        return ['poc'];
    }

    public function purgeDb(): void
    {
        // Exécutez la requête SQL brute pour effectuer un TRUNCATE FORCE
        $tableName = $this->em->getClassMetadata(Organization::class)->getTableName();
        $truncateSql = "TRUNCATE TABLE $tableName";
        $this->connection->executeQuery($truncateSql);

        $accessTable = $this->em->getClassMetadata(Access::class)->getTableName();
        $truncateSql = "TRUNCATE TABLE $accessTable";
        $this->connection->executeQuery($truncateSql);
    }

    public function load(ObjectManager $em): void
    {
        // Purge DB before populating new fixtures
        // $this->purgeDb();
        // create an organization with a network, legal status accesses, Param , name, id and settings
        $network = new Network();
        $network->setName('NET');
        $em->persist($network);

        $contactPoint0 = new ContactPoint();
        $contactPoint0->setContactType(ContactPointTypeEnum::PRINCIPAL);
        $em->persist($contactPoint0);

        // Create the root organization (opentalent)
        $root = new Organization();
        $root->setName('Root');
        $root->setLegalStatus(LegalEnum::ASSOCIATION_LAW_1901);
        $root->setPrincipalType(PrincipalTypeEnum::NATIONAL_FEDERATION);
        $root->addContactPoint($contactPoint0);

        // subdomain fixtures
        $subdomain = new Subdomain();
        $subdomain->setOrganization($root);
        $subdomain->setSubdomain('subdomain');
        $subdomain->setActive(true);

        $parameters = new Parameters();
        $parameters->setFinancialDate(new \DateTime());
        $parameters->setMusicalDate(new \DateTime());
        $parameters->setStartCourseDate(new \DateTime());
        $parameters->setEndCourseDate(new \DateTime());
        $parameters->setAverage(20);
        $parameters->setEditCriteriaNotationByAdminOnly(true);
        $parameters->setSmsSenderName('MySender');
        $parameters->setLogoDonorsMove(false);
        $parameters->setSubDomain('subdomain');
        $parameters->setWebsite('https://www.example.com');
        $parameters->setOtherWebsite('https://www.otherwebsite.com');
        $parameters->setCustomDomain('https://www.customdomain.com');
        $parameters->setDesactivateOpentalentSiteWeb(false);
        $parameters->setBulletinPeriod(BulletinPeriodEnum::YEAR);
        $parameters->setBulletinWithTeacher(false);
        $parameters->setBulletinPrintAddress(false);
        $parameters->setBulletinSignatureDirector(true);
        $parameters->setBulletinDisplayLevelAcquired(true);
        $parameters->setBulletinShowEducationWithoutEvaluation(false);
        $parameters->setBulletinViewTestResults(false);
        $parameters->setBulletinShowAbsences(false);
        $parameters->setBulletinShowAverages(true);
        $parameters->setBulletinOutput(BulletinOutputEnum::SEND_BY_EMAIL);
        $parameters->setBulletinEditWithoutEvaluation(true);
        $parameters->setBulletinReceiver(SendToBulletinEnum::STUDENTS_AND_THEIR_GUARDIANS);
        $parameters->setBulletinCriteriaSort(BulletinCriteriaSortEnum::ALPHANUM);
        $parameters->setUsernameSMS('username');
        $parameters->setPasswordSMS('password');
        $parameters->setShowAdherentList(true);
        $parameters->setStudentsAreAdherents(false);
        $parameters->setTimezone(TimeZoneEnum::EUROPE_PARIS);
        $parameters->setEducationPeriodicity(PeriodicityEnum::MONTHLY);
        $parameters->setAdvancedEducationNotationType(AdvancedEducationNotationTypeEnum::BY_EDUCATION);
        $parameters->setSendAttendanceEmail(false);
        $parameters->setSendAttendanceSms(false);
        $parameters->setGenerateAttendanceReport(true);
        $parameters->setConsultPedagogicResult(true);
        $parameters->setConsultTeacherListing(true);
        $parameters->setPeriodValidation(true);
        $parameters->setNotifyAdministrationAbsence(false);
        $root->setParameters($parameters);

        // settings fixtures
        $settings = new Settings();
        $settings->setProduct(SettingsProductEnum::SCHOOL);
        $settings->setModules(['BillingAdministration']);
        $root->setSettings($settings);

        // create acesses with orga
        $access = new Access();
        $access->setOrganization($root);
        $access->setRoles(['ROLE_ADMIN', 'ROLE_ADMIN_CORE', 'ROLE_SUPER_ADMIN']);

        $teacherAccess = new Access();
        $teacherAccess->setOrganization($root);
        $teacherAccess->setRoles(['ROLE_TEACHER']);

        // create a person :
        $person = new Person();
        $person->addAccess($access);
        $person->setUsername('username');
        $person->setPassword('password');

        // create BillingSetting with an organization
        $billingSetting = new BillingSetting();
        $billingSetting->setOrganization($root);
        $em->persist($billingSetting);

        // résidence area
        $residenceArea = new ResidenceArea();
        $residenceArea->setLabel('label');
        $residenceArea->setBillingSetting($billingSetting);

        // create an AccessBilling with an access
        $accessBilling = new AccessBilling();
        $accessBilling->setAccess($access);
        $accessBilling->setResidenceArea($residenceArea);

        // Création de quelques cycles
        $cycle1 = new Cycle();
        $cycle1->setOrganization($root);
        $cycle1->setLabel('Cycle 1');
        $cycle1->setCycleEnum(CycleEnum::CYCLE_1);

        $cycle2 = new Cycle();
        $cycle2->setOrganization($root);
        $cycle2->setLabel('Cycle 2');
        $cycle2->setCycleEnum(CycleEnum::CYCLE_2);

        // Création de l'entité EducationCategory
        $educationCategory = new EducationCategory();
        $educationCategory->setOrganization($root);

        // Création de l'entité EducationComplement
        $educationComplement = new EducationComplement();

        // Création d'une Education
        $education = new Education();
        $education->setEducationCategory($educationCategory);
        $education->setEducationComplement($educationComplement);

        // Création d'un CycleByEducation
        $cycleByEducation = new CycleByEducation();
        $cycleByEducation->setCycle($cycle1);
        $cycleByEducation->setEducation($education);

        // Ajout de cycleByEducation à cycle et education
        $cycle1->addCycleByEducation($cycleByEducation);
        $education->addCycleByEducation($cycleByEducation);

        $educationCurriculum = new EducationCurriculum();
        $educationTimings = new EducationTiming();
        $educationTimings->setTiming(45);
        $educationTimings->setOrganization($root);
        $educationStudent = new EducationStudent();
        $educationTimings->addEducationStudent($educationStudent);
        $educationTimings->addEducationCurriculum($educationCurriculum);
        $educationCurriculum->setCycle($cycle1);

        // // education complément
        // $educationComplement = new EducationComplement();
        // $education = (new Education());
        // $educationCategory = new EducationCategory();
        // $educationCategory->setOrganization($root);
        // // $educationCurriculum = new EducationCurriculum();

        // // $education->setEducationComplement($educationComplement);
        // // $educationCategory->setOrganization($root);
        // // $educationCategory->addEducation($education);
        // $education->setEducationCategory($educationCategory);
        // $education->setEducationComplement($educationComplement);
        // $cycleByEducation = new CycleByEducation();

        // // Cycle
        // $cycle = new Cycle();
        // $cycle->setOrganization($root);
        // $cycle->setCycleEnum(CycleEnum::INITIATION_CYCLE);
        // $cycle->setIsSystem(false);
        // $cycle->setLabel('toto');
        // $cycle->setOrder(1);

        // // $cycleByEducation->setEducation();
        // $cycle->addCycleByEducation($cycleByEducation);
        // $cycle->setIsSystem(false);
        // $em->persist($cycle);

        // Booking
        $now = new \DateTime('now');
        $start = $now->add(new \DateInterval('P1M'));
        $end = $now->add(new \DateInterval('P1M1D'));

        $event = new Event();
        $event->setOrganization($root);
        $event->setName('My Event');
        $event->setDatetimeStart($start);
        $event->setDatetimeEnd($end);
        $event->setVisibility(VisibilityEnum::PUBLIC_VISIBILITY);
        $event->setUuid(Uuid::uuid());

        $em->persist($cycle1);
        $em->persist($cycle2);
        $em->persist($educationCategory);
        $em->persist($educationComplement);
        $em->persist($education);
        $em->persist($cycleByEducation);

        // $em->persist($educationComplement);
        // $em->persist($educationCurriculum);
        // $em->persist($educationCategory);
        // $em->persist($education);
        // $em->persist($cycleByEducation);

        $em->persist($root);
        $em->persist($event);
        $em->persist($person);
        $em->persist($access);
        $em->persist($accessBilling);
        $em->persist($billingSetting);
        $em->persist($residenceArea);
        $em->persist($subdomain);
        $em->persist($parameters);

        $em->flush();

        // A circular reference has been detected when serializing the object of
        // class \u0022App\\Entity\\Education\\CycleByEducation\u0022
    }
}
