<?php

declare(strict_types=1);

namespace App\EventListener;

use Symfony\Component\EventDispatcher\Attribute\AsEventListener;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\HttpKernel\KernelInterface;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;

#[AsEventListener(event: 'kernel.request', priority: 10)]
final class MaintenanceModeListener
{
    public function __construct(
        private readonly KernelInterface $kernel,
        private readonly TokenStorageInterface $tokenStorage,
    ) {}

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

        $flagFile = $this->kernel->getProjectDir().'/var/maintenance';

        if (!file_exists($flagFile)) {
            return;
        }

        $request = $event->getRequest();
        $path    = $request->getPathInfo();

        // Always allow maintenance status endpoint and session endpoints
        if (str_starts_with($path, '/api/admin/maintenance')
            || str_starts_with($path, '/api/maintenance/check')
            || str_starts_with($path, '/api/session')
            || str_starts_with($path, '/api/health')
            || str_starts_with($path, '/api/docs')
        ) {
            return;
        }

        // Allow admin users through
        $token = $this->tokenStorage->getToken();
        if ($token && $token->getUser()) {
            $roles = $token->getRoleNames();
            if (in_array('ROLE_ADMIN', $roles, true)) {
                return;
            }
        }

        $event->setResponse(new JsonResponse(
            ['message' => 'Application en maintenance. Veuillez réessayer ultérieurement.'],
            JsonResponse::HTTP_SERVICE_UNAVAILABLE,
        ));
    }
}
