<?php

/*
 * This file is part of the VITICORE2 package.
 *
 * (c) CP Creation <web@cpcreation.fr>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace CpCreation\VitiCore\Bridge\Symfony\Bundle\Controller\Site;

use CpCreation\VitiCore\Bridge\Symfony\Bundle\Provider\LocaleProvider;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Routing\RouterInterface;

final class LocaleController extends AbstractController
{
    public function __construct(
        private readonly RouterInterface $router,
        private readonly RequestStack $requestStack,
        private readonly LocaleProvider $localeProvider,
    ) {
    }

    private function getSession(): ?SessionInterface
    {
        return $this->requestStack->getSession();
    }

    #[Route('/request/locale/{locale}', name: 'setLocale', requirements: ['locale' => '[a-z]{2}'])]
    public function setLocale(Request $request, ?string $locale = null): RedirectResponse
    {
        if (\is_string($locale) && \in_array($locale, $this->localeProvider->getLocales(), true)) {
            $this->getSession()?->set('_locale', $locale);
        }

        $fallbackUrl = $this->router->generate('homepage');
        $referer = $request->headers->get('referer');
        if (!\is_string($referer) || '' === $referer) {
            return new RedirectResponse($fallbackUrl);
        }

        $refererParts = parse_url($referer);
        $requestOriginParts = parse_url($request->getSchemeAndHttpHost());
        if (!\is_array($refererParts)
            || !\is_array($requestOriginParts)
            || mb_strtolower((string) ($refererParts['scheme'] ?? '')) !== mb_strtolower((string) ($requestOriginParts['scheme'] ?? ''))
            || mb_strtolower((string) ($refererParts['host'] ?? '')) !== mb_strtolower((string) ($requestOriginParts['host'] ?? ''))
            || ($refererParts['port'] ?? null) !== ($requestOriginParts['port'] ?? null)) {
            return new RedirectResponse($fallbackUrl);
        }

        $path = $refererParts['path'] ?? '/';
        if (!\is_string($path) || !str_starts_with($path, '/') || str_starts_with($path, '//')) {
            return new RedirectResponse($fallbackUrl);
        }

        $target = $path;
        if (\is_string($refererParts['query'] ?? null) && '' !== $refererParts['query']) {
            $target .= '?'.$refererParts['query'];
        }

        return new RedirectResponse($target);
    }
}
