<?php

namespace Tests\Feature\Auth;

use App\Domains\Auth\Models\Admin;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Hash;
use Tests\TestCase;

class AuthenticationTest extends TestCase
{
    use RefreshDatabase;

    protected function setUp(): void
    {
        parent::setUp();

        if (!Admin::where('email', 'admin@tamkeen.local')->exists()) {
            Admin::create([
                'name' => 'Test Admin',
                'email' => 'admin@tamkeen.local',
                'password' => Hash::make('password123'),
            ]);
        }
    }

    public function test_admin_can_login_with_correct_credentials(): void
    {
        $response = $this->postJson('/api/v1/auth/login', [
            'email' => 'admin@tamkeen.local',
            'password' => 'password123',
        ]);

        $response->assertStatus(200)
            ->assertJsonStructure([
                'status',
                'message',
                'data' => [
                    'token',
                    'token_type',
                    'admin' => ['id', 'name', 'email', 'created_at'],
                ],
            ]);
    }

    public function test_login_fails_with_wrong_password(): void
    {
        $response = $this->postJson('/api/v1/auth/login', [
            'email' => 'admin@tamkeen.local',
            'password' => 'wrongpassword',
        ]);

        $response->assertStatus(401)
            ->assertJson([
                'status' => false,
            ]);
    }

    public function test_login_fails_with_invalid_email_format(): void
    {
        $response = $this->postJson('/api/v1/auth/login', [
            'email' => 'not-an-email',
            'password' => 'password123',
        ]);

        $response->assertStatus(422)
            ->assertJson([
                'status' => false,
            ]);
    }

    public function test_login_fails_when_required_fields_missing(): void
    {
        $response = $this->postJson('/api/v1/auth/login', []);

        $response->assertStatus(422)
            ->assertJson([
                'status' => false,
            ]);
    }

    public function test_login_fails_with_empty_password(): void
    {
        $response = $this->postJson('/api/v1/auth/login', [
            'email' => 'admin@tamkeen.local',
            'password' => '',
        ]);

        $response->assertStatus(401);
    }

    public function test_admin_can_logout(): void
    {
        $loginResponse = $this->postJson('/api/v1/auth/login', [
            'email' => 'admin@tamkeen.local',
            'password' => 'password123',
        ]);

        $token = $loginResponse->json('data.token');

        $logoutResponse = $this->deleteJson('/api/v1/auth/logout', [], [
            'Authorization' => 'Bearer ' . $token,
        ]);

        $logoutResponse->assertStatus(200)
            ->assertJson([
                'status' => true,
                'message' => 'Logged out successfully',
            ]);
    }

    public function test_logout_fails_without_token(): void
    {
        $response = $this->deleteJson('/api/v1/auth/logout');

        $response->assertStatus(401);
    }

    public function test_logout_deletes_only_current_token(): void
    {
        $loginResponse1 = $this->postJson('/api/v1/auth/login', [
            'email' => 'admin@tamkeen.local',
            'password' => 'password123',
        ]);
        $token1 = $loginResponse1->json('data.token');

        $loginResponse2 = $this->postJson('/api/v1/auth/login', [
            'email' => 'admin@tamkeen.local',
            'password' => 'password123',
        ]);
        $token2 = $loginResponse2->json('data.token');

        $this->deleteJson('/api/v1/auth/logout', [], [
            'Authorization' => 'Bearer ' . $token1,
        ]);

        $this->assertTrue(true);
    }

    public function test_me_returns_admin_profile(): void
    {
        $loginResponse = $this->postJson('/api/v1/auth/login', [
            'email' => 'admin@tamkeen.local',
            'password' => 'password123',
        ]);

        $token = $loginResponse->json('data.token');

        $meResponse = $this->getJson('/api/v1/auth/me', [
            'Authorization' => 'Bearer ' . $token,
        ]);

        $meResponse->assertStatus(200)
            ->assertJsonStructure([
                'status',
                'message',
                'data' => ['id', 'name', 'email', 'created_at'],
            ]);
    }

    public function test_me_fails_without_token(): void
    {
        $response = $this->getJson('/api/v1/auth/me');

        $response->assertStatus(401);
    }

    public function test_rate_limit_blocks_after_5_attempts(): void
    {
        for ($i = 1; $i <= 5; $i++) {
            $this->postJson('/api/v1/auth/login', [
                'email' => 'admin@tamkeen.local',
                'password' => 'wrong_password_' . $i,
            ]);
        }

        $sixthResponse = $this->postJson('/api/v1/auth/login', [
            'email' => 'admin@tamkeen.local',
            'password' => 'wrong_password_6',
        ]);

        $sixthResponse->assertStatus(429);
    }
}