<?php

namespace AutoAdmin\Bundle\Content\EventListener;

use AutoAdmin\Bundle\Content\Context\ContentContext;
use AutoAdmin\Bundle\Content\Event\ContentEvents;
use AutoAdmin\Bundle\Content\Event\ContentMatchEvent;
use AutoAdmin\Bundle\Content\Event\ContentMetadataEvent;
use AutoAdmin\Bundle\Content\Event\PostContentMetadataEvent;
use AutoAdmin\Bundle\Seo\Model\Header;
use AutoAdmin\Bundle\Seo\Model\SeoPage;
use AutoAdmin\Bundle\Seo\Renderer\RendererManager;
use Setono\BotDetectionBundle\BotDetector\BotDetectorInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\Cookie;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\KernelEvent;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\HttpKernel\Event\ResponseEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;

class MainContentRequestSubscriber implements EventSubscriberInterface
{
    public function __construct(
        private ContentContext $contentContext,
        private EventDispatcherInterface $eventDispatcher,
        private BotDetectorInterface $botDetector,
        private RendererManager $rendererManager
    ) {
    }

    public static function getSubscribedEvents(): array
    {
        return [
            KernelEvents::REQUEST => ['onKernelRequest', 0],
            KernelEvents::RESPONSE => ['onKernelResponse', 0],
        ];
    }

    protected function isSupportedRequest(KernelEvent $event)
    {
        if (!$event->isMainRequest()) {
            return false;
        }

        $request = $event->getRequest();
        $route = $request->get('_route');

        // todo, here, use content config to know if we have to handle current route
        if ($route === null || str_starts_with($route, '_') || str_starts_with($route, 'aa_admin_')) {
            return false;
        }

        return true;
    }

    public function onKernelRequest(RequestEvent $event)
    {
        if (!$this->isSupportedRequest($event)) {
            return;
        }

        $request = $event->getRequest();

        // ContentEvents::MATCH
        $event = new ContentMatchEvent($this->contentContext, $request);
        $this->eventDispatcher->dispatch($event, ContentEvents::MATCH);
    }

    public function onKernelResponse(ResponseEvent $event): Response|null
    {
        if (!$this->isSupportedRequest($event)) {
            return $event->getResponse();
        }

        $request = $event->getRequest();

//        $this->eventDispatcher->dispatch(
//            (new ContentMatchEvent($this->contentContext, $request)),
//            ContentEvents::MATCH
//        );

        // ContentEvents::METADATA
        $this->eventDispatcher->dispatch(
            (new ContentMetadataEvent($this->contentContext, $request)),
            ContentEvents::METADATA
        );

        // ContentEvents::POST_METADATA
        $this->eventDispatcher->dispatch(
            (new PostContentMetadataEvent($this->contentContext, $request)),
            ContentEvents::POST_METADATA
        );

        $response = $event->getResponse();

        if ($seoPage = $this->contentContext->getSeoPage()) {
            foreach ($this->rendererManager->getRenderers() as $renderer) {
                $response = $renderer->render($response, $seoPage);
            }
        }

        $response->headers->setCookie(
            Cookie::create(
                'aa_is_bot',
                $this->botDetector->isBotRequest(),
                0,
                '/',
                null,
                false,
                false,
            )
        );

        return $response;
    }

    /*
     * Beware, if we do not create X-Robots-Tag here,
     * \Symfony\Component\HttpKernel\EventListener\DisallowRobotsIndexingListener will create a noindex rule for "DEV" env
     */
    private function addRobotsTagHeader(Response $response, ?SeoPage $seoPage): Response
    {
        if ($seoPage->getResponseHeaders()) {
            /** @var Header $header */
            foreach ($seoPage->getResponseHeaders() as $header) {
                if (!$response->headers->has($header->getName())) {
                    $response->headers->set($header->getName(), $header->getValue());
                }
            }
        }

        return $response;
    }
}
