<?php

declare(strict_types=1);

use App\Filament\Resources\StoredReportResource;
use App\Filament\Resources\StoredReportResource\Pages\ViewStoredReport;
use App\Models\StoredReport;
use App\Models\ManagedEnvironment;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Livewire\Livewire;

uses(RefreshDatabase::class);

function storedReportDetailPermissionReport(ManagedEnvironment $tenant, array $payload = [], array $attributes = []): StoredReport
{
    return StoredReport::factory()
        ->permissionPosture($payload)
        ->create(array_merge([
            'managed_environment_id' => (int) $tenant->getKey(),
            'workspace_id' => (int) $tenant->workspace_id,
            'fingerprint' => 'permission-detail',
        ], $attributes));
}

function storedReportDetailEntraReport(ManagedEnvironment $tenant, array $payload = [], array $attributes = []): StoredReport
{
    return StoredReport::factory()
        ->entraAdminRoles($payload)
        ->create(array_merge([
            'managed_environment_id' => (int) $tenant->getKey(),
            'workspace_id' => (int) $tenant->workspace_id,
            'fingerprint' => 'entra-detail',
        ], $attributes));
}

function storedReportDetailHeaderActionNames(ViewStoredReport $page): array
{
    if ($page->getCachedHeaderActions() === []) {
        $page->cacheInteractsWithHeaderActions();
    }

    return collect($page->getCachedHeaderActions())
        ->map(static fn ($action): ?string => method_exists($action, 'getName') ? $action->getName() : null)
        ->filter()
        ->values()
        ->all();
}

it('renders current permission-posture detail with summary before raw payload', function (): void {
    [$user, $tenant] = createUserWithTenant(role: 'owner');
    $report = storedReportDetailPermissionReport($tenant, [
        'posture_score' => 75,
        'required_count' => 4,
        'granted_count' => 3,
        'permissions' => [
            ['key' => 'DeviceManagementConfiguration.Read.All', 'status' => 'granted'],
            ['key' => 'DeviceManagementApps.ReadWrite.All', 'status' => 'missing'],
        ],
    ], [
        'fingerprint' => 'permission-fingerprint',
    ]);

    $this->actingAs($user)
        ->get(StoredReportResource::getUrl('view', ['record' => $report], tenant: $tenant, panel: 'admin'))
        ->assertOk()
        ->assertSeeInOrder([
            'Outcome summary',
            'Stored report',
            'Permission posture summary',
            'Posture score',
            '75',
            'Required permissions',
            '4',
            'Granted permissions',
            '3',
            'Missing permissions',
            '1',
            'DeviceManagementApps.ReadWrite.All',
            'Raw payload',
        ])
        ->assertSee('Current')
        ->assertSee('Measured at')
        ->assertSee('permission-fingerprint');

    $this->actingAs($user);
    setAdminEnvironmentContext($tenant);

    $component = Livewire::test(ViewStoredReport::class, ['record' => $report->getKey()])
        ->assertActionHidden('open_current_report')
        ->assertSuccessful();

    expect(storedReportDetailHeaderActionNames($component->instance()))->toBe(['open_current_report']);
});

it('renders historical Entra admin-roles detail with a single current-report jump', function (): void {
    [$user, $tenant] = createUserWithTenant(role: 'owner');

    $historical = storedReportDetailEntraReport($tenant, [
        'totals' => [
            'roles_total' => 10,
            'assignments_total' => 20,
            'high_privilege_assignments' => 8,
        ],
        'high_privilege' => [
            [
                'role_display_name' => 'Privileged Role Administrator',
                'principal_display_name' => 'Bob Operator',
                'severity' => 'high',
            ],
            [
                'role_display_name' => 'Global Administrator',
                'principal_display_name' => 'Alice Admin',
                'severity' => 'critical',
            ],
        ],
    ], [
        'created_at' => now()->subDays(2),
        'updated_at' => now()->subDays(2),
        'fingerprint' => 'entra-old-fingerprint',
    ]);

    $current = storedReportDetailEntraReport($tenant, [
        'totals' => [
            'roles_total' => 11,
            'assignments_total' => 21,
            'high_privilege_assignments' => 3,
        ],
    ], [
        'created_at' => now()->subDay(),
        'updated_at' => now()->subDay(),
        'fingerprint' => 'entra-current-fingerprint',
        'previous_fingerprint' => 'entra-old-fingerprint',
    ]);

    $this->actingAs($user)
        ->get(StoredReportResource::getUrl('view', ['record' => $historical], tenant: $tenant, panel: 'admin'))
        ->assertOk()
        ->assertSeeInOrder([
            'Historical',
            'Entra admin roles summary',
            'Roles total',
            '10',
            'Assignments total',
            '20',
            'High-privilege assignments',
            '8',
            'Global Administrator assigned to Alice Admin (critical)',
            'Raw payload',
        ]);

    $this->actingAs($user);
    setAdminEnvironmentContext($tenant);

    Livewire::test(ViewStoredReport::class, ['record' => $historical->getKey()])
        ->assertActionVisible('open_current_report')
        ->assertActionExists('open_current_report', fn ($action): bool => $action->getLabel() === 'Open current report'
            && $action->getUrl() === StoredReportResource::getUrl('view', ['record' => $current], panel: 'admin', tenant: $tenant))
        ->assertSuccessful();
});

it('does not render unsupported report families through the v1 detail route', function (): void {
    [$user, $tenant] = createUserWithTenant(role: 'owner');

    $unsupported = StoredReport::query()->create([
        'managed_environment_id' => (int) $tenant->getKey(),
        'workspace_id' => (int) $tenant->workspace_id,
        'report_type' => 'future.report',
        'payload' => ['summary' => 'Unsupported'],
    ]);

    $this->actingAs($user)
        ->get(StoredReportResource::getUrl('view', ['record' => $unsupported], tenant: $tenant, panel: 'admin'))
        ->assertNotFound();
});
