<?php

namespace App\Form;

use App\Entity\Activity;
use App\Entity\Ministry;
use App\Entity\Programm;
use App\Entity\Action;
use App\Entity\Commune;
use App\Entity\Direction;
use App\Repository\MinistryRepository;
use App\Repository\CommuneRepository;
use App\Repository\ProgrammRepository;
use App\Repository\ActionRepository;
use App\Repository\DirectionRepository;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\FormEvents;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\MoneyType;
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
use Symfony\Component\OptionsResolver\OptionsResolver;

class ActivityType 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']; 

        $builder
            ->add('code', TextType::class, [
                'label' => 'basics.code'
            ])
            ->add('name', TextType::class, [
                'label' => 'basics.name'
            ])
             ->add('amount', MoneyType::class, [
                'label' => 'basics.amount',
                'currency' => 'XOF',
                'grouping' => true,
                'scale' => 0,
             ]);
            if($options['sessionMinistry'] || $options['sessionCommune']){
             $builder->add('action', EntityType::class, [
                'label' => 'basics.action',
                'class'       => Action::class,
                'choice_label' => 'name',
                'placeholder' => 'Sélectionnez une action',
                'query_builder' => function (ActionRepository $repository) use($options) {
                    return $repository->createQueryBuilder('a')
                        ->orderBy('a.code', 'ASC')
                        ->andWhere('a.year = :year')
                        ->andWhere('a.programm = :programm')
                        ->setParameter('year', $options['sessionYear'])
                        ->setParameter('programm', $options['defaultProgramm'] ? $options['defaultProgramm']->getId() : null);
                    }
                ]);
            }else{
                $builder->add('action', EntityType::class, [
                    'label' => 'basics.action',
                    'class'       => Action::class,
                    'choice_label' => 'name',
                    'placeholder' => 'Sélectionnez d\'abord un programme',
                    'choices' =>[],
                    ]);
            }

            if($options['sessionMinistry']==null && $options['sessionCommune']==null && $options['sessionDepartement']==null){
                $builder->add('type', ChoiceType::class, [
                    'choices' => [
                        'Ministère' => 'ministere',
                        'Commune' => 'commune',
                    ],
                    'placeholder' => 'Sélectionnez une structure',
                    'mapped' => false,
                    'required' => true,
                    'label' => 'Structure',
                    '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());
                    }
                );
            }
        
        $builder->addEventListener(
            FormEvents::PRE_SUBMIT,
            function (FormEvent $event) use ($options) {
                $data = $event->getData();
                $form = $event->getForm();
                if($options['sessionMinistry']==null && $options['sessionCommune']==null){
                    if ($data['type']!=""  && $data['entite']!="") {
                        if ($data['type'] === 'ministere') {
                            $ministry = $this->entityManager->getRepository(Ministry::class)->find($data['entite']);
                            $this->addDirectionField($form, $ministry, null,$options);
                            $this->addProgrammField($form, $ministry, null, $options);
                        }elseif ($data['type'] === 'commune') {
                            $commune = $this->entityManager->getRepository(Commune::class)->find($data['entite']);
                            $this->addProgrammField($form, null, $commune, $options);
                            $this->addDirectionField($form, null, $commune,$options);
                        }
                    }
                }
                if(isset($data['programm']) && $data['programm'] !=""){
                    $programm = $this->entityManager->getRepository(Programm::class)->find($data['programm']);
                    $this->addActionField($form, $programm, $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);
                    $form->get('programm')->setData($programm);

                    if($options['sessionMinistry']==null && $options['sessionCommune']==null){
                        $this->addActionField($form, $programm, $options);
                    }

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

                $direction = $data->getDirection();
                if ($direction) {
                    $ministry = $direction->getMinistry();
                    $commune = $direction->getCommune();
                    $this->addDirectionField($form, $ministry, $commune,$options);
                } else {
                    if($options['sessionMinistry']){
                        $this->addDirectionField($form, $options['sessionMinistry'], null, $options);
                    } else if($options['sessionCommune']){
                        $this->addDirectionField($form, null,  $options['sessionCommune'], $options);
                    }else {
                        $this->addDirectionField($form, null, null, $options);
                    }
                }
            }
        );
    }

    private function addProgrammField(FormInterface $form, ?Ministry $ministry, ?Commune $commune,  array $options)
    {
        if($ministry || $commune) {
            $builder = $form->getConfig()->getFormFactory()->createNamedBuilder(
                'programm',
                EntityType::class,
                null,
                [
                    'label' => 'basics.programm',
                    'class' => Programm::class,
                    'choice_label' => 'name',
                    'placeholder' => 'basics.programm.placeholder',
                    'mapped' => false,
                    'required' => false,
                    'data' => $options['defaultProgramm'],
                    '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' => 'Sélectionnez d\'abord un ministère ou une commune',
                    'mapped' => false,
                    'required' => false,
                    'auto_initialize' => false,
                    'choices' =>[]
                ]
            );
        }

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

    private function addActionField(FormInterface $form, ?Programm $programm, array $options)
    {
        if($programm){
            $form->add('action', EntityType::class, [
            'label' => 'basics.action',
            'class'       => Action::class,
            'choice_label' => 'name',
            'placeholder' => 'basics.action.placeholder',
            'query_builder' => function (ActionRepository $repository) use($programm, $options) {
                return $repository->createQueryBuilder('a')
                    ->orderBy('a.code', 'ASC')
                    ->andWhere('a.year = :year')
                    ->andWhere('a.programm = :programm')
                    ->setParameter('year', $options['sessionYear'])
                    ->setParameter('programm', $programm ? $programm->getId() : null);
                },
            ]);
        }else{
            $form->add('action', EntityType::class, [
            'label' => 'basics.action',
            'class'       => Action::class,
            'choice_label' => 'name',
            'placeholder' => 'Sélectionnez d\'abord un programme',
            'choices' =>[],
            ]);
        }
    }

    private function addDirectionField(FormInterface $form, ?Ministry $ministry, ?Commune $commune, array $options)
    {
        if($ministry || $commune){
            $form->add('direction', EntityType::class, [
                'label' => 'basics.direction',
                'class' => Direction::class,
                'choice_label' => 'name',
                'placeholder' => 'basics.direction.placeholder',
                'query_builder' => function (DirectionRepository $repository) use($options, $ministry, $commune) {
                    return $repository->findDirectionByYear('%'.$options['sessionYear'].'%', $ministry, $commune);
                },
            ]);
        }else{
            $form->add('direction', EntityType::class, [
                'label' => 'basics.direction',
                'class' => Direction::class,
                'choice_label' => 'name',
                'placeholder' => 'Sélection d\'abord un ministère ou une commune',
                'choices' => []
            ]);
        }
    }

    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 un type d\'entité',
                'choices' => [],
            ]);
        }
    }
    
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => Activity::class,
            'sessionYear' => null,
            'sessionMinistry' => null,
            'sessionCommune' => null,
            'sessionDepartement' => null,
            'defaultType' => null,
            'defaultEntite' => null,
            'defaultProgramm' => null,
        ));
    }
}
