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

export default class MournbladeInvocationEspritDialog {

  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 => MournbladeInvocationEspritDialog._normalize(k))
    return actor.items.find(item => {
      if (item.type !== "competence") return false
      const norm = MournbladeInvocationEspritDialog._normalize(item.name)
      return normKeys.every(k => norm.includes(k))
    }) ?? null
  }

  /** Seuil and soul cost per puissance */
  static SEUILS = { mineur: 15, median: 20, majeur: 25 }

  static async create(actor, rollData) {
    const ameDisponible = Math.max(0, actor.system.ame.currentmax - actor.system.ame.value)

    const persuasionComp = MournbladeInvocationEspritDialog._findCompetence(actor, "persuasion")
    const hautParlerComp = MournbladeInvocationEspritDialog._findCompetence(actor, "haut", "parler")
    const loiChaosComp   = MournbladeInvocationEspritDialog._findCompetence(actor, "loi", "chaos")

    const isLoyal = actor.system.balance.loi > actor.system.balance.chaos
    const hasRuneLoi = actor.items.some(i =>
      i.type === "rune" && MournbladeInvocationEspritDialog._normalize(i.name).includes("loi")
    )
    const prerequisOk = isLoyal && hasRuneLoi

    const automatonTypes = {
      combat:      "Combat",
      voyage:      "Voyage",
      perception:  "Perception",
      restauration:"Restauration",
      reparateur:  "Réparateur",
    }

    const context = {
      ...rollData,
      img: actor.img,
      name: actor.name,
      ameDisponible,
      treValeur: actor.system.attributs?.tre?.value ?? 0,
      persuasionNiveau: persuasionComp?.system?.niveau ?? null,
      hautParlerNiveau: hautParlerComp?.system?.niveau ?? null,
      loiChaosNiveau:   loiChaosComp?.system?.niveau ?? null,
      isLoyal,
      hasRuneLoi,
      prerequisOk,
      automatonTypes,
      seuils: MournbladeInvocationEspritDialog.SEUILS,
      modOptions: Array.from({ length: 21 }, (_, i) => i - 10),
    }

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

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

    return foundry.applications.api.DialogV2.wait({
      window: { title: "Invoquer un Esprit de la Loi", icon: "fa-solid fa-star" },
      classes: ["mournblade-roll-dialog"],
      position: { width: 520 },
      modal: false,
      content,
      buttons: [
        {
          action: "invoquer",
          label: "Invoquer",
          icon: "fa-solid fa-star",
          default: true,
          callback: async (event, button, dialog) => {
            MournbladeInvocationEspritDialog._updateRollData(rollData, button.form.elements, actor, {
              persuasionComp, hautParlerComp, loiChaosComp
            })
            await MournbladeUtility.rollInvocationEsprit(rollData)
          }
        },
      ],
      rejectClose: false,
    })
  }

  static _attachListeners(html, ameDisponible, prerequisOk = true) {
    const invoquerBtn = html.querySelector('button[data-action="invoquer"]')
    if (invoquerBtn) invoquerBtn.disabled = !prerequisOk

    const puissanceEl = html.querySelector('[name="puissance"]')
    const seuilEl     = html.querySelector('#esprit-seuil-total')
    const coutEl      = html.querySelector('#esprit-cout-ame')
    const hiddenEl    = html.querySelector('#esprit-seuil-hidden')
    const warnEl      = html.querySelector('#esprit-ame-warn')
    const dureeEl     = html.querySelector('#esprit-duree')

    const DUREE = { mineur: "1 heure", median: "1 jour", majeur: "1 semaine" }

    const recalculate = () => {
      const puissance = puissanceEl?.value ?? "mineur"
      const seuil = MournbladeInvocationEspritDialog.SEUILS[puissance] ?? 15
      if (seuilEl)  seuilEl.textContent = seuil
      if (coutEl)   coutEl.textContent  = seuil
      if (hiddenEl) hiddenEl.value = seuil
      if (dureeEl)  dureeEl.textContent = DUREE[puissance] ?? "1 heure"
      if (warnEl)   warnEl.style.display = seuil > ameDisponible ? "" : "none"
    }

    if (puissanceEl) puissanceEl.addEventListener("change", recalculate)
    recalculate()
  }

  static _updateRollData(rollData, formElements, actor, { persuasionComp }) {
    const seuil       = parseInt(formElements["seuil"]?.value ?? 15)
    const modificateur = parseInt(formElements["modificateur"]?.value ?? 0)
    const automatonType  = formElements["automatonType"]?.value ?? "combat"
    const puissance      = formElements["puissance"]?.value ?? "mineur"

    rollData.invocationSeuil     = seuil
    rollData.invocationSoulCost  = seuil
    rollData.difficulte          = seuil
    rollData.modificateur        = modificateur
    rollData.competence          = persuasionComp ?? null
    rollData.automatonType       = automatonType
    rollData.automatonPuissance  = puissance
  }
}
