<?php

declare(strict_types=1);

use App\Models\OperationRun;
use App\Models\ManagedEnvironment;
use App\Support\Workspaces\WorkspaceContext;
use Filament\Facades\Filament;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Bus;
use Illuminate\Support\Facades\Queue;
use Tests\TestCase;

final class CanonicalDetailRenderTest extends TestCase
{
    use RefreshDatabase;

    public function test_renders_canonical_detail_for_a_workspace_member_when_tenant_context_exists(): void
    {
        [$user, $tenant] = createUserWithTenant(role: 'owner');

        Filament::setTenant(null, true);

        $run = OperationRun::factory()->create([
            'workspace_id' => (int) $tenant->workspace_id,
            'managed_environment_id' => (int) $tenant->getKey(),
            'type' => 'policy.sync',
            'status' => 'completed',
            'outcome' => 'succeeded',
            'context' => [
                'target_scope' => [
                    'entra_tenant_name' => 'Contoso',
                    'entra_tenant_id' => '11111111-1111-1111-1111-111111111111',
                ],
            ],
            'summary_counts' => [
                'total' => 10,
                'processed' => 10,
                'succeeded' => 10,
                'failed' => 0,
                'skipped' => 0,
            ],
        ]);

        $this->actingAs($user)
            ->withSession([WorkspaceContext::SESSION_KEY => (int) $tenant->workspace_id])
            ->get(\App\Support\OperationRunLinks::tenantlessView($run))
            ->assertOk()
            ->assertSee(\App\Support\OperationRunLinks::identifier($run))
            ->assertSee('Policy sync')
            ->assertSee('Counts')
            ->assertSee('Context')
            ->assertSee('Contoso');
    }

    public function test_renders_canonical_detail_gracefully_when_tenant_id_is_null(): void
    {
        [$user, $tenant] = createUserWithTenant(role: 'owner');

        Filament::setTenant(null, true);

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

        $this->actingAs($user)
            ->withSession([WorkspaceContext::SESSION_KEY => (int) $tenant->workspace_id])
            ->get(\App\Support\OperationRunLinks::tenantlessView($run))
            ->assertOk()
            ->assertSee('No target scope details were recorded for this operation.');
    }

    public function test_returns_404_on_canonical_detail_for_non_members(): void
    {
        $tenant = ManagedEnvironment::factory()->create();
        [$otherUser] = createUserWithTenant(role: 'owner');

        $run = OperationRun::factory()->create([
            'workspace_id' => (int) $tenant->workspace_id,
            'managed_environment_id' => (int) $tenant->getKey(),
            'type' => 'policy.sync',
            'status' => 'completed',
            'outcome' => 'succeeded',
        ]);

        $this->actingAs($otherUser)
            ->get(\App\Support\OperationRunLinks::tenantlessView($run))
            ->assertNotFound();
    }

    public function test_renders_canonical_detail_db_only_with_no_job_dispatch(): void
    {
        Bus::fake();
        Queue::fake();

        [$user, $tenant] = createUserWithTenant(role: 'owner');

        $run = OperationRun::factory()->create([
            'workspace_id' => (int) $tenant->workspace_id,
            'managed_environment_id' => (int) $tenant->getKey(),
            'type' => 'provider.connection.check',
            'status' => 'completed',
            'outcome' => 'failed',
            'context' => [
                'verification_report' => json_decode(
                    (string) file_get_contents(repo_path('specs/074-verification-checklist/contracts/examples/fail.json')),
                    true,
                    512,
                    JSON_THROW_ON_ERROR,
                ),
            ],
        ]);

        assertNoOutboundHttp(function () use ($user, $run): void {
            $this->actingAs($user)
                ->get(\App\Support\OperationRunLinks::tenantlessView($run))
                ->assertOk()
                ->assertSee('Verification report');
        });

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