<?php

declare(strict_types=1);

use App\Filament\System\Widgets\CustomerHealthTopWorkspaces;
use App\Models\Finding;
use App\Models\OperationRun;
use App\Models\PlatformUser;
use App\Models\ProductUsageEvent;
use App\Models\ProviderConnection;
use App\Models\ReviewPack;
use App\Models\ManagedEnvironment;
use App\Models\Workspace;
use App\Support\Auth\PlatformCapabilities;
use App\Support\OperationRunOutcome;
use App\Support\OperationRunStatus;
use App\Support\ProductTelemetry\ProductUsageEventCatalog;
use App\Support\Providers\ProviderConsentStatus;
use App\Support\Providers\ProviderVerificationStatus;
use App\Support\System\SystemDirectoryLinks;
use App\Support\System\SystemOperationRunLinks;
use App\Support\SystemConsole\SystemConsoleWindow;
use Carbon\CarbonImmutable;
use Filament\Facades\Filament;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Livewire\Livewire;

uses(RefreshDatabase::class);

beforeEach(function (): void {
    Filament::setCurrentPanel('system');
    Filament::bootCurrentPanel();

    CarbonImmutable::setTestNow(CarbonImmutable::parse('2026-04-27 12:00:00'));
});

afterEach(function (): void {
    CarbonImmutable::setTestNow();
});

it('lists the worst workspaces first with dominant reasons and one platform-safe next link per row', function (): void {
    actingAsExplainabilitySystemUser();

    $opsWorkspace = seedExplainabilityWorkspace('Alpha Operations');
    OperationRun::factory()
        ->forTenant($opsWorkspace['tenant'])
        ->create([
            'workspace_id' => (int) $opsWorkspace['workspace']->getKey(),
            'status' => OperationRunStatus::Queued->value,
            'outcome' => OperationRunOutcome::Pending->value,
            'created_at' => now()->subHours(2),
            'started_at' => null,
        ]);

    $providerWorkspace = seedExplainabilityWorkspace('Beta Provider');
    ProviderConnection::query()
        ->where('managed_environment_id', (int) $providerWorkspace['tenant']->getKey())
        ->update([
            'is_enabled' => true,
            'consent_status' => ProviderConsentStatus::Granted->value,
            'verification_status' => ProviderVerificationStatus::Blocked->value,
        ]);

    $viewData = customerHealthTopWorkspaceViewData(SystemConsoleWindow::LastWeek);
    $rows = collect($viewData['rows'])->take(2)->values();

    expect($rows[0]['workspace_label'])->toBe('Alpha Operations')
        ->and($rows[0]['overall']['label'])->toBe('Critical')
        ->and(array_column($rows[0]['dominant_dimensions'], 'label'))->toBe(['Operational stability'])
        ->and($rows[0]['next_link'])->toBe([
            'label' => 'Open runs',
            'url' => SystemOperationRunLinks::index(),
        ])
        ->and($rows[1]['workspace_label'])->toBe('Beta Provider')
        ->and($rows[1]['overall']['label'])->toBe('Critical')
        ->and(array_column($rows[1]['dominant_dimensions'], 'label'))->toBe(['Provider connection health'])
        ->and($rows[1]['next_link'])->toBe([
            'label' => 'Review health details',
            'url' => SystemDirectoryLinks::tenantDetail($providerWorkspace['tenant']).'?window='.SystemConsoleWindow::LastWeek,
        ])
        ->and($rows->every(fn (array $row): bool => count($row['dominant_dimensions']) <= 2))->toBeTrue()
        ->and($rows->every(fn (array $row): bool => ! str_contains($row['next_link']['url'], '/admin/')))->toBeTrue()
        ->and(array_key_exists('failed_count', $rows[0]))->toBeFalse();
});

/**
 * @return array<string, mixed>
 */
function customerHealthTopWorkspaceViewData(string $window = SystemConsoleWindow::LastDay): array
{
    $component = Livewire::withQueryParams([
        'window' => $window,
    ])->test(CustomerHealthTopWorkspaces::class);

    $method = new ReflectionMethod(CustomerHealthTopWorkspaces::class, 'getViewData');
    $method->setAccessible(true);

    return $method->invoke($component->instance());
}

function actingAsExplainabilitySystemUser(): PlatformUser
{
    $user = PlatformUser::factory()->create([
        'capabilities' => [
            PlatformCapabilities::ACCESS_SYSTEM_PANEL,
            PlatformCapabilities::CONSOLE_VIEW,
            PlatformCapabilities::DIRECTORY_VIEW,
            PlatformCapabilities::OPERATIONS_VIEW,
        ],
        'is_active' => true,
    ]);

    test()->actingAs($user, 'platform');

    return $user;
}

/**
 * @return array{workspace: Workspace, tenant: ManagedEnvironment}
 */
function seedExplainabilityWorkspace(string $workspaceName): array
{
    $workspace = Workspace::factory()->create(['name' => $workspaceName]);
    $tenant = ManagedEnvironment::factory()->for($workspace)->create([
        'name' => $workspaceName.' ManagedEnvironment',
        'status' => ManagedEnvironment::STATUS_ACTIVE,
    ]);

    ProviderConnection::factory()
        ->for($tenant)
        ->verifiedHealthy()
        ->create([
            'workspace_id' => (int) $workspace->getKey(),
            'is_default' => true,
        ]);

    ReviewPack::factory()
        ->for($tenant)
        ->ready()
        ->create([
            'workspace_id' => (int) $workspace->getKey(),
            'created_at' => now()->subHour(),
            'generated_at' => now()->subHour(),
            'expires_at' => now()->addDays(30),
        ]);

    ProductUsageEvent::factory()
        ->for($tenant)
        ->forEvent(ProductUsageEventCatalog::ONBOARDING_CHECKPOINT_COMPLETED)
        ->create([
            'workspace_id' => (int) $workspace->getKey(),
            'occurred_at' => now()->subMinutes(20),
        ]);

    OperationRun::factory()
        ->forTenant($tenant)
        ->create([
            'workspace_id' => (int) $workspace->getKey(),
            'status' => OperationRunStatus::Completed->value,
            'outcome' => OperationRunOutcome::Succeeded->value,
            'created_at' => now()->subMinutes(10),
            'started_at' => now()->subMinutes(15),
            'completed_at' => now()->subMinutes(5),
        ]);

    Finding::factory()
        ->for($tenant)
        ->closed()
        ->create([
            'severity' => Finding::SEVERITY_LOW,
        ]);

    return [
        'workspace' => $workspace,
        'tenant' => $tenant,
    ];
}