<?php

declare(strict_types=1);

namespace Tests\Unit\Models;

use App\Models\PasswordReset;
use Tests\TestCase;

class PasswordResetTest extends TestCase
{
    private PasswordReset $passwordResetModel;

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

    public function testCreateToken(): void
    {
        $userId = $this->createTestUser();
        $token = bin2hex(random_bytes(32));

        $id = $this->passwordResetModel->createToken($userId, $token, 3600);
        $this->assertIsInt($id);
        $this->assertGreaterThan(0, $id);
    }

    public function testFindValidToken(): void
    {
        $userId = $this->createTestUser();
        $token = bin2hex(random_bytes(32));
        $this->passwordResetModel->createToken($userId, $token, 3600);

        $reset = $this->passwordResetModel->findValidToken($token);
        $this->assertNotNull($reset);
        $this->assertEquals($userId, $reset['user_id']);
        $this->assertEquals(0, $reset['used']);
    }

    public function testFindInvalidToken(): void
    {
        $reset = $this->passwordResetModel->findValidToken('token-falso');
        $this->assertNull($reset);
    }

    public function testUsedTokenNotFound(): void
    {
        $userId = $this->createTestUser();
        $token = bin2hex(random_bytes(32));
        $id = $this->passwordResetModel->createToken($userId, $token, 3600);

        $this->passwordResetModel->markAsUsed($id);

        $reset = $this->passwordResetModel->findValidToken($token);
        $this->assertNull($reset);
    }

    public function testMarkAsUsed(): void
    {
        $userId = $this->createTestUser();
        $token = bin2hex(random_bytes(32));
        $id = $this->passwordResetModel->createToken($userId, $token, 3600);

        $result = $this->passwordResetModel->markAsUsed($id);
        $this->assertTrue($result);
    }

    public function testInvalidateExistingTokens(): void
    {
        $userId = $this->createTestUser();
        $token1 = bin2hex(random_bytes(32));
        $token2 = bin2hex(random_bytes(32));

        $this->passwordResetModel->createToken($userId, $token1, 3600);
        $this->passwordResetModel->createToken($userId, $token2, 3600);

        $this->passwordResetModel->invalidateExistingTokens($userId);

        $this->assertNull($this->passwordResetModel->findValidToken($token1));
        $this->assertNull($this->passwordResetModel->findValidToken($token2));
    }
}
