<?php

declare(strict_types=1);

namespace CpCreation\VitiCore\Bridge\Symfony\Bundle\EventListener;

use CpCreation\VitiCore\PageBuilder\Routing\PageBuilderEntryResolver;
use Symfony\Component\EventDispatcher\Attribute\AsEventListener;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;

#[AsEventListener(event: KernelEvents::REQUEST, method: 'onKernelRequest', priority: 1)]
final readonly class PageBuilderRedirectListener
{
    public function __construct(
        private PageBuilderEntryResolver $pageBuilderEntryResolver,
        private UrlGeneratorInterface $urlGenerator,
    ) {
    }

    public function onKernelRequest(RequestEvent $event): void
    {
        if (!$event->isMainRequest()) {
            return;
        }

        $request = $event->getRequest();
        if (!$request->isMethod('GET') || !$request->query->getBoolean('builder')) {
            return;
        }

        $routeName = trim((string) $request->attributes->get('_route'));
        if (!$this->supportsRoute($routeName)) {
            return;
        }

        $page = match ($routeName) {
            'cms_homepage', 'cms_page' => $this->pageBuilderEntryResolver->findCmsPageForRequest($request),
            default => $this->pageBuilderEntryResolver->findOrCreateSystemPageForRequest($request),
        };

        if (null === $page) {
            throw new NotFoundHttpException();
        }

        $event->setResponse(new RedirectResponse($this->urlGenerator->generate('cms_page_builder', [
            'id' => (string) $page->getId(),
            '_locale' => $request->getLocale(),
        ])));
    }

    private function supportsRoute(string $routeName): bool
    {
        if ('' === $routeName || 'cms_page_builder' === $routeName) {
            return false;
        }

        if (\in_array($routeName, ['_wdt', '_profiler', '_error'], true)) {
            return false;
        }

        return !str_starts_with($routeName, 'admin_')
            && !str_starts_with($routeName, 'api_')
            && !str_starts_with($routeName, '_');
    }
}
