<?php

declare (strict_types=1);
namespace Rector\Symfony\FormHelper;

use RectorPrefix202605\Nette\Utils\Strings;
use Rector\Symfony\Contract\Tag\TagInterface;
use Rector\Symfony\DataProvider\ServiceMapProvider;
final class FormTypeStringToTypeProvider
{
    /**
     * @readonly
     */
    private ServiceMapProvider $serviceMapProvider;
    /**
     * @var array<string, string>
     */
    private const SYMFONY_CORE_NAME_TO_TYPE_MAP = ['form' => 'Symfony\Component\Form\Extension\Core\Type\FormType', 'birthday' => 'Symfony\Component\Form\Extension\Core\Type\BirthdayType', 'checkbox' => 'Symfony\Component\Form\Extension\Core\Type\CheckboxType', 'collection' => 'Symfony\Component\Form\Extension\Core\Type\CollectionType', 'country' => 'Symfony\Component\Form\Extension\Core\Type\CountryType', 'currency' => 'Symfony\Component\Form\Extension\Core\Type\CurrencyType', 'date' => 'Symfony\Component\Form\Extension\Core\Type\DateType', 'datetime' => 'Symfony\Component\Form\Extension\Core\Type\DatetimeType', 'email' => 'Symfony\Component\Form\Extension\Core\Type\EmailType', 'file' => 'Symfony\Component\Form\Extension\Core\Type\FileType', 'hidden' => 'Symfony\Component\Form\Extension\Core\Type\HiddenType', 'integer' => 'Symfony\Component\Form\Extension\Core\Type\IntegerType', 'language' => 'Symfony\Component\Form\Extension\Core\Type\LanguageType', 'locale' => 'Symfony\Component\Form\Extension\Core\Type\LocaleType', 'money' => 'Symfony\Component\Form\Extension\Core\Type\MoneyType', 'number' => 'Symfony\Component\Form\Extension\Core\Type\NumberType', 'password' => 'Symfony\Component\Form\Extension\Core\Type\PasswordType', 'percent' => 'Symfony\Component\Form\Extension\Core\Type\PercentType', 'radio' => 'Symfony\Component\Form\Extension\Core\Type\RadioType', 'range' => 'Symfony\Component\Form\Extension\Core\Type\RangeType', 'repeated' => 'Symfony\Component\Form\Extension\Core\Type\RepeatedType', 'search' => 'Symfony\Component\Form\Extension\Core\Type\SearchType', 'textarea' => 'Symfony\Component\Form\Extension\Core\Type\TextareaType', 'text' => 'Symfony\Component\Form\Extension\Core\Type\TextType', 'time' => 'Symfony\Component\Form\Extension\Core\Type\TimeType', 'timezone' => 'Symfony\Component\Form\Extension\Core\Type\TimezoneType', 'url' => 'Symfony\Component\Form\Extension\Core\Type\UrlType', 'button' => 'Symfony\Component\Form\Extension\Core\Type\ButtonType', 'submit' => 'Symfony\Component\Form\Extension\Core\Type\SubmitType', 'reset' => 'Symfony\Component\Form\Extension\Core\Type\ResetType', 'entity' => 'Symfony\Bridge\Doctrine\Form\Type\EntityType', 'choice' => 'Symfony\Component\Form\Extension\Core\Type\ChoiceType'];
    /**
     * @var array<string, string>
     */
    private array $customServiceFormTypeByAlias = [];
    public function __construct(ServiceMapProvider $serviceMapProvider)
    {
        $this->serviceMapProvider = $serviceMapProvider;
    }
    public function matchClassForNameWithPrefix(string $name): ?string
    {
        $nameToTypeMap = $this->getNameToTypeMap();
        if (strncmp($name, 'form.type.', strlen('form.type.')) === 0) {
            $name = Strings::substring($name, strlen('form.type.'));
        }
        return $nameToTypeMap[$name] ?? null;
    }
    /**
     * @return array<string, string>
     */
    private function getNameToTypeMap(): array
    {
        $customServiceFormTypeByAlias = $this->provideCustomServiceFormTypeByAliasFromContainerXml();
        return array_merge(self::SYMFONY_CORE_NAME_TO_TYPE_MAP, $customServiceFormTypeByAlias);
    }
    /**
     * @return array<string, string>
     */
    private function provideCustomServiceFormTypeByAliasFromContainerXml(): array
    {
        if ($this->customServiceFormTypeByAlias !== []) {
            return $this->customServiceFormTypeByAlias;
        }
        $serviceMap = $this->serviceMapProvider->provide();
        $formTypeServiceDefinitions = $serviceMap->getServicesByTag('form.type');
        foreach ($formTypeServiceDefinitions as $formTypeServiceDefinition) {
            $formTypeTag = $formTypeServiceDefinition->getTag('form.type');
            if (!$formTypeTag instanceof TagInterface) {
                continue;
            }
            $alias = $formTypeTag->getData()['alias'] ?? null;
            if (!is_string($alias)) {
                continue;
            }
            $class = $formTypeServiceDefinition->getClass();
            if ($class === null) {
                continue;
            }
            $this->customServiceFormTypeByAlias[$alias] = $class;
        }
        return $this->customServiceFormTypeByAlias;
    }
}
