<?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\MainBundle\Form\Type;

use Chill\MainBundle\Entity\Center;
use Chill\MainBundle\Entity\Scope;
use Chill\MainBundle\Entity\User;
use Chill\MainBundle\Form\DataMapper\ScopePickerDataMapper;
use Chill\MainBundle\Security\Authorization\AuthorizationHelperInterface;
use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\Form\FormView;
use Symfony\Component\OptionsResolver\Options;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Security\Core\Role\Role;
use Symfony\Bundle\SecurityBundle\Security;

/**
 * Allow to pick amongst available scope for the current
 * user.
 *
 * options :
 *
 * - `center`: the center of the entity
 * - `role`  : the role of the user
 */
class ScopePickerType extends AbstractType
{
    public function __construct(
        private readonly AuthorizationHelperInterface $authorizationHelper,
        private readonly Security $security,
        private readonly TranslatableStringHelperInterface $translatableStringHelper,
    ) {}

    public function buildForm(FormBuilderInterface $builder, array $options): void
    {
        $items = array_values(
            array_filter(
                $this->authorizationHelper->getReachableScopes(
                    $this->security->getUser(),
                    $options['role'],
                    $options['center']
                ),
                static fn (Scope $s) => $s->isActive()
            )
        );

        if (0 === \count($items)) {
            throw new \RuntimeException('no scopes are reachable. This form should not be shown to user');
        }

        if (1 !== \count($items)) {
            $builder->add('scope', EntityType::class, [
                'class' => Scope::class,
                'placeholder' => 'Choose the circle',
                'choice_label' => fn (Scope $c) => $this->translatableStringHelper->localize($c->getName()),
                'choices' => $items,
            ]);
            $builder->setDataMapper(new ScopePickerDataMapper());
        } else {
            $builder->add('scope', HiddenType::class, [
                'data' => $items[0]->getId(),
            ]);
            $builder->setDataMapper(new ScopePickerDataMapper($items[0]));
        }
    }

    public function buildView(FormView $view, FormInterface $form, array $options): void
    {
        $view->vars['fullWidth'] = true;
    }

    public function configureOptions(OptionsResolver $resolver): void
    {
        $resolver
          // create `center` option
            ->setRequired('center')
            ->setAllowedTypes('center', [Center::class, 'array', 'null'])
          // create ``role` option
            ->setRequired('role')
            ->setAllowedTypes('role', ['string']);
    }
}
