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

use Chill\CustomFieldsBundle\Entity\CustomFieldsGroup;
use Chill\CustomFieldsBundle\Form\DataTransformer\CustomFieldsGroupToIdTransformer;
use Chill\CustomFieldsBundle\Service\CustomFieldProvider;
use Chill\MainBundle\Form\Type\TranslatableStringFormType;
use Chill\MainBundle\Templating\TranslatableStringHelper;
use Doctrine\Persistence\ObjectManager;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
use Symfony\Component\Form\Extension\Core\Type\NumberType;
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;

class CustomFieldType extends AbstractType
{
    public function __construct(private readonly CustomFieldProvider $customFieldProvider, private readonly ObjectManager $om, private readonly TranslatableStringHelper $translatableStringHelper) {}

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $customFieldsList = [];

        foreach ($this->customFieldProvider->getAllFields() as $key => $field) {
            $customFieldsList[$key] = $field->getName();
        }

        $builder
            ->add('name', TranslatableStringFormType::class)
            ->add('active', CheckboxType::class, ['required' => false]);

        if ('entity' === $options['group_widget']) {
            $builder->add('customFieldsGroup', EntityType::class, [
                'class' => CustomFieldsGroup::class,
                'choice_label' => fn ($g) => $this->translatableStringHelper->localize($g->getName()),
            ]);
        } elseif ('hidden' === $options['group_widget']) {
            $builder->add('customFieldsGroup', HiddenType::class);
            $builder->get('customFieldsGroup')
                ->addViewTransformer(new CustomFieldsGroupToIdTransformer($this->om));
        } else {
            throw new \LogicException('The value of group_widget is not handled');
        }

        $builder
            ->add('ordering', NumberType::class)
            ->add('required', CheckboxType::class, [
                'required' => false,
                // 'expanded' => TRUE,
                'label' => 'Required field',
            ])
            ->add('type', HiddenType::class, ['data' => $options['type']])
            ->addEventListener(FormEvents::PRE_SET_DATA, static function (FormEvent $event) {
                $customField = $event->getData();
                $form = $event->getForm();

                // check if the customField object is "new"
                // If no data is passed to the form, the data is "null".
                // This should be considered a new "customField"
                if (!$customField || null === $customField->getId()) {
                    $form->add('slug', TextType::class);
                }
            });

        $builder->add(
            $this->customFieldProvider
                ->getCustomFieldByType($options['type'])
                ->buildOptionsForm(
                    $builder
                        ->create('options', null, ['compound' => true])
                        ->setRequired(false)
                )
        );
    }

    /**
     * @param OptionsResolverInterface $resolver
     */
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'data_class' => \Chill\CustomFieldsBundle\Entity\CustomField::class,
        ]);

        $resolver->setRequired(['type', 'group_widget'])
            ->addAllowedValues('type', array_keys($this->customFieldProvider->getAllFields()))
            ->addAllowedValues('group_widget', ['hidden', 'entity'])
            ->setDefault('group_widget', 'entity');
    }

    /**
     * @return string
     */
    public function getBlockPrefix()
    {
        return 'custom_field_choice';
    }
}
