<?php

declare(strict_types=1);

use Tests\Support\TestLaneBudget;
use Tests\Support\TestLaneTrendFixtures;

function recalibrationEvidenceHistory(string $laneId, int $count): array
{
    $report = TestLaneTrendFixtures::buildReport(
        laneId: $laneId,
        wallClockSeconds: $laneId === 'confidence' ? 438.0 : 188.0,
        durationsByFile: [
            'tests/Feature/Guards/TestLaneRecalibrationPolicyTest.php' => 12.0,
        ],
        ciContext: [
            'workflowId' => $laneId === 'confidence' ? 'main-confidence' : 'pr-fast-feedback',
            'triggerClass' => $laneId === 'confidence' ? 'mainline-push' : 'pull-request',
            'entryPointResolved' => true,
            'workflowLaneMatched' => true,
        ],
        comparisonProfile: in_array($laneId, ['fast-feedback', 'confidence'], true) ? 'shared-test-fixture-slimming' : null,
    );

    $templateRecord = $report['trendHistoryArtifact']['history'][0];

    return array_values(array_map(
        static function (int $index) use ($templateRecord): array {
            $record = $templateRecord;
            $record['runRef'] = sprintf('%s-evidence-%d', $templateRecord['laneId'], $index + 1);
            $record['generatedAt'] = sprintf('2026-04-%02dT10:00:00+00:00', $index + 1);

            return $record;
        },
        range(0, $count - 1),
    ));
}

it('keeps baseline and budget recalibration rules separate and enforces the stronger budget evidence window', function (): void {
    $assessment = [
        'recalibrationRecommendation' => 'review-baseline',
    ];
    $baselineHistory = recalibrationEvidenceHistory('fast-feedback', 3);
    $budgetHistory = recalibrationEvidenceHistory('confidence', 5);

    $baselineDecision = TestLaneBudget::buildRecalibrationDecisionRecord(
        laneId: 'fast-feedback',
        targetType: 'baseline',
        assessment: $assessment,
        historyRecords: $baselineHistory,
        decisionStatus: 'approved',
        rationaleCode: 'lane-scope-change',
        recordedIn: 'specs/211-runtime-trend-recalibration/spec.md',
        proposedValueSeconds: 184.0,
    );
    $budgetDecision = TestLaneBudget::buildRecalibrationDecisionRecord(
        laneId: 'confidence',
        targetType: 'budget',
        assessment: ['recalibrationRecommendation' => 'review-budget'],
        historyRecords: $budgetHistory,
        decisionStatus: 'approved',
        rationaleCode: 'sustained-erosion',
        recordedIn: 'specs/211-runtime-trend-recalibration/spec.md',
        proposedValueSeconds: 470.0,
    );

    expect($baselineDecision['targetType'])->toBe('baseline')
        ->and($baselineDecision['decisionStatus'])->toBe('approved')
        ->and($budgetDecision['targetType'])->toBe('budget')
        ->and($budgetDecision['decisionStatus'])->toBe('approved')
        ->and($budgetDecision['evidenceRunRefs'])->toHaveCount(5);

    expect(static fn () => TestLaneBudget::buildRecalibrationDecisionRecord(
        laneId: 'confidence',
        targetType: 'budget',
        assessment: ['recalibrationRecommendation' => 'review-budget'],
        historyRecords: recalibrationEvidenceHistory('confidence', 4),
        decisionStatus: 'approved',
        rationaleCode: 'sustained-erosion',
        recordedIn: 'specs/211-runtime-trend-recalibration/spec.md',
        proposedValueSeconds: 470.0,
    ))->toThrow(InvalidArgumentException::class);
});

it('requires approved versus rejected rationale handling that matches the policy', function (): void {
    $history = recalibrationEvidenceHistory('fast-feedback', 3);

    $rejectedDecision = TestLaneBudget::buildRecalibrationDecisionRecord(
        laneId: 'fast-feedback',
        targetType: 'budget',
        assessment: ['recalibrationRecommendation' => 'investigate'],
        historyRecords: [$history[0]],
        decisionStatus: 'rejected',
        rationaleCode: 'noise-rejected',
        recordedIn: 'specs/211-runtime-trend-recalibration/spec.md',
    );

    expect($rejectedDecision['decisionStatus'])->toBe('rejected')
        ->and($rejectedDecision['rationaleCode'])->toBe('noise-rejected');

    expect(static fn () => TestLaneBudget::buildRecalibrationDecisionRecord(
        laneId: 'fast-feedback',
        targetType: 'baseline',
        assessment: ['recalibrationRecommendation' => 'review-baseline'],
        historyRecords: $history,
        decisionStatus: 'approved',
        rationaleCode: 'sustained-erosion',
        recordedIn: 'specs/211-runtime-trend-recalibration/spec.md',
        proposedValueSeconds: 184.0,
    ))->toThrow(InvalidArgumentException::class);
});
