namespace Theriapolis.Core.Rules.Stats;

/// <summary>
/// Skill list used by Theriapolis — extends the d20 baseline with 12
/// additional skills (M6.18) so each ability has 5 skills tied to it.
/// New skills appended at the end of the byte enum to preserve save-game
/// compatibility with characters created before M6.18. Each skill is
/// backed by a single ability — see <see cref="SkillIdExtensions.Ability"/>.
/// </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,

    // M6.18 — Theriapolis-flavored expansions, 5 per ability.
    Brawl           = 18,   // STR
    BuildRead       = 19,   // STR
    Driving         = 20,   // DEX
    Endurance       = 21,   // CON
    Force           = 22,   // STR
    Fortitude       = 23,   // CON
    Hardiness       = 24,   // CON
    Haulage         = 25,   // STR
    LungCraft       = 26,   // CON
    Marksmanship    = 27,   // DEX
    PainTolerance   = 28,   // CON
    ScentSpeak      = 29,   // CHA
}

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,

        SkillId.Brawl           => AbilityId.STR,
        SkillId.BuildRead       => AbilityId.STR,
        SkillId.Driving         => AbilityId.DEX,
        SkillId.Endurance       => AbilityId.CON,
        SkillId.Force           => AbilityId.STR,
        SkillId.Fortitude       => AbilityId.CON,
        SkillId.Hardiness       => AbilityId.CON,
        SkillId.Haulage         => AbilityId.STR,
        SkillId.LungCraft       => AbilityId.CON,
        SkillId.Marksmanship    => AbilityId.DEX,
        SkillId.PainTolerance   => AbilityId.CON,
        SkillId.ScentSpeak      => AbilityId.CHA,
        _ => 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,

        "brawl"             => SkillId.Brawl,
        "build_read"        => SkillId.BuildRead,
        "driving"           => SkillId.Driving,
        "endurance"         => SkillId.Endurance,
        "force"             => SkillId.Force,
        "fortitude"         => SkillId.Fortitude,
        "hardiness"         => SkillId.Hardiness,
        "haulage"           => SkillId.Haulage,
        "lung_craft"        => SkillId.LungCraft,
        "marksmanship"      => SkillId.Marksmanship,
        "pain_tolerance"    => SkillId.PainTolerance,
        "scent_speak"       => SkillId.ScentSpeak,
        _ => throw new ArgumentException($"Unknown skill: '{raw}'"),
    };
}
