<?php


namespace AutoAdmin\Bundle\Admin\Search;


use AutoAdmin\Bundle\Admin\Form\Type\Component\RichSelect;
use AutoAdmin\Bundle\Content\Entity\Content;
use AutoAdmin\Bundle\Content\Model\NameInterface;
use AutoAdmin\Bundle\Content\Model\SiteInterface;
use AutoAdmin\Bundle\Content\Model\TitleInterface;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Mapping\ClassMetadataInfo;
use ReflectionClass;
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
use Symfony\Component\Form\Extension\Core\Type\FormType;
use Symfony\Component\Form\FormFactoryInterface;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;

class EntitySearchHelper
{
    private FormFactoryInterface $formFactory;
    private EntityManagerInterface $em;
    private ?Request $request = null;

    public function __construct(
        FormFactoryInterface   $formFactory,
        EntityManagerInterface $em,
        RequestStack           $requestStack
    )
    {
        $this->formFactory = $formFactory;
        $this->em = $em;
        $this->request = $requestStack->getMainRequest();
    }

    public function createForm(array $fieldMapping): ?FormInterface
    {
        $property = $fieldMapping['fieldName'];

        $filterOptionsByType = self::getFilterOptions();

        $fieldType = $fieldMapping['type'];

        $allQuery = $this->request->query->all();
        $data = $allQuery['filter_' . $property] ?? null;

        if ($data) {
            foreach ($data as $key => $value) {
                if (preg_match('#(.*)_empty#', $key)) {
                    $data[$key] = (bool)$value;
                }
            }
        }

        $fb = $this->formFactory->createNamedBuilder(
            'filter_' . $property,
            FormType::class,
            $data,
            [
                'attr' => [
                    'class' => 'multi-form-entity-table searching-widget searching-by-empty-type',
                ],
                'csrf_protection' => false,
                'method' => 'GET',
            ]
        );

        if ($fieldType === ClassMetadataInfo::MANY_TO_ONE) {
            $relClass = $fieldMapping['targetEntity'];
            $refl = new ReflectionClass($relClass);
            if (class_exists($relClass . 'Translation')) {
                $transRefl = new ReflectionClass($relClass . 'Translation');
            }

            $repo = $this->em->getRepository($relClass);
            $isContent = $refl->isSubclassOf(Content::class);
            if ($refl->implementsInterface(SiteInterface::class)) {
                $entities = $repo->contentFindBy([]);
            } else {
                $entities = $repo->findAll();
            }
            $filterChoices = [];
            foreach ($entities as $entity) {
                if ($isContent && $transRefl->implementsInterface(TitleInterface::class)) {
                    $label = $entity->getCurrentTranslation()->getTitle();
                } elseif ($isContent && $transRefl->implementsInterface(NameInterface::class)) {
                    $label = $entity->getCurrentTranslation()->getName();
                } elseif (!$isContent && $refl->implementsInterface(TitleInterface::class)) {
                    $label = $entity->getTitle();
                } elseif (!$isContent && $refl->implementsInterface(NameInterface::class)) {
                    $label = $entity->getName();
                } else {
                    $label = $refl->getShortName() . ' #' . $entity->getId();
                }
                $filterChoices[$label] = $entity->getId();
            }

            if ($filterChoices) {
                ksort($filterChoices);
            }

            $fb->add(
                $property,
                RichSelect::class,
                [
                    'label' => false,
                    'placeholder' => '--',
                    'choices' => $filterChoices,
                    'translation_domain' => false,
                ]
            );

            $fb->add(
                $property . '_empty',
                CheckboxType::class,
                [
                    'label_html' => true,
                    'label' => '<i class="fa fa-ban" aria-hidden="true"></i>',
                    'label_attr' => [
                        'class' => 'search-empty-label',
                        'title' => 'Filtrer les non renseignés',
                    ],
                    'attr' => ['class' => 'search-empty-input'],
                    'required' => false
                ]
            );

            $form = $fb->getForm();
        } else {
            if (!empty($filterOptionsByType[$fieldType])) {
                $fb->add(
                    $property,
                    RichSelect::class,
                    [
                        'label' => false,
                        'placeholder' => '--',
                        'choices' => $filterOptionsByType[$fieldType],
                        'translation_domain' => false,
                    ]
                );

                $form = $fb->getForm();
            } else {
                $form = null;
            }

        }

        return $form;
    }

    public static function getFilterOptions(): array
    {
        $filterDates = [
            'Vide' => 'empty',
            'Aujourd\'hui' => 'last_day',
            'Dernière heure' => 'last_hour',
            'Dernières 24 heures' => 'last_24hour',
            'Dernières 72 heures' => 'last_72hour',
            'Dernière semaine' => 'last_week',
            'Dernier mois' => 'last_month',
            'Dernière année' => 'last_year',
        ];

        return [
            'boolean' => [
                'On' => true,
                'Off' => false,
            ],
            //            disable dates for now
            //            'date' => $filterDates,
            //            'datetime' => $filterDates,
        ];
    }
}
