<?php

declare(strict_types=1);

namespace App\Support\Ui\EnterpriseDetail;

final class FactPresentation
{
    /**
     * @var array<string, string>
     */
    private const SEMANTIC_EQUIVALENTS = [
        'yes' => 'boolean_enabled',
        'enabled' => 'boolean_enabled',
        'no' => 'boolean_disabled',
        'disabled' => 'boolean_disabled',
    ];

    /**
     * @param  array<string, mixed>  $fact
     */
    public static function value(array $fact): ?string
    {
        $value = $fact['value'] ?? null;

        if (! is_scalar($value)) {
            return null;
        }

        $displayValue = trim((string) $value);

        if ($displayValue === '') {
            return null;
        }

        $badgeLabel = self::badgeLabel(is_array($fact['badge'] ?? null) ? $fact['badge'] : null);

        if ($badgeLabel !== null && self::isEquivalent($displayValue, $badgeLabel)) {
            return null;
        }

        return $displayValue;
    }

    /**
     * @param  array<string, mixed>|null  $badge
     */
    public static function badgeLabel(?array $badge): ?string
    {
        $label = $badge['label'] ?? null;

        if (! is_scalar($label)) {
            return null;
        }

        $displayLabel = trim((string) $label);

        return $displayLabel !== '' ? $displayLabel : null;
    }

    private static function normalize(string $value): string
    {
        return mb_strtolower(preg_replace('/\s+/', ' ', trim($value)) ?? trim($value));
    }

    private static function isEquivalent(string $value, string $badgeLabel): bool
    {
        $normalizedValue = self::normalize($value);
        $normalizedBadgeLabel = self::normalize($badgeLabel);

        if ($normalizedValue === $normalizedBadgeLabel) {
            return true;
        }

        return self::semanticToken($normalizedValue) !== null
            && self::semanticToken($normalizedValue) === self::semanticToken($normalizedBadgeLabel);
    }

    private static function semanticToken(string $value): ?string
    {
        return self::SEMANTIC_EQUIVALENTS[$value] ?? null;
    }
}
