<?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\Scope;
use Chill\MainBundle\Security\RoleProvider;
use Chill\MainBundle\Templating\TranslatableStringHelper;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;

/**
 * Form to Edit/create a role scope. If the role scope does not
 * exists in the database, he is generated.
 */
class ComposedRoleScopeType extends AbstractType
{
    private readonly RoleProvider $roleProvider;

    /**
     * @var string[]
     */
    private array $roles = [];

    /**
     * @var string[]
     */
    private array $rolesWithoutScope = [];

    public function __construct(
        private readonly TranslatableStringHelper $translatableStringHelper,
        RoleProvider $roleProvider,
    ) {
        $this->roles = $roleProvider->getRoles();
        $this->rolesWithoutScope = $roleProvider->getRolesWithoutScopes();
        $this->roleProvider = $roleProvider;
    }

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        // store values used in internal function
        $translatableStringHelper = $this->translatableStringHelper;
        $rolesWithoutScopes = $this->rolesWithoutScope;

        // build roles
        $values = [];

        foreach ($this->roles as $role) {
            $values[$role] = $role;
        }

        $builder
            ->add('role', ChoiceType::class, [
                'choices' => array_combine(array_values($values), array_keys($values)),
                'placeholder' => 'Choose amongst roles',
                'choice_attr' => static function ($role) use ($rolesWithoutScopes) {
                    if (\in_array($role, $rolesWithoutScopes, true)) {
                        return ['data-has-scope' => '0'];
                    }

                    return ['data-has-scope' => '1'];
                },
                'group_by' => fn ($role, $key, $index) => $this->roleProvider->getRoleTitle($role),
            ])
            ->add('scope', EntityType::class, [
                'class' => Scope::class,
                'choice_label' => static fn (Scope $scope) => $translatableStringHelper->localize($scope->getName()),
                'placeholder' => 'Choose amongst scopes',
                'required' => false,
                'data' => null,
            ]);
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefault('data_class', \Chill\MainBundle\Entity\RoleScope::class);
    }
}
