<?php

namespace App\Tests\Security;

use App\Security\LoginSuccessHandler;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\RouterInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;

class LoginSuccessHandlerTest extends TestCase
{
    private RouterInterface $router;
    private AuthorizationCheckerInterface $authorizationChecker;
    private LoginSuccessHandler $handler;

    protected function setUp(): void
    {
        $this->router = $this->createStub(RouterInterface::class);
        $this->authorizationChecker = $this->createStub(AuthorizationCheckerInterface::class);
        $this->handler = new LoginSuccessHandler($this->router, $this->authorizationChecker);
    }

    #[DataProvider('provideRolesAndRoutes')]
    public function testOnAuthenticationSuccess(string $role, string $routeName): void
    {
        $request = new Request();
        $token = $this->createStub(TokenInterface::class);

        $this->authorizationChecker->method('isGranted')
            ->willReturnCallback(fn ($r) => $r === $role);

        $this->router->method('generate')
            ->willReturnCallback(fn ($route) => '/'.$route);

        $response = $this->handler->onAuthenticationSuccess($request, $token);

        $this->assertEquals('/'.$routeName, $response->getTargetUrl());
    }

    public static function provideRolesAndRoutes(): iterable
    {
        yield ['ROLE_EMPLOYE', 'app_admin_dashboard'];
        yield ['ROLE_REVENDEUR', 'app_espace_prestataire_index'];
        yield ['ROLE_CUSTOMER', 'app_espace_client_index'];
    }

    public function testOnAuthenticationSuccessDefault(): void
    {
        $request = new Request();
        $token = $this->createStub(TokenInterface::class);

        $this->authorizationChecker->method('isGranted')->willReturn(false);

        $this->router->method('generate')
            ->willReturnCallback(fn ($route) => '/');

        $response = $this->handler->onAuthenticationSuccess($request, $token);

        $this->assertEquals('/', $response->getTargetUrl());
    }
}
