<?php

declare(strict_types=1);

use App\Models\OperationRun;
use App\Support\OperationRunOutcome;
use App\Support\OperationRunStatus;
use App\Support\OpsUx\RunDetailPolling;
use Illuminate\Support\Carbon;

it('returns the expected interval for active runs based on age', function (string $status, int $ageSeconds, string $expectedInterval): void {
    $referenceTime = now();

    Carbon::setTestNow($referenceTime);

    try {
        $run = OperationRun::factory()->make([
            'status' => $status,
            'outcome' => OperationRunOutcome::Pending->value,
            'created_at' => $referenceTime->copy()->subSeconds($ageSeconds),
        ]);

        expect(RunDetailPolling::interval($run))->toBe($expectedInterval);
    } finally {
        Carbon::setTestNow();
    }
})->with([
    'queued runs younger than 10 seconds poll every second' => [
        OperationRunStatus::Queued->value,
        9,
        '1s',
    ],
    'queued runs at 10 seconds slow to 5 seconds' => [
        OperationRunStatus::Queued->value,
        10,
        '5s',
    ],
    'running runs younger than 60 seconds poll every 5 seconds' => [
        OperationRunStatus::Running->value,
        59,
        '5s',
    ],
    'running runs at 60 seconds slow to 10 seconds' => [
        OperationRunStatus::Running->value,
        60,
        '10s',
    ],
])->group('ops-ux');

it('disables run-detail polling once the run is terminal or unrecognized', function (string $status, string $outcome): void {
    $run = OperationRun::factory()->make([
        'status' => $status,
        'outcome' => $outcome,
    ]);

    expect(RunDetailPolling::interval($run))->toBeNull();
})->with([
    'completed succeeded' => [
        OperationRunStatus::Completed->value,
        OperationRunOutcome::Succeeded->value,
    ],
    'completed partially succeeded' => [
        OperationRunStatus::Completed->value,
        OperationRunOutcome::PartiallySucceeded->value,
    ],
    'completed failed' => [
        OperationRunStatus::Completed->value,
        OperationRunOutcome::Failed->value,
    ],
    'legacy failed status' => [
        'failed',
        OperationRunOutcome::Pending->value,
    ],
    'unknown status fallback' => [
        'stalled',
        OperationRunOutcome::Pending->value,
    ],
])->group('ops-ux');
