<?php

declare(strict_types=1);

use App\Filament\Resources\FindingResource;
use App\Filament\Widgets\Dashboard\RecentDriftFindings;
use App\Models\Finding;
use App\Models\InventoryItem;
use App\Support\Baselines\BaselineSubjectKey;
use Filament\Facades\Filament;
use Livewire\Livewire;

it('renders readable role definition evidence and no-restore messaging on the finding detail page', function (): void {
    [$user, $tenant] = createUserWithTenant(role: 'owner');

    $subjectExternalId = BaselineSubjectKey::workspaceSafeSubjectExternalIdForPolicy(
        'intuneRoleDefinition',
        'Security Reader',
        'rbac-role-1',
    );

    $finding = Finding::factory()->create([
        'tenant_id' => (int) $tenant->getKey(),
        'finding_type' => Finding::FINDING_TYPE_DRIFT,
        'source' => 'baseline.compare',
        'subject_type' => 'policy',
        'subject_external_id' => (string) $subjectExternalId,
        'evidence_fidelity' => 'content',
        'severity' => Finding::SEVERITY_LOW,
        'evidence_jsonb' => [
            'change_type' => 'different_version',
            'policy_type' => 'intuneRoleDefinition',
            'subject_key' => hash('sha256', 'intuneRoleDefinition|rbac-role-1'),
            'display_name' => 'Security Reader',
            'summary' => [
                'kind' => 'rbac_role_definition',
            ],
            'baseline' => [
                'policy_version_id' => 10,
                'hash' => 'baseline',
            ],
            'current' => [
                'policy_version_id' => 11,
                'hash' => 'current',
            ],
            'rbac_role_definition' => [
                'diff_kind' => 'metadata_only',
                'diff_fingerprint' => 'rbac-diff-1',
                'changed_keys' => ['Role definition > Description'],
                'metadata_keys' => ['Role definition > Description'],
                'permission_keys' => [],
                'baseline' => [
                    'normalized' => [
                        'Role definition > Display name' => 'Security Reader',
                        'Role definition > Description' => 'Baseline description',
                        'Role definition > Role source' => 'Custom',
                    ],
                    'is_built_in' => false,
                    'role_permission_count' => 1,
                ],
                'current' => [
                    'normalized' => [
                        'Role definition > Display name' => 'Security Reader',
                        'Role definition > Description' => 'Updated description',
                        'Role definition > Role source' => 'Custom',
                    ],
                    'is_built_in' => false,
                    'role_permission_count' => 1,
                ],
            ],
            'fidelity' => 'content',
            'provenance' => [
                'baseline_profile_id' => 1,
                'baseline_snapshot_id' => 1,
                'compare_operation_run_id' => 1,
                'inventory_sync_run_id' => 1,
            ],
        ],
    ]);

    $this->actingAs($user)
        ->get(FindingResource::getUrl('view', ['record' => $finding], tenant: $tenant))
        ->assertOk()
        ->assertSee('Intune RBAC Role Definition drift')
        ->assertSee('Metadata-only change')
        ->assertSee('Changed fields')
        ->assertSee('Role definition > Description')
        ->assertSee('Baseline description')
        ->assertSee('Updated description')
        ->assertSee('Role Assignments are not included')
        ->assertSee('RBAC restore is not supported');
});

it('shows RBAC labels and display-name fallback in the recent drift findings widget', function (): void {
    [$user, $tenant] = createUserWithTenant(role: 'owner');

    $this->actingAs($user);

    $tenant->makeCurrent();
    Filament::setCurrentPanel(Filament::getPanel('tenant'));
    Filament::setTenant($tenant, true);

    $subjectExternalId = 'rbac-role-1';

    InventoryItem::factory()->create([
        'tenant_id' => (int) $tenant->getKey(),
        'workspace_id' => (int) $tenant->workspace_id,
        'external_id' => $subjectExternalId,
        'policy_type' => 'intuneRoleDefinition',
        'display_name' => 'Security Reader',
        'meta_jsonb' => ['etag' => 'E1'],
        'last_seen_at' => now(),
    ]);

    $finding = Finding::factory()->create([
        'tenant_id' => (int) $tenant->getKey(),
        'finding_type' => Finding::FINDING_TYPE_DRIFT,
        'source' => 'baseline.compare',
        'subject_type' => 'policy',
        'subject_external_id' => (string) $subjectExternalId,
        'severity' => Finding::SEVERITY_HIGH,
        'status' => Finding::STATUS_NEW,
        'evidence_jsonb' => [
            'change_type' => 'missing_policy',
            'policy_type' => 'intuneRoleDefinition',
            'subject_key' => hash('sha256', 'intuneRoleDefinition|rbac-role-1'),
            'display_name' => 'Security Reader',
            'summary' => [
                'kind' => 'rbac_role_definition',
            ],
            'baseline' => ['policy_version_id' => 10],
            'current' => ['policy_version_id' => null],
            'rbac_role_definition' => [
                'diff_kind' => 'missing',
            ],
            'fidelity' => 'mixed',
            'provenance' => [
                'baseline_profile_id' => 1,
                'baseline_snapshot_id' => 1,
                'compare_operation_run_id' => 1,
                'inventory_sync_run_id' => null,
            ],
        ],
    ]);

    Livewire::actingAs($user)->test(RecentDriftFindings::class)
        ->assertCanSeeTableRecords([$finding])
        ->assertSee('Security Reader')
        ->assertSee('Intune RBAC Role Definition drift');
});
