import LethalFantasyUtils from "../utils.mjs"
export default class LethalFantasyActor extends Actor {

  static async create(data, options) {

    // Case of compendium global import
    if (data instanceof Array) {
      return super.create(data, options);
    }
    // If the created actor already has items (duplicated or imported) bypass the new actor creation logic.
    // Use .length check because Foundry V2 initializes data.items as an empty array by default
    // (truthy), which would incorrectly skip the layperson skill auto-population.
    if (data.items?.length > 0) {
      let actor = super.create(data, options);
      return actor;
    }

    if (data.type === 'character') {
      const skills = await LethalFantasyUtils.loadCompendium("fvtt-lethal-fantasy.lf-skills")
      data.items = data.items || []
      for (let skill of skills) {
        if (skill.system.category === "layperson") {
          data.items.push(skill.toObject())
        }
      }
    }

    return super.create(data, options);
  }

  async _preCreate(data, options, user) {
    await super._preCreate(data, options, user)

    // Configure prototype token settings
    const prototypeToken = {}
    if (this.type === "character") {
      Object.assign(prototypeToken, {
        sight: { enabled: true },
        actorLink: true,
        disposition: CONST.TOKEN_DISPOSITIONS.FRIENDLY,
      })
      this.updateSource({ prototypeToken })
    }
  }

  /* *************************************************/
  getBestWeaponClassSkill(skills, rollType, multiplier = 1.0) {
    let maxValue = 0
    let goodSkill = skills[0]
    for (let s of skills) {
      if (rollType === "weapon-attack") {
        if (s.system.weaponBonus.attack > maxValue) {
          maxValue = Number(s.system.weaponBonus.attack)
          goodSkill = s
        }
      }
      if (rollType === "weapon-defense") {
        if (s.system.weaponBonus.defense > maxValue) {
          maxValue = Number(s.system.weaponBonus.defense)
          goodSkill = s
        }
      }
      if (rollType.includes("weapon-damage")) {
        if (s.system.weaponBonus.damage > maxValue) {
          maxValue = Number(s.system.weaponBonus.damage)
          goodSkill = s
        }
      }
    }
    goodSkill.weaponSkillModifier = Math.ceil(maxValue * multiplier)
    return goodSkill
  }

  /* *************************************************/
  async applyDamage(hpLoss) {
    let hp = this.system.hp.value + hpLoss
    await this.update({ "system.hp.value": hp })
  }

  /* *************************************************/
  getNaturalDR() {
    if (this.type === "monster") {
      return Number(this.system.hp?.damageResistance) || 0
    }
    return Number(this.system.biodata?.naturalDR) || 0
  }

  /* *************************************************/
  getMagicDR() {
    if (this.type === "monster") return 0
    return Number(this.system.biodata?.magicDR) || 0
  }

  /* *************************************************/
  computeDamageReduction() {
    if (this.type === "monster") {
      let hpDR = this.getNaturalDR()
      let combatDR = Number(this.system.combat?.damageReduction) || 0
      return hpDR + combatDR
    }
    let naturalDR = this.getNaturalDR()
    let magicDR = this.getMagicDR()
    let armorDR = this.getArmorDR()
    return naturalDR + magicDR + armorDR
  }

  /* *************************************************/
  getShieldDR() {
    // Pour les monstres, utiliser combat.shieldDamageReduction
    if (this.type === "monster") {
      return Number(this.system.combat?.shieldDamageReduction) || 0
    }
    // Pour les personnages, utiliser les items de type shield
    let dr = 0
    for (let item of this.items) {
      if (item.type === "shield" && item.system.equipped) {
        dr += Number(item.system.damageReduction)
      }
    }
    return dr
  }

  /* *************************************************/
  getArmorDR() {
    let dr = 0
    for (let item of this.items) {
      if (item.type === "armor" && item.system.equipped) {
        dr += Number(item.system.damageReduction)
      }
    }
    return dr
  }

  /* *************************************************/
  getArmorDefenseValue() {
    let defenseValue = 0
    for (let item of this.items) {
      if (item.type === "armor" && item.system.equipped) {
        defenseValue += Number(item.system.defense)
      }
    }
    return defenseValue
  }

  /* *************************************************/
  fuzzyNameSearchWeaponSkills(weaponName, weaponClass = null) {
    // Get all weapon skills without the " skill" suffix
    let skills = this.items.filter((i) => i.type === "skill" && i.system.weaponClass === weaponClass && i.system.category === "weapon")
    // Remove parenthesis in the weapon name for better matching
    weaponName = weaponName.replace(/\(.*?\)/g, "").trim()
    // Now search if we find all the words of the weapon name in the skill name
    skills = skills.filter((s) => {
      let skillName = s.name.toLowerCase().replace(" skill", "").trim()
      let wName = weaponName.toLowerCase().trim()
      let wWords = wName.split(" ")
      for (let w of wWords) {
        if (!skillName.includes(w)) {
          return false
        }
      }
      return true
    })
    return skills
  }

  /* *************************************************/
  async prepareRoll(rollType, rollKey, rollDice, defenderId, defenderTokenId, extraShieldDr = 0, d30Effects = {}) {
    log("Preparing roll", rollType, rollKey, rollDice, defenderId)
    let rollTarget
    switch (rollType) {
      case "granted":
        rollTarget = {
          name: rollKey,
          formula: foundry.utils.duplicate(this.system.granted[rollKey]),
          rollKey: rollKey
        }
        if (rollTarget.formula === "" || rollTarget.formula === undefined) {
          rollTarget.formula = 0
        }
        break;
      case "challenge":
        rollTarget = foundry.utils.duplicate(this.system.challenges[rollKey])
        rollTarget.rollKey = rollKey
        break
      case "save":
        rollTarget = foundry.utils.duplicate(this.system.saves[rollKey])
        rollTarget.rollKey = rollKey
        rollTarget.rollDice = rollDice
        break
      case "spell":
        rollTarget = this.items.find((i) => i.type === "spell" && i.id === rollKey)
        rollTarget.rollKey = rollKey
        break
      case "miracle":
        rollTarget = this.items.find((i) => i.type === "miracle" && i.id === rollKey)
        rollTarget.rollKey = rollKey
        break
      case "skill":
        rollTarget = this.items.find((i) => i.type === "skill" && i.id === rollKey)
        rollTarget.rollKey = rollKey
        if (rollTarget.system.category === "weapon") {
          ui.notifications.warn(game.i18n.localize("LETHALFANTASY.Notifications.rollFromWeapon"))
          return
        }
        break
      case "spell-attack":
      case "spell-power":
      case "miracle-attack":
      case "miracle-power":
        rollTarget = foundry.utils.duplicate(this.items.find((i) => (i.type === "miracle" || i.type == "spell") && i.id === rollKey))
        rollTarget.rollKey = rollKey
        // Read damage tier from combatant currentAction if available
        const activeCombatant = game.combat?.combatants?.find(c => c.actorId === this.id)
        const currentAction = activeCombatant?.getFlag(SYSTEM.id, "currentAction")
        let damageTier = currentAction?.damageTier
        // No tier from combat action — prompt the user if multiple tiers exist
        if (!damageTier) {
          const tierMap = { standard: "damageDice", overpowered: "damageDiceOverpowered", overpowered2: "damageDiceOverpowered2" }
          const available = Object.entries(tierMap).filter(([k, v]) => rollTarget.system?.[v])
          if (available.length > 1) {
            const buttons = available.map(([id]) => ({
              action: id,
              type: "button",
              label: id.charAt(0).toUpperCase() + id.slice(1),
              callback: () => id,
            }))
            damageTier = await foundry.applications.api.DialogV2.wait({
              window: { title: "Choose spell tier" },
              classes: ["lethalfantasy"],
              content: await foundry.applications.handlebars.renderTemplate("systems/fvtt-lethal-fantasy/templates/dialogs/power-level.hbs", {itemName: rollTarget.name}),
              buttons,
              rejectClose: false,
            }) || "standard"
          } else {
            damageTier = "standard"
          }
        }
        rollTarget.damageTier = damageTier
        if (rollType === "spell-attack" || rollType === "spell-power") {
          const tierCostMap = { standard: "cost", overpowered: "costOverpowered", overpowered2: "costOverpowered2" }
          const costField = tierCostMap[damageTier] || "cost"
          const cost = Number(rollTarget.system?.[costField]) || 0
          const currentAether = Number(this.system.aetherPoints?.value) || 0
          if (cost > currentAether) {
            ui.notifications.warn(`${this.name} cannot cast ${rollTarget.name}: insufficient Aether (needs ${cost}, has ${currentAether}).`)
            return
          }
        }
        if (rollType === "miracle-attack" || rollType === "miracle-power") {
          const cost = Number(rollTarget.system?.level) || 0
          const currentGrace = Number(this.system.divinityPoints?.value) || 0
          if (cost > currentGrace) {
            ui.notifications.warn(`${this.name} cannot invoke ${rollTarget.name}: insufficient Grace (needs ${cost}, has ${currentGrace}).`)
            return
          }
        }
        break
      case "shield-roll": {
        rollTarget = this.items.find((i) => i.type === "shield" && i.id === rollKey)
        let shieldSkill = this.items.find((i) => i.type === "skill" && i.name.toLowerCase() === rollTarget.name.toLowerCase())
        rollTarget.skill = shieldSkill
        rollTarget.rollKey = rollKey
      }
        break;
      case "weapon-damage":
      case "weapon-attack":
      case "weapon-defense": {
        let weapon = this.items.find((i) => i.type === "weapon" && i.id === rollKey)
        let skill
        let skills = this.items.filter((i) => i.type === "skill" && i.system.category === "weapon" && i.name.toLowerCase() === weapon.name.toLowerCase())
        if (skills.length > 0) {
          skill = this.getBestWeaponClassSkill(skills, rollType, 1.0)
        } else {
          skills = this.fuzzyNameSearchWeaponSkills(weapon.name, weapon.system.weaponClass)
          if (skills.length > 0) {
            skill = this.getBestWeaponClassSkill(skills, rollType, 1.0)
          } else {
            skills = this.items.filter((i) => i.type === "skill" && i.system.category === "weapon" && i.system.weaponClass === weapon.system.weaponClass)
            if (skills.length > 0) {
              skill = this.getBestWeaponClassSkill(skills, rollType, 0.5)
            } else {
              skills = this.items.filter((i) => i.type === "skill" && i.system.category === "weapon" && i.system.weaponClass.includes(SYSTEM.WEAPON_CATEGORIES[weapon.system.weaponClass]))
              if (skills.length > 0) {
                skill = this.getBestWeaponClassSkill(skills, rollType, 0.25)
              } else {
                ui.notifications.warn(game.i18n.localize("LETHALFANTASY.Notifications.skillNotFound"))
                return
              }
            }
          }
        }
        if (!weapon || !skill) {
          console.error("Weapon or skill not found", weapon, skill)
          ui.notifications.warn(game.i18n.localize("LETHALFANTASY.Notifications.skillNotFound"))
          return
        }
        // Créer un objet plain au lieu de modifier directement le skill
        rollTarget = {
          ...skill,
          weapon: weapon,
          weaponSkillModifier: skill.weaponSkillModifier,
          rollKey: rollKey,
          combat: foundry.utils.duplicate(this.system.combat),
          isRangedAttack: weapon.system.weaponType === "ranged"
        }
        if (rollType === "weapon-damage") {
          rollTarget.grantedDice = this.system.granted.damageDice
        }
        if (rollType === "weapon-attack") {
          rollTarget.grantedDice = this.system.granted.attackDice
        }
        if (rollType === "weapon-defense") {
          rollTarget.armorDefense = this.getArmorDefenseValue()
          rollTarget.grantedDice = this.system.granted.defenseDice
          // Check if this is a ranged defense
          rollTarget.isRangedDefense = game.lethalFantasy?.nextDefenseData?.isRanged ?? false
        }
      }
        break
      default:
        ui.notifications.error(game.i18n.localize("LETHALFANTASY.Notifications.rollTypeNotFound") + String(rollType))
        return
    }

    // In all cases
    rollTarget.magicUser = this.system.biodata.magicUser
    rollTarget.actorModifiers = foundry.utils.duplicate(this.system.modifiers)
    rollTarget.actorLevel = this.system.biodata.level
    await this.system.roll(rollType, rollTarget, defenderId, defenderTokenId, extraShieldDr, d30Effects)
  }

}
