<?php

namespace CpCreation\VitiCore\Bridge\Symfony\Bundle\Form\Admin;

use CpCreation\VitiCore\User\Model\User;
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\PasswordType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;

final class UserType extends AbstractType
{
    /**
     * @param array<string, mixed> $roleHierarchyRoles
     */
    public function __construct(
        private readonly array $roleHierarchyRoles,
    ) {
    }

    public function buildForm(FormBuilderInterface $builder, array $options): void
    {
        $builder
            ->add('email', EmailType::class, [
                'label' => 'Email',
                'required' => true,
            ])
            ->add('plainPassword', PasswordType::class, [
                'label' => 'Mot de passe',
                'required' => $options['require_password'],
                'empty_data' => '',
            ])
            ->add('assignableRoles', ChoiceType::class, [
                'label' => 'Droits',
                'choices' => $this->buildRoleChoices(),
                'expanded' => true,
                'multiple' => true,
                'required' => true,
            ]);
    }

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

        $resolver->setAllowedTypes('require_password', 'bool');
    }

    /**
     * @return array<string, string>
     */
    private function buildRoleChoices(): array
    {
        $choices = [];
        $excludedRoles = ['ROLE_SUPER_ADMIN', 'ROLE_USER'];

        foreach (array_keys($this->roleHierarchyRoles) as $role) {
            if (!\is_string($role) || \in_array($role, $excludedRoles, true)) {
                continue;
            }

            $choices[$this->formatRoleLabel($role)] = $role;
        }

        ksort($choices);

        return $choices;
    }

    private function formatRoleLabel(string $role): string
    {
        $label = preg_replace('/^ROLE_/', '', $role) ?? $role;
        $label = str_replace('_', ' ', $label);

        return ucfirst(strtolower($label));
    }
}
