<?php

declare(strict_types=1);

use App\Support\Badges\BadgeCatalog;
use App\Support\Badges\BadgeDomain;
use App\Support\Ui\GovernanceArtifactTruth\ArtifactTruthDimension;
use App\Support\Ui\GovernanceArtifactTruth\ArtifactTruthEnvelope;
use App\Support\Ui\GovernanceArtifactTruth\ArtifactTruthPresenter;
use App\Support\Ui\GovernanceArtifactTruth\SurfaceCompressionContext;
use App\Support\Ui\OperatorExplanation\OperatorExplanationBuilder;
use Tests\Feature\Concerns\BuildsOperatorExplanationFixtures;

uses(BuildsOperatorExplanationFixtures::class);

function compressionFixtureEnvelope(array $overrides = []): ArtifactTruthEnvelope
{
    $draft = test()->makeArtifactTruthEnvelope($overrides);

    return new ArtifactTruthEnvelope(
        artifactFamily: $draft->artifactFamily,
        artifactKey: $draft->artifactKey,
        workspaceId: $draft->workspaceId,
        tenantId: $draft->tenantId,
        executionOutcome: $draft->executionOutcome,
        artifactExistence: $draft->artifactExistence,
        contentState: $draft->contentState,
        freshnessState: $draft->freshnessState,
        publicationReadiness: $draft->publicationReadiness,
        supportState: $draft->supportState,
        actionability: $draft->actionability,
        primaryLabel: $draft->primaryLabel,
        primaryExplanation: $draft->primaryExplanation,
        diagnosticLabel: $draft->diagnosticLabel,
        nextActionLabel: $draft->nextActionLabel,
        nextActionUrl: $draft->nextActionUrl,
        relatedRunId: $draft->relatedRunId,
        relatedArtifactUrl: $draft->relatedArtifactUrl,
        dimensions: $overrides['dimensions'] ?? $draft->dimensions,
        reason: $draft->reason,
        operatorExplanation: app(OperatorExplanationBuilder::class)->fromArtifactTruthEnvelope($draft),
    );
}

it('keeps evidence compression centered on usability while reusing the canonical badge mapping', function (): void {
    $truth = compressionFixtureEnvelope([
        'artifactFamily' => 'evidence_snapshot',
        'contentState' => 'trusted',
        'freshnessState' => 'current',
        'actionability' => 'none',
        'primaryLabel' => 'Trustworthy artifact',
        'primaryExplanation' => 'A current evidence snapshot is available for review work.',
        'dimensions' => [
            new ArtifactTruthDimension(
                axis: 'content_fidelity',
                state: 'trusted',
                label: BadgeCatalog::spec(BadgeDomain::GovernanceArtifactContent, 'trusted')->label,
                classification: 'primary',
                badgeDomain: BadgeDomain::GovernanceArtifactContent,
                badgeState: 'trusted',
            ),
        ],
    ]);

    $outcome = app(ArtifactTruthPresenter::class)->compressedOutcomeFromEnvelope(
        $truth,
        SurfaceCompressionContext::evidenceSnapshot(),
    );

    expect($outcome->decisionDirection)->toBe('usable')
        ->and($outcome->primaryLabel)->toBe('Trustworthy artifact')
        ->and($outcome->primaryReason)->toBe('A current evidence snapshot is available for review work.')
        ->and($outcome->nextActionText)->toBe('No action needed')
        ->and($outcome->primaryBadge->label)->toBe(BadgeCatalog::spec(BadgeDomain::GovernanceArtifactContent, 'trusted')->label)
        ->and($outcome->surfaceFamily)->toBe('evidence_snapshot');
});

it('keeps review-register compression publication-first without inventing a new badge dialect', function (): void {
    $truth = compressionFixtureEnvelope([
        'artifactFamily' => 'environment_review',
        'contentState' => 'partial',
        'freshnessState' => 'stale',
        'publicationReadiness' => 'internal_only',
        'actionability' => 'optional',
        'primaryLabel' => 'Internal only',
        'primaryExplanation' => 'This review is useful internally, but stale evidence should be refreshed before stakeholder publication.',
        'nextActionLabel' => 'Refresh the evidence basis before publishing this review',
    ]);

    $outcome = app(ArtifactTruthPresenter::class)->compressedOutcomeFromEnvelope(
        $truth,
        SurfaceCompressionContext::reviewRegister(),
    );

    expect($outcome->decisionDirection)->toBe('internal_only')
        ->and($outcome->primaryLabel)->toBe('Internal only')
        ->and($outcome->nextActionText)->toBe('Refresh the evidence basis before publishing this review')
        ->and(collect($outcome->secondaryFacts)->pluck('label')->all())->toContain('Freshness', 'Coverage');
});

it('keeps operation-run artifact compression aligned with the linked artifact direction', function (): void {
    $truth = compressionFixtureEnvelope([
        'artifactFamily' => 'artifact_run',
        'executionOutcome' => 'failed',
        'artifactExistence' => 'created_but_not_usable',
        'contentState' => 'missing_input',
        'actionability' => 'required',
        'primaryLabel' => 'Artifact not usable',
        'primaryExplanation' => 'The result exists, but missing inputs keep it from being decision-grade.',
        'nextActionLabel' => 'Inspect the related capture diagnostics before using this snapshot',
        'diagnosticLabel' => 'Execution failed',
    ]);

    $outcome = app(ArtifactTruthPresenter::class)->compressedOutcomeFromEnvelope(
        $truth,
        SurfaceCompressionContext::operationRunArtifact(),
    );

    expect($outcome->decisionDirection)->toBe('blocked')
        ->and($outcome->primaryReason)->toContain('missing inputs')
        ->and($outcome->diagnosticsAvailable)->toBeTrue()
        ->and($outcome->toArray()['primaryBadge']['label'])->toBe($outcome->primaryBadge->label);
});
