import { SYSTEM } from "../config/system.mjs"

export default class OathHammerWeapon extends foundry.abstract.TypeDataModel {
  static defineSchema() {
    const fields = foundry.data.fields
    const requiredInteger = { required: true, nullable: false, integer: true }
    const schema = {}

    schema.description = new fields.HTMLField({ required: true, textSearch: true })

    // Proficiency group (Common, Dueling, Heavy, Polearms, Bows, Throwing)
    schema.proficiencyGroup = new fields.StringField({
      required: true, initial: "common", choices: SYSTEM.WEAPON_PROFICIENCY_GROUPS
    })

    // Damage: melee/throwing = Might rank + damageMod dice; bows = baseDice (fixed, no Might)
    // usesMight is now derived from proficiencyGroup (see getter below)
    schema.damageMod = new fields.NumberField({ ...requiredInteger, initial: 0, min: -4, max: 15 })

    // AP (Armor Penetration): penalty imposed on armor/defense rolls
    schema.ap = new fields.NumberField({ ...requiredInteger, initial: 0, min: 0, max: 16 })

    // Reach (melee, in ft: 5 / 10 / 15) — ignored for ranged/throwing
    schema.reach = new fields.NumberField({ ...requiredInteger, initial: 5, min: 5 })

    // Range (ranged & throwing, in ft): short and long
    schema.shortRange = new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 })
    schema.longRange  = new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 })

    // Traits — stored as a Set of trait keys (Block, Brutal, Nimble, Parry, etc.)
    schema.traits = new fields.SetField(
      new fields.StringField({ choices: SYSTEM.WEAPON_TRAITS }),
      { required: true, initial: [] }
    )

    // Special Properties — crafting enhancements (Accurate, Master-Crafted, etc. p.98)
    schema.specialProperties = new fields.SetField(
      new fields.StringField({ choices: SYSTEM.WEAPON_SPECIAL_PROPERTIES }),
      { required: true, initial: [] }
    )

    // Item slots (when stowed; 0 = does not occupy slots)
    schema.slots = new fields.NumberField({ ...requiredInteger, initial: 1, min: 0 })

    schema.rarity = new fields.StringField({ required: true, initial: "common", choices: SYSTEM.RARITY_CHOICES })

    schema.equipped  = new fields.BooleanField({ required: true, initial: false })
    schema.cost      = new fields.NumberField({ ...requiredInteger, initial: 0, min: 0 })
    schema.currency  = new fields.StringField({ required: true, initial: "gp", choices: SYSTEM.CURRENCY_CHOICES })

    // --- Magic properties (only relevant when isMagic = true) ---
    schema.isMagic     = new fields.BooleanField({ initial: false })
    schema.magicQuality = new fields.StringField({
      required: false, nullable: true, initial: null, choices: SYSTEM.MAGIC_QUALITY_CHOICES
    })
    schema.isCursed    = new fields.BooleanField({ initial: false })
    // Enchantment description (displayed when isMagic is true)
    schema.magicEffect = new fields.HTMLField({ required: false, textSearch: true })
    // Class/lineage restriction, e.g. "Dwarves only" (empty = no restriction)
    schema.classRestriction = new fields.StringField({ required: false, nullable: true, initial: null, choices: SYSTEM.CLASS_RESTRICTION_CHOICES })

    // Override which skill (and its linked attribute) is used for attack rolls.
    // Null / "" = auto-detect (fighting for melee, shooting for ranged).
    // Use this for abilities like Magic Bolt that roll Magic+Willpower instead.
    schema.skillOverride = new fields.StringField({ required: false, nullable: true, initial: null })

    // Attached runic spells (max 2; each is a snapshot of the spell item)
    schema.runes = new fields.ArrayField(new fields.ObjectField(), { required: true, initial: [] })

    return schema
  }

  static LOCALIZATION_PREFIXES = ["OATHHAMMER.Weapon"]

  static migrateData(source) {
    if (typeof source.rarity === "number") {
      const map = { 0: "common", 1: "uncommon", 2: "rare", 3: "very-rare", 4: "legendary", 5: "legendary", 6: "legendary" }
      source.rarity = map[source.rarity] ?? "common"
    }
    // Remove legacy usesMight field — now derived from proficiencyGroup
    delete source.usesMight
    return super.migrateData(source)
  }

  /** Derived: only bows skip Might for damage. Throwing weapons keep Might (arm strength). */
  get usesMight() {
    return this.proficiencyGroup !== "bows"
  }

  /**
   * Human-readable damage formula for display, e.g. "M+2", "M-1", "6"
   */
  get damageLabel() {
    if (this.usesMight) {
      const mod = this.damageMod
      if (mod === 0) return "M+0"
      return mod > 0 ? `M+${mod}` : `M${mod}`
    }
    return String(this.damageMod) // bows: store base dice count in damageMod
  }
}
