<?php

declare(strict_types=1);

namespace Gls\GlsPoland\PrestaShop\Hook\Front;

use Gls\GlsPoland\Configuration\Initializer\ConfigurationInitializerInterface;
use Gls\GlsPoland\EventDispatcher\Adapter\EventDispatcher as EventDispatcherAdapter;
use Gls\GlsPoland\EventDispatcher\EventDispatcherInterface;
use Gls\GlsPoland\PrestaShop\Checkout\Module\SuperCheckout\FixRequestParamsListener;
use Gls\GlsPoland\PrestaShop\Event\FrontControllerInitializedEvent;
use Gls\GlsPoland\PrestaShop\Hook\AliasedHookInterface;
use Gls\GlsPoland\PrestaShop\Hook\VersionRange;
use Symfony\Component\EventDispatcher\EventDispatcher;
use Symfony\Component\HttpFoundation\Request;

final class ActionFrontControllerInitAfter implements AliasedHookInterface
{
    public const HOOK_NAME = 'actionFrontControllerInitAfter';
    private const HOOK_ALIAS = 'actionFrontControllerAfterInit';

    private $initializers;

    /**
     * @var EventDispatcherInterface
     */
    private $dispatcher;

    /**
     * @param iterable<ConfigurationInitializerInterface> $initializers
     */
    public function __construct(iterable $initializers, ?EventDispatcherInterface $dispatcher = null)
    {
        $this->initializers = $initializers;
        $this->dispatcher = $dispatcher ?? self::createEventDispatcher();
    }

    public static function getAliases(): array
    {
        return [
            self::HOOK_ALIAS => new VersionRange(null, '1.7.7'),
            self::HOOK_NAME => new VersionRange('1.7.7'),
        ];
    }

    /**
     * @param array{controller: \FrontControllerCore, request?: Request} $parameters
     */
    public function execute(array $parameters): void
    {
        $controller = $parameters['controller'] ?? \Context::getContext()->controller; // controller is not passed as a hook parameter on PS 1.7.6

        if (!$controller instanceof \FrontControllerCore) {
            return;
        }

        foreach ($this->initializers as $initializer) {
            $initializer->init();
        }

        $this->dispatcher->dispatch(new FrontControllerInitializedEvent($controller, $parameters['request'] ?? null));
    }

    private static function createEventDispatcher(): EventDispatcherInterface
    {
        @trigger_error(sprintf('Not passing an event dispatcher to "%s::__construct()" is deprecated since 1.1.0.', __CLASS__), E_USER_DEPRECATED);

        $dispatcher = new EventDispatcher();
        $dispatcher->addSubscriber(new FixRequestParamsListener());

        return new EventDispatcherAdapter($dispatcher);
    }
}
