using System.Text.Json.Serialization;
namespace Theriapolis.Core.Data;
///
/// Immutable class definition loaded from classes.json. Phase 5 reads
/// every field — including the full level table — but only level-1
/// features have runtime effect; higher-level entries are forward-compat
/// scaffolding for the level-up flow shipped in Phase 5.5 / 6.
///
public sealed record ClassDef
{
[JsonPropertyName("id")]
public string Id { get; init; } = "";
[JsonPropertyName("name")]
public string Name { get; init; } = "";
/// Codex-voice calling description: in-character quote followed
/// by a one-paragraph profile (mirrors CladeDef / SpeciesDef). Surfaced
/// on the Step III calling card.
[JsonPropertyName("description")]
public string Description { get; init; } = "";
/// Hit die size: 6 / 8 / 10 / 12.
[JsonPropertyName("hit_die")]
public int HitDie { get; init; } = 8;
/// Primary ability key(s) (STR / DEX / CON / INT / WIS / CHA).
[JsonPropertyName("primary_ability")]
public string[] PrimaryAbility { get; init; } = Array.Empty();
/// Saving-throw proficiencies.
[JsonPropertyName("saves")]
public string[] Saves { get; init; } = Array.Empty();
/// Armor proficiency tags: "light", "medium", "heavy", "shields".
[JsonPropertyName("armor_proficiencies")]
public string[] ArmorProficiencies { get; init; } = Array.Empty();
/// Weapon proficiency tags: "simple", "martial", "natural", or specific item ids.
[JsonPropertyName("weapon_proficiencies")]
public string[] WeaponProficiencies { get; init; } = Array.Empty();
/// Tool proficiency tags.
[JsonPropertyName("tool_proficiencies")]
public string[] ToolProficiencies { get; init; } = Array.Empty();
[JsonPropertyName("skills_choose")]
public int SkillsChoose { get; init; } = 0;
[JsonPropertyName("skill_options")]
public string[] SkillOptions { get; init; } = Array.Empty();
///
/// Per-level entries. Level 1..20. Phase 5 only consults level 1, but
/// the full table loads so the level-up flow doesn't need a schema bump.
///
[JsonPropertyName("level_table")]
public ClassLevelEntry[] LevelTable { get; init; } = Array.Empty();
/// Description of each named feature referenced from level_table.
[JsonPropertyName("feature_definitions")]
public Dictionary FeatureDefinitions { get; init; } = new();
/// Allowed subclass ids (cross-reference into subclasses.json).
[JsonPropertyName("subclass_ids")]
public string[] SubclassIds { get; init; } = Array.Empty();
///
/// Items handed to a level-1 character of this class at creation time.
/// adds each entry to the
/// inventory and, if is true,
/// equips it into .
///
[JsonPropertyName("starting_kit")]
public StartingKitItem[] StartingKit { get; init; } = Array.Empty();
}
///
/// One row in : the item id, quantity, and
/// optional auto-equip target. ItemId must resolve against items.json.
///
public sealed record StartingKitItem
{
[JsonPropertyName("item_id")]
public string ItemId { get; init; } = "";
[JsonPropertyName("qty")]
public int Qty { get; init; } = 1;
/// If true, the item is equipped into at creation.
[JsonPropertyName("auto_equip")]
public bool AutoEquip { get; init; } = false;
/// "main_hand" / "off_hand" / "body" / "helm" / "cloak" / "boots" / "adaptive_pack" / etc.
[JsonPropertyName("equip_slot")]
public string EquipSlot { get; init; } = "";
}
public sealed record ClassLevelEntry
{
[JsonPropertyName("level")]
public int Level { get; init; } = 1;
[JsonPropertyName("prof")]
public int ProficiencyBonus { get; init; } = 2;
/// Feature ids unlocked at this level. Resolves into .
[JsonPropertyName("features")]
public string[] Features { get; init; } = Array.Empty();
}
public sealed record ClassFeatureDef
{
[JsonPropertyName("name")]
public string Name { get; init; } = "";
[JsonPropertyName("description")]
public string Description { get; init; } = "";
/// "passive", "active", "choice", "bonus_action", "reaction", "stub".
[JsonPropertyName("kind")]
public string Kind { get; init; } = "passive";
[JsonPropertyName("uses_per_short_rest")]
public int? UsesPerShortRest { get; init; }
[JsonPropertyName("uses_per_long_rest")]
public int? UsesPerLongRest { get; init; }
/// For "choice" features: the available pick ids.
[JsonPropertyName("options")]
public string[]? Options { get; init; }
}