<?php

namespace AutoAdmin\Bundle\Seo\Doctrine\EventListener;

use AutoAdmin\Bundle\Content\Model\NameInterface;
use AutoAdmin\Bundle\Content\Model\TitleInterface;
use AutoAdmin\Bundle\Content\Model\TranslatableInterface;
use AutoAdmin\Bundle\Core\Doctrine\Traits\ListenerStateManagerTrait;
use AutoAdmin\Bundle\Seo\Model\SeoContentTranslationInterface;
use Doctrine\Common\EventSubscriber;
use Doctrine\ORM\Event\PrePersistEventArgs;
use Doctrine\ORM\Event\PreUpdateEventArgs;
use Doctrine\ORM\Events;

class MetaDataSubscriber implements EventSubscriber
{
    use ListenerStateManagerTrait;

    public function getSubscribedEvents(): array
    {
        return [
            Events::prePersist,
            Events::preUpdate,
        ];
    }

    public function prePersist(PrePersistEventArgs $args): void
    {
        if (!$this->canRun()) {
            return;
        }

        $this->generateMetaTitle($args->getObject());
    }

    public function preUpdate(PreUpdateEventArgs $args): void
    {
        if (!$this->canRun()) {
            return;
        }

        $this->generateMetaTitle($args->getObject());
    }

    private function generateMetaTitle(object $entity): void
    {
        if ($entity instanceof SeoContentTranslationInterface) {
            if (empty($entity->getSeoMetadata()->getTitle())) {
                $nameInput = $this->getNameInput($entity);

                if ($nameInput !== null) {
                    $entity->getSeoMetadata()->setTitle($nameInput);
                }
            }
        }

        if ($entity instanceof TranslatableInterface) {
            if ($translation = $entity->getCurrentTranslation()) {
                $this->generateMetaTitle($translation);
            }
        }
    }

    private function getNameInput(SeoContentTranslationInterface $entity): ?string
    {
        if ($entity instanceof NameInterface) {
            return $entity->getName();
        }

        if ($entity instanceof TitleInterface) {
            return $entity->getTitle();
        }

        return null;
    }
}
