<?php


namespace AutoAdmin\Bundle\Media\EventListener\Form;


use AutoAdmin\Bundle\Media\Model\FileInterface;
use Doctrine\Persistence\ManagerRegistry;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;

class MediaListener implements EventSubscriberInterface
{
    protected array $deleteStack = [];
    private ManagerRegistry $doctrine;

    public function __construct(ManagerRegistry $doctrine)
    {
        $this->doctrine = $doctrine;
    }

    public static function getSubscribedEvents(): array
    {
        return [
            FormEvents::POST_SET_DATA => 'onPostSetData',
            FormEvents::SUBMIT => 'onSubmit',
            FormEvents::POST_SUBMIT => 'onPostSubmit',
        ];
    }

    public function onPostSetData(FormEvent $event)
    {
        $form = $event->getForm();
        $parentForm = $form->getParent();
        if ($parentForm) {
            // if entry_type is different from null, chances are we are child of a collection type form
            $isCollection = $parentForm->getConfig()->getOption('entry_type') !== null;
            $isRequired = $parentForm->getConfig()->getOption('required');
            if (
                !$isRequired && (
                    !$isCollection
                    || $form->getConfig()->getOption('display_delete_button') === true
                )
            ) {
                $form->add(
                    'delete_media',
                    CheckboxType::class,
                    [
                        'mapped' => false,
                        'required' => false,
                        'label' => 'media.delete',
                        'translation_domain' => 'aa_admin',
                    ]
                );
            }
        }
    }

    public function onSubmit(FormEvent $event)
    {
        $data = $event->getData();
        $form = $event->getForm();
        if ($data instanceof FileInterface) {
            $data->setMapping($event->getForm()->getConfig()->getOption('mapping'));
        }

        if (
            $form
            && $form->has('delete_media')
            && ($delete = $form->get('delete_media')->getData())
        ) {
            $event->setData(null);
            $this->deleteStack[spl_object_id($form)] = $form->getData();
        }
    }

    public function onPostSubmit(FormEvent $event)
    {
        $form = $event->getForm();
        if (
            !empty($this->deleteStack[spl_object_id($form)])
            && $deleteObject = $this->deleteStack[spl_object_id($form)]
        ) {
            $this->doctrine->getManager()->remove($deleteObject);
        }
    }
}