<?php

declare(strict_types=1);

use App\Filament\System\Widgets\ProductTelemetryKpis;
use App\Models\PlatformUser;
use App\Models\ProductUsageEvent;
use App\Models\ManagedEnvironment;
use App\Models\User;
use App\Support\Auth\PlatformCapabilities;
use App\Support\ProductTelemetry\ProductUsageEventCatalog;
use App\Support\SystemConsole\SystemConsoleWindow;
use Carbon\CarbonImmutable;
use Filament\Facades\Filament;
use Filament\Widgets\StatsOverviewWidget\Stat;
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();
});

function productTelemetryStats($component): array
{
    $method = new ReflectionMethod(ProductTelemetryKpis::class, 'getStats');
    $method->setAccessible(true);

    return collect($method->invoke($component->instance()))
        ->mapWithKeys(fn (Stat $stat): array => [
            (string) $stat->getLabel() => [
                'value' => (string) $stat->getValue(),
                'description' => $stat->getDescription(),
            ],
        ])
        ->all();
}

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

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

    return $user;
}

function seedProductTelemetryEvent(
    ManagedEnvironment $tenant,
    User $user,
    string $eventName,
    array $metadata,
    string $subjectType,
    int|string $subjectId,
    CarbonImmutable $occurredAt,
): ProductUsageEvent {
    return ProductUsageEvent::factory()
        ->forEvent($eventName, $metadata)
        ->create([
            'managed_environment_id' => (int) $tenant->getKey(),
            'workspace_id' => (int) $tenant->workspace_id,
            'user_id' => (int) $user->getKey(),
            'subject_type' => $subjectType,
            'subject_id' => (string) $subjectId,
            'occurred_at' => $occurredAt,
        ]);
}

it('summarizes the five visible telemetry families and active workspaces for the selected window', function (): void {
    actingAsSystemConsoleUser();

    $tenantA = ManagedEnvironment::factory()->create();
    $tenantB = ManagedEnvironment::factory()->create();
    $userA = User::factory()->create();
    $userB = User::factory()->create();

    seedProductTelemetryEvent(
        tenant: $tenantA,
        user: $userA,
        eventName: ProductUsageEventCatalog::ONBOARDING_CHECKPOINT_COMPLETED,
        metadata: [
            'checkpoint_key' => 'tenant_connected',
            'lifecycle_state' => 'ready',
            'completed_at' => CarbonImmutable::now()->subHour(),
        ],
        subjectType: 'managed_environment_onboarding_session',
        subjectId: 101,
        occurredAt: CarbonImmutable::now()->subHour(),
    );

    seedProductTelemetryEvent(
        tenant: $tenantA,
        user: $userA,
        eventName: ProductUsageEventCatalog::SUPPORT_DIAGNOSTICS_OPENED,
        metadata: [
            'source_surface' => 'tenant_dashboard',
        ],
        subjectType: 'tenant',
        subjectId: (int) $tenantA->getKey(),
        occurredAt: CarbonImmutable::now()->subMinutes(90),
    );

    seedProductTelemetryEvent(
        tenant: $tenantB,
        user: $userB,
        eventName: ProductUsageEventCatalog::OPERATIONS_STARTED,
        metadata: [
            'operation_type' => 'review_pack.generate',
        ],
        subjectType: 'operation_run',
        subjectId: 202,
        occurredAt: CarbonImmutable::now()->subHours(2),
    );

    seedProductTelemetryEvent(
        tenant: $tenantB,
        user: $userB,
        eventName: ProductUsageEventCatalog::REVIEW_PACK_REQUESTED,
        metadata: [
            'source_surface' => 'tenant',
            'include_operations' => true,
            'include_pii' => false,
        ],
        subjectType: 'review_pack',
        subjectId: 303,
        occurredAt: CarbonImmutable::now()->subHours(3),
    );

    seedProductTelemetryEvent(
        tenant: $tenantB,
        user: $userB,
        eventName: ProductUsageEventCatalog::STORED_REPORT_CREATED,
        metadata: [
            'report_type' => 'permission_posture',
        ],
        subjectType: 'stored_report',
        subjectId: 404,
        occurredAt: CarbonImmutable::now()->subDays(2),
    );

    $lastDayStats = productTelemetryStats(Livewire::withQueryParams([
        'window' => SystemConsoleWindow::LastDay,
    ])->test(ProductTelemetryKpis::class));

    expect($lastDayStats['Active workspaces'])->toBe([
        'value' => '2',
        'description' => '4 events in Last 24 hours',
    ])
        ->and($lastDayStats['Onboarding checkpoints']['value'])->toBe('1')
        ->and($lastDayStats['Support diagnostics']['value'])->toBe('1')
        ->and($lastDayStats['Operations started']['value'])->toBe('1')
        ->and($lastDayStats['Stored reports']['value'])->toBe('0')
        ->and($lastDayStats['Review packs requested']['value'])->toBe('1');

    $lastWeekStats = productTelemetryStats(Livewire::withQueryParams([
        'window' => SystemConsoleWindow::LastWeek,
    ])->test(ProductTelemetryKpis::class));

    expect($lastWeekStats['Active workspaces'])->toBe([
        'value' => '2',
        'description' => '5 events in Last 7 days',
    ])
        ->and($lastWeekStats['Stored reports']['value'])->toBe('1');
});

it('renders an explicit zero state when the selected window has no telemetry rows', function (): void {
    actingAsSystemConsoleUser();

    $stats = productTelemetryStats(Livewire::withQueryParams([
        'window' => SystemConsoleWindow::LastDay,
    ])->test(ProductTelemetryKpis::class));

    expect($stats['Active workspaces'])->toBe([
        'value' => '0',
        'description' => 'No telemetry recorded in Last 24 hours.',
    ])
        ->and($stats['Onboarding checkpoints']['value'])->toBe('0')
        ->and($stats['Support diagnostics']['value'])->toBe('0')
        ->and($stats['Operations started']['value'])->toBe('0')
        ->and($stats['Stored reports']['value'])->toBe('0')
        ->and($stats['Review packs requested']['value'])->toBe('0');
});

it('uses the injected dashboard window when the livewire request query is absent', function (): void {
    actingAsSystemConsoleUser();

    $tenant = ManagedEnvironment::factory()->create();
    $user = User::factory()->create();

    seedProductTelemetryEvent(
        tenant: $tenant,
        user: $user,
        eventName: ProductUsageEventCatalog::ONBOARDING_CHECKPOINT_COMPLETED,
        metadata: [
            'checkpoint_key' => 'tenant_connected',
            'lifecycle_state' => 'ready',
            'completed_at' => CarbonImmutable::now()->subDays(3),
        ],
        subjectType: 'managed_environment_onboarding_session',
        subjectId: 909,
        occurredAt: CarbonImmutable::now()->subDays(3),
    );

    $stats = productTelemetryStats(Livewire::test(ProductTelemetryKpis::class, [
        'window' => SystemConsoleWindow::LastWeek,
    ]));

    expect($stats['Active workspaces'])->toBe([
        'value' => '1',
        'description' => '1 events in Last 7 days',
    ])
        ->and($stats['Onboarding checkpoints'])->toBe([
            'value' => '1',
            'description' => 'Last 7 days',
        ]);
});