<?php
/**
 * Copyright since 2025 InPost S.A.
 *
 * For the full license information, please view the LICENSE file bundled with the module.
 *
 * @author InPost S.A.
 * @copyright since 2025 InPost S.A.
 * @license MIT
 */

declare(strict_types=1);

namespace InPost\International\PickupOrder\Form;

use Doctrine\ORM\EntityRepository;
use InPost\International\Api\Pickup\Request\CutoffTimeRequest;
use InPost\International\Country;
use InPost\International\Entity\PickupAddress;
use InPost\International\Enum\Form\Type\EnumType;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\DataMapperInterface;
use Symfony\Component\Form\Exception\UnexpectedTypeException;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormInterface;
use Symfony\Contracts\Translation\TranslatorInterface;

if (!defined('_PS_VERSION_')) {
    exit;
}

final class CutoffTimeRequestType extends AbstractType implements DataMapperInterface
{
    /**
     * @var TranslatorInterface
     */
    private $translator;

    public function __construct(TranslatorInterface $translator)
    {
        $this->translator = $translator;
    }

    public function buildForm(FormBuilderInterface $builder, array $options): void
    {
        $builder
            ->add('address', EntityType::class, [
                'class' => PickupAddress::class,
                'query_builder' => static function (EntityRepository $repository) {
                    return $repository
                        ->createQueryBuilder('a')
                        ->where('a.deleted = 0');
                },
                'choice_attr' => static function (PickupAddress $address): array {
                    return [
                        'data-country-code' => $address->getAddress()->getCountry()->value,
                        'data-postal-code' => $address->getAddress()->getPostcode(),
                    ];
                },
                'mapped' => false,
                'required' => false,
                'label' => $this->translator->trans('Pickup address', [], 'Modules.Inpostinternational.Pickup'),
                'placeholder' => $this->translator->trans('Select an address', [], 'Modules.Inpostinternational.Pickup'),
            ])
            ->add('countryCode', EnumType::class, [
                'class' => Country::class,
                'choices' => [Country::Poland()],
                'label' => $this->translator->trans('Country', [], 'Admin.Global'),
            ])
            ->add('postalCode', TextType::class, [
                'label' => $this->translator->trans('Zip/Postal code', [], 'Admin.Global'),
            ])
            ->setDataMapper($this);
    }

    /**
     * @param CutoffTimeRequest|null $viewData
     * @param iterable<FormInterface> $forms
     */
    public function mapDataToForms($viewData, $forms): void
    {
        if (null === $viewData) {
            return;
        }

        if (!$viewData instanceof CutoffTimeRequest) {
            throw new UnexpectedTypeException($viewData, CutoffTimeRequest::class);
        }

        $forms = is_array($forms) ? $forms : iterator_to_array($forms);

        $forms['countryCode']->setData($viewData->getCountryCode());
        $forms['postalCode']->setData($viewData->getPostalCode());
    }

    /**
     * @param iterable<FormInterface> $forms
     * @param CutoffTimeRequest|null $viewData
     */
    public function mapFormsToData($forms, &$viewData): void
    {
        $forms = is_array($forms) ? $forms : iterator_to_array($forms);

        $viewData = new CutoffTimeRequest(
            $forms['countryCode']->getData(),
            $forms['postalCode']->getData()
        );
    }
}
