<?php

namespace App\Form;

use App\Entity\Notation;
use App\Entity\Ministry;
use App\Entity\Commune;
use App\Entity\Department;
use App\Entity\Programm;
use App\Entity\Action;
use App\Repository\MinistryRepository;
use App\Repository\CommuneRepository;
use App\Repository\ProgrammRepository;
use App\Repository\ActionRepository;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\Form\Extension\Core\Type\CollectionType;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;

class EvaluationType extends AbstractType
{
    private $year;
    private $entityManager;

    public function __construct(EntityManagerInterface $entityManager)
    {
        $this->entityManager = $entityManager;
    }
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $this->year = $options['sessionYear']; 
        
        if($options['sessionMinistry']==null && $options['sessionCommune']==null && $options['sessionDepartement']==null){
            $builder->add('type', ChoiceType::class, [
                'choices' => [
                    'Ministère' => 'ministere',
                    'Commune' => 'commune',
                ],
                'placeholder' => 'Sélectionnez un type',
                'mapped' => false,
                'required' => true,
                'label' => 'Type entité',
                'data' => $options['defaultType'],
                'disabled' => $options['defaultType'] ? true : false,
            ]);

            if ($options['defaultType'] && $options['defaultEntite']) {
                if($options['defaultType']=='ministere'){
                    $builder->add('entite', EntityType::class, [
                        'label' => 'Ministères/Communes',
                        'class' => Ministry::class,
                        'required' => true,
                        'mapped' => false,
                        'placeholder' => 'Sélectionnez un ministère',
                        'data' => $options['defaultEntite'],
                        'disabled' => $options['defaultEntite'] ? true : false,
                    ]);
                }else if($options['defaultType']=='commune'){
                    $builder->add('entite', EntityType::class, [
                        'label' => 'Ministères/Communes',
                        'class' => Commune::class,
                        'required' => true,
                        'mapped' => false,
                        'placeholder' => 'Sélectionnez une commune',
                        'data' => $options['defaultEntite'],
                        'disabled' => $options['defaultEntite'] ? true : false,
                    ]);
                }
            }else{
                $builder->add('entite', EntityType::class, [
                    'label' => 'Ministères/Communes',
                    'class' => Ministry::class,
                    'required' => true,
                    'mapped' => false,
                    'placeholder' => 'Sélectionnez d\'abord une structure',
                    'choices' => [],
                ]);
            }

            

            $builder->get('type')->addEventListener(
                FormEvents::POST_SUBMIT,
                function (FormEvent $event) use($options) {
                    $form = $event->getForm();
                    $this->addEntiteField($form->getParent(), $form->getData());
                }
            );
        }else if($options['sessionDepartement']){
            $builder->add('entite', EntityType::class, [
                'class' => Commune::class, // Classe par défaut, ajustée dynamiquement
                'placeholder' => 'Sélectionnez une commune',
                'required' => false,
                'mapped' => false,
                'choice_label' => 'name', 
                'label' => 'Communes',
                'data' => $options['defaultEntite'],
                'query_builder' => function (CommuneRepository $er) use($options) {
                    return $er->createQueryBuilder('m')
                            ->where('m.department = :departement') 
                            ->setParameter('departement', $options['sessionDepartement'])
                            ->orderBy('m.name', 'ASC'); // Tri par nom en ordre croissant
                },
                
            ]);
            
            $builder->get('entite')->addEventListener(
                FormEvents::POST_SUBMIT,
                function (FormEvent $event) use($options) {
                    $form = $event->getForm();
                    $this->addProgrammField($form->getParent(), null,$form->getData(),null, $options);
                }
            );

        }

        $builder->addEventListener(
            FormEvents::PRE_SUBMIT,
            function (FormEvent $event) use ($options) {
                $data = $event->getData();
                $form = $event->getForm();
                if($options['sessionMinistry']==null && $options['sessionCommune']==null && $options['sessionDepartement']==null){
                    if (isset($data['type']) && $data['type']!=""  && isset($data['entite']) && $data['entite']!="") {
                        if ($data['type'] === 'ministere') {
                            $ministry = $this->entityManager->getRepository(Ministry::class)->find($data['entite']);
                            $this->addProgrammField($form, $ministry, null, $options['sessionDepartement'], $options);
                        }elseif ($data['type'] === 'commune') {
                            $commune = $this->entityManager->getRepository(Commune::class)->find($data['entite']);
                            $this->addProgrammField($form, null, $commune, $options['sessionDepartement'], $options);
                        }
                    }
                }
            }
        );

        $builder->addEventListener(
            FormEvents::POST_SET_DATA,
            function (FormEvent $event) use($options) {
                $form = $event->getForm();
                $data = $event->getData();

                $action = $data->getAction();
                if ($action) {
                    $programm = $action->getProgramm();
                    $ministry = $programm->getMinistry();
                    $commune = $programm->getCommune();
                    
                    $this->addProgrammField($form, $ministry, $commune, $options['sessionDepartement'], $options);
                    $this->addActionField($form, $programm, $options);
                    $form->get('programm')->setData($programm);
                    if($ministry){
                        if($options['sessionMinistry']==null && $options['sessionCommune']==null){
                            $form->get('type')->setData('ministere');
                            $this->addEntiteField($form, 'ministere');
                            $form->get('entite')->setData($ministry);
                        }
                    }else if($commune){
                        if($options['sessionMinistry']==null && $options['sessionCommune']==null && $options['sessionDepartement']==null){
                            $form->get('type')->setData('commune');
                            $this->addEntiteField($form, 'commune');
                            $form->get('entite')->setData($commune);
                        }
                    }
                } else {
                    if($options['sessionMinistry']){
                        $this->addProgrammField($form, $options['sessionMinistry'], null,$options['sessionDepartement'],$options);
                    }else if ($options['sessionCommune']){
                        $this->addProgrammField($form, null, $options['sessionCommune'], $options['sessionDepartement'], $options);
                    }else{
                        $this->addProgrammField($form, null, null, $options['sessionDepartement'], $options);
                    }
                    $this->addActionField($form, null, $options);
                    if($options['sessionMinistry']==null && $options['sessionCommune']==null && $options['sessionDepartement']==null){
                        $this->addEntiteField($form, null);
                    }
                }
            }
        );
    }

    private function addProgrammField(FormInterface $form, ?Ministry $ministry, ?Commune $commune, ?Department $department, Array $options)
    {
        if($department){
            $builder = $form->getConfig()->getFormFactory()->createNamedBuilder(
            'programm',
            EntityType::class,
            null,
            [
                'label' => 'basics.programm',
                'class' => Programm::class,
                'choice_label' => 'name',
                'placeholder' => ($ministry || $commune) ? 'basics.programm.placeholder' : 'Sélectionnez d\'abord une commune',
                'required' => false,
                'auto_initialize' => false,
                'query_builder' => function (ProgrammRepository $repository) use($options, $ministry, $commune) {
                    return $repository->findProgrammByYear('%'.$options['sessionYear'].'%', $ministry, $commune);
                },
            ]
            );
        }else{
            $builder = $form->getConfig()->getFormFactory()->createNamedBuilder(
                'programm',
                EntityType::class,
                null,
                [
                    'label' => 'basics.programm',
                    'class' => Programm::class,
                    'choice_label' => 'name',
                    'placeholder' => ($ministry || $commune) ? 'basics.programm.placeholder' : 'Sélectionnez d\'abord un ministère ou une commune',
                    'required' => false,
                    'auto_initialize' => false,
                    'query_builder' => function (ProgrammRepository $repository) use($options, $ministry, $commune) {
                        return $repository->findProgrammByYear('%'.$options['sessionYear'].'%', $ministry, $commune);
                    },
                ]
                );
        }

        $builder->addEventListener(
            FormEvents::POST_SUBMIT,
            function (FormEvent $event) use($options) {
                $form = $event->getForm();
                $this->addActionField($form->getParent(), $form->getData(), $options);
            }
        );

        $form->add($builder->getForm());
    }

    private function addActionField(FormInterface $form, ?Programm $programm, Array $options)
    {
        $form->add('action', EntityType::class, [
            'label' => 'basics.action',
            'class'       => Action::class,
            'placeholder' => $programm ? 'basics.action.placeholder' : 'Sélectionnez d\'abord un programme',
            'required' => false,
            'attr' => [
                'onchange' => 'this.form.submit()'
            ],
            'query_builder' => function (ActionRepository $repository) use($programm, $options) {
                return $repository->createQueryBuilder('a')
                    ->orderBy('a.code', 'ASC')
                    ->andWhere('a.year = :year')
                    ->andWhere('a.programm = :programm')
                    ->andWhere('a.validated = :validated')
                    ->setParameter('year', $options['sessionYear'])
                    ->setParameter('programm', $programm ? $programm->getId() : null)
                    ->setParameter('validated', true)
                ;
            },
        ]);
    }

    private function addEntiteField(FormInterface $form,  $type)
    {
        if($type){
            if($type=='commune'){
                $form->add('entite', EntityType::class, [
                    'class' => Commune::class, // Classe par défaut, ajustée dynamiquement
                    'placeholder' => 'Sélectionnez une commune',
                    'required' => true,
                    'mapped' => false,
                    'choice_label' => 'name', 
                    'label' => 'Liste des Communes',
                    'query_builder' => function (CommuneRepository $er) {
                        return $er->createQueryBuilder('m')
                                ->orderBy('m.name', 'ASC'); // Tri par nom en ordre croissant
                    },
                    
                ]);
            }else if($type=='ministere'){
                $form->add('entite', EntityType::class, [
                    'class' => Ministry::class, // Classe par défaut, ajustée dynamiquement
                    'placeholder' => 'Sélectionnez un ministère',
                    'required' => true,
                    'mapped' => false,
                    'choice_label' => 'name', 
                    'label' => 'Liste des Ministères',
                    'query_builder' => function(MinistryRepository $repository)  {
                        return $repository->findMinistryByYear(
                            '%'.$this->year.'%', null
                        );
                    },
                ]);
            }
        }else{
            $form->add('entite', EntityType::class, [
                'label' => 'Ministères/Communes',
                'class' => Ministry::class,
                'required' => true,
                'mapped' => false,
                'placeholder' => 'Sélectionnez d\'abord une structure',
                'choices' => [],
            ]);
        }
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
            'sessionYear' => null,
            'sessionMinistry' => null,
            'sessionCommune' => null,
            'sessionDepartement' => null,
            'defaultType' => null,
            'defaultEntite' => null,
            'defaultProgramm' => null,
        ));
    }
}
