<?php

declare(strict_types=1);

namespace Plugin\tnt_stabila_shop\src\Helper;

/**
 * Pure decision helper for threshold-based alerting.
 *
 * Given the severity of a collected error event and a configured minimum
 * severity threshold, it decides whether an admin alert should be dispatched.
 * Severities follow Sentry's levels (debug < info < warning < error < fatal).
 *
 * An unconfigured threshold (null) preserves the historic behaviour of
 * alerting on every event, so enabling the feature is opt-in.
 */
class AlertSeverityDecider
{
    public const RANK_DEBUG   = 0;
    public const RANK_INFO    = 1;
    public const RANK_WARNING = 2;
    public const RANK_ERROR   = 3;
    public const RANK_FATAL   = 4;

    /** @var array<string, int> */
    private const SEVERITY_RANKS = [
        'debug'   => self::RANK_DEBUG,
        'info'    => self::RANK_INFO,
        'warning' => self::RANK_WARNING,
        'error'   => self::RANK_ERROR,
        'fatal'   => self::RANK_FATAL,
    ];

    /**
     * Decide whether an event of the given severity should trigger an admin alert.
     *
     * @param string   $severity        Sentry severity label (e.g. "warning", "error", "fatal").
     * @param int|null $minSeverityRank Configured minimum rank (0-4); null = unconfigured -> alert on everything.
     * @return bool True when an alert should be dispatched.
     */
    public static function shouldAlert(string $severity, ?int $minSeverityRank): bool
    {
        // Unconfigured threshold: preserve the historic "alert on every event" behaviour.
        if ($minSeverityRank === null) {
            return true;
        }
        $rank = self::rankOf($severity);
        // Unknown severity: fail open so no event is ever silently dropped.
        if ($rank === null) {
            return true;
        }

        return $rank >= $minSeverityRank;
    }

    /**
     * Resolve a severity label to its numeric rank.
     *
     * @param string $severity Sentry severity label (case-insensitive).
     * @return int|null Numeric rank, or null when the label is unknown.
     */
    public static function rankOf(string $severity): ?int
    {
        return self::SEVERITY_RANKS[\strtolower(\trim($severity))] ?? null;
    }
}
