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

/**
 * Roll dialogs for weapon attacks and damage.
 *
 * Attack flow:
 *   1. promptAttack(actor, weapon) → options
 *   2. rollWeaponAttack posts a chat card with a "Roll Damage" button
 *   3. Clicking the button calls promptDamage with attackSuccesses pre-filled
 *   4. rollWeaponDamage posts the damage chat card
 */
export default class OathHammerWeaponDialog {

  // ------------------------------------------------------------------ //
  //  ATTACK DIALOG
  // ------------------------------------------------------------------ //

  static async promptAttack(actor, weapon) {
    const sys      = weapon.system
    const actorSys = actor.system

    const isRanged     = sys.proficiencyGroup === "bows" || sys.proficiencyGroup === "throwing"
    const skillKey     = isRanged ? "shooting" : "fighting"
    const skillDef     = SYSTEM.SKILLS[skillKey]
    const defaultAttr  = skillDef.attribute
    const attrRank     = actorSys.attributes[defaultAttr].rank
    const skillRank    = actorSys.skills[skillKey].rank
    const skillColor   = actorSys.skills[skillKey].colorDiceType ?? "white"
    const threshold    = skillColor === "black" ? 2 : skillColor === "red" ? 3 : 4

    const hasNimble = sys.traits.has("nimble")

    // Luck
    const availableLuck    = actorSys.luck?.value ?? 0
    const isHuman          = (actorSys.lineage?.name ?? "").toLowerCase() === "human"
    const luckDicePerPoint = isHuman ? 3 : 2
    const luckOptions      = Array.from({ length: availableLuck + 1 }, (_, i) => ({
      value: i,
      label: i === 0 ? "0" : `${i} (+${i * luckDicePerPoint}d)`,
      selected: i === 0,
    }))

    // Auto-bonuses from special properties
    let autoAttackBonus = 0
    if (sys.specialProperties.has("master-crafted")) autoAttackBonus += 1
    if (sys.specialProperties.has("accurate"))        autoAttackBonus += 1   // bows
    if (sys.specialProperties.has("balanced"))        autoAttackBonus += 1   // grants Fast

    // Damage info for reference
    const hasBrutal       = sys.traits.has("brutal")
    const hasDeadly       = sys.traits.has("deadly")
    const damageColorType = hasDeadly ? "black" : hasBrutal ? "red" : "white"
    const damageThreshold = hasDeadly ? 2 : hasBrutal ? 3 : 4
    const damageColorLabel = hasDeadly ? "⬛" : hasBrutal ? "🔴" : "⬜"
    const mightRank       = actorSys.attributes.might.rank
    const baseDamageDice  = sys.usesMight ? Math.max(mightRank + sys.damageMod, 1) : Math.max(sys.damageMod, 1)

    const traitLabels = [...sys.traits].map(t => {
      const key = SYSTEM.WEAPON_TRAITS[t]
      return key ? game.i18n.localize(key) : t
    })

    // Option arrays
    const attackBonusOptions = Array.from({ length: 13 }, (_, i) => {
      const v = i - 6
      return { value: v, label: v > 0 ? `+${v}` : String(v), selected: v === 0 }
    })

    const rangeConditions = [
      { name: "range_long",        penalty: -1, label: `${game.i18n.localize("OATHHAMMER.Dialog.RangeLong")} (−1)` },
      { name: "range_moving",      penalty: -2, label: `${game.i18n.localize("OATHHAMMER.Dialog.RangeMoving")} (−2)` },
      { name: "range_concealment", penalty: -2, label: `${game.i18n.localize("OATHHAMMER.Dialog.RangeConcealment")} (−2)` },
      { name: "range_cover",       penalty: -3, label: `${game.i18n.localize("OATHHAMMER.Dialog.RangeCover")} (−3)` },
    ]

    const rollModes = foundry.utils.duplicate(CONFIG.Dice.rollModes)

    const context = {
      actorName:       actor.name,
      weaponName:      weapon.name,
      weaponImg:       weapon.img,
      skillKey,
      skillLabel:      game.i18n.localize(skillDef.label),
      attrKey:         defaultAttr,
      attrLabel:       game.i18n.localize(`OATHHAMMER.Attribute.${_cap(defaultAttr)}`),
      attrRank,
      skillRank,
      colorType:       skillColor,
      threshold,
      baseAttackPool:  attrRank + skillRank,
      autoAttackBonus,
      hasNimble,
      mightLabel:      game.i18n.localize("OATHHAMMER.Attribute.Might"),
      mightRank,
      agilityLabel:    game.i18n.localize("OATHHAMMER.Attribute.Agility"),
      agilityRank:     actorSys.attributes.agility.rank,
      isRanged,
      shortRange:      sys.shortRange,
      longRange:       sys.longRange,
      damageLabel:     sys.damageLabel,
      damageColorType,
      damageThreshold,
      damageColorLabel,
      baseDamageDice,
      apValue:         sys.ap,
      traits:          traitLabels,
      attackBonusOptions,
      rangeConditions,
      colorOptions:    _colorOptions(skillColor),
      rollModes,
      visibility:      game.settings.get("core", "rollMode"),
      availableLuck,
      isHuman,
      luckOptions,
    }

    const content = await foundry.applications.handlebars.renderTemplate(
      "systems/fvtt-oath-hammer/templates/weapon-attack-dialog.hbs",
      context
    )

    const result = await foundry.applications.api.DialogV2.wait({
      window:      { title: game.i18n.format("OATHHAMMER.Dialog.AttackTitle", { weapon: weapon.name }), resizable: true },
      classes:     ["fvtt-oath-hammer"],
      position:    { width: 420 },
      content,
      rejectClose: false,
      buttons: [{
        label:    game.i18n.localize("OATHHAMMER.Dialog.RollAttack"),
        callback: (_ev, btn) => {
          const out = {}
          for (const el of btn.form.elements) {
            if (!el.name) continue
            out[el.name] = el.type === "checkbox" ? String(el.checked) : el.value
          }
          return out
        },
      }],
    })

    if (!result) return null
    return {
      attackBonus:    parseInt(result.attackBonus)    || 0,
      rangeCondition: (result.range_long        === "true" ? -1 : 0)
                    + (result.range_moving      === "true" ? -2 : 0)
                    + (result.range_concealment === "true" ? -2 : 0)
                    + (result.range_cover       === "true" ? -3 : 0),
      attrOverride:   result.attrOverride || defaultAttr,
      colorOverride:  result.colorOverride || skillColor,
      visibility:     result.visibility ?? game.settings.get("core", "rollMode"),
      autoAttackBonus,
      explodeOn5:     result.explodeOn5 === "true",
      luckSpend:      Math.min(Math.max(0, parseInt(result.luckSpend) || 0), availableLuck),
      luckIsHuman:    result.luckIsHuman === "true",
    }
  }

  // ------------------------------------------------------------------ //
  //  DEFENSE DIALOG
  // ------------------------------------------------------------------ //

  /**
   * Show the weapon defense dialog and return resolved options.
   *
   * Defense pool = Agility (or Might) + Defense skill + trait bonuses + armor penalty + diminish penalty + bonus
   *
   * Parry trait → red dice vs melee; +1 if two Parry weapons equipped
   * Block  trait → red dice vs ranged; +1 bonus always
   * Diminishing defense: -2 per additional defense after the first in a turn
   */
  static async promptDefense(actor, weapon) {
    const sys      = weapon.system
    const actorSys = actor.system

    const agiRank   = actorSys.attributes.agility.rank
    const mightRank = actorSys.attributes.might.rank
    const defRank   = actorSys.skills.defense.rank

    // Detect this weapon's defense-relevant traits
    const hasParry = sys.traits.has("parry")
    const hasBlock = sys.traits.has("block")

    // Count all equipped parry/block weapons (for +1 with two Parry weapons)
    const equipped   = actor.items.filter(i => i.type === "weapon" && i.system.equipped)
    const parryCount = equipped.filter(w => w.system.traits?.has?.("parry") || [...(w.system.traits ?? [])].includes("parry")).length
    const blockCount = equipped.filter(w => w.system.traits?.has?.("block") || [...(w.system.traits ?? [])].includes("block")).length

    // Armor penalty from all equipped armors
    const armorPenalty = actor.items
      .filter(i => i.type === "armor" && i.system.equipped)
      .reduce((sum, a) => sum + (a.system.penalty ?? 0), 0)

    // Luck
    const availableLuck    = actorSys.luck?.value ?? 0
    const isHuman          = (actorSys.lineage?.name ?? "").toLowerCase() === "human"
    const luckDicePerPoint = isHuman ? 3 : 2
    const luckOptions      = Array.from({ length: availableLuck + 1 }, (_, i) => ({
      value: i,
      label: i === 0 ? "0" : `${i} (+${i * luckDicePerPoint}d)`,
      selected: i === 0,
    }))

    // Pre-select attack type: block weapons default to ranged, parry to melee
    const defaultAttackType = hasBlock && !hasParry ? "ranged" : "melee"

    const traitLabels = [...sys.traits].map(t => {
      const key = SYSTEM.WEAPON_TRAITS[t]
      return key ? game.i18n.localize(key) : t
    })

    const attackTypeOptions = [
      { value: "melee",  label: game.i18n.localize("OATHHAMMER.Dialog.DefenseMelee"),  selected: defaultAttackType === "melee" },
      { value: "ranged", label: game.i18n.localize("OATHHAMMER.Dialog.DefenseRanged"), selected: defaultAttackType === "ranged" },
    ]

    const attrOptions = [
      { value: "agility", label: `${game.i18n.localize("OATHHAMMER.Attribute.Agility")} (${agiRank})`,  selected: true },
      { value: "might",   label: `${game.i18n.localize("OATHHAMMER.Attribute.Might")} (${mightRank})`,   selected: false },
    ]

    const diminishOptions = [
      { value: 0,  label: game.i18n.localize("OATHHAMMER.Dialog.DiminishFirst"),  selected: true },
      { value: -2, label: game.i18n.localize("OATHHAMMER.Dialog.DiminishSecond"), selected: false },
      { value: -4, label: game.i18n.localize("OATHHAMMER.Dialog.DiminishThird"),  selected: false },
    ]

    // Default dice color: red if parry/block trait matches the default attack type, else white
    const defaultDefenseColor = (
      (defaultAttackType === "melee"  && hasParry) ||
      (defaultAttackType === "ranged" && hasBlock)
    ) ? "red" : "white"

    const bonusOptions = Array.from({ length: 13 }, (_, i) => {
      const v = i - 6
      return { value: v, label: v > 0 ? `+${v}` : String(v), selected: v === 0 }
    })

    const rollModes = foundry.utils.duplicate(CONFIG.Dice.rollModes)

    const context = {
      actorName:        actor.name,
      weaponName:       weapon.name,
      weaponImg:        weapon.img,
      agiRank,
      mightRank,
      defRank,
      hasParry,
      hasBlock,
      parryCount,
      blockCount,
      armorPenalty,
      traits:           traitLabels,
      attackTypeOptions,
      attrOptions,
      diminishOptions,
      bonusOptions,
      colorOptions:     _colorOptions(defaultDefenseColor),
      rollModes,
      visibility:       game.settings.get("core", "rollMode"),
      availableLuck,
      isHuman,
      luckOptions,
    }

    const content = await foundry.applications.handlebars.renderTemplate(
      "systems/fvtt-oath-hammer/templates/weapon-defense-dialog.hbs",
      context
    )

    const result = await foundry.applications.api.DialogV2.wait({
      window:      { title: game.i18n.format("OATHHAMMER.Dialog.WeaponDefenseTitle", { weapon: weapon.name }), resizable: true },
      classes:     ["fvtt-oath-hammer"],
      position:    { width: 420 },
      content,
      rejectClose: false,
      buttons: [{
        label:    game.i18n.localize("OATHHAMMER.Dialog.RollDefense"),
        callback: (_ev, btn) => {
          const out = {}
          for (const el of btn.form.elements) {
            if (!el.name) continue
            out[el.name] = el.type === "checkbox" ? String(el.checked) : el.value
          }
          return out
        },
      }],
    })

    if (!result) return null

    const attackType      = result.attackType ?? defaultAttackType
    const attrChoice      = result.attribute  ?? "agility"
    const attrRank        = attrChoice === "might" ? mightRank : agiRank
    const diminishPenalty = parseInt(result.diminish) || 0
    const bonus           = parseInt(result.bonus)    || 0
    const colorOverride   = result.colorOverride || defaultDefenseColor

    // Trait bonus based on selected attack type (color is now user-controlled)
    let traitBonus = 0
    if (attackType === "melee"  && hasParry) traitBonus = parryCount >= 2 ? 1 : 0
    if (attackType === "ranged" && hasBlock)  traitBonus = 1

    return {
      attackType,
      attrRank,
      attrChoice,
      colorOverride,
      traitBonus,
      armorPenalty,
      diminishPenalty,
      bonus,
      visibility:  result.visibility ?? game.settings.get("core", "rollMode"),
      explodeOn5:  result.explodeOn5 === "true",
      luckSpend:   Math.min(Math.max(0, parseInt(result.luckSpend) || 0), availableLuck),
      luckIsHuman: result.luckIsHuman === "true",
    }
  }

  // ------------------------------------------------------------------ //
  //  DAMAGE DIALOG
  // ------------------------------------------------------------------ //

  static async promptDamage(actor, weapon, defaultSV = 0) {
    const sys      = weapon.system
    const actorSys = actor.system

    const hasBrutal       = sys.traits.has("brutal")
    const hasDeadly       = sys.traits.has("deadly")
    const damageColorType = hasDeadly ? "black" : hasBrutal ? "red" : "white"
    const damageThreshold = hasDeadly ? 2 : hasBrutal ? 3 : 4
    const damageColorLabel = hasDeadly ? "⬛" : hasBrutal ? "🔴" : "⬜"
    const mightRank       = actorSys.attributes.might.rank
    const baseDamageDice  = sys.usesMight ? Math.max(mightRank + sys.damageMod, 1) : Math.max(sys.damageMod, 1)

    // Auto-bonuses from special properties
    let autoDamageBonus = 0
    if (sys.specialProperties.has("master-crafted")) autoDamageBonus += 1
    if (sys.specialProperties.has("tempered"))        autoDamageBonus += 1
    if (sys.specialProperties.has("heavy-draw"))      autoDamageBonus += 1

    const svOptions = Array.from({ length: 11 }, (_, i) => ({
      value: i,
      label: i === 0 ? "0" : `+${i}d`,
      selected: i === defaultSV,
    }))

    const damageBonusOptions = Array.from({ length: 9 }, (_, i) => {
      const v = i - 4
      return { value: v, label: v > 0 ? `+${v}` : String(v), selected: v === 0 }
    })

    const rollModes = foundry.utils.duplicate(CONFIG.Dice.rollModes)

    const context = {
      actorName:       actor.name,
      weaponName:      weapon.name,
      weaponImg:       weapon.img,
      damageLabel:     sys.damageLabel,
      damageColorType,
      damageThreshold,
      damageColorLabel,
      baseDamageDice,
      autoDamageBonus,
      apValue:         sys.ap,
      defaultSV,
      svOptions,
      damageBonusOptions,
      rollModes,
      visibility:      game.settings.get("core", "rollMode"),
    }

    const content = await foundry.applications.handlebars.renderTemplate(
      "systems/fvtt-oath-hammer/templates/weapon-damage-dialog.hbs",
      context
    )

    const result = await foundry.applications.api.DialogV2.wait({
      window:      { title: game.i18n.format("OATHHAMMER.Dialog.DamageTitle", { weapon: weapon.name }), resizable: true },
      classes:     ["fvtt-oath-hammer"],
      position:    { width: 420 },
      content,
      rejectClose: false,
      buttons: [{
        label:    game.i18n.localize("OATHHAMMER.Dialog.RollDamage"),
        callback: (_ev, btn) => Object.fromEntries(
          [...btn.form.elements].filter(e => e.name).map(e => [e.name, e.value])
        ),
      }],
    })

    if (!result) return null
    return {
      sv:           parseInt(result.sv)          || 0,
      damageBonus:  parseInt(result.damageBonus) || 0,
      visibility:   result.visibility ?? game.settings.get("core", "rollMode"),
      autoDamageBonus,
    }
  }
}

function _cap(str) {
  return str.charAt(0).toUpperCase() + str.slice(1)
}

function _colorOptions(defaultColor = "white") {
  return [
    { value: "white", label: "⬜ White (4+)", selected: defaultColor === "white" },
    { value: "red",   label: "🔴 Red (3+)",   selected: defaultColor === "red"   },
    { value: "black", label: "⬛ Black (2+)",  selected: defaultColor === "black" },
  ]
}
