<?php

declare(strict_types=1);

namespace Plugin\tnt_mcp\src\Mcp\Admin;

/**
 * Turns an audit outcome code into something a merchant can read.
 *
 * The audit log stores machine outcomes — `ok`, `denied:scope`, `refused:blocked_action`,
 * `failed:…` — and the Server-Status summary rendered them verbatim, so the tab's one aggregate
 * view answered in API vocabulary (docs/UI_REVIEW.md U28). The prefix before the colon is the
 * verdict and the part after it is the reason, which is exactly the shape a label wants: one
 * translated sentence for the verdict, the raw reason kept beside it because it is the only thing
 * that distinguishes two refusals.
 *
 * An unknown code is NOT mapped to "other": a code this class has not seen yet is shown as itself,
 * because a summary that quietly buckets something it does not understand hides the one row a
 * developer is looking for.
 */
final class AuditOutcome
{
    /** Verdict prefix → chip tone, in {@see \Plugin\tnt_mcp\adminmenu\Controller\Ui::chips()}. */
    private const TONES = [
        'ok'      => 'success',
        'denied'  => 'warning',
        'refused' => 'warning',
        'blocked' => 'warning',
        'failed'  => 'danger',
        'error'   => 'danger',
    ];

    /** @var array<string, array{de: string, en: string}> */
    private const LABELS = [
        'ok'      => ['de' => 'erfolgreich', 'en' => 'succeeded'],
        'denied'  => ['de' => 'abgelehnt', 'en' => 'denied'],
        'refused' => ['de' => 'verweigert', 'en' => 'refused'],
        'blocked' => ['de' => 'blockiert', 'en' => 'blocked'],
        'failed'  => ['de' => 'fehlgeschlagen', 'en' => 'failed'],
        'error'   => ['de' => 'Fehler', 'en' => 'error'],
    ];

    public static function tone(string $outcome): string
    {
        return self::TONES[self::verdict($outcome)] ?? 'neutral';
    }

    /**
     * `denied:scope` → "abgelehnt (scope)". The reason stays raw: it names a scope, an action id or
     * a mode, and translating those would make the row impossible to grep for.
     */
    public static function label(string $outcome, string $language): string
    {
        $verdict = self::verdict($outcome);
        $texts   = self::LABELS[$verdict] ?? null;
        if ($texts === null) {
            return $outcome;
        }

        $label  = AdminLanguage::pick($texts, $language);
        $reason = \substr($outcome, \strlen($verdict) + 1);

        return \trim($reason) === '' ? $label : $label . ' (' . $reason . ')';
    }

    private static function verdict(string $outcome): string
    {
        $colon = \strpos($outcome, ':');

        return $colon === false ? $outcome : \substr($outcome, 0, $colon);
    }
}
