<?php

declare(strict_types=1);

namespace Apexl\Tests\User\FeatureTests;

use apexl\Io\modules\user\entities\userEntity;
use apexl\Io\TestInfrastructure\FeatureTest;
use PHPUnit\Framework\Attributes\Test;

final class LoginTest extends FeatureTest
{
    #[Test]
    function successfulLoginTest(): void
    {
        $email = $this->faker->email();
        $password = $this->faker->password();

        userEntity::factory()->create([
            'email' => $email,
            'password' => $password,
        ]);

        $data = $this->post('/api/v1/user/action/login', [
            'username' => $email,
            'password' => $password,
        ]);

        $this->assertSuccessfulResponse($data);

        $redirect = '/foo';
        $data = $this->post('/api/v1/user/action/login', [
            'username' => $email,
            'password' => $password,
            'redirect' => $redirect,
        ]);

        $this->assertSuccessfulResponse($data, $redirect);
    }

    private function assertSuccessfulResponse(array $data, string $expectedRedirect = '/'): void
    {
        $this->assertIsArray($data);
        $this->assertTrue($data['success']);
        $this->assertIsString($data['access_token']);
        $this->assertIsString($data['refresh_token']);
        $this->assertSame($expectedRedirect, $data['redirect']);
        $this->assertIsInt($data['expires_in']);

    }

    #[Test]
    function inactiveUserTest(): void
    {
        $email = $this->faker->email();
        $password = $this->faker->password();

        userEntity::factory()->create([
            'email' => $email,
            'password' => $password,
            'active' => false,
        ]);

        $this->post('/api/v1/user/action/login', [
            'username' => $email,
            'password' => $password,
        ], 401);
    }

    #[Test]
    function missingUsernameTest(): void
    {
        $email = $this->faker->email();
        $password = $this->faker->password();

        userEntity::factory()->create([
            'email' => $email,
            'password' => $password,
            'active' => false,
        ]);

        $this->post('/api/v1/user/action/login', [
            'password' => $password,
        ], 422);

    }

    #[Test]
    function missingPasswordTest(): void
    {
        $email = $this->faker->email();
        $password = $this->faker->password();

        userEntity::factory()->create([
            'email' => $email,
            'password' => $password,
            'active' => false,
        ]);

        $this->post('/api/v1/user/action/login', [
            'username' => $email,
        ], 422);
    }

    #[Test]
    function emptyRequestBodyTest(): void
    {
        $email = $this->faker->email();
        $password = $this->faker->password();

        userEntity::factory()->create([
            'email' => $email,
            'password' => $password,
            'active' => false,
        ]);

        $this->post('/api/v1/user/action/login', [], 422);
    }

    #[Test]
    function invalidUsernameTest(): void
    {
        $email = $this->faker->unique()->email();
        $password = $this->faker->password();

        userEntity::factory()->create([
            'email' => $email,
            'password' => $password,
            'active' => false,
        ]);

        $invalidEmail = $this->faker->unique()->email();

        $this->post('/api/v1/user/action/login', [
            'username' => $invalidEmail,
            'password' => $password,
        ], 401);
    }

    #[Test]
    function invalidPasswordTest(): void
    {
        $email = $this->faker->unique()->email();
        $password = $this->faker->unique()->password();

        userEntity::factory()->create([
            'email' => $email,
            'password' => $password,
            'active' => false,
        ]);

        $invalidPassword = $this->faker->unique()->password();

        $this->post('/api/v1/user/action/login', [
            'username' => $email,
            'password' => $invalidPassword,
        ], 401);
    }
}