<?php

use App\Filament\System\Pages\Dashboard;
use App\Models\AuditLog;
use App\Models\PlatformUser;
use App\Models\ManagedEnvironment;
use App\Support\Auth\PlatformCapabilities;
use Carbon\CarbonImmutable;
use Filament\Facades\Filament;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Livewire\Livewire;

uses(RefreshDatabase::class);

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

    ManagedEnvironment::factory()->create([
        'managed_environment_id' => null,
        'external_id' => 'platform',
        'name' => 'Platform',
    ]);

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

afterEach(function () {
    CarbonImmutable::setTestNow();
});

it('hides the break-glass action when disabled', function () {
    config()->set('tenantpilot.break_glass.enabled', false);

    $user = PlatformUser::factory()->create([
        'capabilities' => [
            PlatformCapabilities::ACCESS_SYSTEM_PANEL,
            PlatformCapabilities::CONSOLE_VIEW,
            PlatformCapabilities::USE_BREAK_GLASS,
        ],
    ]);

    $this->actingAs($user, 'platform');

    Livewire::test(Dashboard::class)
        ->assertActionHidden('enter_break_glass');
});

it('can enter and exit break-glass mode and audits transitions', function () {
    $user = PlatformUser::factory()->create([
        'capabilities' => [
            PlatformCapabilities::ACCESS_SYSTEM_PANEL,
            PlatformCapabilities::CONSOLE_VIEW,
            PlatformCapabilities::USE_BREAK_GLASS,
        ],
    ]);

    $this->actingAs($user, 'platform');

    Livewire::test(Dashboard::class)
        ->callAction('enter_break_glass', data: [
            'reason' => 'Recovery test',
        ]);

    $this->get('/system')->assertSuccessful()->assertSee('Recovery mode active');

    Livewire::test(Dashboard::class)
        ->callAction('exit_break_glass');

    $this->get('/system')->assertSuccessful()->assertDontSee('Recovery mode active');

    $tenant = ManagedEnvironment::query()->where('slug', 'platform')->firstOrFail();

    expect(AuditLog::query()->where('managed_environment_id', $tenant->getKey())->where('action', 'platform.break_glass.enter')->exists())->toBeTrue();
    expect(AuditLog::query()->where('managed_environment_id', $tenant->getKey())->where('action', 'platform.break_glass.exit')->exists())->toBeTrue();
});

it('expires break-glass mode after TTL and audits expiry', function () {
    config()->set('tenantpilot.break_glass.ttl_minutes', 1);

    $user = PlatformUser::factory()->create([
        'capabilities' => [
            PlatformCapabilities::ACCESS_SYSTEM_PANEL,
            PlatformCapabilities::CONSOLE_VIEW,
            PlatformCapabilities::USE_BREAK_GLASS,
        ],
    ]);

    $this->actingAs($user, 'platform');

    CarbonImmutable::setTestNow(CarbonImmutable::parse('2026-01-27 12:00:00'));

    Livewire::test(Dashboard::class)
        ->callAction('enter_break_glass', data: [
            'reason' => 'TTL test',
        ]);

    $this->get('/system')->assertSuccessful()->assertSee('Recovery mode active');

    CarbonImmutable::setTestNow(CarbonImmutable::parse('2026-01-27 12:02:00'));

    $this->get('/system')->assertSuccessful()->assertDontSee('Recovery mode active');

    $tenant = ManagedEnvironment::query()->where('slug', 'platform')->firstOrFail();

    expect(AuditLog::query()->where('managed_environment_id', $tenant->getKey())->where('action', 'platform.break_glass.expired')->exists())->toBeTrue();
});
