namespace Theriapolis.Core.Rules.Stats;

/// <summary>
/// Standard d20-adjacent skill list. Each skill is backed by a single
/// ability — see <see cref="SkillAbility"/>.
/// </summary>
public enum SkillId : byte
{
    Acrobatics      = 0,
    AnimalHandling  = 1,
    Arcana          = 2,    // Theriapolis: "Advanced Engineering"
    Athletics       = 3,
    Deception       = 4,
    History         = 5,
    Insight         = 6,
    Intimidation    = 7,
    Investigation   = 8,
    Medicine        = 9,
    Nature          = 10,
    Perception      = 11,
    Performance     = 12,
    Persuasion      = 13,
    Religion        = 14,   // Theriapolis: Covenant lore
    SleightOfHand   = 15,
    Stealth         = 16,
    Survival        = 17,
}

public static class SkillIdExtensions
{
    public static AbilityId Ability(this SkillId s) => s switch
    {
        SkillId.Acrobatics      => AbilityId.DEX,
        SkillId.AnimalHandling  => AbilityId.WIS,
        SkillId.Arcana          => AbilityId.INT,
        SkillId.Athletics       => AbilityId.STR,
        SkillId.Deception       => AbilityId.CHA,
        SkillId.History         => AbilityId.INT,
        SkillId.Insight         => AbilityId.WIS,
        SkillId.Intimidation    => AbilityId.CHA,
        SkillId.Investigation   => AbilityId.INT,
        SkillId.Medicine        => AbilityId.WIS,
        SkillId.Nature          => AbilityId.INT,
        SkillId.Perception      => AbilityId.WIS,
        SkillId.Performance     => AbilityId.CHA,
        SkillId.Persuasion      => AbilityId.CHA,
        SkillId.Religion        => AbilityId.INT,
        SkillId.SleightOfHand   => AbilityId.DEX,
        SkillId.Stealth         => AbilityId.DEX,
        SkillId.Survival        => AbilityId.WIS,
        _ => throw new ArgumentOutOfRangeException(nameof(s)),
    };

    /// <summary>Parses a snake_case JSON value (e.g. "animal_handling") into a SkillId.</summary>
    public static SkillId FromJson(string raw) => raw.ToLowerInvariant() switch
    {
        "acrobatics"        => SkillId.Acrobatics,
        "animal_handling"   => SkillId.AnimalHandling,
        "arcana"            => SkillId.Arcana,
        "athletics"         => SkillId.Athletics,
        "deception"         => SkillId.Deception,
        "history"           => SkillId.History,
        "insight"           => SkillId.Insight,
        "intimidation"      => SkillId.Intimidation,
        "investigation"     => SkillId.Investigation,
        "medicine"          => SkillId.Medicine,
        "nature"            => SkillId.Nature,
        "perception"        => SkillId.Perception,
        "performance"       => SkillId.Performance,
        "persuasion"        => SkillId.Persuasion,
        "religion"          => SkillId.Religion,
        "sleight_of_hand"   => SkillId.SleightOfHand,
        "stealth"           => SkillId.Stealth,
        "survival"          => SkillId.Survival,
        _ => throw new ArgumentException($"Unknown skill: '{raw}'"),
    };
}
