// Basic ID pattern types
type HeroId = string; // Pattern: "^H_[1-9]\\d*$"
type RaceId = string; // Pattern: "^R_[1-9]\\d*$"
type RaceVariantId = string; // Pattern: "^RV_[1-9]\\d*$"
type CultureId = string; // Pattern: "^C_[1-9]\\d*$"
type ProfessionId = string; // Pattern: "^P_[1-9]\\d*$"
type ProfessionVariantId = string; // Pattern: "^PV_[1-9]\\d*$"
type ExperienceLevelId = string; // Pattern: "^EL_[1-9]\\d*$"
type AttributeId = string; // Pattern: "^ATTR_[1-9]\\d*$"
type TalentId = string; // Pattern: "^TAL_[1-9]\\d*$"
type CombatTechniqueId = string; // Pattern: "^CT_[1-9]\\d*$"
type SpellId = string; // Pattern: "^SPELL_[1-9]\\d*$"
type CantripId = string; // Pattern: "^CANTRIP_[1-9]\\d*$"
type LiturgyId = string; // Pattern: "^LITURGY_[1-9]\\d*$"
type BlessingId = string; // Pattern: "^BLESSING_[1-9]\\d*$"
type ItemId = string; // Pattern: "^ITEM_[1-9]\\d*$"
type ActivatableId = string; // Pattern: "^(ADV|DISADV|SA)_[1-9]\\d*$"

// Adventure Points
interface AdventurePoints {
  total: number; // minimum: 1
}

// Rules configuration
interface Rules {
  higherParadeValues: 0 | 2 | 4;
  attributeValueLimit: boolean;
  enableAllRuleBooks: boolean;
  enabledRuleBooks: string[];
  enableLanguageSpecializations: boolean;
}

// Personal data
interface PersonalData {
  family?: string;
  placeofbirth?: string;
  dateofbirth?: string;
  age?: string;
  haircolor?: string;
  eyecolor?: string;
  size?: string;
  weight?: string;
  title?: string;
  socialstatus?: number; // 1-5
  characteristics?: string;
  otherinfo?: string;
  cultureAreaKnowledge?: string;
}

// Activatable items (advantages, disadvantages, special abilities)
interface ActivatableOption {
  sid?: string | number;
  sid2?: string | number;
  sid3?: string | number;
  tier?: number; // minimum: 1
  cost?: number; // minimum: 0
}

// Permanent energy attributes
interface PermanentEnergy {
  lost: number; // minimum: 0
  redeemed?: number; // minimum: 0
}

interface PermanentLP {
  lost: number; // minimum: 0
}

// Attribute value (older version - tuple format)
type AttributeTuple = [AttributeId, number, number]; // [id, value, adjustment]

// Attribute value (newer version - object format)
interface AttributeValue {
  id: AttributeId;
  value: number; // minimum: 8
}

// Attributes - supports both old and new formats
interface AttributesOld {
  values: AttributeTuple[];
  lp: number; // minimum: 0
  ae: number; // minimum: 0
  kp: number; // minimum: 0
  permanentLP?: PermanentLP;
  permanentAE: PermanentEnergy;
  permanentKP: PermanentEnergy;
}

interface AttributesNew {
  values: AttributeValue[];
  attributeAdjustmentSelected: AttributeId;
  lp: number; // minimum: 0
  ae: number; // minimum: 0
  kp: number; // minimum: 0
  permanentLP?: PermanentLP;
  permanentAE: PermanentEnergy;
  permanentKP: PermanentEnergy;
}

// Belongings
interface Item {
  id: ItemId;
  price?: number; // minimum: 0
  weight?: number; // minimum: 0
}

interface Belongings {
  items: Record<ItemId, Item>;
}

// Main CharacterSheet type
export interface CharacterSheet {
  id: HeroId;
  name: string;
  clientVersion: string; // Version pattern: (0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(-(\\w+)\\.(0|[1-9]\\d*))?
  dateCreated: string; // ISO date-time format
  dateModified: string; // ISO date-time format
  locale?: string; // Pattern: "^[a-z]\\-[A-Z]$"
  avatar?: string;
  ap: AdventurePoints;
  r?: RaceId;
  rv?: RaceVariantId;
  c?: CultureId;
  isCulturalPackageActive?: boolean;
  p?: ProfessionId;
  professionName?: string;
  pv?: ProfessionVariantId;
  sex: "m" | "f";
  rules: Rules;
  phase: 1 | 2 | 3; // 1: RCP selection, 2: standard creation, 3: after creation
  el: ExperienceLevelId;
  pers: PersonalData;
  activatable: Record<ActivatableId, ActivatableOption[]>;
  attr: AttributesOld | AttributesNew;
  talents: Record<TalentId, number>; // minimum: 0
  ct: Record<CombatTechniqueId, number>; // minimum: 0
  spells: Record<SpellId, number>; // minimum: 0
  cantrips: CantripId[];
  liturgies: Record<LiturgyId, number>; // minimum: 0
  blessings: BlessingId[];
  belongings?: Belongings;
}
