<?php
namespace App\Form;

use Symfony\Component\Form\Form;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormView;
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
use Symfony\Component\HttpFoundation\Request;
use phpDocumentor\Reflection\Types\Mixed_;

/**
 * Generic form
 */
abstract class AbstractFormManager
{

    /** @var Form Generated form */
    protected $form;

    /** @var string Unique ID of the form */
    protected $id;

    /** @var bool If the form uses a token to check validity */
    protected $usesToken = true;

    /**
     * @param FormBuilderInterface $formBuilder
     * @param array $data Additional data
     * @param bool $usesToken If the form uses a token to check validity
     */
    public function __construct(FormBuilderInterface $formBuilder, array $data = [], bool $usesToken = true)
    {
        $this->usesToken = $usesToken;
        $this->id = md5(json_encode([
            'class' => get_class($this),
            'name' => $formBuilder->getName(),
        ]));
        $this->addFields($formBuilder, $data);
        if ($usesToken) {
            $formBuilder->add('_ID', HiddenType::class, [
                'attr' => [
                    'value' => $this->id,
                ],
            ]);
        }
        $this->form = $formBuilder->getForm();
    }

    /**
     * Get the generated form view
     *
     * @return FormView
     */
    public function getFormView(): FormView
    {
        return $this->form->createView();
    }

    /**
     * Alias of form handleRequest method
     *
     * @param Request $request
     *
     * @see form::handleRequest()
     */
    public function handleRequest(Request $request): void
    {
        $this->form->handleRequest($request);
    }

    /**
     * Alias for form isSubmitted method
     *
     * @return bool
     *
     * @see Form::isSubmitted()
     */
    public function isSubmitted(): bool
    {
        if ($this->form->isSubmitted()) {
            $data = $this->form->getData();
            return !$this->usesToken || $data['_ID'] == $this->id;
        }
        return false;
    }

    /**
     * Alias of form isValid method
     *
     * @return bool
     *
     * @see Form::isValid()
     */
    public function isValid(): bool
    {
        return $this->form->isValid();
    }

    /**
     * Alias of form getData methos
     *
     * @return array
     *
     * @see Form::getData()
     */
    public function getData(): array
    {
        return $this->form->getData();
    }

    /**
     * Get the list of erros, empty if no errors
     *
     * @return array List of error string
     */
    public function validate(): array
    {
        return [];
    }

    /**
     * Get the template, return null if there is no specific template
     *
     * @return string|NULL
     */
    public function getTemplate(): ?string
    {
        return Null;
    }

    public function getNormData(): Mixed_
    {
    }

    /**
     * @param FormBuilderInterface $formBuilder
     * @param array $data Additional data
     */
    protected function addFields(FormBuilderInterface $formBuilder, array $data): void
    {
    }
}
