<?php

/*
 * This file is part of the VitiCore 2.
 *
 * (c) CP Creation <web@cpcreation.fr>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace CpCreation\VitiCore\Bridge\Symfony\Bundle\Form\Admin;

use CpCreation\VitiCore\Bridge\Symfony\Bundle\Form\Admin\DataTransformer\TransformCounties;
use CpCreation\VitiCore\Product\Model\ProductPriceGroup;
use CpCreation\VitiCore\Shop\Model\ShippingCountry;
use CpCreation\VitiCore\Shop\Model\ShippingCounty;
use CpCreation\VitiCore\Shop\Model\ShippingZone;
use CpCreation\VitiCore\Shop\Repository\ShippingCountryRepository;
use CpCreation\VitiCore\Shop\Repository\ShippingCountyRepository;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\Intl\Countries;
use Symfony\Component\OptionsResolver\OptionsResolver;

final class ShippingZoneType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options): void
    {
        $builder
            ->add('name', TextType::class, ['label' => 'Nom de la zone', 'required' => true])
            ->add(
                'countries', EntityType::class, [
                    'class' => ShippingCountry::class,
                    'query_builder' => function (ShippingCountryRepository $repository) {
                        return $repository->findCountriesNotDisabledNotAssignedQueryBuilder();
                    },
                    'choice_label' => function ($choice, $key, $value) {
                        /** @var ProductPriceGroup $group */
                        $groups = [];
                        foreach ($choice->getGroups() as $group) {
                            $groups[] = $group->getName();
                        }

                        return Countries::getName($choice->getCode()).'('.implode('-', $groups).')';
                    },

                    'multiple' => true,
                    'attr' => [
                        'class' => 'select2',
                    ],
                    'label' => 'Pays',
                    'required' => true,
                ]
            )
            ->add(
                'counties', EntityType::class,
                [
                    'class' => ShippingCounty::class,
                    'query_builder' => function (ShippingCountyRepository $er) {
                        return $er->findWithZoneNotNullQuery();
                    },
                    'label' => 'Département (2 chiffres)',
                    'multiple' => true,
                    'choice_label' => function ($county) {
                        /* @var ShippingCounty $county */
                        return $county->getCode();
                    },
                    'choice_value' => 'code',
                    'attr' => [
                        'class' => 'select2-tag',
                    ],
                    'required' => false,
                ]
            );
        $builder->get('counties')->addModelTransformer(new TransformCounties());
        $builder->addEventListener(
            FormEvents::PRE_SUBMIT,
            function (FormEvent $event) {
                $form = $event->getForm();
                $data = $event->getData();
                $choices = [];
                if (isset($data['counties'])) {
                    $dataCounties = $data['counties'];
                    $origCounties = [];
                    if ($form->getData()) {
                        $origCounties = $form->getData()->getCounties()->toArray();
                        foreach ($origCounties as $origCounty) {
                            $choices[] = $origCounty;
                        }
                    }
                    foreach ($dataCounties as $dataCounty) {
                        $exist = false;
                        foreach ($origCounties as $origCounty) {
                            if ($origCounty->getCode() === $dataCounty) {
                                $exist = true;
                                break;
                            }
                        }
                        if (!$exist) {
                            $county = new ShippingCounty();
                            $county->setCode($dataCounty);
                            $choices[] = $county;
                            if ($form->getData()) {
                                $form->remove('counties');
                                $form->add(
                                    'counties', EntityType::class, [
                                        'class' => 'CpCreation\VitiCore\Shop\Model\ShippingCounty',
                                        'required' => true,
                                        'multiple' => true,
                                        'choices' => $choices,
                                        'choice_label' => function ($county) {
                                            /* @var ShippingCounty $county */
                                            return $county->getCode();
                                        },
                                        'choice_value' => 'code',
                                        'attr' => ['class' => 'select2-tag'],
                                    ]
                                );
                                $form->getData()->addCounty($county);
                            }
                        }
                    }
                }
                if (!$form->getData()) {
                    $form->add(
                        'counties', EntityType::class, [
                            'class' => 'CpCreation\VitiCore\Shop\Model\ShippingCounty',
                            'required' => true,
                            'multiple' => true,
                            'choices' => $choices,
                            'choice_label' => function ($county) {
                                /* @var ShippingCounty $county */
                                return $county->getCode();
                            },
                            'choice_value' => 'code',
                            'attr' => ['class' => 'select2-tag'],
                        ]
                    );
                }
            }
        );
    }

    public function configureOptions(OptionsResolver $resolver): void
    {
        $resolver->setDefaults(
            [
                'data_class' => ShippingZone::class,
            ]
        );
    }
}
