<?php

declare(strict_types=1);

use App\Filament\Pages\Operations\TenantlessOperationRunViewer;
use App\Models\OperationRun;
use App\Models\ProviderConnection;
use App\Models\ManagedEnvironment;
use App\Models\ManagedEnvironmentOnboardingSession;
use App\Models\User;
use App\Models\Workspace;
use App\Models\WorkspaceMembership;
use App\Support\Verification\VerificationReportWriter;
use App\Support\Workspaces\WorkspaceContext;
use Filament\Facades\Filament;
use Illuminate\Support\Facades\Bus;
use Illuminate\Support\Facades\Queue;
use Livewire\Livewire;

it('renders the verification report viewer DB-only (no outbound HTTP, no job dispatch)', function (): void {
    Bus::fake();

    [$user, $tenant] = createUserWithTenant(role: 'operator');
    $this->actingAs($user);

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

    $report = json_decode(
        (string) file_get_contents(repo_path('specs/074-verification-checklist/contracts/examples/fail.json')),
        true,
        512,
        JSON_THROW_ON_ERROR,
    );

    $run = OperationRun::factory()->create([
        'managed_environment_id' => (int) $tenant->getKey(),
        'user_id' => (int) $user->getKey(),
        'type' => 'provider.connection.check',
        'status' => 'completed',
        'outcome' => 'failed',
        'context' => [
            'verification_report' => $report,
        ],
    ]);

    assertNoOutboundHttp(function () use ($run): void {
        $component = Livewire::test(TenantlessOperationRunViewer::class, ['run' => $run])
            ->assertSee('Verification report')
            ->assertSee('Blocked')
            ->assertSee('Token acquisition works');

        expect($component->html())
            ->toContain('data-shared-detail-family="verification-report"')
            ->toContain('data-host-kind="operation_run_detail"')
            ->toContain('data-shared-zone="summary"')
            ->toContain('data-shared-zone="issues"')
            ->toContain('data-shared-zone="diagnostics"');

        $component
            ->call('$refresh')
            ->assertSee('Token acquisition works');
    });

    Bus::assertNothingDispatched();
});

it('shows the protected-value note while keeping safe configuration phrases readable', function (): void {
    Bus::fake();

    [$user, $tenant] = createUserWithTenant(role: 'operator');
    $this->actingAs($user);

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

    $run = OperationRun::factory()->create([
        'managed_environment_id' => (int) $tenant->getKey(),
        'user_id' => (int) $user->getKey(),
        'type' => 'provider.connection.check',
        'status' => 'completed',
        'outcome' => 'failed',
        'context' => [
            'verification_report' => [
                'schema_version' => '1.5.0',
                'flow' => 'provider.connection.check',
                'generated_at' => now()->toIso8601String(),
                'summary' => [
                    'overall' => 'needs_attention',
                    'counts' => [
                        'total' => 1,
                        'pass' => 0,
                        'fail' => 1,
                        'warn' => 0,
                        'skip' => 0,
                        'running' => 0,
                    ],
                ],
                'checks' => [[
                    'key' => 'safe_phrase',
                    'title' => 'Safe phrase',
                    'status' => 'fail',
                    'severity' => 'high',
                    'blocking' => false,
                    'reason_code' => 'provider_permission_denied',
                    'message' => 'passwordMinimumLength is readable while client_secret=supersecret must be hidden.',
                    'evidence' => [],
                    'next_steps' => [],
                ]],
            ],
        ],
    ]);

    assertNoOutboundHttp(function () use ($run): void {
        Livewire::test(TenantlessOperationRunViewer::class, ['run' => $run])
            ->assertSee('passwordMinimumLength')
            ->assertSee('Protected values are intentionally hidden as [REDACTED]. Secret-only changes remain detectable without revealing the value.')
            ->assertDontSee('supersecret');
    });

    Bus::assertNothingDispatched();
});

it('renders onboarding verify surfaces DB-only (no outbound HTTP, no job/queue dispatch)', function (): void {
    Bus::fake();
    Queue::fake();

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

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

    session()->put(WorkspaceContext::SESSION_KEY, (int) $workspace->getKey());

    $tenant = ManagedEnvironment::factory()->create([
        'workspace_id' => (int) $workspace->getKey(),
        'status' => ManagedEnvironment::STATUS_ONBOARDING,
    ]);

    $user->tenants()->syncWithoutDetaching([
        $tenant->getKey() => ['role' => 'owner'],
    ]);

    $connection = ProviderConnection::factory()->create([
        'workspace_id' => (int) $workspace->getKey(),
        'managed_environment_id' => (int) $tenant->getKey(),
        'is_default' => true,
    ]);

    $report = VerificationReportWriter::build('provider.connection.check', [
        [
            'key' => 'onboarding_check',
            'title' => 'Onboarding check',
            'status' => 'fail',
            'severity' => 'high',
            'blocking' => false,
            'reason_code' => 'missing_configuration',
            'message' => 'Setup missing.',
            'evidence' => [],
            'next_steps' => [],
        ],
    ]);

    $run = OperationRun::factory()->create([
        'workspace_id' => (int) $workspace->getKey(),
        'managed_environment_id' => (int) $tenant->getKey(),
        'type' => 'provider.connection.check',
        'status' => 'completed',
        'outcome' => 'failed',
        'context' => [
            'provider_connection_id' => (int) $connection->getKey(),
            'verification_report' => $report,
        ],
    ]);

    ManagedEnvironmentOnboardingSession::query()->create([
        'workspace_id' => (int) $workspace->getKey(),
        'managed_environment_id' => (int) $tenant->getKey(),
        'entra_tenant_id' => (string) $tenant->managed_environment_id,
        'current_step' => 'verify',
        'state' => [
            'provider_connection_id' => (int) $connection->getKey(),
            'verification_operation_run_id' => (int) $run->getKey(),
        ],
        'started_by_user_id' => (int) $user->getKey(),
        'updated_by_user_id' => (int) $user->getKey(),
    ]);

    assertNoOutboundHttp(function () use ($user): void {
        $response = $this->actingAs($user)
            ->followingRedirects()
            ->get('/admin/onboarding')
            ->assertSuccessful()
            ->assertSee('Onboarding check');

        expect($response->getContent())
            ->toContain('data-shared-detail-family="verification-report"')
            ->toContain('data-host-kind="onboarding_wizard"')
            ->toContain('data-shared-zone="summary"')
            ->toContain('data-shared-zone="issues"')
            ->not->toContain('data-shared-zone="diagnostics"');
    });

    Bus::assertNothingDispatched();
    Queue::assertNothingPushed();
});
