<?php

declare(strict_types=1);

use App\Models\ProductUsageEvent;
use App\Models\ManagedEnvironment;
use App\Services\OperationRunService;
use App\Support\OperationRunType;
use App\Support\ProductTelemetry\ProductUsageEventCatalog;
use Illuminate\Foundation\Testing\RefreshDatabase;

uses(RefreshDatabase::class);

it('records telemetry for user-initiated tenant-bound operation starts only once per created run', function (): void {
    $tenant = ManagedEnvironment::factory()->create();
    [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'operator');

    $service = app(OperationRunService::class);

    $run = $service->ensureRun(
        tenant: $tenant,
        type: OperationRunType::ReviewPackGenerate->value,
        inputs: [
            'include_pii' => true,
            'include_operations' => true,
        ],
        initiator: $user,
    );

    $sameRun = $service->ensureRun(
        tenant: $tenant,
        type: OperationRunType::ReviewPackGenerate->value,
        inputs: [
            'include_pii' => true,
            'include_operations' => true,
        ],
        initiator: $user,
    );

    expect($sameRun->getKey())->toBe($run->getKey())
        ->and(ProductUsageEvent::query()->count())->toBe(1);

    $event = ProductUsageEvent::query()->sole();
    $serializedEvent = json_encode($event->toArray(), JSON_THROW_ON_ERROR);

    expect($event->event_name)->toBe(ProductUsageEventCatalog::OPERATIONS_STARTED)
        ->and($event->managed_environment_id)->toBe((int) $tenant->getKey())
        ->and($event->workspace_id)->toBe((int) $tenant->workspace_id)
        ->and($event->user_id)->toBe((int) $user->getKey())
        ->and($event->subject_type)->toBe('operation_run')
        ->and($event->subject_id)->toBe((string) $run->getKey())
        ->and($event->metadata)->toBe([
            'operation_type' => OperationRunType::ReviewPackGenerate->value,
        ])
        ->and($serializedEvent)->not->toContain('@')
        ->and($serializedEvent)->not->toContain($user->name)
        ->and($serializedEvent)->not->toContain((string) $tenant->name);
});

it('does not record telemetry for system-initiated operation starts', function (): void {
    $tenant = ManagedEnvironment::factory()->create();

    app(OperationRunService::class)->ensureRun(
        tenant: $tenant,
        type: OperationRunType::ReviewPackGenerate->value,
        inputs: [
            'include_pii' => true,
        ],
        initiator: null,
    );

    expect(ProductUsageEvent::query()->count())->toBe(0);
});