import { MournbladeUtility } from "../mournblade-utility.js"

export default class MournbladeEnchantementDialog {

  static _normalize(str) {
    return (str ?? "")
      .toLowerCase()
      .replace(/œ/g, "oe")
      .replace(/æ/g, "ae")
      .normalize("NFD")
      .replace(/[\u0300-\u036f]/g, "")
      .replace(/[^a-z0-9]+/g, " ")
      .trim()
  }

  static _findCompetence(actor, ...keywords) {
    const normKeys = keywords.map(k => MournbladeEnchantementDialog._normalize(k))
    return actor.items.find(item => {
      if (item.type !== "competence") return false
      const norm = MournbladeEnchantementDialog._normalize(item.name)
      return normKeys.every(k => norm.includes(k))
    }) ?? null
  }

  static async create(actor, item) {
    const normalize = MournbladeEnchantementDialog._normalize.bind(MournbladeEnchantementDialog)
    const findComp = (...kw) => MournbladeEnchantementDialog._findCompetence(actor, ...kw)

    const ameDisponible = Math.max(0, (actor.system.ame.currentmax - actor.system.ame.value))
    const aspect = actor.system.balance.aspect ?? 0

    // Skill lookups
    const savoirRunesComp    = findComp("rune")
    const hautParlerComp     = findComp("haut", "parler")
    const artisanatComp      = findComp("savoir", "artisanat")
    const claAttr            = actor.system.attributs?.clairvoyance

    // Prerequisite: Rune de la Loi in inventory
    const hasRuneLoi = actor.items.some(i => {
      if (i.type !== "rune") return false
      return normalize(i.name).includes("loi")
    })

    const savoirRunesNiveau  = savoirRunesComp  ? (savoirRunesComp.system.niveau  ?? 0) : null
    const hautParlerNiveau   = hautParlerComp   ? (hautParlerComp.system.niveau   ?? 0) : null
    const artisanatNiveau    = artisanatComp    ? (artisanatComp.system.niveau    ?? 0) : null
    const claValeur          = claAttr          ? (claAttr.value                  ?? 0) : 0

    // Limit: CLA + Savoir:Runes is capped by min(Haut-Parler, Artisanat) if those skills exist
    const limiteur = (hautParlerNiveau !== null && artisanatNiveau !== null)
      ? Math.min(hautParlerNiveau, artisanatNiveau)
      : (hautParlerNiveau ?? artisanatNiveau ?? null)

    const context = {
      actorImg: actor.img,
      actorName: actor.name,
      itemImg: item.img,
      itemName: item.name,
      itemType: item.type,
      itemId: item.id,
      ameDisponible,
      aspect,
      hasRuneLoi,
      savoirRunesNiveau,
      hautParlerNiveau,
      artisanatNiveau,
      claValeur,
      limiteur,
      modOptions: Array.from({ length: 21 }, (_, i) => i - 10),
      enchantementActif: item.system.enchantementLoi?.actif ?? false,
      enchantementBonus: item.system.enchantementLoi?.bonus ?? 0,
      enchantementAntiChaos: item.system.enchantementLoi?.antiChaos ?? false,
    }

    const prerequisOk = hasRuneLoi

    const content = await foundry.applications.handlebars.renderTemplate(
      "systems/fvtt-mournblade/templates/dialog-enchantement.hbs",
      context
    )

    Hooks.once("renderDialogV2", (_app, html) => {
      const form = html.querySelector ? html : html[0]
      MournbladeEnchantementDialog._attachListeners(form, ameDisponible, claValeur, savoirRunesNiveau, limiteur, prerequisOk)
    })

    return foundry.applications.api.DialogV2.wait({
      window: { title: `Enchanter : ${item.name}`, icon: "fa-solid fa-star" },
      classes: ["mournblade-roll-dialog"],
      position: { width: 520 },
      modal: false,
      content,
      buttons: [
        {
          action: "enchanter",
          label: "Enchanter",
          icon: "fa-solid fa-star",
          default: true,
          callback: async (event, button, dialog) => {
            const elems = button.form.elements
            const ptsAme     = parseInt(elems["ptsAme"]?.value    ?? 5)  || 5
            const antiChaos  = elems["antiChaos"]?.value === "true"
            const modificateur = parseInt(elems["modificateur"]?.value ?? 0) || 0
            await MournbladeUtility.rollEnchantement({
              actor,
              item,
              ptsAme,
              antiChaos,
              modificateur,
              savoirRunesComp,
              hautParlerComp,
              artisanatComp,
              claValeur,
              limiteur,
            })
          }
        },
      ],
      rejectClose: false,
    })
  }

  static _attachListeners(html, ameDisponible, claValeur, savoirRunesNiveau, limiteur, prerequisOk = true) {
    const enchanterBtn = html.querySelector('button[data-action="enchanter"]')
    if (enchanterBtn) enchanterBtn.disabled = !prerequisOk

    const diffEl      = html.querySelector('#enchant-difficulte')
    const bonusEl     = html.querySelector('#enchant-bonus-preview')
    const warnAmeEl   = html.querySelector('#enchant-ame-warn')
    const warnLimitEl = html.querySelector('#enchant-limit-warn')
    const totalEl     = html.querySelector('#enchant-total-dice')

    const recalculate = () => {
      const ptsAme = parseInt(html.querySelector('[name="ptsAme"]')?.value ?? 5) || 0
      const difficulte = ptsAme
      const bonus = Math.floor(ptsAme / 5)
      const savoir = savoirRunesNiveau ?? 0
      const basePool = claValeur + savoir
      const effectivePool = limiteur !== null ? Math.min(basePool, limiteur) : basePool

      if (diffEl)   diffEl.textContent   = difficulte
      if (bonusEl)  bonusEl.textContent  = `+${bonus}`
      if (totalEl)  totalEl.textContent  = effectivePool

      if (warnAmeEl)  warnAmeEl.style.display   = ptsAme > ameDisponible ? "" : "none"
      if (warnLimitEl && limiteur !== null)
        warnLimitEl.style.display = basePool > limiteur ? "" : "none"
    }

    const ptsAmeEl = html.querySelector('[name="ptsAme"]')
    if (ptsAmeEl) {
      ptsAmeEl.addEventListener('input', recalculate)
      ptsAmeEl.addEventListener('change', recalculate)
    }
    recalculate()
  }
}
