<?php

namespace App\EventSubscriber\Blog;

use App\Core\Entity\EntityInterface;
use App\Core\Event\EntityManager\EntityManagerEvent;
use App\Core\EventSubscriber\EntityManagerEventSubscriber;
use App\Core\Slugify\Slugify;
use App\Entity\Blog\Post;
use App\Repository\Blog\PostRepositoryQuery;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\Finder\Finder;

/**
 * class PostEventSubscriber.
 *
 * @author Simon Vieille <simon@deblan.fr>
 */
class PostEventSubscriber extends EntityManagerEventSubscriber
{
    protected Filesystem $filesystem;
    protected PostRepositoryQuery $query;
    protected Slugify $slugify;

    public function __construct(Filesystem $filesystem, PostRepositoryQuery $query, Slugify $slugify)
    {
        $this->filesystem = $filesystem;
        $this->query = $query;
        $this->slugify = $slugify;
    }

    public function supports(EntityInterface $entity)
    {
        return $entity instanceof Post;
    }

    public function onUpdate(EntityManagerEvent $event)
    {
        if (!$this->supports($event->getEntity())) {
            return;
        }

        $this->removeOrphanUploads();
    }

    public function onDelete(EntityManagerEvent $event)
    {
        if (!$this->supports($event->getEntity())) {
            return;
        }

        $this->removeOrphanUploads();
    }

    public function onPreUpdate(EntityManagerEvent $event)
    {
        if (!$this->supports($event->getEntity())) {
            return;
        }

        if ($event->getEntity()->getSlug()) {
            return;
        }

        $event->getEntity()->setSlug($this->slugify->slugify($event->getEntity()->getTitle()));
    }

    public function onPreCreate(EntityManagerEvent $event)
    {
        return $this->onPreUpdate($event);
    }

    protected function removeOrphanUploads()
    {
        $finder = new Finder();
        $finder->files()->in('uploads/post');

        foreach ($finder as $file) {
            $image = $file->getPathname();

            $post = $this->query->create()
                ->where('.image = :image')
                ->setParameter(':image', $image)
                ->findOne()
            ;

            if (null === $post) {
                $this->filesystem->remove($file->getRealPath());
            }
        }
    }
}
