<?php

declare(strict_types=1);

namespace Tests\Unit\Models;

use App\Models\UserSession;
use Tests\TestCase;

class UserSessionTest extends TestCase
{
    private UserSession $sessionModel;

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

    public function testCreateSession(): void
    {
        $userId = $this->createTestUser();
        $token = 'test-jwt-token-' . uniqid();

        $id = $this->sessionModel->createSession($userId, $token, '127.0.0.1', 'PHPUnit', 3600);
        $this->assertIsInt($id);
        $this->assertGreaterThan(0, $id);
    }

    public function testFindByToken(): void
    {
        $userId = $this->createTestUser();
        $token = 'test-jwt-find-' . uniqid();
        $this->sessionModel->createSession($userId, $token, '127.0.0.1', 'PHPUnit', 3600);

        $session = $this->sessionModel->findByToken($token);
        $this->assertNotNull($session);
        $this->assertEquals($userId, $session['user_id']);
    }

    public function testFindByTokenNotFound(): void
    {
        $session = $this->sessionModel->findByToken('token-inexistente');
        $this->assertNull($session);
    }

    public function testInvalidateToken(): void
    {
        $userId = $this->createTestUser();
        $token = 'test-jwt-invalidate-' . uniqid();
        $this->sessionModel->createSession($userId, $token, '127.0.0.1', 'PHPUnit', 3600);

        $result = $this->sessionModel->invalidateToken($token);
        $this->assertTrue($result);

        $session = $this->sessionModel->findByToken($token);
        $this->assertNull($session);
    }

    public function testInvalidateAllUserTokens(): void
    {
        $userId = $this->createTestUser();
        $token1 = 'test-jwt-all-1-' . uniqid();
        $token2 = 'test-jwt-all-2-' . uniqid();

        $this->sessionModel->createSession($userId, $token1, '127.0.0.1', 'PHPUnit', 3600);
        $this->sessionModel->createSession($userId, $token2, '127.0.0.1', 'PHPUnit', 3600);

        $this->sessionModel->invalidateAllUserTokens($userId);

        $this->assertNull($this->sessionModel->findByToken($token1));
        $this->assertNull($this->sessionModel->findByToken($token2));
    }

    public function testCleanExpired(): void
    {
        $userId = $this->createTestUser();
        $db = \App\Models\Database::connect();

        $stmt = $db->prepare(
            "INSERT INTO sessions (user_id, token, ip_address, user_agent, expires_at)
             VALUES (:user_id, :token, '127.0.0.1', 'PHPUnit', DATE_SUB(NOW(), INTERVAL 1 HOUR))"
        );
        $stmt->execute([
            'user_id' => $userId,
            'token' => 'expired-token-' . uniqid(),
        ]);

        $this->sessionModel->cleanExpired();

        $session = $this->sessionModel->findByToken('expired-token-' . uniqid());
        $this->assertNull($session);
    }
}
