<?php

/*
 * This file is part of the Serenity package.
 *
 * (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 Serenity\CoreBundle\Shared\Form\Type\Common;

use Serenity\CoreBundle\Shared\Feature\NestedTreeInterface;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\ChoiceList\View\ChoiceView;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\Form\FormView;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Contracts\Translation\TranslatableInterface;
use Symfony\Contracts\Translation\TranslatorInterface;

final class TreeType extends AbstractType
{
    public function __construct(private readonly TranslatorInterface $translator)
    {
    }

    public function buildView(FormView $view, FormInterface $form, array $options): void
    {
        parent::buildView($view, $form, $options);

        /** @var list<ChoiceView> $choices */
        $choices = $view->vars['choices'];

        foreach ($choices as $choice) {
            if (!$choice instanceof ChoiceView) {
                continue;
            }

            $data = $choice->data;
            if (!$data instanceof NestedTreeInterface) {
                continue;
            }

            $prefix = str_repeat('. ', max(0, $data->getLvl() + 1));

            $rawLabel = $choice->label;

            $label = match (true) {
                $rawLabel instanceof TranslatableInterface => $rawLabel->trans($this->translator),
                \is_string($rawLabel) => $rawLabel,
                default => '',
            };

            $choice->label = $prefix.$label;
        }
    }

    public function finishView(FormView $view, FormInterface $form, array $options): void
    {
        parent::finishView($view, $form, $options);

        /** @var list<ChoiceView> $choices */
        $choices = $view->vars['choices'];

        foreach ($view->children as $key => $child) {
            if (!isset($choices[$key])) {
                continue;
            }

            $data = $choices[$key]->data;
            if (!$data instanceof NestedTreeInterface) {
                continue;
            }

            $rowAttr = $child->vars['row_attr'] ?? [];

            $rowAttr['data-lvl'] = $data->getLvl();
            $rowAttr['data-children'] = $data->getChildren()->count() > 0 ? 1 : 0;

            $child->vars['row_attr'] = $rowAttr;
        }
    }

    public function configureOptions(OptionsResolver $resolver): void
    {
        $resolver->setDefaults([
            // Attendu par EntityType
            'class' => NestedTreeInterface::class,
        ]);
    }

    public function getParent(): string
    {
        return EntityType::class;
    }
}
