<?php

/*
 * This file is part of the VitiCore 2.
 *
 * (c) CP Creation <web@cpcreation.fr>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

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

use CpCreation\VitiCore\User\Model\User;
use Symfony\Component\Validator\Constraints\Count;
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\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\OptionsResolver\OptionsResolver;

final class UserType extends AbstractType
{
    /** @var array<string,string> */
    private array $roles;

    /**
     * @param array<string, string[]|string> $roleHierarchyRoles ex: ['ROLE_ADMIN' => ['ROLE_USER'], ...]
     */
    public function __construct(array $roleHierarchyRoles)
    {
        // On veut une liste unique de rôles configurés (keys + children)
        $all = [];

        foreach ($roleHierarchyRoles as $parent => $children) {
            $all[] = (string) $parent;
            foreach ((array) $children as $child) {
                $all[] = (string) $child;
            }
        }

        $all = array_values(array_unique($all));
        sort($all);
        $all = array_values(array_filter($all, static fn (string $role): bool => 'ROLE_USER' !== $role));

        // ChoiceType attend label => value
        $this->roles = array_combine($all, $all) ?: [];
    }

    public function buildForm(FormBuilderInterface $builder, array $options): void
    {
        $builder
            ->add('username', TextType::class, [
                'label' => 'Identifiant',
                'required' => true,
            ])
            ->add('email', EmailType::class, [
                'label' => 'Email',
                'required' => true,
            ])
            ->add('roles', ChoiceType::class, [
                'label' => 'Rôles',
                'property_path' => 'assignableRoles',
                'multiple' => true,
                'expanded' => false,
                'choices' => $this->roles,
                'choice_label' => static fn (string $choice): string => mb_strtoupper($choice),
                'attr' => ['class' => 'select2'],
                'required' => true,
                'constraints' => [
                    new Count(min: 1, minMessage: 'Sélectionnez au moins un rôle administrateur.'),
                ],
            ])
            ->addEventListener(FormEvents::PRE_SET_DATA, [$this, 'onPreSetData']);
    }

    public function onPreSetData(FormEvent $event): void
    {
        $data = $event->getData();

        // nouveau user si pas d'objet ou pas d'id (selon ton modèle)
        $isNew = !$data instanceof User || (method_exists($data, 'getId') && null === $data->getId());

        $event->getForm()->add('plainPassword', PasswordType::class, [
            'label' => 'Mot de passe',
            'required' => $isNew,
        ]);
    }

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