<?php

declare(strict_types=1);

use App\Models\ManagedEnvironment;
use App\Models\OperationRun;
use App\Support\ManagedEnvironmentLinks;
use App\Support\Navigation\CanonicalNavigationContext;
use App\Support\OperationRunLinks;
use App\Support\Workspaces\WorkspaceContext;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;

final class CanonicalOperationViewerDeepLinkTrustTest extends TestCase
{
    use RefreshDatabase;

    public function test_trusts_canonical_run_links_opened_from_a_tenant_surface_after_the_header_tenant_changes(): void
    {
        $runTenant = ManagedEnvironment::factory()->create([
            'name' => 'ManagedEnvironment Surface',
        ]);
        [$user, $runTenant] = createUserWithTenant(tenant: $runTenant, role: 'owner');

        $otherTenant = ManagedEnvironment::factory()->create([
            'name' => 'Other ManagedEnvironment',
            'workspace_id' => (int) $runTenant->workspace_id,
        ]);

        createUserWithTenant(tenant: $otherTenant, user: $user, role: 'owner');

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

        $context = new CanonicalNavigationContext(
            sourceSurface: 'tenant.detail',
            canonicalRouteName: 'admin.operations.view',
            tenantId: (int) $runTenant->getKey(),
            backLinkLabel: 'Back to tenant',
            backLinkUrl: ManagedEnvironmentLinks::viewUrl($runTenant),
        );

        setAdminPanelContext($otherTenant);

        $this->actingAs($user)
            ->withSession([WorkspaceContext::SESSION_KEY => (int) $runTenant->workspace_id])
            ->get(OperationRunLinks::view($run, $runTenant, $context))
            ->assertOk()
            ->assertSee('Back to tenant')
            ->assertSee(ManagedEnvironmentLinks::viewUrl($runTenant), false)
            ->assertSee('Canonical workspace view')
            ->assertDontSee('Current environment context differs from this operation');
    }

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

        $run = OperationRun::factory()->create([
            'workspace_id' => (int) $tenant->workspace_id,
            'managed_environment_id' => (int) $tenant->getKey(),
            'type' => 'inventory_sync',
        ]);

        setAdminPanelContext();

        $this->actingAs($user)
            ->withSession([WorkspaceContext::SESSION_KEY => (int) $tenant->workspace_id])
            ->get(OperationRunLinks::tenantlessView($run))
            ->assertOk()
            ->assertSee(OperationRunLinks::identifier($run))
            ->assertSee('Canonical workspace view');
    }

    public function test_uses_canonical_collection_link_for_default_back_and_show_all_fallbacks(): void
    {
        $runTenant = ManagedEnvironment::factory()->create();
        [$user, $runTenant] = createUserWithTenant(tenant: $runTenant, role: 'owner');

        $otherTenant = ManagedEnvironment::factory()->create([
            'workspace_id' => (int) $runTenant->workspace_id,
        ]);

        createUserWithTenant(tenant: $otherTenant, user: $user, role: 'owner');

        $run = OperationRun::factory()->create([
            'workspace_id' => (int) $runTenant->workspace_id,
            'managed_environment_id' => (int) $runTenant->getKey(),
            'type' => 'inventory_sync',
        ]);

        setAdminPanelContext($otherTenant);

        $this->actingAs($user)
            ->withSession([WorkspaceContext::SESSION_KEY => (int) $runTenant->workspace_id])
            ->get(OperationRunLinks::tenantlessView($run))
            ->assertOk()
            ->assertSee('Back to Operations')
            ->assertDontSee('Show all operations')
            ->assertSee(OperationRunLinks::index(), false);
    }

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

        $run = OperationRun::factory()->create([
            'workspace_id' => (int) $tenant->workspace_id,
            'managed_environment_id' => (int) $tenant->getKey(),
            'type' => 'provider.connection.check',
            '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,
                ),
            ],
        ]);

        $context = new CanonicalNavigationContext(
            sourceSurface: 'verification.report',
            canonicalRouteName: 'admin.operations.view',
            tenantId: (int) $tenant->getKey(),
            backLinkLabel: 'Back to verification',
            backLinkUrl: '/admin/verification/report',
        );

        setAdminPanelContext();

        $this->actingAs($user)
            ->withSession([WorkspaceContext::SESSION_KEY => (int) $tenant->workspace_id])
            ->get(OperationRunLinks::tenantlessView($run, $context))
            ->assertOk()
            ->assertSee('Verification report')
            ->assertSee('Back to verification')
            ->assertSee('/admin/verification/report', false);
    }
}
