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 has items (only applicable to duplicated actors) bypass the new actor creation logic
    if (data.items) {
      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
    if (hp < 0) {
      hp = 0
    }
    this.update({ "system.hp.value": hp })
  }

  /* *************************************************/
  computeDamageReduction() {
    // Pour les monstres, utiliser hp.damageResistance et combat.damageReduction
    if (this.type === "monster") {
      let hpDR = Number(this.system.hp?.damageResistance) || 0
      let combatDR = Number(this.system.combat?.damageReduction) || 0
      return hpDR + combatDR
    }
    // Pour les personnages, utiliser biodata et items
    let naturalDR = Number(this.system.biodata?.naturalDR) || 0
    let magicDR = Number(this.system.biodata?.magicDR) || 0
    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) {
    console.log("Preparing roll", rollType, rollKey, rollDice)
    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 = this.items.find((i) => (i.type === "miracle" || i.type == "spell") && i.id === rollKey)
        rollTarget.rollKey = rollKey
        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-small":
      case "weapon-damage-medium":
      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)
        }
        if (rollType === "weapon-damage-small" || rollType === "weapon-damage-medium") {
          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
        }
      }
        break
      default:
        ui.notifications.error(game.i18n.localize("LETHALFANTASY.Notifications.rollTypeNotFound") + String(rollType))
        break
    }

    // 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)
  }

}
