<?php

namespace App\Support\Badges\Domains;

use App\Support\Badges\BadgeCatalog;
use App\Support\Badges\BadgeDomain;
use App\Support\Badges\BadgeMapper;
use App\Support\Badges\BadgeSpec;
use App\Support\Badges\OperatorOutcomeTaxonomy;
use App\Support\OperationRunOutcome;
use App\Support\OperationRunStatus;
use App\Support\Operations\OperationRunFreshnessState;

final class OperationRunOutcomeBadge implements BadgeMapper
{
    public function spec(mixed $value): BadgeSpec
    {
        $state = null;

        if (is_array($value)) {
            $outcome = BadgeCatalog::normalizeState($value['outcome'] ?? null);
            $status = BadgeCatalog::normalizeState($value['status'] ?? null);
            $freshnessState = BadgeCatalog::normalizeState($value['freshness_state'] ?? null);

            if ($outcome === null) {
                if ($freshnessState === OperationRunFreshnessState::ReconciledFailed->value) {
                    $outcome = OperationRunOutcome::Failed->value;
                } elseif (
                    $freshnessState === OperationRunFreshnessState::LikelyStale->value
                    || in_array($status, [OperationRunStatus::Queued->value, OperationRunStatus::Running->value], true)
                ) {
                    $outcome = OperationRunOutcome::Pending->value;
                }
            }

            if ($outcome === OperationRunOutcome::Failed->value
                && $freshnessState === OperationRunFreshnessState::ReconciledFailed->value
            ) {
                return new BadgeSpec(
                    label: 'Reconciled failed',
                    color: 'danger',
                    icon: 'heroicon-m-arrow-path-rounded-square',
                    iconColor: 'danger',
                );
            }

            $state = $outcome;
        }

        $state ??= BadgeCatalog::normalizeState($value);

        return match ($state) {
            OperationRunOutcome::Pending->value => OperatorOutcomeTaxonomy::spec(BadgeDomain::OperationRunOutcome, $state, 'heroicon-m-clock'),
            OperationRunOutcome::Succeeded->value => OperatorOutcomeTaxonomy::spec(BadgeDomain::OperationRunOutcome, $state, 'heroicon-m-check-circle'),
            OperationRunOutcome::PartiallySucceeded->value => OperatorOutcomeTaxonomy::spec(BadgeDomain::OperationRunOutcome, $state, 'heroicon-m-exclamation-triangle'),
            OperationRunOutcome::Blocked->value, 'operation.blocked' => OperatorOutcomeTaxonomy::spec(BadgeDomain::OperationRunOutcome, $state, 'heroicon-m-no-symbol'),
            OperationRunOutcome::Failed->value => OperatorOutcomeTaxonomy::spec(BadgeDomain::OperationRunOutcome, $state, 'heroicon-m-x-circle'),
            OperationRunOutcome::Cancelled->value => OperatorOutcomeTaxonomy::spec(BadgeDomain::OperationRunOutcome, $state, 'heroicon-m-minus-circle'),
            default => BadgeSpec::unknown(),
        } ?? BadgeSpec::unknown();
    }
}
