<?php

declare(strict_types=1);

namespace Gls\GlsPoland\Form\Type;

use Gls\GlsPoland\AdePlus\Services\Services;
use Gls\GlsPoland\PrestaShop\Message\CreateCourierCarrierCommand;
use Gls\GlsPoland\Translation\TranslatorAwareTrait;
use PrestaShop\PrestaShop\Core\Form\ChoiceProvider\CountryByIsoCodeChoiceProvider;
use PrestaShop\PrestaShop\Core\Form\FormChoiceProviderInterface;
use PrestaShopBundle\Form\Admin\Type\Material\MaterialChoiceTableType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\ChoiceList\Loader\CallbackChoiceLoader;
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\Form\FormInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;

final class CreateCourierCarrierType extends AbstractType
{
    use TranslatorAwareTrait;

    private $countryChoiceProvider;

    /**
     * @param CountryByIsoCodeChoiceProvider $countryChoiceProvider
     */
    public function __construct(FormChoiceProviderInterface $countryChoiceProvider)
    {
        $this->countryChoiceProvider = $countryChoiceProvider;
    }

    public function buildForm(FormBuilderInterface $builder, array $options): void
    {
        $builder
            ->add('name', TextType::class, [
                'label' => $this->getTranslator()->trans('Name', [], 'Admin.Global'),
                'attr' => [
                    'class' => 'js-carrier-name',
                    'data-default-name' => $this->getTranslator()->trans('GLS Courier', [], 'Modules.Glspoland.Carrier'),
                    'data-service-suffix-map' => json_encode([
                        Services::CASH_ON_DELIVERY => $this->getTranslator()->trans('Cash on Delivery', [], 'Modules.Glspoland.Service'),
                        Services::SATURDAY_DELIVERY => [
                            '' => $this->getTranslator()->trans('Saturday delivery', [], 'Modules.Glspoland.Service'),
                            Services::DELIVERY_BEFORE_10 => $this->getTranslator()->trans('Saturday delivery by 10:00 AM', [], 'Modules.Glspoland.Service'),
                            Services::DELIVERY_BEFORE_12 => $this->getTranslator()->trans('Saturday delivery by 12:00 AM', [], 'Modules.Glspoland.Service'),
                        ],
                        Services::DELIVERY_BEFORE_10 => $this->getTranslator()->trans('by 10:00 AM', [], 'Modules.Glspoland.Service'),
                        Services::DELIVERY_BEFORE_12 => $this->getTranslator()->trans('by 12:00 AM', [], 'Modules.Glspoland.Service'),
                    ]),
                ],
            ])
            ->add('countryIsoCodes', MaterialChoiceTableType::class, [
                'choice_loader' => new CallbackChoiceLoader([$this->countryChoiceProvider, 'getChoices']),
                'preferred_choices' => ['PL'],
                'label' => $this->getTranslator()->trans('Countries', [], 'Admin.Global'),
                'attr' => [
                    'class' => 'js-country-choice',
                ],
                'searchable' => true,
            ])
            ->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) {
                $data = $event->getData();
                $isDomesticCarrier = $data instanceof CreateCourierCarrierCommand ? $data->isDomestic() : true;

                $this->addServicesField($event->getForm(), $isDomesticCarrier);
            });

        $builder->get('countryIsoCodes')->addEventListener(FormEvents::POST_SUBMIT, function (FormEvent $event) {
            $this->addServicesField($event->getForm()->getParent(), ['PL'] === $event->getData());
        });
    }

    public function configureOptions(OptionsResolver $resolver): void
    {
        $resolver->setDefault('data_class', CreateCourierCarrierCommand::class);
    }

    private function addServicesField(FormInterface $form, bool $isDomesticCarrier): void
    {
        $form->add('services', CarrierAdditionalServicesType::class, [
            'label' => $this->getTranslator()->trans('Additional services', [], 'Modules.Glspoland.Carrier'),
            'domestic_carrier' => $isDomesticCarrier,
        ]);
    }
}
