<?php

declare(strict_types=1);

use App\Support\Ui\OperatorExplanation\CountDescriptor;
use App\Support\Ui\OperatorExplanation\ExplanationFamily;
use App\Support\Ui\OperatorExplanation\OperatorExplanationBuilder;
use App\Support\Ui\OperatorExplanation\TrustworthinessLevel;
use Tests\Feature\Concerns\BuildsOperatorExplanationFixtures;

uses(BuildsOperatorExplanationFixtures::class);

it('maps blocked artifact truth into an explanation-first pattern', function (): void {
    $reason = $this->makeExplanationReasonEnvelope([
        'internalCode' => 'review_publish_blocked',
        'operatorLabel' => 'Publication blocked',
        'shortExplanation' => 'A required approval or prerequisite is missing for this review.',
        'trustImpact' => TrustworthinessLevel::Unusable->value,
        'absencePattern' => 'blocked_prerequisite',
        'nextSteps' => [\App\Support\ReasonTranslation\NextStepOption::instruction('Resolve review blockers before publication.')],
    ]);

    $truth = $this->makeArtifactTruthEnvelope([
        'executionOutcome' => 'blocked',
        'artifactExistence' => 'created_but_not_usable',
        'contentState' => 'missing_input',
        'actionability' => 'required',
        'primaryLabel' => 'Artifact not usable',
        'primaryExplanation' => 'The review exists, but it is blocked from publication.',
        'nextActionLabel' => 'Resolve review blockers before publication',
    ], $reason);

    $explanation = app(OperatorExplanationBuilder::class)->fromArtifactTruthEnvelope($truth, [
        new CountDescriptor('Publish blockers', 2, CountDescriptor::ROLE_RELIABILITY_SIGNAL, 'resolve before publish'),
    ]);

    expect($explanation->family)->toBe(ExplanationFamily::BlockedPrerequisite)
        ->and($explanation->evaluationResult)->toBe('unavailable')
        ->and($explanation->trustworthinessLevel)->toBe(TrustworthinessLevel::Unusable)
        ->and($explanation->dominantCauseLabel)->toBe('Publication blocked')
        ->and($explanation->dominantCauseExplanation)->toContain('missing for this review')
        ->and($explanation->nextActionText)->toBe('Resolve review blockers before publication')
        ->and($explanation->countDescriptors)->toHaveCount(1);
});

it('keeps trustworthy artifact truth separate from no-action guidance', function (): void {
    $truth = $this->makeArtifactTruthEnvelope([
        'executionOutcome' => 'succeeded',
        'artifactExistence' => 'created',
        'contentState' => 'trusted',
        'freshnessState' => 'current',
        'actionability' => 'none',
        'primaryLabel' => 'Trustworthy artifact',
        'primaryExplanation' => 'The artifact is ready for the intended operator task.',
    ]);

    $explanation = app(OperatorExplanationBuilder::class)->fromArtifactTruthEnvelope($truth, [
        new CountDescriptor('Findings', 3, CountDescriptor::ROLE_EVALUATION_OUTPUT),
    ]);

    expect($explanation->family)->toBe(ExplanationFamily::TrustworthyResult)
        ->and($explanation->evaluationResult)->toBe('full_result')
        ->and($explanation->trustworthinessLevel)->toBe(TrustworthinessLevel::Trustworthy)
        ->and($explanation->nextActionCategory)->toBe('none')
        ->and($explanation->nextActionText)->toBe('No action needed')
        ->and($explanation->coverageStatement)->toContain('sufficient');
});

it('maps retryable transient reasons into retry-later guidance', function (): void {
    $reason = $this->makeExplanationReasonEnvelope([
        'internalCode' => 'baseline_capture_transient_timeout',
        'operatorLabel' => 'Capture paused',
        'shortExplanation' => 'The capture hit a transient timeout while collecting evidence.',
        'actionability' => 'retryable_transient',
        'nextSteps' => [\App\Support\ReasonTranslation\NextStepOption::instruction('Retry the capture after worker capacity recovers.')],
    ]);

    $truth = $this->makeArtifactTruthEnvelope([
        'executionOutcome' => 'partially_succeeded',
        'artifactExistence' => 'created_but_not_usable',
        'contentState' => 'missing_input',
        'actionability' => 'required',
        'primaryLabel' => 'Artifact not usable',
        'primaryExplanation' => 'The capture did not finish cleanly enough to produce a usable artifact.',
        'nextActionLabel' => 'Retry the capture after worker capacity recovers',
    ], $reason);

    $explanation = app(OperatorExplanationBuilder::class)->fromArtifactTruthEnvelope($truth);

    expect($explanation->nextActionCategory)->toBe('retry_later')
        ->and($explanation->nextActionText)->toBe('Retry the capture after worker capacity recovers');
});
