<?php

declare(strict_types=1);

use App\Filament\System\Pages\Directory\ViewWorkspace;
use App\Models\AuditLog;
use App\Models\PlatformUser;
use App\Models\SupportAccessGrant;
use App\Models\ManagedEnvironment;
use App\Models\Workspace;
use App\Services\Auth\BreakGlassSession;
use App\Support\Audit\AuditActionId;
use App\Support\Auth\PlatformCapabilities;
use Filament\Actions\Action;
use Filament\Facades\Filament;
use Livewire\Livewire;

beforeEach(function (): void {
    Filament::setCurrentPanel('system');
    Filament::bootCurrentPanel();

    config()->set('tenantpilot.support_access.max_ttl_minutes', 120);
    config()->set('tenantpilot.break_glass.enabled', true);
    config()->set('tenantpilot.break_glass.ttl_minutes', 15);
});

function spec276_system_platform_user(array $extraCapabilities = []): PlatformUser
{
    return PlatformUser::factory()->create([
        'capabilities' => array_values(array_unique([
            PlatformCapabilities::ACCESS_SYSTEM_PANEL,
            PlatformCapabilities::DIRECTORY_VIEW,
            ...$extraCapabilities,
        ])),
    ]);
}

it('lets an authorized platform operator start and end audit-view support access from the workspace detail page', function (): void {
    $workspace = Workspace::factory()->create(['name' => 'Acme Recovery']);
    $platformUser = spec276_system_platform_user([
        PlatformCapabilities::SUPPORT_ACCESS_MANAGE,
    ]);

    $component = Livewire::actingAs($platformUser, 'platform')
        ->test(ViewWorkspace::class, ['workspace' => $workspace])
        ->assertActionVisible('request_support_access')
        ->assertActionExists('request_support_access', fn (Action $action): bool => $action->isConfirmationRequired())
        ->callAction('request_support_access', data: [
            'scope' => SupportAccessGrant::SCOPE_AUDIT_VIEW,
            'reason' => 'Investigate managed tenant audit evidence',
            'ttl_minutes' => 45,
        ])
        ->assertNotified('Support access active')
        ->assertActionVisible('end_support_access')
        ->assertActionExists('end_support_access', fn (Action $action): bool => $action->isConfirmationRequired());

    $grant = SupportAccessGrant::query()
        ->where('workspace_id', (int) $workspace->getKey())
        ->firstOrFail();

    expect($grant->status)->toBe(SupportAccessGrant::STATUS_ACTIVE)
        ->and($grant->reason)->toBe('Investigate managed tenant audit evidence');

    $component
        ->callAction('end_support_access')
        ->assertNotified('Support access ended');

    expect($grant->fresh()->status)->toBe(SupportAccessGrant::STATUS_ENDED);

    expect(AuditLog::query()
        ->where('workspace_id', (int) $workspace->getKey())
        ->whereIn('action', [
            AuditActionId::SupportAccessRequested->value,
            AuditActionId::SupportAccessActivated->value,
            AuditActionId::SupportAccessEnded->value,
        ])
        ->count())->toBe(3);
});

it('hides support-access mutations from platform users without support-access capability', function (): void {
    $workspace = Workspace::factory()->create();
    $platformUser = spec276_system_platform_user();

    Livewire::actingAs($platformUser, 'platform')
        ->test(ViewWorkspace::class, ['workspace' => $workspace])
        ->assertActionHidden('request_support_access')
        ->assertActionHidden('end_support_access');
});

it('activates ownerless workspace-recovery support access only through a break-glass waiver', function (): void {
    ManagedEnvironment::factory()->create([
        'managed_environment_id' => null,
        'external_id' => 'platform',
        'name' => 'Platform',
    ]);

    $workspace = Workspace::factory()->create(['name' => 'Ownerless Support Workspace']);
    $platformUser = spec276_system_platform_user([
        PlatformCapabilities::SUPPORT_ACCESS_MANAGE,
        PlatformCapabilities::USE_BREAK_GLASS,
    ]);

    $this->actingAs($platformUser, 'platform');
    app(BreakGlassSession::class)->start($platformUser, 'Ownerless recovery support access');

    Livewire::actingAs($platformUser, 'platform')
        ->test(ViewWorkspace::class, ['workspace' => $workspace])
        ->callAction('request_support_access', data: [
            'scope' => SupportAccessGrant::SCOPE_WORKSPACE_RECOVERY,
            'reason' => 'Recover ownerless workspace safely',
            'ttl_minutes' => 30,
            'waiver_reason' => 'Verified the workspace has no owner membership',
        ])
        ->assertNotified('Support access active');

    $grant = SupportAccessGrant::query()
        ->where('workspace_id', (int) $workspace->getKey())
        ->where('scope', SupportAccessGrant::SCOPE_WORKSPACE_RECOVERY)
        ->firstOrFail();

    expect($grant->status)->toBe(SupportAccessGrant::STATUS_ACTIVE)
        ->and($grant->approval_mode)->toBe(SupportAccessGrant::APPROVAL_MODE_OWNERLESS_WAIVER)
        ->and($grant->waiver_reason)->toBe('Verified the workspace has no owner membership');

    expect(AuditLog::query()
        ->where('workspace_id', (int) $workspace->getKey())
        ->where('action', AuditActionId::SupportAccessOwnerlessWaiverUsed->value)
        ->exists())->toBeTrue();
});

it('renders current support-access posture on the system workspace detail page', function (): void {
    $workspace = Workspace::factory()->create(['name' => 'Northwind Workspace']);
    $platformUser = spec276_system_platform_user([
        PlatformCapabilities::SUPPORT_ACCESS_MANAGE,
    ]);

    SupportAccessGrant::factory()->create([
        'workspace_id' => (int) $workspace->getKey(),
        'requested_by_platform_user_id' => (int) $platformUser->getKey(),
        'scope' => SupportAccessGrant::SCOPE_AUDIT_VIEW,
        'reason' => 'Inspect audit evidence for a support case',
    ]);

    $this->actingAs($platformUser, 'platform')
        ->get(ViewWorkspace::getUrl(panel: 'system', parameters: ['workspace' => $workspace]))
        ->assertSuccessful()
        ->assertSee('Support access')
        ->assertSee('Audit trail review')
        ->assertSee('Inspect audit evidence for a support case');
});
