<?php

declare(strict_types=1);

/*
 * This file is part of the Ferienpass package.
 *
 * (c) Richard Henkenjohann <richard@ferienpass.online>
 *
 * For more information visit the project website <https://ferienpass.online>
 * or the documentation under <https://docs.ferienpass.online>.
 */

namespace Ferienpass\AdminBundle\Form;

use Ferienpass\AdminBundle\Form\Builder\DynamicFormBuilder;
use Ferienpass\AdminBundle\Form\CompoundType\PostalAddressesType;
use Ferienpass\CoreBundle\Entity\Host;
use Ferienpass\CoreBundle\Entity\PostalAddress;
use Ferienpass\CoreBundle\Entity\User;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Bundle\SecurityBundle\Security;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\EmailType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\OptionsResolver\OptionsResolver;

class EditAccountType extends AbstractType
{
    public function __construct(private readonly Security $security)
    {
    }

    public function configureOptions(OptionsResolver $resolver): void
    {
        $resolver->setDefaults([
            'data_class' => User::class,
            'label_format' => 'accounts.label.%name%',
            'translation_domain' => 'admin',
            'required' => false,
            'validation_groups' => ['Default', 'email_unique'],
        ]);
    }

    public function buildForm(FormBuilderInterface $builder, array $options): void
    {
        $builder->addEventListener(FormEvents::PRE_SET_DATA, static function (FormEvent $event) {
            $user = $event->getData();
            if (!$user instanceof User) {
                return;
            }

            if ($user->getPostalAddresses()->isEmpty()) {
                $user->getPostalAddresses()->add(new PostalAddress());
            }
        });

        $builder = DynamicFormBuilder::fromBuilder($builder) ?? new DynamicFormBuilder($builder);

        /** @var User $data */
        $data = $options['data'];

        $isHost = static fn () => \in_array('ROLE_HOST', $data->getRoles(), true);
        $isAdmin = static fn () => \in_array('ROLE_ADMIN', $data->getRoles(), true);

        $builder
            ->add('firstname', options: ['section' => 'default', 'width' => '1/2', 'required' => true])
            ->add('lastname', options: ['section' => 'default', 'width' => '1/2', 'required' => true])
            ->add('phone', options: ['section' => 'contact', 'width' => '1/2'])
            ->add('mobile', options: ['section' => 'contact', 'width' => '1/2'])
            ->add('email', EmailType::class, ['section' => 'default', 'width' => '1/2|clr', 'required' => true])
            ->add('postalAddresses', PostalAddressesType::class, ['section' => 'address', 'label' => false])
            ->addIf('accountRoles', null, fn () => $this->security->isGranted('ROLE_ADMIN'), ChoiceType::class, [
                'choices' => User::ACCOUNT_ROLES,
                'choice_label' => static fn (string $role): string => "accounts.role.$role",
                'multiple' => true,
                'expanded' => true,
                'by_reference' => false,
                'section' => 'account',
                'label' => 'accounts.label.accountRoles',
                'help' => 'accounts.help.accountRoles',
            ])
            ->addIf('hosts', null, $isHost, EntityType::class, [
                'class' => Host::class,
                'choice_label' => 'name',
                'section' => 'default',
                'multiple' => true,
                'expanded' => false,
                'help' => 'accounts.help.hosts',
                'autocomplete' => true,
                'by_reference' => false,
            ])
            ->addIf('superAdmin', null, $isAdmin, CheckboxType::class, ['section' => 'account', 'help' => 'accounts.help.superAdmin'])
            ->addIf('adminRoles', null, static fn () => \in_array('ROLE_ADMIN', $data->getRoles(), true) && !$data->isSuperAdmin(), ChoiceType::class, [
                'choices' => User::ADMIN_ROLES,
                'choice_label' => static fn (string $role): string => "accounts.role.$role",
                'multiple' => true,
                'expanded' => true,
                'by_reference' => false,
                'section' => 'account',
                'label' => 'accounts.label.adminRoles',
                'help' => 'accounts.help.adminRoles',
            ])
            ->add('disabled', CheckboxType::class, ['section' => 'account', 'help' => 'accounts.help.disabled'])
        ;
    }
}
