<?php

declare(strict_types=1);

use App\Filament\Pages\Operations\TenantlessOperationRunViewer;
use App\Models\OperationRun;
use App\Models\ManagedEnvironment;
use App\Support\Baselines\BaselineReasonCodes;
use App\Support\Workspaces\WorkspaceContext;
use Filament\Facades\Filament;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Livewire\Features\SupportTesting\Testable;
use Livewire\Livewire;
use Tests\Feature\Concerns\BuildsGovernanceArtifactTruthFixtures;
use Tests\TestCase;

uses(RefreshDatabase::class, BuildsGovernanceArtifactTruthFixtures::class);

function governanceVisibleText(Testable $component): string
{
    $html = $component->html();
    $html = preg_replace('/<script\b[^>]*>.*?<\/script>/is', '', $html) ?? $html;
    $html = preg_replace('/<style\b[^>]*>.*?<\/style>/is', '', $html) ?? $html;
    $html = preg_replace('/\s+wire:snapshot="[^"]*"/', '', $html) ?? $html;
    $html = preg_replace('/\s+wire:effects="[^"]*"/', '', $html) ?? $html;

    return trim((string) preg_replace('/\s+/', ' ', strip_tags($html)));
}

function governanceRunViewer(TestCase $testCase, $user, ManagedEnvironment $tenant, OperationRun $run): Testable
{
    Filament::setTenant(null, true);
    $testCase->withSession([WorkspaceContext::SESSION_KEY => (int) $tenant->workspace_id]);
    session([WorkspaceContext::SESSION_KEY => (int) $tenant->workspace_id]);

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

it('renders a summary-first hierarchy for zero-output baseline compare runs', function (): void {
    $tenant = ManagedEnvironment::factory()->create();
    [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner');

    $run = OperationRun::factory()->create([
        'managed_environment_id' => (int) $tenant->getKey(),
        'workspace_id' => (int) $tenant->workspace_id,
        'type' => 'baseline_compare',
        'status' => 'completed',
        'outcome' => 'partially_succeeded',
        'context' => [
            'baseline_compare' => [
                'reason_code' => 'coverage_unproven',
                'coverage' => [
                    'proof' => false,
                ],
            ],
        ],
        'summary_counts' => [
            'total' => 0,
            'processed' => 0,
            'errors_recorded' => 1,
        ],
        'completed_at' => now(),
    ]);

    $component = governanceRunViewer($this, $user, $tenant, $run)
        ->assertSee('Decision')
        ->assertSee('Artifact impact')
        ->assertSee('Dominant cause')
        ->assertSee('Primary next step')
        ->assertSee('The compare finished, but no decision-grade result is available yet.')
        ->assertSee('Artifact truth details')
        ->assertSee('Monitoring detail');

    $pageText = governanceVisibleText($component);

    expect(mb_strpos($pageText, 'Decision'))->toBeLessThan(mb_strpos($pageText, 'Artifact truth details'))
        ->and(mb_strpos($pageText, 'Decision'))->toBeLessThan(mb_strpos($pageText, 'Monitoring detail'))
        ->and($pageText)->toContain('no decision-grade result is available yet');
});

it('keeps blocked baseline capture summaries ahead of diagnostics without adding new run-detail actions', function (): void {
    $tenant = ManagedEnvironment::factory()->create();
    [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner');

    $run = OperationRun::factory()->create([
        'managed_environment_id' => (int) $tenant->getKey(),
        'workspace_id' => (int) $tenant->workspace_id,
        'type' => 'baseline_capture',
        'status' => 'completed',
        'outcome' => 'blocked',
        'context' => [
            'reason_code' => 'missing_capability',
            'baseline_capture' => [
                'subjects_total' => 0,
                'gaps' => [
                    'count' => 0,
                ],
            ],
        ],
        'failure_summary' => [[
            'reason_code' => 'missing_capability',
            'message' => 'A required capability is missing for this run.',
        ]],
        'completed_at' => now(),
    ]);

    $component = governanceRunViewer($this, $user, $tenant, $run)
        ->assertActionVisible('operate_hub_back_to_operations')
        ->assertActionVisible('refresh')
        ->assertSee('Blocked by prerequisite')
        ->assertSee('No baseline was captured')
        ->assertSee('Artifact impact')
        ->assertSee('Dominant cause');

    $pageText = governanceVisibleText($component);

    expect(mb_substr_count($pageText, 'No baseline was captured'))->toBe(1)
        ->and(mb_strpos($pageText, 'No baseline was captured'))->toBeLessThan(mb_strpos($pageText, 'Artifact truth details'));
});

it('shows processing outcome separately from artifact impact for stale evidence snapshot runs', function (): void {
    $tenant = ManagedEnvironment::factory()->create();
    [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner');

    $run = $this->makeArtifactTruthRun($tenant, 'tenant.evidence.snapshot.generate');

    $this->makeStaleArtifactTruthEvidenceSnapshot(
        tenant: $tenant,
        snapshotOverrides: [
            'operation_run_id' => (int) $run->getKey(),
        ],
    );

    governanceRunViewer($this, $user, $tenant, $run)
        ->assertSee('Outcome')
        ->assertSee('Artifact impact')
        ->assertSee('Completed successfully')
        ->assertSee('The snapshot finished processing, but its evidence basis is already stale.')
        ->assertSee('Result trust');
});

it('preserves a dominant cause plus secondary causes for degraded review composition runs', function (): void {
    $tenant = ManagedEnvironment::factory()->create();
    [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner');

    $run = $this->makeArtifactTruthRun($tenant, 'environment.review.compose');
    $snapshot = $this->makeStaleArtifactTruthEvidenceSnapshot($tenant);

    $this->makeArtifactTruthReview(
        tenant: $tenant,
        user: $user,
        snapshot: $snapshot,
        reviewOverrides: [
            'operation_run_id' => (int) $run->getKey(),
            'completeness_state' => 'partial',
        ],
        summaryOverrides: [
            'section_state_counts' => [
                'complete' => 4,
                'partial' => 1,
                'missing' => 1,
                'stale' => 0,
            ],
        ],
    );

    $component = governanceRunViewer($this, $user, $tenant, $run)
        ->assertSee('Dominant cause')
        ->assertSee('Missing sections')
        ->assertSee('Secondary causes')
        ->assertSee('Stale evidence basis');

    $pageText = governanceVisibleText($component);

    expect(mb_strpos($pageText, 'Missing sections'))->toBeLessThan(mb_strpos($pageText, 'Secondary causes'))
        ->and($pageText)->toContain('stale evidence');
});

it('shows failed-latest-inventory baseline capture summaries before diagnostics', function (): void {
    $tenant = ManagedEnvironment::factory()->create();
    [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner');

    $run = OperationRun::factory()->create([
        'managed_environment_id' => (int) $tenant->getKey(),
        'workspace_id' => (int) $tenant->workspace_id,
        'type' => 'baseline_capture',
        'status' => 'completed',
        'outcome' => 'blocked',
        'context' => [
            'reason_code' => BaselineReasonCodes::CAPTURE_INVENTORY_FAILED,
            'baseline_capture' => [
                'reason_code' => BaselineReasonCodes::CAPTURE_INVENTORY_FAILED,
                'subjects_total' => 0,
                'current_baseline_changed' => false,
            ],
        ],
        'failure_summary' => [[
            'reason_code' => BaselineReasonCodes::CAPTURE_INVENTORY_FAILED,
            'message' => 'Capture blocked because the latest inventory sync failed.',
        ]],
        'completed_at' => now(),
    ]);

    $component = governanceRunViewer($this, $user, $tenant, $run)
        ->assertSee('The baseline capture was blocked because the latest inventory sync failed.')
        ->assertSee('Latest inventory sync failed')
        ->assertSee('Artifact impact')
        ->assertSee('Dominant cause');

    $pageText = governanceVisibleText($component);

    expect(mb_strpos($pageText, 'The baseline capture was blocked because the latest inventory sync failed.'))
        ->toBeLessThan(mb_strpos($pageText, 'Artifact truth details'));
});

it('shows zero-subject baseline capture summaries before diagnostics', function (): void {
    $tenant = ManagedEnvironment::factory()->create();
    [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner');

    $run = OperationRun::factory()->create([
        'managed_environment_id' => (int) $tenant->getKey(),
        'workspace_id' => (int) $tenant->workspace_id,
        'type' => 'baseline_capture',
        'status' => 'completed',
        'outcome' => 'partially_succeeded',
        'context' => [
            'reason_code' => BaselineReasonCodes::CAPTURE_ZERO_SUBJECTS,
            'baseline_capture' => [
                'reason_code' => BaselineReasonCodes::CAPTURE_ZERO_SUBJECTS,
                'subjects_total' => 0,
                'current_baseline_changed' => false,
            ],
        ],
        'summary_counts' => [
            'total' => 0,
            'processed' => 0,
            'failed' => 0,
        ],
        'completed_at' => now(),
    ]);

    $component = governanceRunViewer($this, $user, $tenant, $run)
        ->assertSee('The baseline capture finished without a usable baseline because no governed subjects were in scope.')
        ->assertSee('No subjects were in scope')
        ->assertSee('Primary next step');

    $pageText = governanceVisibleText($component);

    expect(mb_strpos($pageText, 'The baseline capture finished without a usable baseline because no governed subjects were in scope.'))
        ->toBeLessThan(mb_strpos($pageText, 'Artifact truth details'));
});
