<?php

declare(strict_types=1);

use App\Filament\Pages\Operations\TenantlessOperationRunViewer;
use App\Models\AuditLog;
use App\Models\EvidenceSnapshot;
use App\Models\Finding;
use App\Models\ManagedEnvironmentMembership;
use App\Models\OperationRun;
use App\Models\ProviderConnection;
use App\Models\ReviewPack;
use App\Models\StoredReport;
use App\Models\ManagedEnvironment;
use App\Models\EnvironmentReview;
use App\Models\User;
use App\Models\Workspace;
use App\Models\WorkspaceMembership;
use App\Support\OperationRunLinks;
use App\Support\OperationRunOutcome;
use App\Support\OperationRunStatus;
use App\Support\OperationRunType;
use App\Support\Providers\ProviderReasonCodes;
use App\Support\Providers\ProviderVerificationStatus;
use App\Support\Workspaces\WorkspaceContext;
use Filament\Actions\Action;
use Filament\Facades\Filament;
use Livewire\Livewire;

function operationSupportDiagnosticsComponent(User $user, OperationRun $run): \Livewire\Features\SupportTesting\Testable
{
    test()->actingAs($user);
    Filament::setTenant(null, true);
    session()->put(WorkspaceContext::SESSION_KEY, (int) $run->workspace_id);

    return Livewire::actingAs($user)->test(TenantlessOperationRunViewer::class, ['run' => $run]);
}

it('opens a redacted support diagnostic bundle from the tenantless operation viewer', function (): void {
    $tenant = ManagedEnvironment::factory()->create(['name' => 'Contoso Support ManagedEnvironment']);
    [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'operator');

    $connection = ProviderConnection::factory()
        ->withCredential()
        ->create([
            'managed_environment_id' => (int) $tenant->getKey(),
            'workspace_id' => (int) $tenant->workspace_id,
            'display_name' => 'Contoso Microsoft connection',
            'verification_status' => ProviderVerificationStatus::Blocked->value,
            'last_error_reason_code' => ProviderReasonCodes::ProviderPermissionMissing,
            'last_error_message' => 'raw-provider-secret-message',
            'last_health_check_at' => now()->subMinutes(15),
        ]);

    $run = OperationRun::factory()
        ->forTenant($tenant)
        ->create([
            'type' => OperationRunType::BaselineCompare->value,
            'status' => OperationRunStatus::Completed->value,
            'outcome' => OperationRunOutcome::Failed->value,
            'summary_counts' => [
                'total' => 0,
                'processed' => 0,
            ],
            'context' => [
                'provider_connection_id' => (int) $connection->getKey(),
                'raw_response_body' => 'secret-provider-body',
            ],
            'failure_summary' => [[
                'message' => 'Run failed after provider validation.',
            ]],
            'completed_at' => now()->subMinutes(10),
        ]);

    $finding = Finding::factory()->create([
        'managed_environment_id' => (int) $tenant->getKey(),
        'workspace_id' => (int) $tenant->workspace_id,
        'current_operation_run_id' => (int) $run->getKey(),
        'severity' => Finding::SEVERITY_HIGH,
        'last_seen_at' => now()->subMinutes(8),
    ]);

    StoredReport::factory()->create([
        'managed_environment_id' => (int) $tenant->getKey(),
        'workspace_id' => (int) $tenant->workspace_id,
        'report_type' => StoredReport::REPORT_TYPE_PERMISSION_POSTURE,
        'payload' => [
            'raw_response_body' => 'stored-report-secret-body',
        ],
        'fingerprint' => 'permission-fingerprint',
    ]);

    $evidenceSnapshot = EvidenceSnapshot::query()->create([
        'managed_environment_id' => (int) $tenant->getKey(),
        'workspace_id' => (int) $tenant->workspace_id,
        'operation_run_id' => (int) $run->getKey(),
        'initiated_by_user_id' => (int) $user->getKey(),
        'fingerprint' => fake()->sha256(),
        'status' => 'active',
        'completeness_state' => 'complete',
        'summary' => [
            'dimension_count' => 1,
            'missing_dimensions' => 0,
            'stale_dimensions' => 0,
        ],
        'generated_at' => now()->subMinutes(7),
    ]);

    $review = EnvironmentReview::factory()->ready()->create([
        'managed_environment_id' => (int) $tenant->getKey(),
        'workspace_id' => (int) $tenant->workspace_id,
        'evidence_snapshot_id' => (int) $evidenceSnapshot->getKey(),
        'operation_run_id' => (int) $run->getKey(),
        'generated_at' => now()->subMinutes(7),
    ]);

    $pack = ReviewPack::factory()->ready()->create([
        'managed_environment_id' => (int) $tenant->getKey(),
        'workspace_id' => (int) $tenant->workspace_id,
        'environment_review_id' => (int) $review->getKey(),
        'operation_run_id' => (int) $run->getKey(),
        'generated_at' => now()->subMinutes(6),
    ]);

    $review->forceFill(['current_export_review_pack_id' => (int) $pack->getKey()])->save();

    AuditLog::query()->create([
        'workspace_id' => (int) $tenant->workspace_id,
        'managed_environment_id' => (int) $tenant->getKey(),
        'operation_run_id' => (int) $run->getKey(),
        'action' => 'operation.failed',
        'resource_type' => 'operation_run',
        'resource_id' => (string) $run->getKey(),
        'target_label' => 'Operation #'.$run->getKey(),
        'metadata' => [
            'raw_response_body' => 'audit-secret-body',
            'reason_code' => 'provider_permission_missing',
        ],
        'outcome' => 'success',
        'recorded_at' => now()->subMinutes(5),
    ]);

    operationSupportDiagnosticsComponent($user, $run)
        ->assertActionVisible('openSupportDiagnostics')
        ->assertActionEnabled('openSupportDiagnostics')
        ->assertActionExists('openSupportDiagnostics', fn (Action $action): bool => $action->getLabel() === 'Open support diagnostics')
        ->assertActionHasIcon('openSupportDiagnostics', 'heroicon-o-lifebuoy')
        ->mountAction('openSupportDiagnostics')
        ->assertMountedActionModalSee('Support diagnostics')
        ->assertMountedActionModalSee(OperationRunLinks::identifier($run))
        ->assertMountedActionModalSee('The compare finished, but no decision-grade result is available yet.')
        ->assertMountedActionModalSee('Contoso Microsoft connection')
        ->assertMountedActionModalSee('High finding #'.$finding->getKey())
        ->assertMountedActionModalSee('permission posture report')
        ->assertMountedActionModalSee('ManagedEnvironment review #'.$review->getKey())
        ->assertMountedActionModalSee('Review pack #'.$pack->getKey())
        ->assertMountedActionModalSee('Operation failed')
        ->assertMountedActionModalSee('default-redacted')
        ->assertMountedActionModalSee('[REDACTED]')
        ->assertMountedActionModalDontSee('raw-provider-secret-message')
        ->assertMountedActionModalDontSee('secret-provider-body')
        ->assertMountedActionModalDontSee('stored-report-secret-body')
        ->assertMountedActionModalDontSee('audit-secret-body');
});

it('keeps tenantless operation detail deny-as-not-found for workspace members without tenant entitlement', function (): void {
    $workspace = Workspace::factory()->create();
    $tenant = ManagedEnvironment::factory()->create([
        'workspace_id' => (int) $workspace->getKey(),
    ]);

    $user = User::factory()->create();

    WorkspaceMembership::factory()->create([
        'workspace_id' => (int) $workspace->getKey(),
        'user_id' => (int) $user->getKey(),
        'role' => 'owner',
    ]);
    $allowedTenant = ManagedEnvironment::factory()->create([
        'workspace_id' => (int) $workspace->getKey(),
    ]);

    ManagedEnvironmentMembership::query()->create([
        'managed_environment_id' => (int) $allowedTenant->getKey(),
        'user_id' => (int) $user->getKey(),
        'role' => 'owner',
        'source' => 'manual',
        'source_ref' => null,
        'created_by_user_id' => null,
    ]);

    $run = OperationRun::factory()->create([
        'managed_environment_id' => (int) $tenant->getKey(),
        'workspace_id' => (int) $workspace->getKey(),
        'type' => OperationRunType::BaselineCompare->value,
        'status' => OperationRunStatus::Completed->value,
        'outcome' => OperationRunOutcome::Succeeded->value,
        'completed_at' => now(),
    ]);

    $this->actingAs($user)
        ->withSession([WorkspaceContext::SESSION_KEY => (int) $workspace->getKey()])
        ->get(\App\Support\OperationRunLinks::tenantlessView($run))
        ->assertNotFound();
});
