<?php

declare(strict_types=1);

use App\Filament\Pages\Monitoring\AuditLog as AuditLogPage;
use App\Models\AuditLog as AuditLogModel;
use App\Models\ManagedEnvironment;
use App\Models\User;
use App\Models\Workspace;
use App\Models\WorkspaceMembership;
use App\Services\Auth\WorkspaceCapabilityResolver;
use App\Support\Workspaces\WorkspaceContext;
use Filament\Facades\Filament;
use Livewire\Livewire;

function auditLogAuthorizationTestRecord(ManagedEnvironment $tenant, array $attributes = []): AuditLogModel
{
    return AuditLogModel::query()->create(array_merge([
        'workspace_id' => (int) $tenant->workspace_id,
        'managed_environment_id' => (int) $tenant->getKey(),
        'actor_email' => 'auditor@example.com',
        'action' => 'verification.completed',
        'status' => 'success',
        'resource_type' => 'tenant',
        'resource_id' => (string) $tenant->getKey(),
        'summary' => 'Verification completed',
        'metadata' => [],
        'recorded_at' => now(),
    ], $attributes));
}

it('returns 404 when the user is not a member of the active workspace', function (): void {
    $user = User::factory()->create();
    $workspace = Workspace::factory()->create();

    $this->actingAs($user)
        ->withSession([WorkspaceContext::SESSION_KEY => (int) $workspace->getKey()])
        ->get(route('admin.monitoring.audit-log'))
        ->assertNotFound();
});

it('returns 403 when the user is a workspace member without audit capability', function (): void {
    $user = User::factory()->create();
    $workspace = Workspace::factory()->create();

    WorkspaceMembership::query()->create([
        'workspace_id' => (int) $workspace->getKey(),
        'user_id' => (int) $user->getKey(),
        'role' => 'readonly',
    ]);

    $resolver = \Mockery::mock(WorkspaceCapabilityResolver::class);
    $resolver->shouldReceive('isMember')->andReturnTrue();
    $resolver->shouldReceive('can')->andReturnFalse();
    app()->instance(WorkspaceCapabilityResolver::class, $resolver);

    $this->actingAs($user)
        ->withSession([WorkspaceContext::SESSION_KEY => (int) $workspace->getKey()])
        ->get(route('admin.monitoring.audit-log'))
        ->assertForbidden();
});

it('limits audit rows and event inspection to the user tenant scope', function (): void {
    [$user, $tenantA] = createUserWithTenant(role: 'owner');

    $tenantB = ManagedEnvironment::factory()->create([
        'workspace_id' => (int) $tenantA->workspace_id,
    ]);

    $visible = auditLogAuthorizationTestRecord($tenantA, [
        'summary' => 'ManagedEnvironment A audit event',
    ]);

    $hidden = auditLogAuthorizationTestRecord($tenantB, [
        'summary' => 'ManagedEnvironment B audit event',
    ]);

    test()->actingAs($user);
    Filament::setTenant(null, true);

    Livewire::actingAs($user)->test(AuditLogPage::class)
        ->assertCanSeeTableRecords([$visible])
        ->assertCanNotSeeTableRecords([$hidden]);

    $this->actingAs($user)
        ->withSession([WorkspaceContext::SESSION_KEY => (int) $tenantA->workspace_id])
        ->get(route('admin.monitoring.audit-log').'?event='.(int) $hidden->getKey())
        ->assertSuccessful()
        ->assertDontSee('ManagedEnvironment B audit event');

    Livewire::withQueryParams(['event' => (int) $hidden->getKey()])
        ->actingAs($user)
        ->test(AuditLogPage::class)
        ->assertSet('selectedAuditLogId', null)
        ->assertCanSeeTableRecords([$visible])
        ->assertCanNotSeeTableRecords([$hidden]);
});
