using System.Text.Json;

/// <summary>
/// Shared read helper for converters that write DB-wire strings (e.g. "ICU")
/// but must also accept default System.Text.Json client payloads (numeric enums)
/// and PascalCase enum names.
/// </summary>
internal static class DbStringEnumJson
{
    public static TEnum Read<TEnum>(ref Utf8JsonReader reader, Func<string, TEnum> fromDbString)
        where TEnum : struct, Enum
    {
        switch (reader.TokenType)
        {
            case JsonTokenType.Number:
                if (reader.TryGetInt32(out var numeric)
                    && Enum.IsDefined(typeof(TEnum), numeric))
                    return (TEnum)Enum.ToObject(typeof(TEnum), numeric);
                throw new JsonException($"Invalid numeric value for {typeof(TEnum).Name}.");

            case JsonTokenType.String:
                var raw = reader.GetString()
                    ?? throw new JsonException($"Null string for {typeof(TEnum).Name}.");
                try
                {
                    return fromDbString(raw);
                }
                catch (ArgumentOutOfRangeException) when (
                    Enum.TryParse(raw, ignoreCase: true, out TEnum byName))
                {
                    return byName;
                }

            default:
                throw new JsonException(
                    $"Unexpected token {reader.TokenType} when parsing {typeof(TEnum).Name}.");
        }
    }
}
