<?php

declare(strict_types=1);

/*
 * This file is part of the Ferienpass package.
 *
 * (c) Richard Henkenjohann <richard@ferienpass.online>
 *
 * For more information visit the project website <https://ferienpass.online>
 * or the documentation under <https://docs.ferienpass.online>.
 */

namespace Ferienpass\CmsBundle\Tests\EventListener\Routing;

use Ferienpass\CmsBundle\EventListener\Routing\LocaleRedirectListener;
use PHPUnit\Framework\TestCase;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\HttpKernel\HttpKernelInterface;

class LocaleRedirectListenerTest extends TestCase
{
    public function testRedirectToPreferredLanguage(): void
    {
        $request = Request::create('/');
        $request->headers->set('Accept-Language', 'ar-SA');

        $event = new RequestEvent(
            $this->createStub(HttpKernelInterface::class),
            $request,
            HttpKernelInterface::MAIN_REQUEST
        );

        $listener = new LocaleRedirectListener();
        $listener->onKernelRequest($event);

        $response = $event->getResponse();
        $this->assertNotNull($response);
        $this->assertSame(302, $response->getStatusCode());
        $this->assertSame('/ar/', $response->headers->get('Location'));
    }

    public function testNoRedirectForDefaultLanguage(): void
    {
        $request = Request::create('/');
        $request->headers->set('Accept-Language', 'de-DE');

        $event = new RequestEvent(
            $this->createStub(HttpKernelInterface::class),
            $request,
            HttpKernelInterface::MAIN_REQUEST
        );

        $listener = new LocaleRedirectListener();
        $listener->onKernelRequest($event);

        $this->assertNull($event->getResponse());
    }

    public function testNoRedirectWhenRefererFromSameHost(): void
    {
        $request = Request::create('http://localhost/');
        $request->headers->set('Accept-Language', 'ar-SA');
        $request->headers->set('Referer', 'http://localhost/ar/');

        $event = new RequestEvent(
            $this->createStub(HttpKernelInterface::class),
            $request,
            HttpKernelInterface::MAIN_REQUEST
        );

        $listener = new LocaleRedirectListener();
        $listener->onKernelRequest($event);

        $this->assertNull($event->getResponse());
    }

    public function testRedirectToPreferredLanguageWithQueryString(): void
    {
        $request = Request::create('/?foo=bar');
        $request->headers->set('Accept-Language', 'ar-SA');

        $event = new RequestEvent(
            $this->createStub(HttpKernelInterface::class),
            $request,
            HttpKernelInterface::MAIN_REQUEST
        );

        $listener = new LocaleRedirectListener();
        $listener->onKernelRequest($event);

        $response = $event->getResponse();
        $this->assertNotNull($response);
        $this->assertSame(302, $response->getStatusCode());
        $this->assertSame('/ar/?foo=bar', $response->headers->get('Location'));
    }

    public function testNoRedirectForSubpages(): void
    {
        $request = Request::create('/some-page');
        $request->headers->set('Accept-Language', 'ar-SA');

        $event = new RequestEvent(
            $this->createStub(HttpKernelInterface::class),
            $request,
            HttpKernelInterface::MAIN_REQUEST
        );

        $listener = new LocaleRedirectListener();
        $listener->onKernelRequest($event);

        $this->assertNull($event->getResponse());
    }

    public function testNoRedirectForSubRequest(): void
    {
        $request = Request::create('/');
        $request->headers->set('Accept-Language', 'ar-SA');

        $event = new RequestEvent(
            $this->createStub(HttpKernelInterface::class),
            $request,
            HttpKernelInterface::SUB_REQUEST
        );

        $listener = new LocaleRedirectListener();
        $listener->onKernelRequest($event);

        $this->assertNull($event->getResponse());
    }

    public function testNoRedirectWhenNoPreferredLanguageMatches(): void
    {
        // Use a language not in LocaleRouteProviderDecorator::MAP
        $request = Request::create('/');
        $request->headers->set('Accept-Language', 'zh-CN');
        // zh-CN → 'zh' which is not in the map, so getPreferredLanguage returns null
        // Actually we need to pass an Accept-Language that has no match at all
        // Let's override headers to empty so getPreferredLanguage returns null
        $request->headers->remove('Accept-Language');

        $event = new RequestEvent(
            $this->createStub(HttpKernelInterface::class),
            $request,
            HttpKernelInterface::MAIN_REQUEST
        );

        $listener = new LocaleRedirectListener();
        $listener->onKernelRequest($event);

        $this->assertNull($event->getResponse());
    }
}
