<?php

declare(strict_types=1);

use App\Models\ManagedEnvironment;
use App\Support\Tenants\ReferencedTenantLifecyclePresentation;
use App\Support\Tenants\TenantLifecycle;
use App\Support\Tenants\TenantLifecyclePresentation;
use Illuminate\Foundation\Testing\RefreshDatabase;

uses(RefreshDatabase::class);

it('maps every canonical lifecycle value to a canonical presentation contract', function (string $value, string $label, string $color): void {
    $presentation = TenantLifecyclePresentation::fromValue($value);

    expect($presentation->value)->toBe($value)
        ->and($presentation->label)->toBe($label)
        ->and($presentation->badge()->color)->toBe($color)
        ->and($presentation->isInvalidFallback)->toBeFalse()
        ->and($presentation->lifecycle?->value)->toBe($value);
})->with([
    'draft' => ['draft', 'Draft', 'gray'],
    'onboarding' => ['onboarding', 'Onboarding', 'warning'],
    'active' => ['active', 'Active', 'success'],
    'archived' => ['archived', 'Archived', 'gray'],
]);

it('builds lifecycle presentation from tenant soft-delete state', function (): void {
    $tenant = ManagedEnvironment::factory()->archived()->create();

    $presentation = TenantLifecyclePresentation::fromTenant($tenant);

    expect($presentation->lifecycle)->toBe(TenantLifecycle::Archived)
        ->and($presentation->label)->toBe('Archived')
        ->and($presentation->longDescription)->toContain('inspection and audit history');
});

it('uses explicit invalid fallback for non-canonical lifecycle data', function (): void {
    $presentation = TenantLifecyclePresentation::fromValue('pending');

    expect($presentation->isInvalidFallback)->toBeTrue()
        ->and($presentation->label)->toBe('Invalid lifecycle')
        ->and($presentation->badge()->color)->toBe('danger')
        ->and($presentation->value)->toBe('pending');
});

it('marks invalid referenced tenant lifecycle as unavailable for selector context', function (): void {
    $presentation = ReferencedTenantLifecyclePresentation::forInvalid('operation_run', normalizedValue: 'inactive');

    expect($presentation->selectorAvailabilityMessage())->toBe('This tenant has an invalid lifecycle value and may not appear in the tenant selector.')
        ->and($presentation->contextNote)->toBe('Some tenant follow-up actions may be unavailable from this canonical workspace view.');
});

it('describes non-selectable referenced tenant lifecycle using canonical wording', function (): void {
    $tenant = ManagedEnvironment::factory()->create([
        'status' => ManagedEnvironment::STATUS_ONBOARDING,
        'name' => 'Onboarding ManagedEnvironment',
    ]);

    $presentation = ReferencedTenantLifecyclePresentation::forOperationRun($tenant);

    expect($presentation->selectorAvailabilityMessage())->toBe('This tenant is currently onboarding and may not appear in the tenant selector.')
        ->and($presentation->presentation->label)->toBe('Onboarding');
});
