<?php

declare(strict_types=1);

namespace Tests\Unit\Middlewares;

use App\Helpers\Request;
use App\Helpers\Session as SessionHelper;
use App\Middlewares\AuthMiddleware;
use Tests\TestCase;

class AuthMiddlewareTest extends TestCase
{
    private AuthMiddleware $middleware;

    protected function setUp(): void
    {
        parent::setUp();
        $this->middleware = new AuthMiddleware();
    }

    public function testNoTokenReturnsError(): void
    {
        $_SERVER['REQUEST_METHOD'] = 'GET';
        $_SERVER['REQUEST_URI'] = '/api/test';
        unset($_SERVER['HTTP_AUTHORIZATION']);

        $request = new Request();
        $result = $this->middleware->handle($request);

        $this->assertIsString($result);
        $this->assertEquals('Token no proporcionado', $result);
    }

    public function testInvalidTokenReturnsError(): void
    {
        $_SERVER['REQUEST_METHOD'] = 'GET';
        $_SERVER['REQUEST_URI'] = '/api/test';
        $_SERVER['HTTP_AUTHORIZATION'] = 'Bearer token-invalido.fake.firma';

        $request = new Request();
        $result = $this->middleware->handle($request);

        $this->assertIsString($result);
        $this->assertStringContainsString('Token', $result);
    }

    public function testValidTokenWithoutSession(): void
    {
        $userId = $this->createTestUser('sessiontest@test.com', 'super_admin');
        $user = [
            'id' => $userId,
            'role' => 'super_admin',
            'current_event_id' => null,
        ];
        $token = SessionHelper::generateToken($user, 3600);

        $_SERVER['REQUEST_METHOD'] = 'GET';
        $_SERVER['REQUEST_URI'] = '/api/test';
        $_SERVER['HTTP_AUTHORIZATION'] = 'Bearer ' . $token;

        $request = new Request();
        $result = $this->middleware->handle($request);

        $this->assertIsString($result);
        $this->assertStringContainsString('Sesión', $result);
    }

    public function testValidTokenWithSessionPasses(): void
    {
        $userId = $this->createTestUser('validtoken@test.com', 'comercial_manager');
        $user = [
            'id' => $userId,
            'role' => 'comercial_manager',
            'current_event_id' => null,
        ];
        $token = SessionHelper::generateToken($user, 3600);
        $this->createTestSession($userId, $token);

        $_SERVER['REQUEST_METHOD'] = 'GET';
        $_SERVER['REQUEST_URI'] = '/api/test';
        $_SERVER['HTTP_AUTHORIZATION'] = 'Bearer ' . $token;

        $request = new Request();
        $result = $this->middleware->handle($request);

        $this->assertNull($result);
        $this->assertEquals($userId, $request->param('auth_user_id'));
        $this->assertEquals('comercial_manager', $request->param('auth_user_role'));
    }

    public function testExtractsUserDataFromToken(): void
    {
        $userId = $this->createTestUser('extract@test.com', 'super_admin');
        $user = [
            'id' => $userId,
            'role' => 'super_admin',
            'current_event_id' => 5,
        ];
        $token = SessionHelper::generateToken($user, 3600);
        $this->createTestSession($userId, $token);

        $_SERVER['REQUEST_METHOD'] = 'GET';
        $_SERVER['REQUEST_URI'] = '/api/test';
        $_SERVER['HTTP_AUTHORIZATION'] = 'Bearer ' . $token;

        $request = new Request();
        $this->middleware->handle($request);

        $this->assertEquals($userId, $request->param('auth_user_id'));
        $this->assertEquals('super_admin', $request->param('auth_user_role'));
        $this->assertEquals(5, $request->param('auth_user_event_id'));
    }
}
