<?php

namespace Tests\Feature\Auth;

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

class LoginTest extends TestCase
{
    use RefreshDatabase;

    public function test_user_can_login_with_email(): void
    {
        $user = User::factory()->create([
            'email' => 'user@example.com',
            'password' => bcrypt('password123'),
        ]);

        $response = $this->postJson('/api/v1/login', [
            'username' => 'user@example.com',
            'password' => 'password123',
        ]);

        $response->assertOk();
        $response->assertJsonStructure([
            'user' => ['id', 'first_name', 'last_name', 'email', 'phone'],
            'access_token',
            'token_type',
        ]);
    }

    public function test_user_can_login_with_phone(): void
    {
        $user = User::factory()->create([
            'phone' => '+1234567890',
            'password' => bcrypt('password123'),
        ]);

        $response = $this->postJson('/api/v1/login', [
            'username' => '+1234567890',
            'password' => 'password123',
        ]);

        $response->assertOk();
        $response->assertJsonStructure([
            'user' => ['id', 'first_name', 'last_name', 'email', 'phone'],
            'access_token',
            'token_type',
        ]);
    }

    public function test_login_fails_with_invalid_credentials(): void
    {
        User::factory()->create([
            'email' => 'user@example.com',
            'password' => bcrypt('password123'),
        ]);

        $response = $this->postJson('/api/v1/login', [
            'username' => 'user@example.com',
            'password' => 'wrongpassword',
        ]);

        $response->assertUnauthorized();
        $response->assertJsonPath('message', 'Invalid credentials');
    }

    public function test_login_fails_with_nonexistent_user(): void
    {
        $response = $this->postJson('/api/v1/login', [
            'username' => 'nonexistent@example.com',
            'password' => 'password123',
        ]);

        $response->assertUnauthorized();
        $response->assertJsonPath('message', 'Invalid credentials');
    }

    public function test_login_issues_access_token(): void
    {
        User::factory()->create([
            'email' => 'token@example.com',
            'password' => bcrypt('password123'),
        ]);

        $response = $this->postJson('/api/v1/login', [
            'username' => 'token@example.com',
            'password' => 'password123',
        ]);

        $response->assertOk();
        $this->assertNotEmpty($response->json('access_token'));
        $this->assertEquals('Bearer', $response->json('token_type'));
    }

    public function test_authenticated_user_can_logout(): void
    {
        $user = User::factory()->create();
        $token = $user->createToken('auth-token')->plainTextToken;

        $response = $this->postJson('/api/v1/logout', [], [
            'Authorization' => "Bearer $token",
        ]);

        $response->assertOk();
        $response->assertJsonPath('message', 'Logged out successfully');
    }

    public function test_authenticated_user_can_get_profile(): void
    {
        $user = User::factory()->create([
            'first_name' => 'John',
            'last_name' => 'Doe',
            'email' => 'john@example.com',
        ]);
        $token = $user->createToken('auth-token')->plainTextToken;

        $response = $this->getJson('/api/v1/user', [
            'Authorization' => "Bearer $token",
        ]);

        $response->assertOk();
        $response->assertJsonPath('data.first_name', 'John');
        $response->assertJsonPath('data.last_name', 'Doe');
        $response->assertJsonPath('data.email', 'john@example.com');
    }

    public function test_unauthenticated_user_cannot_access_protected_route(): void
    {
        $response = $this->getJson('/api/v1/user');

        $response->assertUnauthorized();
    }
}
