<?php

declare(strict_types=1);

/*
 * Chill is a software for social workers
 *
 * For the full copyright and license information, please view
 * the LICENSE file that was distributed with this source code.
 */

namespace Chill\ThirdPartyBundle\Form\Type;

use Chill\MainBundle\Templating\TranslatableStringHelper;
use Chill\ThirdPartyBundle\Entity\ThirdPartyCategory;
use Chill\ThirdPartyBundle\Repository\ThirdPartyCategoryRepository;
use Chill\ThirdPartyBundle\ThirdPartyType\ThirdPartyTypeManager;
use Symfony\Component\Form\Exception\UnexpectedTypeException;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Contracts\Translation\TranslatorInterface;

class PickThirdPartyTypeCategoryType extends \Symfony\Component\Form\AbstractType
{
    private const PREFIX_TYPE = 'chill_3party.key_label.';

    public function __construct(private readonly ThirdPartyCategoryRepository $thirdPartyCategoryRepository, private readonly ThirdPartyTypeManager $thirdPartyTypeManager, private readonly TranslatableStringHelper $translatableStringHelper, private readonly TranslatorInterface $translator) {}

    public function configureOptions(OptionsResolver $resolver)
    {
        $choices = \array_merge(
            $this->thirdPartyCategoryRepository->findBy(['active' => true]),
            $this->thirdPartyTypeManager->getTypes()
        );

        \uasort($choices, function ($itemA, $itemB) {
            $strA = $itemA instanceof ThirdPartyCategory ? $this->translatableStringHelper
                ->localize($itemA->getName()) : $this->translator->trans(self::PREFIX_TYPE.$itemA);
            $strB = $itemB instanceof ThirdPartyCategory ? $this->translatableStringHelper
                ->localize($itemB->getName()) : $this->translator->trans(self::PREFIX_TYPE.$itemB);

            return $strA <=> $strB;
        });

        $resolver->setDefaults([
            'choices' => $choices,
            'attr' => ['class' => 'select2'],
            'multiple' => true,
            'choice_label' => function ($item) {
                if ($item instanceof ThirdPartyCategory) {
                    return $this->translatableStringHelper->localize($item->getName());
                }

                return self::PREFIX_TYPE.$item;
            },
            'choice_value' => fn ($item) => $this->reverseTransform($item),
        ]);
    }

    public function getParent()
    {
        return ChoiceType::class;
    }

    private function reverseTransform($value)
    {
        if (null === $value) {
            return null;
        }

        if ($value instanceof ThirdPartyCategory) {
            return 'category:'.$value->getId();
        }

        if (\is_string($value)) {
            return 'type:'.$value;
        }

        throw new UnexpectedTypeException($value, \implode(' or ', ['array', 'string', ThirdPartyCategory::class]));
    }
}
