<?php

use App\Enums\PermissionSlug;
use App\Enums\RoleSlug;
use App\Models\User;
use Database\Seeders\PermissionSeeder;
use Database\Seeders\RoleSeeder;
use Illuminate\Foundation\Testing\LazilyRefreshDatabase;
use Illuminate\Support\Facades\Route;

uses(LazilyRefreshDatabase::class);

beforeEach(function () {
    $this->withHeaders([
        'Origin' => 'http://localhost:3000',
        'Referer' => 'http://localhost:3000/',
    ]);

    Route::middleware(RoleSlug::middleware(RoleSlug::Admin, RoleSlug::Manager))
        ->get('/api/staff-area', fn () => response()->json(['ok' => true]));

    Route::middleware(RoleSlug::middleware(RoleSlug::Admin))
        ->get('/api/admin-area', fn () => response()->json(['ok' => true]));

    Route::middleware(PermissionSlug::middleware(PermissionSlug::CustomersCreate))
        ->get('/api/customer-create-area', fn () => response()->json(['ok' => true]));

    Route::middleware(PermissionSlug::middleware(PermissionSlug::UsersDelete))
        ->get('/api/user-admin-area', fn () => response()->json(['ok' => true]));
});

it('allows a matching role through role middleware', function () {
    $admin = User::factory()->admin()->create();

    $this->actingAs($admin)
        ->getJson('/api/admin-area')
        ->assertSuccessful()
        ->assertJsonPath('ok', true);
});

it('returns 403 when the role does not match', function () {
    $manager = User::factory()->manager()->create();

    $this->actingAs($manager)
        ->getJson('/api/admin-area')
        ->assertForbidden();
});

it('returns 403 when an unauthenticated user hits role middleware', function () {
    $this->getJson('/api/admin-area')
        ->assertForbidden();
});

it('allows a matching permission through permission middleware', function () {
    $this->seed([
        PermissionSeeder::class,
        RoleSeeder::class,
    ]);

    $manager = User::factory()->manager()->create();

    $this->actingAs($manager)
        ->getJson('/api/customer-create-area')
        ->assertSuccessful()
        ->assertJsonPath('ok', true);
});

it('returns 403 when the permission does not match', function () {
    $this->seed([
        PermissionSeeder::class,
        RoleSeeder::class,
    ]);

    $manager = User::factory()->manager()->create();

    $this->actingAs($manager)
        ->getJson('/api/user-admin-area')
        ->assertForbidden();
});

it('returns 403 when an unauthenticated user hits permission middleware', function () {
    $this->getJson('/api/customer-create-area')
        ->assertForbidden();
});
