<?php

declare(strict_types=1);

use App\Filament\Resources\ProviderConnectionResource;
use App\Filament\Resources\ProviderConnectionResource\Pages\ListProviderConnections;
use App\Models\ManagedEnvironment;
use App\Models\ProviderConnection;
use App\Support\Workspaces\WorkspaceContext;
use Filament\Facades\Filament;
use Livewire\Livewire;

it('Spec314 provider connections sidebar entry is workspace wide', function (): void {
    $environmentA = ManagedEnvironment::factory()->active()->create([
        'name' => 'Provider Environment A',
        'external_id' => 'provider-environment-a',
    ]);
    [$user, $environmentA] = createUserWithTenant(tenant: $environmentA, role: 'owner');

    $environmentB = ManagedEnvironment::factory()->active()->create([
        'workspace_id' => (int) $environmentA->workspace_id,
        'name' => 'Provider Environment B',
        'external_id' => 'provider-environment-b',
    ]);
    createUserWithTenant(tenant: $environmentB, user: $user, role: 'owner');

    ProviderConnection::factory()->create([
        'workspace_id' => (int) $environmentA->workspace_id,
        'managed_environment_id' => (int) $environmentA->getKey(),
        'display_name' => 'Spec314 Provider A',
    ]);
    ProviderConnection::factory()->create([
        'workspace_id' => (int) $environmentB->workspace_id,
        'managed_environment_id' => (int) $environmentB->getKey(),
        'display_name' => 'Spec314 Provider B',
    ]);

    Filament::setTenant($environmentA, true);

    $url = ProviderConnectionResource::getUrl('index', panel: 'admin');

    expect($url)->not->toContain('managed_environment_id');

    $this->actingAs($user)
        ->withSession([
            WorkspaceContext::SESSION_KEY => (int) $environmentA->workspace_id,
            WorkspaceContext::LAST_ENVIRONMENT_IDS_SESSION_KEY => [
                (string) $environmentA->workspace_id => (int) $environmentA->getKey(),
            ],
        ])
        ->get($url)
        ->assertOk()
        ->assertSee('Spec314 Provider A')
        ->assertSee('Spec314 Provider B')
        ->assertSee(__('localization.shell.no_environment_selected'));
});

it('Spec314 provider connections keeps explicit environment CTA filters explicit', function (): void {
    $environment = ManagedEnvironment::factory()->active()->create([
        'external_id' => 'provider-explicit-environment',
    ]);
    [$user, $environment] = createUserWithTenant(tenant: $environment, role: 'owner');

    $url = ProviderConnectionResource::getUrl('index', [
        'environment_id' => (int) $environment->getKey(),
    ], panel: 'admin');

    expect($url)
        ->toContain('environment_id='.(int) $environment->getKey())
        ->not->toContain('managed_environment_id=');

    $this->actingAs($user)
        ->withSession([WorkspaceContext::SESSION_KEY => (int) $environment->workspace_id])
        ->get($url)
        ->assertOk();
});

it('Spec314 provider connections ignores stale persisted environment filters on clean entry', function (): void {
    $environmentA = ManagedEnvironment::factory()->active()->create([
        'external_id' => 'provider-stale-a',
    ]);
    [$user, $environmentA] = createUserWithTenant(tenant: $environmentA, role: 'owner');

    $environmentB = ManagedEnvironment::factory()->active()->create([
        'workspace_id' => (int) $environmentA->workspace_id,
        'external_id' => 'provider-stale-b',
    ]);
    createUserWithTenant(tenant: $environmentB, user: $user, role: 'owner');

    $connectionA = ProviderConnection::factory()->create([
        'workspace_id' => (int) $environmentA->workspace_id,
        'managed_environment_id' => (int) $environmentA->getKey(),
        'display_name' => 'Spec314 Provider Stale A',
    ]);
    $connectionB = ProviderConnection::factory()->create([
        'workspace_id' => (int) $environmentB->workspace_id,
        'managed_environment_id' => (int) $environmentB->getKey(),
        'display_name' => 'Spec314 Provider Stale B',
    ]);

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

    $component = Livewire::actingAs($user)->test(ListProviderConnections::class);
    $filtersSessionKey = $component->instance()->getTableFiltersSessionKey();

    session()->put($filtersSessionKey, [
        'tenant' => ['value' => (string) $environmentA->external_id],
    ]);

    Livewire::actingAs($user)
        ->test(ListProviderConnections::class)
        ->assertCanSeeTableRecords([$connectionA, $connectionB]);

    expect(data_get(session()->get($filtersSessionKey, []), 'tenant.value'))->toBeNull();
});
