<?php

declare(strict_types=1);

use App\Models\AuditLog;
use App\Models\OperationRun;
use App\Models\ProductUsageEvent;
use App\Models\ReviewPack;
use App\Models\StoredReport;
use App\Models\ManagedEnvironment;
use App\Models\User;
use App\Support\ProductTelemetry\ProductUsageEventCatalog;
use Illuminate\Foundation\Testing\RefreshDatabase;

uses(RefreshDatabase::class);

it('prunes only product usage events older than the configured retention window', function (): void {
    config()->set('tenantpilot.product_usage_event_retention_days', 90);

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

    $oldEvent = ProductUsageEvent::factory()->forEvent(
        ProductUsageEventCatalog::OPERATIONS_STARTED,
        ['operation_type' => 'review_pack.generate'],
    )->create([
        'managed_environment_id' => (int) $tenant->getKey(),
        'workspace_id' => (int) $tenant->workspace_id,
        'user_id' => (int) $user->getKey(),
        'subject_type' => 'operation_run',
        'subject_id' => 'prune-old-run',
        'occurred_at' => now()->subDays(120),
    ]);

    $recentEvent = ProductUsageEvent::factory()->forEvent(
        ProductUsageEventCatalog::OPERATIONS_STARTED,
        ['operation_type' => 'review_pack.generate'],
    )->create([
        'managed_environment_id' => (int) $tenant->getKey(),
        'workspace_id' => (int) $tenant->workspace_id,
        'user_id' => (int) $user->getKey(),
        'subject_type' => 'operation_run',
        'subject_id' => 'prune-recent-run',
        'occurred_at' => now()->subDays(10),
    ]);

    $operationRun = OperationRun::factory()->forTenant($tenant)->create([
        'created_at' => now()->subDays(120),
    ]);

    $storedReport = StoredReport::factory()->create([
        'managed_environment_id' => (int) $tenant->getKey(),
        'created_at' => now()->subDays(120),
    ]);

    $reviewPack = ReviewPack::factory()->ready()->create([
        'managed_environment_id' => (int) $tenant->getKey(),
        'workspace_id' => (int) $tenant->workspace_id,
        'initiated_by_user_id' => (int) $user->getKey(),
        'created_at' => now()->subDays(120),
    ]);

    $auditLog = AuditLog::query()->create([
        'managed_environment_id' => (int) $tenant->getKey(),
        'workspace_id' => (int) $tenant->workspace_id,
        'action' => 'platform.test.audit',
        'status' => 'success',
        'metadata' => [],
        'recorded_at' => now()->subDays(120),
    ]);

    $this->artisan('tenantpilot:product-usage:prune')
        ->expectsOutputToContain('Deleted 1 product usage event(s) older than 90 days.')
        ->assertSuccessful();

    expect(ProductUsageEvent::query()->whereKey($oldEvent->getKey())->exists())->toBeFalse()
        ->and(ProductUsageEvent::query()->whereKey($recentEvent->getKey())->exists())->toBeTrue()
        ->and(OperationRun::query()->whereKey($operationRun->getKey())->exists())->toBeTrue()
        ->and(StoredReport::query()->whereKey($storedReport->getKey())->exists())->toBeTrue()
        ->and(ReviewPack::query()->whereKey($reviewPack->getKey())->exists())->toBeTrue()
        ->and(AuditLog::query()->whereKey($auditLog->getKey())->exists())->toBeTrue();
});

it('honors the explicit days override when pruning product usage events', function (): void {
    $tenant = ManagedEnvironment::factory()->create();
    $user = User::factory()->create();

    $oldEvent = ProductUsageEvent::factory()->forEvent(
        ProductUsageEventCatalog::STORED_REPORT_CREATED,
        ['report_type' => 'permission_posture'],
    )->create([
        'managed_environment_id' => (int) $tenant->getKey(),
        'workspace_id' => (int) $tenant->workspace_id,
        'user_id' => (int) $user->getKey(),
        'subject_type' => 'stored_report',
        'subject_id' => 'old-report',
        'occurred_at' => now()->subDays(35),
    ]);

    $recentEvent = ProductUsageEvent::factory()->forEvent(
        ProductUsageEventCatalog::STORED_REPORT_CREATED,
        ['report_type' => 'permission_posture'],
    )->create([
        'managed_environment_id' => (int) $tenant->getKey(),
        'workspace_id' => (int) $tenant->workspace_id,
        'user_id' => (int) $user->getKey(),
        'subject_type' => 'stored_report',
        'subject_id' => 'recent-report',
        'occurred_at' => now()->subDays(10),
    ]);

    $this->artisan('tenantpilot:product-usage:prune --days=30')
        ->expectsOutputToContain('Deleted 1 product usage event(s) older than 30 days.')
        ->assertSuccessful();

    expect(ProductUsageEvent::query()->whereKey($oldEvent->getKey())->exists())->toBeFalse()
        ->and(ProductUsageEvent::query()->whereKey($recentEvent->getKey())->exists())->toBeTrue();
});