<?php

declare(strict_types=1);

use App\Models\BaselineProfile;
use App\Models\BaselineSnapshot;
use App\Models\ManagedEnvironment;
use App\Models\Workspace;
use App\Support\Badges\BadgeCatalog;
use App\Support\Badges\BadgeDomain;
use App\Support\Baselines\BaselineReasonCodes;
use App\Support\Ui\GovernanceArtifactTruth\ArtifactTruthPresenter;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\Feature\Concerns\BuildsGovernanceArtifactTruthFixtures;

uses(RefreshDatabase::class, BuildsGovernanceArtifactTruthFixtures::class);

it('maps each curated governance-artifact truth badge to a known label', function (BadgeDomain $domain, string $state): void {
    $spec = BadgeCatalog::spec($domain, $state);

    expect($spec->label)->not->toBe('Unknown')
        ->and($spec->icon)->not->toBeNull();
})->with([
    'healthy baseline artifact' => [BadgeDomain::GovernanceArtifactContent, 'trusted'],
    'false-green baseline artifact' => [BadgeDomain::GovernanceArtifactExistence, 'created_but_not_usable'],
    'historical baseline trace' => [BadgeDomain::GovernanceArtifactExistence, 'historical_only'],
    'healthy evidence snapshot' => [BadgeDomain::GovernanceArtifactContent, 'trusted'],
    'partial evidence snapshot' => [BadgeDomain::GovernanceArtifactContent, 'partial'],
    'stale evidence snapshot' => [BadgeDomain::GovernanceArtifactFreshness, 'stale'],
    'internal environment review' => [BadgeDomain::GovernanceArtifactPublicationReadiness, 'internal_only'],
    'blocked environment review' => [BadgeDomain::GovernanceArtifactPublicationReadiness, 'blocked'],
    'publishable environment review' => [BadgeDomain::GovernanceArtifactPublicationReadiness, 'publishable'],
    'historical review pack' => [BadgeDomain::GovernanceArtifactExistence, 'historical_only'],
    'blocked review pack' => [BadgeDomain::GovernanceArtifactPublicationReadiness, 'blocked'],
    'artifact requires action' => [BadgeDomain::GovernanceArtifactActionability, 'required'],
]);

it('separates review existence from publication readiness', function (): void {
    $tenant = ManagedEnvironment::factory()->create();
    [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner');
    $snapshot = $this->makeArtifactTruthEvidenceSnapshot($tenant);
    $review = $this->makeArtifactTruthReview(
        tenant: $tenant,
        user: $user,
        snapshot: $snapshot,
        reviewOverrides: [
            'status' => 'draft',
            'completeness_state' => 'complete',
        ],
        summaryOverrides: [
            'publish_blockers' => ['Review the missing approval note before publication.'],
        ],
    );

    $truth = app(ArtifactTruthPresenter::class)->forEnvironmentReview($review);

    expect($truth->artifactExistence)->toBe('created')
        ->and($truth->publicationReadiness)->toBe('blocked')
        ->and($truth->primaryLabel)->toBe('Publication blocked')
        ->and($truth->nextStepText())->toContain('Resolve');
});

it('marks ready review packs as publishable only when their source review stays publishable', function (): void {
    $tenant = ManagedEnvironment::factory()->create();
    [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner');
    $snapshot = $this->makeArtifactTruthEvidenceSnapshot($tenant);
    $review = $this->makeArtifactTruthReview($tenant, $user, $snapshot);
    $pack = $this->makeArtifactTruthReviewPack($tenant, $user, $snapshot, $review);

    $truth = app(ArtifactTruthPresenter::class)->forReviewPack($pack);

    expect($truth->artifactExistence)->toBe('created')
        ->and($truth->publicationReadiness)->toBe('publishable')
        ->and($truth->primaryLabel)->toBe('Publishable')
        ->and($truth->nextStepText())->toBe('No action needed');
});

it('keeps baseline snapshot lifecycle truth separate from current-vs-historical artifact truth', function (): void {
    $workspace = Workspace::factory()->create();
    $profile = BaselineProfile::factory()->active()->create([
        'workspace_id' => (int) $workspace->getKey(),
    ]);

    $historicalSnapshot = BaselineSnapshot::factory()->complete()->create([
        'workspace_id' => (int) $workspace->getKey(),
        'baseline_profile_id' => (int) $profile->getKey(),
        'captured_at' => now()->subDay(),
        'completed_at' => now()->subDay(),
    ]);

    $currentSnapshot = BaselineSnapshot::factory()->complete()->create([
        'workspace_id' => (int) $workspace->getKey(),
        'baseline_profile_id' => (int) $profile->getKey(),
        'captured_at' => now(),
        'completed_at' => now(),
    ]);

    $incompleteSnapshot = BaselineSnapshot::factory()->incomplete(BaselineReasonCodes::SNAPSHOT_CAPTURE_FAILED)->create([
        'workspace_id' => (int) $workspace->getKey(),
        'baseline_profile_id' => (int) $profile->getKey(),
    ]);

    $profile->update(['active_snapshot_id' => (int) $currentSnapshot->getKey()]);

    $historicalTruth = app(ArtifactTruthPresenter::class)->forBaselineSnapshot($historicalSnapshot->fresh());
    $incompleteTruth = app(ArtifactTruthPresenter::class)->forBaselineSnapshot($incompleteSnapshot->fresh());

    expect($historicalTruth->artifactExistence)->toBe('historical_only')
        ->and($historicalTruth->diagnosticLabel)->toBe('Superseded')
        ->and(BadgeCatalog::spec(BadgeDomain::BaselineSnapshotLifecycle, $historicalSnapshot->lifecycleState()->value)->label)->toBe('Complete');

    expect($incompleteTruth->artifactExistence)->toBe('created_but_not_usable')
        ->and($incompleteTruth->diagnosticLabel)->toBe('Incomplete')
        ->and($incompleteTruth->reason?->reasonCode)->toBe(BaselineReasonCodes::SNAPSHOT_CAPTURE_FAILED);
});

it('maps shared operator explanations onto blocked environment-review and incomplete baseline-snapshot truth envelopes', function (): void {
    $tenant = ManagedEnvironment::factory()->create();
    [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner');
    $snapshot = $this->makeArtifactTruthEvidenceSnapshot($tenant);
    $review = $this->makeArtifactTruthReview(
        tenant: $tenant,
        user: $user,
        snapshot: $snapshot,
        reviewOverrides: [
            'status' => 'draft',
            'completeness_state' => 'complete',
        ],
        summaryOverrides: [
            'publish_blockers' => ['Review the missing approval note before publication.'],
        ],
    );

    $reviewTruth = app(ArtifactTruthPresenter::class)->forEnvironmentReview($review);

    expect($reviewTruth->operatorExplanation)->not->toBeNull()
        ->and($reviewTruth->operatorExplanation?->nextActionText)->toBe('Resolve the review blockers before publication')
        ->and($reviewTruth->operatorExplanation?->trustworthinessLabel())->toBe('Not usable yet');

    $workspace = Workspace::factory()->create();
    $profile = BaselineProfile::factory()->active()->create([
        'workspace_id' => (int) $workspace->getKey(),
    ]);

    $incompleteSnapshot = BaselineSnapshot::factory()->incomplete(BaselineReasonCodes::SNAPSHOT_CAPTURE_FAILED)->create([
        'workspace_id' => (int) $workspace->getKey(),
        'baseline_profile_id' => (int) $profile->getKey(),
    ]);

    $snapshotTruth = app(ArtifactTruthPresenter::class)->forBaselineSnapshot($incompleteSnapshot->fresh());

    expect($snapshotTruth->operatorExplanation)->not->toBeNull()
        ->and($snapshotTruth->operatorExplanation?->headline)->toBe('The result exists, but missing inputs keep it from being decision-grade.')
        ->and($snapshotTruth->operatorExplanation?->nextActionText)->toContain('Inspect the related capture diagnostics');
});
