<?php

declare(strict_types=1);

namespace Core\Framework\Event\Listener;

use Core\General\Translation\Service\Translator;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\ExceptionEvent;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
use Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException;
use Symfony\Component\HttpKernel\KernelEvents;

/**
 * Implemented according to
 *
 * @see https://symfony.com/doc/current/security/access_denied_handler.html#customizing-all-access-denied-responses
 */
readonly class ExceptionListener implements EventSubscriberInterface
{
    public function __construct(
        private Translator $translator)
    {
    }

    public static function getSubscribedEvents(): array
    {
        return [
            KernelEvents::EXCEPTION => ['onKernelException', 2],
        ];
    }

    public function onKernelException(ExceptionEvent $event): void
    {
        $exception = $event->getThrowable();

        switch (true) {
            case $exception instanceof AccessDeniedHttpException:
                $this->onAccessDeniedException();
            case $exception instanceof UnauthorizedHttpException:
                $this->onUnauthorizedException();
            default:
        }
    }

    /**
     * @throws AccessDeniedHttpException
     */
    private function onAccessDeniedException(): void
    {
        $message = $this->translator->translateMessage('exception.access_denied');

        throw new AccessDeniedHttpException($message);
    }

    /**
     * @throws UnauthorizedHttpException
     */
    private function onUnauthorizedException(): void
    {
        $message = $this->translator->translateMessage('exception.unauthorized');

        throw new UnauthorizedHttpException('', $message);
    }
}
