<?php

declare(strict_types=1);

use App\Filament\Resources\ManagedEnvironmentResource\Pages\ListManagedEnvironments;
use App\Filament\Resources\ManagedEnvironmentResource\Pages\ViewManagedEnvironment;
use App\Models\ProviderConnection;
use App\Models\ManagedEnvironment;
use App\Support\Providers\ProviderConsentStatus;
use App\Support\Providers\ProviderVerificationStatus;
use App\Support\Workspaces\WorkspaceContext;
use Filament\Facades\Filament;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Livewire\Livewire;

uses(RefreshDatabase::class);

it('removes tenant app status from tenant list primary truth and filters', function (): void {
    $tenant = ManagedEnvironment::factory()->active()->create([
        'name' => 'Primary Truth ManagedEnvironment',
        'app_status' => 'ok',
    ]);

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

    ProviderConnection::factory()->create([
        'workspace_id' => (int) $tenant->workspace_id,
        'managed_environment_id' => (int) $tenant->getKey(),
        'provider' => 'microsoft',
        'display_name' => 'Primary Truth Connection',
        'is_default' => true,
        'is_enabled' => true,
        'consent_status' => ProviderConsentStatus::Granted->value,
        'verification_status' => ProviderVerificationStatus::Unknown->value,
    ]);

    expect($tenant->fresh()->app_status)->toBe('ok');

    $this->actingAs($user);

    session()->put(WorkspaceContext::SESSION_KEY, (int) $tenant->workspace_id);
    Filament::setTenant(null, true);

    $component = Livewire::actingAs($user)
        ->test(ListManagedEnvironments::class)
        ->assertCanSeeTableRecords([$tenant]);

    $table = $component->instance()->getTable();
    $filterNames = array_keys($table->getFilters());
    $visibleColumnNames = collect($table->getVisibleColumns())
        ->map(fn ($column): string => $column->getName())
        ->values()
        ->all();

    expect($filterNames)->not->toContain('app_status')
        ->and($visibleColumnNames)->not->toContain('app_status')
        ->and($visibleColumnNames)->not->toContain('consent_status')
        ->and($visibleColumnNames)->not->toContain('verification_status')
        ->and($visibleColumnNames)->not->toContain('provider_connection_state');
});

it('keeps legacy app status as opt-in test setup instead of a factory default', function (): void {
    expect(array_key_exists('app_status', ManagedEnvironment::factory()->raw()))->toBeFalse();

    $tenant = ManagedEnvironment::factory()->create([
        'name' => 'Explicit Historical App Status ManagedEnvironment',
        'app_status' => 'error',
    ]);

    expect($tenant->fresh()->app_status)->toBe('error');
});

it('keeps lifecycle and rbac separate while leading the provider summary with consent and verification', function (): void {
    $tenant = ManagedEnvironment::factory()->create([
        'status' => ManagedEnvironment::STATUS_ONBOARDING,
        'app_status' => 'consent_required',
        'rbac_status' => 'failed',
        'name' => 'Truth Cleanup ManagedEnvironment',
    ]);

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

    ProviderConnection::factory()->create([
        'workspace_id' => (int) $tenant->workspace_id,
        'managed_environment_id' => (int) $tenant->getKey(),
        'provider' => 'microsoft',
        'display_name' => 'Truth Cleanup Connection',
        'is_default' => true,
        'is_enabled' => false,
        'consent_status' => ProviderConsentStatus::Granted->value,
        'verification_status' => ProviderVerificationStatus::Blocked->value,
    ]);

    expect($tenant->fresh()->app_status)->toBe('consent_required');

    $this->actingAs($user);

    session()->put(WorkspaceContext::SESSION_KEY, (int) $tenant->workspace_id);
    Filament::setTenant(null, true);

    Livewire::test(ViewManagedEnvironment::class, ['record' => $tenant->getRouteKey()])
        ->assertSee('Lifecycle summary')
        ->assertSee('This environment is still onboarding. It remains visible on management and review surfaces, but it is not selectable as active context until onboarding completes.')
        ->assertSee('RBAC status')
        ->assertSee('Failed')
        ->assertDontSee('App status')
        ->assertDontSee('Consent required')
        ->assertSee('Truth Cleanup Connection')
        ->assertSee('Lifecycle')
        ->assertSee('Disabled')
        ->assertSee('Granted')
        ->assertSee('Blocked')
        ->assertDontSee('Legacy status')
        ->assertDontSee('Connected')
        ->assertDontSee('Legacy health')
        ->assertDontSee('OK');
});

it('flags tenants that have microsoft connections but no default connection configured', function (): void {
    $tenant = ManagedEnvironment::factory()->active()->create([
        'name' => 'Missing Default ManagedEnvironment',
    ]);

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

    ProviderConnection::factory()->create([
        'workspace_id' => (int) $tenant->workspace_id,
        'managed_environment_id' => (int) $tenant->getKey(),
        'provider' => 'microsoft',
        'display_name' => 'Fallback Microsoft Connection',
        'is_default' => false,
        'is_enabled' => true,
        'consent_status' => ProviderConsentStatus::Granted->value,
        'verification_status' => ProviderVerificationStatus::Healthy->value,
    ]);

    $this->actingAs($user);

    session()->put(WorkspaceContext::SESSION_KEY, (int) $tenant->workspace_id);
    Filament::setTenant(null, true);

    Livewire::test(ViewManagedEnvironment::class, ['record' => $tenant->getRouteKey()])
        ->assertSee('Needs action: set a default provider connection.')
        ->assertSee('Fallback Microsoft Connection')
        ->assertSee('Open Provider Connections');
});

it('does not collapse active lifecycle and blocked provider verification into readiness language', function (): void {
    $tenant = ManagedEnvironment::factory()->active()->create([
        'name' => 'No False Readiness ManagedEnvironment',
        'app_status' => 'ok',
        'rbac_status' => 'configured',
    ]);

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

    ProviderConnection::factory()->create([
        'workspace_id' => (int) $tenant->workspace_id,
        'managed_environment_id' => (int) $tenant->getKey(),
        'provider' => 'microsoft',
        'display_name' => 'Blocked Connection',
        'is_default' => true,
        'is_enabled' => true,
        'consent_status' => ProviderConsentStatus::Granted->value,
        'verification_status' => ProviderVerificationStatus::Blocked->value,
    ]);

    $this->actingAs($user);

    session()->put(WorkspaceContext::SESSION_KEY, (int) $tenant->workspace_id);
    Filament::setTenant(null, true);

    Livewire::test(ViewManagedEnvironment::class, ['record' => $tenant->getRouteKey()])
        ->assertSee('Active')
        ->assertSee('Granted')
        ->assertSee('Blocked')
        ->assertSee('RBAC status')
        ->assertDontSee('Ready');
});
