<?php

declare(strict_types=1);

use App\Models\ProductUsageEvent;
use App\Models\ManagedEnvironment;
use App\Models\User;
use App\Models\Workspace;
use App\Support\ProductTelemetry\ProductTelemetrySummaryQuery;
use App\Support\ProductTelemetry\ProductUsageEventCatalog;
use Illuminate\Foundation\Testing\RefreshDatabase;

uses(RefreshDatabase::class);

it('summarizes visible families and active workspaces for a selected window', function () {
    $user = User::factory()->create();

    $workspaceA = Workspace::factory()->create();
    $tenantA = ManagedEnvironment::factory()->for($workspaceA)->create();

    $workspaceB = Workspace::factory()->create();
    $tenantB = ManagedEnvironment::factory()->for($workspaceB)->create();

    ProductUsageEvent::factory()
        ->forEvent(ProductUsageEventCatalog::ONBOARDING_CHECKPOINT_COMPLETED, [
            'checkpoint_key' => 'tenant_connected',
            'lifecycle_state' => 'completed',
        ])
        ->create([
            'workspace_id' => (int) $workspaceA->getKey(),
            'managed_environment_id' => (int) $tenantA->getKey(),
            'user_id' => (int) $user->getKey(),
            'subject_type' => 'managed_environment_onboarding_session',
            'subject_id' => '11',
            'occurred_at' => now()->subHours(2),
        ]);

    ProductUsageEvent::factory()
        ->forEvent(ProductUsageEventCatalog::OPERATIONS_STARTED, [
            'operation_type' => 'environment.review_pack.generate',
        ])
        ->create([
            'workspace_id' => (int) $workspaceB->getKey(),
            'managed_environment_id' => (int) $tenantB->getKey(),
            'user_id' => (int) $user->getKey(),
            'subject_type' => 'operation_run',
            'subject_id' => '22',
            'occurred_at' => now()->subHours(1),
        ]);

    ProductUsageEvent::factory()
        ->forEvent(ProductUsageEventCatalog::STORED_REPORT_CREATED, [
            'report_type' => 'permission_posture',
        ])
        ->create([
            'workspace_id' => (int) $workspaceB->getKey(),
            'managed_environment_id' => (int) $tenantB->getKey(),
            'user_id' => (int) $user->getKey(),
            'subject_type' => 'stored_report',
            'subject_id' => '33',
            'occurred_at' => now()->subMinutes(30),
        ]);

    ProductUsageEvent::factory()
        ->forEvent(ProductUsageEventCatalog::SUPPORT_DIAGNOSTICS_OPENED, [
            'source_surface' => 'tenant_dashboard',
        ])
        ->create([
            'workspace_id' => (int) $workspaceA->getKey(),
            'managed_environment_id' => (int) $tenantA->getKey(),
            'user_id' => (int) $user->getKey(),
            'subject_type' => 'tenant',
            'subject_id' => '44',
            'occurred_at' => now()->subDays(3),
        ]);

    $summary = app(ProductTelemetrySummaryQuery::class)->summarize(now()->subDay());

    expect($summary['active_workspaces'])->toBe(2)
        ->and($summary['total_events'])->toBe(3)
        ->and($summary['families'][ProductUsageEventCatalog::ONBOARDING_CHECKPOINT_COMPLETED])
        ->toBe(['label' => 'Onboarding checkpoints', 'count' => 1])
        ->and($summary['families'][ProductUsageEventCatalog::SUPPORT_DIAGNOSTICS_OPENED])
        ->toBe(['label' => 'Support diagnostics', 'count' => 0])
        ->and($summary['families'][ProductUsageEventCatalog::OPERATIONS_STARTED])
        ->toBe(['label' => 'Operations started', 'count' => 1])
        ->and($summary['families'][ProductUsageEventCatalog::STORED_REPORT_CREATED])
        ->toBe(['label' => 'Stored reports', 'count' => 1])
        ->and($summary['families'][ProductUsageEventCatalog::REVIEW_PACK_REQUESTED])
        ->toBe(['label' => 'Review packs requested', 'count' => 0]);
});

it('returns a zero summary when the selected window has no events', function () {
    $summary = app(ProductTelemetrySummaryQuery::class)->summarize(now()->subDay());

    expect($summary['active_workspaces'])->toBe(0)
        ->and($summary['total_events'])->toBe(0)
        ->and(array_column($summary['families'], 'count'))
        ->toBe([0, 0, 0, 0, 0]);
});