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

export default class HamalronSortilegeCasting {
  static CHAT_TEMPLATE = "systems/fvtt-hamalron/templates/chat-sortilege.hbs"
  static DIALOG_TEMPLATE = "systems/fvtt-hamalron/templates/dialog-sortilege-casting.hbs"

  static getModificateur(categorie, niveau) {
    const mods = SYSTEM.SORTILEGE_MODIFICATEURS[niveau]
    return mods?.[categorie] ?? 0
  }

  static getRangMagie(actor) {
    return actor.system.rangMagie || "initie"
  }

  static getEchecMagique(valeurCarteMJ, rang) {
    const rangs = ["ensorceleur", "initie", "thaumaturge"]
    const idx = rangs.indexOf(rang)
    if (idx === -1) return "normal"
    const paliers = [
      { max: 10, resultats: ["normal", "normal", "normal"] },
      { max: 13, resultats: ["critique", "normal", "normal"] },
      { max: 16, resultats: ["critique", "normal", "normal"] },
      { max: 19, resultats: ["critique", "critique", "normal"] },
      { max: 23, resultats: ["critique", "critique", "critique"] },
    ]
    for (const palier of paliers) {
      if (valeurCarteMJ <= palier.max) {
        return palier.resultats[idx]
      }
    }
    return "critique"
  }

  static async prompt(spellItem, actor) {
    const atouts = actor.items.filter(i => i.type === "tarot" && i.system.type === "atout")
    const rang = HamalronSortilegeCasting.getRangMagie(actor)
    const peutUtiliserCoupe = rang === "thaumaturge"
    const cartesCoupe = peutUtiliserCoupe
      ? actor.items.filter(i => i.type === "tarot" && i.system.symbole === "coupe" && i.system.type !== "atout")
      : []

    if (atouts.length === 0) {
      ui.notifications.warn(game.i18n.localize("HAMALRON.Sortilege.noAtout"))
      return
    }

    const niveauData = SYSTEM.NIVEAU_COMPETENCES[spellItem.system.niveauRequis]
    const niveau = niveauData?.id || spellItem.system.niveauRequis
    const modificateur = HamalronSortilegeCasting.getModificateur(spellItem.system.categorie, niveau)

    const categorieLabel = SYSTEM.SORTILEGE_CATEGORIES[spellItem.system.categorie]?.label || spellItem.system.categorie
    const niveauLabel = niveauData?.name || spellItem.system.niveauRequis
    const dialogContext = {
      spell: spellItem,
      actorName: actor.name,
      actorImage: actor.img,
      rang: rang,
      rangLabel: SYSTEM.RANG_MAGICIEN[rang]?.label || rang,
      categorieLabel,
      niveauLabel,
      modificateur: modificateur >= 0 ? `+${modificateur}` : modificateur,
      peutUtiliserCoupe,
      atouts: atouts.map(c => ({
        id: c.id,
        name: c.name,
        img: c.img,
        valeur: c.system.valeur,
        valeurNumerique: HamalronSortilegeCasting.#valeurNumerique(c.system.valeur),
      })),
      cartesCoupe: cartesCoupe.map(c => ({
        id: c.id,
        name: c.name,
        img: c.img,
        valeur: c.system.valeur,
        valeurNumerique: HamalronSortilegeCasting.#valeurNumerique(c.system.valeur),
      })),
    }

    const content = await foundry.applications.handlebars.renderTemplate(
      HamalronSortilegeCasting.DIALOG_TEMPLATE, dialogContext
    )

    const result = await foundry.applications.api.DialogV2.wait({
      window: { title: `${game.i18n.localize("HAMALRON.Sortilege.cast")}: ${spellItem.name}` },
      classes: ["fvtt-hamalron"],
      position: { width: 520 },
      content,
      buttons: [
        {
          action: "cancel",
          label: game.i18n.localize("Cancel"),
          default: false,
        },
        {
          action: "cast",
          label: game.i18n.localize("HAMALRON.Sortilege.cast"),
          default: true,
          disabled: true,
          callback: (event, button, dialog) => {
            const form = button.form.elements
            const carteMJ = Number(form["carte-mj"].value) || 0
            const selectedAtouts = Array.from(form.querySelectorAll('input[name="atout"]:checked'))
              .map(el => atouts.find(c => c.id === el.value))
              .filter(Boolean)
            const selectedCoupe = Array.from(form.querySelectorAll('input[name="coupe"]:checked'))
              .map(el => cartesCoupe.find(c => c.id === el.value))
              .filter(Boolean)
            return { carteMJ, selectedAtouts, selectedCoupe }
          },
        },
      ],
      actions: {},
      rejectClose: false,
      render: (event, dialog) => {
        const calcTotal = () => {
          const carteMJ = Number(document.getElementById("carte-mj")?.value || 0)
          const atoutTotal = Array.from(document.querySelectorAll('input[name="atout"]:checked'))
            .reduce((sum, el) => sum + (Number(el.dataset.value) || 0), 0)
          const coupeTotal = Array.from(document.querySelectorAll('input[name="coupe"]:checked'))
            .reduce((sum, el) => sum + (Number(el.dataset.value) || 0), 0)
          const total = atoutTotal + coupeTotal
          const difficulte = carteMJ + modificateur
          document.getElementById("total-atouts").textContent = String(atoutTotal)
          document.getElementById("total-coupe").textContent = String(coupeTotal)
          document.getElementById("total-joueur").textContent = String(total)
          document.getElementById("difficulte-totale").textContent = String(difficulte)
          const castBtn = document.querySelector("button[data-action='cast']")
          const peutLancer = atoutTotal > 0 && carteMJ > 0
          castBtn.disabled = !peutLancer
        }

        document.querySelectorAll('input[name="atout"], input[name="coupe"], #carte-mj')
          .forEach(el => el.addEventListener("change", calcTotal))

        document.getElementById("draw-card-btn")?.addEventListener("click", async () => {
          const module = await import("./tarot-deck-manager.mjs")
          const HamalronTarotDeckManager = module.default
          if (!HamalronTarotDeckManager._instance) {
            HamalronTarotDeckManager._instance = new HamalronTarotDeckManager()
          }
          const cards = HamalronTarotDeckManager._instance.drawCards(1)
          if (cards.length > 0) {
            const valeurData = SYSTEM.TAROT_VALEURS[cards[0].valeur]
            const value = valeurData?.value || 0
            document.getElementById("carte-mj").value = String(value)
            document.getElementById("carte-mj-nom").textContent = `${cards[0].name} (${value})`
            calcTotal()
          }
        })

        calcTotal()
      },
    })

    if (!result) return
    if (result.carteMJ === 0 || result.selectedAtouts.length === 0) return

    const totalAtouts = result.selectedAtouts.reduce((sum, c) => {
      return sum + (HamalronSortilegeCasting.#valeurNumerique(c.system.valeur) || 0)
    }, 0)
    const totalCoupe = result.selectedCoupe.reduce((sum, c) => {
      return sum + (HamalronSortilegeCasting.#valeurNumerique(c.system.valeur) || 0)
    }, 0)
    const totalJoueur = totalAtouts + totalCoupe
    const difficulte = result.carteMJ + modificateur
    const isSuccess = totalJoueur >= difficulte

    const deckModule = await import("./tarot-deck-manager.mjs")
    const HamalronTarotDeckManager = deckModule.default
    if (!HamalronTarotDeckManager._instance) {
      HamalronTarotDeckManager._instance = new HamalronTarotDeckManager()
    }
    const deckManager = HamalronTarotDeckManager._instance

    if (!isSuccess) {
      const echecType = HamalronSortilegeCasting.getEchecMagique(result.carteMJ, rang)
      const nbCartesADefausser = Math.max(1, result.selectedAtouts.length)

      for (let i = 0; i < nbCartesADefausser && i < result.selectedAtouts.length; i++) {
        const cardToDiscard = result.selectedAtouts[i]
        deckManager.addToDiscard({
          id: cardToDiscard.id,
          name: cardToDiscard.name,
          img: cardToDiscard.img,
          symbole: cardToDiscard.system.symbole,
          valeur: cardToDiscard.system.valeur,
          type: cardToDiscard.system.type,
        })
        const cardItem = actor.items.get(cardToDiscard.id)
        if (cardItem) {
          await actor.deleteEmbeddedDocuments("Item", [cardItem.id])
        }
      }

      const chatDataFail = {
        cssClass: [SYSTEM.id, "sortilege-roll"].join(" "),
        isSuccess: false,
        isNormal: echecType === "normal",
        isCritique: echecType === "critique",
        actingCharImg: actor.img,
        actingCharName: actor.name,
        spell: spellItem,
        categorieLabel,
        niveauLabel,
        atoutsUtilises: result.selectedAtouts,
        cartesCoupeUtilisees: result.selectedCoupe,
        carteMJ: result.carteMJ,
        modificateur,
        difficulte,
        totalJoueur,
      }
      const failContent = await foundry.applications.handlebars.renderTemplate(
        HamalronSortilegeCasting.CHAT_TEMPLATE, chatDataFail
      )
      await ChatMessage.create({
        user: game.user.id,
        speaker: ChatMessage.getSpeaker({ actor }),
        content: failContent,
        style: CONST.CHAT_MESSAGE_STYLES.OTHER,
      })

      await deckManager.saveDeckState()
      deckManager.render()
      return
    }

    for (const card of [...result.selectedAtouts, ...result.selectedCoupe]) {
      deckManager.addToDiscard({
        id: card.id,
        name: card.name,
        img: card.img,
        symbole: card.system.symbole,
        valeur: card.system.valeur,
        type: card.system.type,
      })
      const cardItem = actor.items.get(card.id)
      if (cardItem) {
        await actor.deleteEmbeddedDocuments("Item", [card.id])
      }
    }

    const nbCartesAPiocher = result.selectedAtouts.length + result.selectedCoupe.length
    for (let i = 0; i < nbCartesAPiocher; i++) {
      if (deckManager.deck.length > 0) {
        const drawn = deckManager.drawCards(1)
        if (drawn.length > 0) {
          const originalItem = await HamalronUtils.findTarotItem(drawn[0])
          if (originalItem) {
            await actor.createEmbeddedDocuments("Item", [originalItem.toObject()])
          }
        }
      }
    }

    const chatDataSuccess = {
      cssClass: [SYSTEM.id, "sortilege-roll"].join(" "),
      isSuccess: true,
      actingCharImg: actor.img,
      actingCharName: actor.name,
      spell: spellItem,
      categorieLabel,
      niveauLabel,
      atoutsUtilises: result.selectedAtouts,
      cartesCoupeUtilisees: result.selectedCoupe,
      carteMJ: result.carteMJ,
      modificateur,
      difficulte,
      totalJoueur,
    }
    const chatContent = await foundry.applications.handlebars.renderTemplate(
      HamalronSortilegeCasting.CHAT_TEMPLATE, chatDataSuccess
    )
    await ChatMessage.create({
      user: game.user.id,
      speaker: ChatMessage.getSpeaker({ actor }),
      content: chatContent,
      style: CONST.CHAT_MESSAGE_STYLES.OTHER,
    })

    await deckManager.saveDeckState()
    deckManager.render()
  }

  static #valeurNumerique(valeur) {
    const data = SYSTEM.TAROT_VALEURS[valeur]
    return data?.value ?? (Number.parseInt(valeur) || 0)
  }
}
