<?php

declare(strict_types=1);

namespace App\Support\Tenants;

use App\Models\ManagedEnvironment;
use App\Support\Badges\BadgeSpec;

final readonly class TenantLifecyclePresentation
{
    private function __construct(
        public string $value,
        public string $label,
        public string $badgeColor,
        public ?string $badgeIcon,
        public ?string $badgeIconColor,
        public string $shortDescription,
        public string $longDescription,
        public bool $isInvalidFallback,
        public ?TenantLifecycle $lifecycle,
    ) {}

    public static function fromTenant(ManagedEnvironment $tenant): self
    {
        if ($tenant->trashed()) {
            return self::forLifecycle(TenantLifecycle::Archived);
        }

        return self::fromValue($tenant->lifecycle_status);
    }

    public static function fromValue(mixed $value): self
    {
        $lifecycle = TenantLifecycle::tryFromValue($value);

        if ($lifecycle instanceof TenantLifecycle) {
            return self::forLifecycle($lifecycle);
        }

        return self::invalid(TenantLifecycle::normalize($value));
    }

    public static function forLifecycle(TenantLifecycle $lifecycle): self
    {
        return match ($lifecycle) {
            TenantLifecycle::Draft => new self(
                value: $lifecycle->value,
                label: $lifecycle->label(),
                badgeColor: 'gray',
                badgeIcon: 'heroicon-m-document',
                badgeIconColor: null,
                shortDescription: 'Draft tenant awaiting onboarding completion.',
                longDescription: 'This tenant is still in draft and remains available for setup and review, but it is not selectable as active context until onboarding progresses.',
                isInvalidFallback: false,
                lifecycle: $lifecycle,
            ),
            TenantLifecycle::Onboarding => new self(
                value: $lifecycle->value,
                label: $lifecycle->label(),
                badgeColor: 'warning',
                badgeIcon: 'heroicon-m-arrow-path',
                badgeIconColor: null,
                shortDescription: 'Onboarding is in progress.',
                longDescription: 'This environment is still onboarding. It remains visible on management and review surfaces, but it is not selectable as active context until onboarding completes.',
                isInvalidFallback: false,
                lifecycle: $lifecycle,
            ),
            TenantLifecycle::Active => new self(
                value: $lifecycle->value,
                label: $lifecycle->label(),
                badgeColor: 'success',
                badgeIcon: 'heroicon-m-check-circle',
                badgeIconColor: null,
                shortDescription: 'Active environment available for normal operations.',
                longDescription: 'This environment is active and available across normal management, environment selection, and operational follow-up flows.',
                isInvalidFallback: false,
                lifecycle: $lifecycle,
            ),
            TenantLifecycle::Archived => new self(
                value: $lifecycle->value,
                label: $lifecycle->label(),
                badgeColor: 'gray',
                badgeIcon: 'heroicon-m-archive-box',
                badgeIconColor: null,
                shortDescription: 'Archived environment retained for inspection only.',
                longDescription: 'This environment remains available for inspection and audit history, but it is not selectable as active context until you restore it.',
                isInvalidFallback: false,
                lifecycle: $lifecycle,
            ),
        };
    }

    public static function invalid(?string $normalizedValue = null): self
    {
        return new self(
            value: $normalizedValue ?? 'invalid',
            label: 'Invalid lifecycle',
            badgeColor: 'danger',
            badgeIcon: 'heroicon-m-exclamation-triangle',
            badgeIconColor: 'danger',
            shortDescription: 'Lifecycle data is invalid and requires review.',
            longDescription: 'The stored environment lifecycle value is not canonical. Review the source data before treating this tenant as draft, onboarding, active, or archived.',
            isInvalidFallback: true,
            lifecycle: null,
        );
    }

    public function badge(): BadgeSpec
    {
        return new BadgeSpec(
            label: $this->label,
            color: $this->badgeColor,
            icon: $this->badgeIcon,
            iconColor: $this->badgeIconColor,
        );
    }

    public function isSelectableAsContext(): bool
    {
        return $this->lifecycle?->canSelectAsContext() ?? false;
    }

    public function lowercaseLabel(): string
    {
        return strtolower($this->label);
    }
}
