<?php

/*
 * This file is part of the VITICORE2 package.
 *
 * (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\Site\Order;

use CpCreation\VitiCore\Address\BusinessIdentifierRules;
use CpCreation\VitiCore\Bridge\Symfony\Bundle\Context\GroupContext;
use CpCreation\VitiCore\Cart\Model\DeliveryAddress;
use CpCreation\VitiCore\Shop\Model\ShippingCountry;
use CpCreation\VitiCore\Shop\Repository\ShippingCountryRepository;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\EmailType;
use Symfony\Component\Form\Extension\Core\Type\TelType;
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 DeliveryAddressType extends AbstractType
{
    public function __construct(
        private readonly ShippingCountryRepository $shippingCountryRepository,
    ) {
    }

    public function buildForm(FormBuilderInterface $builder, array $options): void
    {
        $shippingRefreshAttr = [
            'data-action' => 'change->live#action',
            'data-live-action-param' => 'refreshShipping',
        ];

        $builder
            ->add('lastname', TextType::class, [
                'label' => 'shop.form.lastname',
                'attr' => [
                    'placeholder' => 'shop.form.lastname',
                    'autocomplete' => 'shipping family-name',
                ],
                'required' => true,
            ])
            ->add('firstname', TextType::class, [
                'label' => 'shop.form.firstname',
                'attr' => [
                    'placeholder' => 'shop.form.firstname',
                    'autocomplete' => 'shipping given-name',
                ],
                'required' => true,
            ])
            ->add('street', TextType::class, [
                'label' => 'shop.form.address',
                'attr' => [
                    'placeholder' => 'shop.form.address',
                    'autocomplete' => 'shipping street-address',
                ],
                'required' => true,
            ])
            ->add('postal', TextType::class, [
                'label' => 'shop.form.postal_code',
                'attr' => [
                    'placeholder' => 'shop.form.postal_code',
                    'autocomplete' => 'shipping postal-code',
                    ...$shippingRefreshAttr,
                ],
                'required' => true,
            ])
            ->add('city', TextType::class, [
                'label' => 'shop.form.city',
                'attr' => [
                    'placeholder' => 'shop.form.city',
                    'autocomplete' => 'shipping address-level2',
                    ...$shippingRefreshAttr,
                ],
                'required' => true,
            ])

            // champ (sera remplacé en PRE_SET_DATA avec les bonnes choices)
            ->add('country', ChoiceType::class, [
                'label' => 'shop.form.country',
                'required' => true,
                'choices' => ['FR' => 'FR'], // placeholder technique
                'choice_label' => static fn (?string $v): string => $v ? Countries::getName($v) : '',
                'attr' => [
                    'autocomplete' => 'shipping country',
                    ...$shippingRefreshAttr,
                ],
            ])
            ->add('email', EmailType::class, [
                'label' => 'shop.form.delivery_email',
                'attr' => [
                    'placeholder' => 'shop.form.email',
                    'autocomplete' => 'shipping email',
                ],
                'required' => true,
            ])
            ->add('phone', TelType::class, [
                'label' => 'shop.form.phone',
                'attr' => [
                    'placeholder' => 'shop.form.phone',
                    'autocomplete' => 'shipping tel',
                ],
                'required' => true,
            ])
            ->add('company', TextType::class, [
                'label' => 'shop.form.company',
                'attr' => [
                    'placeholder' => 'shop.form.company',
                    'autocomplete' => 'shipping organization',
                ],
                'required' => false,
            ])
            ->add('siret', TextType::class, [
                'label' => 'shop.form.siret',
                'attr' => [
                    'placeholder' => 'shop.form.siret_placeholder',
                    'inputmode' => 'numeric',
                    'maxlength' => 14,
                ],
                'required' => false,
            ])
            ->add('vatId', TextType::class, [
                'label' => 'shop.form.tva',
                'attr' => [
                    'placeholder' => 'shop.form.tva_placeholder',
                    'autocomplete' => 'shipping organization-title',
                ],
                'required' => false,
            ]);

        // Ici on rebuild "country" en fonction de la session + repo
        $builder->addEventListener(FormEvents::PRE_SET_DATA, [$this, 'onPreSetData']);
        $builder->addEventListener(FormEvents::PRE_SUBMIT, [$this, 'onPreSubmit']);
    }

    public function onPreSetData(FormEvent $event): void
    {
        $form = $event->getForm();
        $data = $event->getData(); // DeliveryAddress|null

        $choices = [];
        $countries = $this->shippingCountryRepository->findCountriesAssignedByGroup(GroupContext::$groupId);

        /** @var ShippingCountry $country */
        foreach ($countries as $country) {
            $code = (string) $country->getCode();
            $choices[$code] = $code; // label => value (FR => FR)
        }

        // fallback si aucun pays autorisé (évite un select vide)
        if ([] === $choices) {
            $choices['FR'] = 'FR';
        }

        // Valeur par défaut : FR à la création (ou si country vide)
        $default = 'FR';
        if ($data instanceof DeliveryAddress && $data->getCountry()) {
            $default = (string) $data->getCountry();
        }

        // Si la valeur courante n’est pas dans la liste autorisée, on bascule sur FR (ou le 1er)
        if (!isset($choices[$default])) {
            $default = $choices['FR'] ?? array_key_first($choices) ?? 'FR';
        }

        if ($form->has('country')) {
            $form->remove('country');
        }

        $form->add('country', ChoiceType::class, [
            'label' => 'shop.form.country',
            'required' => true,
            'choices' => $choices,
            'data' => $default,
            'choice_label' => static fn (?string $v): string => $v ? Countries::getName($v) : '',
            'attr' => [
                'separator' => '=====',
                'autocomplete' => 'shipping country',
                'data-action' => 'change->live#action',
                'data-live-action-param' => 'refreshShipping',
            ],
        ]);
    }

    public function onPreSubmit(FormEvent $event): void
    {
        $data = $event->getData();

        if (!\is_array($data)) {
            return;
        }

        $data['siret'] = BusinessIdentifierRules::normalizeIdentifier($data['siret'] ?? null);
        $data['vatId'] = BusinessIdentifierRules::normalizeIdentifier($data['vatId'] ?? null);

        if (!BusinessIdentifierRules::requiresSiret($data['country'] ?? null)) {
            $data['siret'] = null;
        }

        $event->setData($data);
    }

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