using StackExchange.Redis;

 // qSOFA criteria (Sepsis-3 bedside screen):
// - Respiratory rate ≥ 22 breaths/min
// - Systolic blood pressure ≤ 100 mmHg
// - Altered mentation: AVPU ≥ 1 or GCS total < 15 (via SyncAlteredMentationAsync)
public static class QsofaCalculator
{
    public static readonly IReadOnlyList<string> QsofaCodes = new[]
    {
        "RESP_RATE", "SYSTOLIC_BP", "AVPU"
    };

    public static readonly IReadOnlySet<string> QsofaCodeSet =
        new HashSet<string>(QsofaCodes);

    public static bool MeetsCriterion(string observationCode, decimal value) =>
        observationCode switch
        {
            "RESP_RATE"   => value >= 22m,
            "SYSTOLIC_BP" => value <= 100m,
            "AVPU"        => value >= 1m,
            _             => false
        };

    public static bool MeetsGcsAlteredMentation(int gcsTotal) =>
        GcsCalculator.MeetsQsofaAlteredMentation(gcsTotal);

    public static string CriterionKey(Guid encounterId, string code) =>
        $"qsofa:{encounterId}:{code}";

    public static RedisKey[] AllCriterionKeys(Guid encounterId) =>
        QsofaCodes.Select(c => (RedisKey)CriterionKey(encounterId, c)).ToArray();

    public static int CountActiveCriteria(RedisValue[] values) =>
        values.Count(v => v.HasValue);

    public static QsofaCriteriaState ParseCriteriaState(RedisValue[] values) =>
        new(
            ParseOptionalDecimal(values.ElementAtOrDefault(0)),
            ParseOptionalDecimal(values.ElementAtOrDefault(1)),
            ParseOptionalDecimal(values.ElementAtOrDefault(2)));

    public static QsofaCriteriaState ParseCriteriaState(QsofaEvaluation evaluation) =>
        new(evaluation.RespRate, evaluation.SystolicBp, evaluation.Avpu);

    private static decimal? ParseOptionalDecimal(RedisValue value) =>
        value.HasValue ? decimal.Parse(value.ToString()!) : null;
}