using System.Text.Json.Serialization;

namespace Theriapolis.Core.Data;

/// <summary>
/// Immutable item definition loaded from items.json. Covers weapons,
/// armor, shields, consumables, adventuring gear, and natural-weapon
/// enhancers. Phase 5 ships a curated subset focused on combat readiness;
/// the remaining catalog from equipment.md fills in over later phases.
/// </summary>
public sealed record ItemDef
{
    [JsonPropertyName("id")]
    public string Id { get; init; } = "";

    [JsonPropertyName("name")]
    public string Name { get; init; } = "";

    /// <summary>"weapon", "armor", "shield", "consumable", "gear", "natural_weapon_enhancer".</summary>
    [JsonPropertyName("kind")]
    public string Kind { get; init; } = "gear";

    [JsonPropertyName("cost_fang")]
    public float CostFang { get; init; } = 0f;

    [JsonPropertyName("weight_lb")]
    public float WeightLb { get; init; } = 0f;

    /// <summary>Sizes this item is manufactured for: "small" / "medium" / "large".</summary>
    [JsonPropertyName("sizes")]
    public string[] Sizes { get; init; } = new[] { "medium" };

    /// <summary>Free-text properties from equipment.md (e.g. "finesse", "light", "two_handed", "versatile", "heavy", "loading", "thrown", "reach", "ammunition").</summary>
    [JsonPropertyName("properties")]
    public string[] Properties { get; init; } = Array.Empty<string>();

    /// <summary>Free-text description for tooltips and codex.</summary>
    [JsonPropertyName("description")]
    public string Description { get; init; } = "";

    // ── Weapon fields (kind = "weapon") ─────────────────────────────────
    /// <summary>Weapon proficiency category: "simple", "martial", "natural", "firearm".</summary>
    [JsonPropertyName("proficiency")]
    public string Proficiency { get; init; } = "";

    /// <summary>Damage dice expression (e.g. "1d6", "2d6", "1d8+2"). Empty for non-weapons.</summary>
    [JsonPropertyName("damage")]
    public string Damage { get; init; } = "";

    /// <summary>Versatile two-handed damage dice (e.g. "1d10" when used two-handed). Empty if not versatile.</summary>
    [JsonPropertyName("damage_versatile")]
    public string DamageVersatile { get; init; } = "";

    [JsonPropertyName("damage_type")]
    public string DamageType { get; init; } = "";

    /// <summary>Melee reach in tactical tiles. 0 / unset = default (1 for M, 2 for L).</summary>
    [JsonPropertyName("reach_tiles")]
    public int ReachTiles { get; init; } = 0;

    /// <summary>Ranged: short / long ranges in tactical tiles. (0,0) for melee.</summary>
    [JsonPropertyName("range_short_tiles")]
    public int RangeShortTiles { get; init; } = 0;

    [JsonPropertyName("range_long_tiles")]
    public int RangeLongTiles { get; init; } = 0;

    // ── Armor / shield fields (kind = "armor" | "shield") ──────────────
    /// <summary>Base AC value (armor) or AC bonus (shield).</summary>
    [JsonPropertyName("ac_base")]
    public int AcBase { get; init; } = 0;

    /// <summary>Max DEX modifier added to AC (medium = 2, heavy = 0). -1 = unlimited.</summary>
    [JsonPropertyName("ac_max_dex")]
    public int AcMaxDex { get; init; } = -1;

    /// <summary>"light", "medium", "heavy" — for armor only.</summary>
    [JsonPropertyName("armor_class")]
    public string ArmorClass { get; init; } = "";

    [JsonPropertyName("min_str")]
    public int MinStr { get; init; } = 0;

    [JsonPropertyName("stealth_disadvantage")]
    public bool StealthDisadvantage { get; init; } = false;

    // ── Natural-weapon-enhancer fields (kind = "natural_weapon_enhancer") ─
    /// <summary>Which natural-weapon location this enhancer attaches to: "fang", "claw", "hoof", "antler", "horn", "tail".</summary>
    [JsonPropertyName("enhancer_slot")]
    public string EnhancerSlot { get; init; } = "";

    /// <summary>Damage modifier added to the natural attack (e.g. +1 or +2).</summary>
    [JsonPropertyName("damage_bonus")]
    public int DamageBonus { get; init; } = 0;

    /// <summary>Clades this enhancer is fitted for. Empty = universal.</summary>
    [JsonPropertyName("clade_fit")]
    public string[] CladeFit { get; init; } = Array.Empty<string>();

    // ── Consumable fields (kind = "consumable") ─────────────────────────
    /// <summary>"healing", "poison", "pheromone", "performance", "scent_mask", etc.</summary>
    [JsonPropertyName("consumable_kind")]
    public string ConsumableKind { get; init; } = "";

    /// <summary>Healing dice expression for healing consumables (e.g. "1d4", "2d6").</summary>
    [JsonPropertyName("healing")]
    public string Healing { get; init; } = "";
}
