<?php

namespace Tests\Feature;

use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;

class AuthTest extends TestCase
{
    use RefreshDatabase;

    public function test_registration_creates_a_wallet_and_bearer_token(): void
    {
        $response = $this->postJson('/api/v1/auth/register', [
            'email' => 'traveler@example.com',
            'password' => 'secure-password',
            'firstName' => 'Ada',
            'lastName' => 'Lovelace',
        ]);

        $response->assertCreated()
            ->assertJsonPath('user.email', 'traveler@example.com')
            ->assertJsonPath('tokenType', 'Bearer')
            ->assertJsonStructure(['user' => ['id'], 'accessToken', 'expiresAt']);

        $this->assertDatabaseHas('users', ['email' => 'traveler@example.com']);
        $this->assertDatabaseCount('wallets', 1);
        $this->assertDatabaseCount('personal_access_tokens', 1);
    }

    public function test_user_can_login_with_credentials(): void
    {
        User::factory()->create(['email' => 'returning@example.com']);

        $this->postJson('/api/v1/auth/login', [
            'email' => 'returning@example.com',
            'password' => 'password',
        ])->assertOk()
            ->assertJsonPath('user.email', 'returning@example.com')
            ->assertJsonStructure(['accessToken', 'expiresAt']);

        $this->assertDatabaseHas('users', [
            'email' => 'returning@example.com',
            'failed_login_count' => 0,
        ]);
    }

    public function test_protected_auth_routes_require_and_revoke_a_bearer_token(): void
    {
        $this->getJson('/api/v1/auth/user')->assertUnauthorized();

        $registration = $this->postJson('/api/v1/auth/register', [
            'email' => 'member@example.com',
            'password' => 'secure-password',
        ])->assertCreated();

        $token = $registration->json('accessToken');
        $this->withToken($token)->getJson('/api/v1/auth/user')
            ->assertOk()
            ->assertJsonPath('user.email', 'member@example.com');

        $this->withToken($token)->getJson('/api/v1/auth/me')
            ->assertOk()
            ->assertJsonPath('user.email', 'member@example.com');

        $this->withToken($token)->postJson('/api/v1/auth/logout')->assertOk();
        $this->withToken($token)->getJson('/api/v1/auth/user')->assertUnauthorized();
    }
}