<?php

declare(strict_types=1);

namespace MauticPlugin\DealFlowBundle\EventSubscriber;

use Psr\Log\LoggerInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\HttpKernel\KernelEvents;

/**
 * Logs deprecation notices when legacy Deal Flow routes are accessed.
 *
 * Routes listed here still function — this subscriber only instruments them with
 * a notice-level log message so operators can identify callers before removal
 * in v1.0.0.
 *
 * Rate-limiting: each legacy route name is logged at most once per PHP process
 * (request-scoped) to keep logs tidy during high-traffic periods.
 */
final class DeprecationSubscriber implements EventSubscriberInterface
{
    /**
     * Map of legacy route name → canonical (replacement) route name.
     *
     * Add new entries here when additional legacy routes are introduced.
     * Mark the route definition in config.php with "@deprecated" when adding.
     *
     * @var array<string, string>
     */
    private const LEGACY_ROUTE_MAP = [
        'mautic_dealflow_edit_legacy' => 'mautic_dealflow_edit',
    ];

    /**
     * Per-request set of routes already logged (rate-limit: once per process).
     *
     * @var array<string, bool>
     */
    private array $logged = [];

    public function __construct(
        private readonly LoggerInterface $logger,
    ) {
    }

    /**
     * @return array<string, array<int, int|string>>
     */
    public static function getSubscribedEvents(): array
    {
        return [
            KernelEvents::REQUEST => ['onKernelRequest', -10],
        ];
    }

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

        $route = (string) $event->getRequest()->attributes->get('_route', '');

        if (!isset(self::LEGACY_ROUTE_MAP[$route])) {
            return;
        }

        // Rate-limit: log once per route per PHP process / request lifecycle.
        if (isset($this->logged[$route])) {
            return;
        }

        $this->logged[$route] = true;

        $replacement = self::LEGACY_ROUTE_MAP[$route];
        $path = $event->getRequest()->getPathInfo();

        $this->logger->notice(sprintf(
            '[DealFlow] DEPRECATED: Route %s (path: %s) accessed. Use %s instead. Removal target: v1.0.0',
            $route,
            $path,
            $replacement,
        ));
    }

    /**
     * Returns the map of legacy routes for introspection (e.g. in tests).
     *
     * @return array<string, string>
     */
    public static function getLegacyRouteMap(): array
    {
        return self::LEGACY_ROUTE_MAP;
    }
}
