<?php

use App\Models\Branch;
use App\Models\User;

use function Pest\Laravel\postJson;

test('waiter can login with correct credentials and receive sanctum token', function () {
    $owner = User::factory()->create([
        'role' => 'owner',
    ]);

    $branch = Branch::create([
        'user_id' => $owner->id,
        'name' => 'Downtown Branch',
        'slug' => 'downtown-branch',
        'address' => '456 Elm St',
        'phone' => '0987654321',
        'active' => true,
    ]);

    $user = User::factory()->create([
        'email' => 'waiter@test.com',
        'password' => bcrypt('password'),
        'role' => 'waiter',
        'active' => 1,
        'active_branch_id' => $branch->id,
    ]);

    $response = postJson(url('api/waiter/login'), [
        'email' => 'waiter@test.com',
        'password' => 'password',
    ]);

    $response->assertStatus(200)
        ->assertJsonStructure([
            'success',
            'token',
            'user' => [
                'id',
                'name',
                'email',
                'phone_number',
                'role',
                'active_branch_id',
                'active_branch' => [
                    'id',
                    'name',
                ],
            ],
        ]);

    expect($response['success'])->toBeTrue();
    expect($response['token'])->not->toBeEmpty();
    expect($response['user']['role'])->toBe('waiter');
    expect($response['user']['active_branch']['name'])->toBe('Downtown Branch');
});

test('inactive waiter cannot login', function () {
    $user = User::factory()->create([
        'email' => 'inactive_waiter@test.com',
        'password' => bcrypt('password'),
        'role' => 'waiter',
        'active' => 0,
    ]);

    postJson(url('api/waiter/login'), [
        'email' => 'inactive_waiter@test.com',
        'password' => 'password',
    ])
        ->assertStatus(403)
        ->assertJson([
            'message' => 'Your account is inactive. Please contact support.',
        ]);
});

test('non waiter role cannot login to waiter auth endpoint', function () {
    $user = User::factory()->create([
        'email' => 'biller_user@test.com',
        'password' => bcrypt('password'),
        'role' => 'biller',
        'active' => 1,
    ]);

    postJson(url('api/waiter/login'), [
        'email' => 'biller_user@test.com',
        'password' => 'password',
    ])
        ->assertStatus(403)
        ->assertJson([
            'message' => 'Unauthorized. Only waiters can access this panel.',
        ]);
});

test('login requires valid fields and correct password', function () {
    $user = User::factory()->create([
        'email' => 'valid_waiter@test.com',
        'password' => bcrypt('password'),
        'role' => 'waiter',
        'active' => 1,
    ]);

    // Validation missing inputs
    postJson(url('api/waiter/login'), [])
        ->assertStatus(422)
        ->assertJsonValidationErrors(['email', 'password']);

    // Incorrect password
    postJson(url('api/waiter/login'), [
        'email' => 'valid_waiter@test.com',
        'password' => 'wrong_password',
    ])
        ->assertStatus(422)
        ->assertJsonValidationErrors(['email']);
});

test('authenticated waiter can logout and revoke token', function () {
    $user = User::factory()->create([
        'role' => 'waiter',
        'active' => 1,
    ]);

    $token = $user->createToken('test-token')->plainTextToken;

    $response = postJson(
        url('api/waiter/logout'),
        [],
        ['Authorization' => "Bearer $token"]
    );

    $response->assertStatus(200)
        ->assertJson([
            'success' => true,
            'message' => 'Logged out successfully.',
        ]);

    expect($user->tokens()->count())->toBe(0);
});

test('unauthenticated request to waiter logout endpoint is rejected', function () {
    postJson(url('api/waiter/logout'))
        ->assertStatus(401);
});
