<?php

declare(strict_types=1);

use App\Filament\Pages\Monitoring\Operations;
use App\Models\ManagedEnvironment;
use App\Models\OperationRun;
use App\Support\OperationRunLinks;
use App\Support\OperationRunOutcome;
use App\Support\OperationRunStatus;
use App\Support\OpsUx\OperationRunUrl;
use App\Support\Workspaces\WorkspaceContext;
use Livewire\Livewire;

it('preserves tenant context and healthy activity semantics for dashboard operations drill-throughs', function (): void {
    $tenantA = ManagedEnvironment::factory()->create();
    [$user, $tenantA] = createUserWithTenant(tenant: $tenantA, role: 'owner');

    $tenantB = ManagedEnvironment::factory()->create([
        'workspace_id' => (int) $tenantA->workspace_id,
    ]);
    createUserWithTenant(tenant: $tenantB, user: $user, role: 'owner');

    $healthyActive = OperationRun::factory()->create([
        'managed_environment_id' => (int) $tenantA->getKey(),
        'workspace_id' => (int) $tenantA->workspace_id,
        'type' => 'inventory_sync',
        'status' => OperationRunStatus::Running->value,
        'outcome' => OperationRunOutcome::Pending->value,
        'initiator_name' => 'Healthy active visible',
        'created_at' => now()->subMinute(),
        'started_at' => now()->subMinute(),
    ]);

    $staleActive = OperationRun::factory()->create([
        'managed_environment_id' => (int) $tenantA->getKey(),
        'workspace_id' => (int) $tenantA->workspace_id,
        'type' => 'inventory_sync',
        'status' => OperationRunStatus::Queued->value,
        'outcome' => OperationRunOutcome::Pending->value,
        'initiator_name' => 'Stale active hidden',
        'created_at' => now()->subHour(),
    ]);

    $otherTenantActive = OperationRun::factory()->create([
        'managed_environment_id' => (int) $tenantB->getKey(),
        'workspace_id' => (int) $tenantB->workspace_id,
        'type' => 'inventory_sync',
        'status' => OperationRunStatus::Running->value,
        'outcome' => OperationRunOutcome::Pending->value,
        'initiator_name' => 'Other tenant active hidden',
        'created_at' => now()->subMinute(),
        'started_at' => now()->subMinute(),
    ]);

    $this->actingAs($user);
    setAdminPanelContext($tenantA);
    session()->put(WorkspaceContext::SESSION_KEY, (int) $tenantA->workspace_id);

    Livewire::actingAs($user)
        ->test(Operations::class)
        ->filterTable('managed_environment_id', (string) $tenantA->getKey())
        ->set('activeTab', 'active')
        ->assertCanSeeTableRecords([$healthyActive])
        ->assertCanNotSeeTableRecords([$staleActive, $otherTenantActive]);
});

it('uses the stale-attention dashboard landing for likely stale active runs', function (): void {
    $tenantA = ManagedEnvironment::factory()->create();
    [$user, $tenantA] = createUserWithTenant(tenant: $tenantA, role: 'owner');

    $tenantB = ManagedEnvironment::factory()->create([
        'workspace_id' => (int) $tenantA->workspace_id,
    ]);
    createUserWithTenant(tenant: $tenantB, user: $user, role: 'owner');

    $staleRun = OperationRun::factory()->create([
        'managed_environment_id' => (int) $tenantA->getKey(),
        'workspace_id' => (int) $tenantA->workspace_id,
        'type' => 'inventory_sync',
        'status' => OperationRunStatus::Queued->value,
        'outcome' => OperationRunOutcome::Pending->value,
        'initiator_name' => 'Stale active visible',
        'created_at' => now()->subHour(),
    ]);

    $terminalRun = OperationRun::factory()->create([
        'managed_environment_id' => (int) $tenantA->getKey(),
        'workspace_id' => (int) $tenantA->workspace_id,
        'type' => 'policy.sync',
        'status' => OperationRunStatus::Completed->value,
        'outcome' => OperationRunOutcome::Failed->value,
        'initiator_name' => 'Terminal failed hidden',
    ]);

    $otherTenantStale = OperationRun::factory()->create([
        'managed_environment_id' => (int) $tenantB->getKey(),
        'workspace_id' => (int) $tenantB->workspace_id,
        'type' => 'inventory_sync',
        'status' => OperationRunStatus::Queued->value,
        'outcome' => OperationRunOutcome::Pending->value,
        'initiator_name' => 'Other tenant stale hidden',
        'created_at' => now()->subHour(),
    ]);

    $this->actingAs($user);
    setAdminPanelContext($tenantA);
    session()->put(WorkspaceContext::SESSION_KEY, (int) $tenantA->workspace_id);

    Livewire::actingAs($user)
        ->test(Operations::class)
        ->filterTable('managed_environment_id', (string) $tenantA->getKey())
        ->set('activeTab', OperationRun::PROBLEM_CLASS_ACTIVE_STALE_ATTENTION)
        ->assertCanSeeTableRecords([$staleRun])
        ->assertCanNotSeeTableRecords([$terminalRun, $otherTenantStale]);
});

it('uses the terminal follow-up landing for failed, warning, and blocked runs without mixing in stale active work', function (): void {
    $tenantA = ManagedEnvironment::factory()->create();
    [$user, $tenantA] = createUserWithTenant(tenant: $tenantA, role: 'owner');

    $tenantB = ManagedEnvironment::factory()->create([
        'workspace_id' => (int) $tenantA->workspace_id,
    ]);
    createUserWithTenant(tenant: $tenantB, user: $user, role: 'owner');

    $partialRun = OperationRun::factory()->create([
        'managed_environment_id' => (int) $tenantA->getKey(),
        'workspace_id' => (int) $tenantA->workspace_id,
        'type' => 'policy.sync',
        'status' => OperationRunStatus::Completed->value,
        'outcome' => OperationRunOutcome::PartiallySucceeded->value,
        'initiator_name' => 'Partial terminal visible',
    ]);

    $failedRun = OperationRun::factory()->create([
        'managed_environment_id' => (int) $tenantA->getKey(),
        'workspace_id' => (int) $tenantA->workspace_id,
        'type' => 'policy.sync',
        'status' => OperationRunStatus::Completed->value,
        'outcome' => OperationRunOutcome::Failed->value,
        'initiator_name' => 'Failed terminal visible',
    ]);

    $blockedRun = OperationRun::factory()->create([
        'managed_environment_id' => (int) $tenantA->getKey(),
        'workspace_id' => (int) $tenantA->workspace_id,
        'type' => 'policy.sync',
        'status' => OperationRunStatus::Completed->value,
        'outcome' => OperationRunOutcome::Blocked->value,
        'initiator_name' => 'Blocked terminal visible',
    ]);

    $staleRun = OperationRun::factory()->create([
        'managed_environment_id' => (int) $tenantA->getKey(),
        'workspace_id' => (int) $tenantA->workspace_id,
        'type' => 'inventory_sync',
        'status' => OperationRunStatus::Queued->value,
        'outcome' => OperationRunOutcome::Pending->value,
        'initiator_name' => 'Stale active hidden',
        'created_at' => now()->subHour(),
    ]);

    $healthyActive = OperationRun::factory()->create([
        'managed_environment_id' => (int) $tenantA->getKey(),
        'workspace_id' => (int) $tenantA->workspace_id,
        'type' => 'inventory_sync',
        'status' => OperationRunStatus::Queued->value,
        'outcome' => OperationRunOutcome::Pending->value,
        'initiator_name' => 'Healthy active hidden',
        'created_at' => now()->subMinute(),
    ]);

    $otherTenantFailed = OperationRun::factory()->create([
        'managed_environment_id' => (int) $tenantB->getKey(),
        'workspace_id' => (int) $tenantB->workspace_id,
        'type' => 'policy.sync',
        'status' => OperationRunStatus::Completed->value,
        'outcome' => OperationRunOutcome::Failed->value,
        'initiator_name' => 'Other tenant failed hidden',
    ]);

    $this->actingAs($user);
    setAdminPanelContext($tenantA);
    session()->put(WorkspaceContext::SESSION_KEY, (int) $tenantA->workspace_id);

    Livewire::actingAs($user)
        ->test(Operations::class)
        ->filterTable('managed_environment_id', (string) $tenantA->getKey())
        ->set('activeTab', OperationRun::PROBLEM_CLASS_TERMINAL_FOLLOW_UP)
        ->assertCanSeeTableRecords([$partialRun, $failedRun, $blockedRun])
        ->assertCanNotSeeTableRecords([$healthyActive, $otherTenantFailed]);
});

it('allows workspace-originated operations drill-through to clear tenant context and show workspace-wide terminal follow-up', function (): void {
    $tenantA = ManagedEnvironment::factory()->create();
    [$user, $tenantA] = createUserWithTenant(tenant: $tenantA, role: 'owner');

    $tenantB = ManagedEnvironment::factory()->create([
        'workspace_id' => (int) $tenantA->workspace_id,
    ]);
    createUserWithTenant(tenant: $tenantB, user: $user, role: 'owner');

    $workspaceRun = OperationRun::factory()->tenantlessForWorkspace($tenantA->workspace()->firstOrFail())->create([
        'type' => 'policy.sync',
        'status' => OperationRunStatus::Completed->value,
        'outcome' => OperationRunOutcome::Failed->value,
        'initiator_name' => 'Workspace terminal visible',
    ]);

    $otherTenantFailed = OperationRun::factory()->create([
        'managed_environment_id' => (int) $tenantB->getKey(),
        'workspace_id' => (int) $tenantB->workspace_id,
        'type' => 'policy.sync',
        'status' => OperationRunStatus::Completed->value,
        'outcome' => OperationRunOutcome::Failed->value,
        'initiator_name' => 'Other tenant failed visible',
    ]);

    $healthyActive = OperationRun::factory()->create([
        'managed_environment_id' => (int) $tenantA->getKey(),
        'workspace_id' => (int) $tenantA->workspace_id,
        'type' => 'inventory_sync',
        'status' => OperationRunStatus::Running->value,
        'outcome' => OperationRunOutcome::Pending->value,
        'initiator_name' => 'Healthy active hidden',
        'created_at' => now()->subMinute(),
        'started_at' => now()->subMinute(),
    ]);

    $this->actingAs($user);
    setAdminPanelContext(null);
    session()->put(WorkspaceContext::SESSION_KEY, (int) $tenantA->workspace_id);

    Livewire::actingAs($user)
        ->test(Operations::class)
        ->set('activeTab', OperationRun::PROBLEM_CLASS_TERMINAL_FOLLOW_UP)
        ->assertCanSeeTableRecords([$workspaceRun, $otherTenantFailed])
        ->assertCanNotSeeTableRecords([$healthyActive]);
});

it('builds canonical dashboard operations URLs with tenant and tab continuity', function (): void {
    $tenant = ManagedEnvironment::factory()->create();
    $run = OperationRun::factory()->create([
        'workspace_id' => (int) $tenant->workspace_id,
        'managed_environment_id' => (int) $tenant->getKey(),
    ]);

    $urls = [
        OperationRunLinks::index($tenant, activeTab: 'active'),
        OperationRunLinks::index(
            $tenant,
            activeTab: OperationRun::PROBLEM_CLASS_TERMINAL_FOLLOW_UP,
            problemClass: OperationRun::PROBLEM_CLASS_TERMINAL_FOLLOW_UP,
        ),
        OperationRunLinks::index(
            activeTab: OperationRun::PROBLEM_CLASS_TERMINAL_FOLLOW_UP,
            allTenants: true,
            problemClass: OperationRun::PROBLEM_CLASS_TERMINAL_FOLLOW_UP,
            workspace: $tenant->workspace,
        ),
        OperationRunLinks::tenantlessView($run),
        OperationRunUrl::index($tenant),
        OperationRunUrl::view($run, $tenant),
    ];

    foreach ($urls as $url) {
        expect($url)
            ->not->toContain('/admin/tenants')
            ->not->toContain('/admin/t/');
    }

    expect(OperationRunLinks::index($tenant, activeTab: 'active'))
        ->toBe(route('admin.operations.index', [
            'workspace' => $tenant->workspace,
            'environment_id' => (int) $tenant->getKey(),
            'activeTab' => 'active',
        ]))
        ->and(OperationRunLinks::index(
            $tenant,
            activeTab: OperationRun::PROBLEM_CLASS_TERMINAL_FOLLOW_UP,
            problemClass: OperationRun::PROBLEM_CLASS_TERMINAL_FOLLOW_UP,
        ))
        ->toBe(route('admin.operations.index', [
            'workspace' => $tenant->workspace,
            'environment_id' => (int) $tenant->getKey(),
            'activeTab' => OperationRun::PROBLEM_CLASS_TERMINAL_FOLLOW_UP,
            'problemClass' => OperationRun::PROBLEM_CLASS_TERMINAL_FOLLOW_UP,
        ]))
        ->and(OperationRunLinks::index(
            activeTab: OperationRun::PROBLEM_CLASS_TERMINAL_FOLLOW_UP,
            allTenants: true,
            problemClass: OperationRun::PROBLEM_CLASS_TERMINAL_FOLLOW_UP,
            workspace: $tenant->workspace,
        ))
        ->toBe(route('admin.operations.index', [
            'workspace' => $tenant->workspace,
            'activeTab' => OperationRun::PROBLEM_CLASS_TERMINAL_FOLLOW_UP,
            'problemClass' => OperationRun::PROBLEM_CLASS_TERMINAL_FOLLOW_UP,
        ]))
        ->and(OperationRunUrl::index($tenant))->toBe(OperationRunLinks::index($tenant))
        ->and(OperationRunUrl::view($run, $tenant))->toBe(OperationRunLinks::tenantlessView($run));
});

it('keeps explicit environment scope out of operations lists while preserving tab continuity', function (): void {
    $tenantA = ManagedEnvironment::factory()->create();
    [$user, $tenantA] = createUserWithTenant(tenant: $tenantA, role: 'owner');

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

    $visibleRun = OperationRun::factory()->create([
        'managed_environment_id' => (int) $tenantA->getKey(),
        'workspace_id' => (int) $tenantA->workspace_id,
        'type' => 'inventory_sync',
        'status' => OperationRunStatus::Running->value,
        'outcome' => OperationRunOutcome::Pending->value,
        'initiator_name' => 'Scoped tenant active visible',
        'created_at' => now()->subMinute(),
        'started_at' => now()->subMinute(),
    ]);

    $hiddenRun = OperationRun::factory()->create([
        'managed_environment_id' => (int) $foreignTenant->getKey(),
        'workspace_id' => (int) $foreignTenant->workspace_id,
        'type' => 'inventory_sync',
        'status' => OperationRunStatus::Running->value,
        'outcome' => OperationRunOutcome::Pending->value,
        'initiator_name' => 'Out of scope active hidden',
        'created_at' => now()->subMinute(),
        'started_at' => now()->subMinute(),
    ]);

    $this->actingAs($user);
    setAdminPanelContext($tenantA);
    session()->put(WorkspaceContext::SESSION_KEY, (int) $tenantA->workspace_id);

    $component = Livewire::actingAs($user)
        ->test(Operations::class)
        ->set('activeTab', 'active')
        ->assertCanSeeTableRecords([$visibleRun])
        ->assertCanNotSeeTableRecords([$hiddenRun]);

    expect(urldecode($component->instance()->tabUrl(OperationRun::PROBLEM_CLASS_TERMINAL_FOLLOW_UP)))
        ->toContain('activeTab='.OperationRun::PROBLEM_CLASS_TERMINAL_FOLLOW_UP)
        ->toContain('problemClass='.OperationRun::PROBLEM_CLASS_TERMINAL_FOLLOW_UP)
        ->not->toContain('managed_environment_id='.(int) $foreignTenant->getKey());
});
