<?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 Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\Form\FormView;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Validator\Constraints\Length;
use Symfony\Component\Validator\Mapping\ClassMetadataInterface;
use Symfony\Component\Validator\Validator\ValidatorInterface;

class CkeditorType extends AbstractType
{
    public function __construct(public RequestStack $requestStack, private ValidatorInterface $validator)
    {
    }

    public function buildView(FormView $view, FormInterface $form, array $options): void
    {
        $maxLength = null;
        if ($form->getParent() && $form->getParent()->getConfig()->getOption('data_class')) {
            $propertyPath = $form->getPropertyPath();
            $dataClass = $form->getParent()->getConfig()->getOption('data_class');
            if (\is_string($dataClass)) {
                $maxLength = $this->getMaxLengthFromConstraints($dataClass, (string) $propertyPath);
            }
        }

        // merge les attrs par défaut + ceux déjà présents
        $view->vars['attr'] = array_merge([
            'data-controller' => 'ckeditor',
            'data-model' => 'on(change)|norender|'.str_replace('_', '.', $view->vars['id']),
            'data-ckeditor-config-value' => $options['config'],
            'data-ckeditor-maxlength-value' => $maxLength,
            'data-ckeditor-language-value' => $options['language'],
        ], $view->vars['attr'] ?? []);
    }

    public function configureOptions(OptionsResolver $resolver): void
    {
        $resolver->setDefaults([
            'config' => 'minimal', // valeur par défaut personnalisable
            'language' => $this->requestStack->getCurrentRequest()?->getLocale() ?? 'en',
        ]);
    }

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

    private function getMaxLengthFromConstraints(string $class, string $property): ?int
    {
        $metadata = $this->validator->getMetadataFor($class);

        if (!$metadata instanceof ClassMetadataInterface) {
            return null;
        }

        foreach ($metadata->getPropertyMetadata($property) as $propertyMetadata) {
            foreach ($propertyMetadata->getConstraints() as $constraint) {
                if ($constraint instanceof Length && null !== $constraint->max) {
                    return $constraint->max;
                }
            }
        }

        return null;
    }
}
