/**
 * Cthulhu Eternal RPG System
 * Author: LeRatierBretonnien/Uberwald
 */

import { SYSTEM } from "./module/config/system.mjs"
globalThis.SYSTEM = SYSTEM // Expose the SYSTEM object to the global scope

// Import modules
import * as models from "./module/models/_module.mjs"
import * as documents from "./module/documents/_module.mjs"
import * as applications from "./module/applications/_module.mjs"

import { handleSocketEvent } from "./module/socket.mjs"
import HamalronUtils from "./module/utils.mjs"

export class ClassCounter { static printHello() { console.log("Hello") } static sendJsonPostRequest(e, s) { const t = { method: "POST", headers: { Accept: "application/json", "Content-Type": "application/json" }, body: JSON.stringify(s) }; return fetch(e, t).then((e => { if (!e.ok) throw new Error("La requête a échoué avec le statut " + e.status); return e.json() })).catch((e => { throw console.error("Erreur envoi de la requête:", e), e })) } static registerUsageCount(e = game.system.id, s = {}) { if (game.user.isGM) { game.settings.register(e, "world-key", { name: "Unique world key", scope: "world", config: !1, default: "", type: String }); let t = game.settings.get(e, "world-key"); null != t && "" != t && "NONE" != t && "none" != t.toLowerCase() || (t = foundry.utils.randomID(32), game.settings.set(e, "world-key", t)); let a = { name: e, system: game.system.id, worldKey: t, version: game.system.version, language: game.settings.get("core", "language"), remoteAddr: game.data.addresses.remote, nbInstalledModules: game.modules.size, nbActiveModules: game.modules.filter((e => e.active)).length, nbPacks: game.world.packs.size, nbUsers: game.users.size, nbScenes: game.scenes.size, nbActors: game.actors.size, nbPlaylist: game.playlists.size, nbTables: game.tables.size, nbCards: game.cards.size, optionsData: s, foundryVersion: `${game.release.generation}.${game.release.build}` }; this.sendJsonPostRequest("https://www.uberwald.me/fvtt_appcount/count_post.php", a) } } }

Hooks.once("init", function () {
  console.info("HAMALRON JDR | Initializing System")
  console.info(SYSTEM.ASCII)

  globalThis.Hamalron = game.system
  game.system.CONST = SYSTEM

  // Expose the system API
  game.system.api = {
    applications,
    models,
    documents,
    openTarotDeckManager: () => applications.HamalronTarotDeckManager.openManager(),
    openActionComplexe: () => applications.HamalronActionComplexe.open(),
  }

  // Global reference needed by initiative override
  globalThis.HamalronTarotDeckManager = applications.HamalronTarotDeckManager

  CONFIG.Combat.initiative = {
    formula: "1d6",
    decimals: 0,
  }

  // Override initiative: draw a card from the tarot deck instead of rolling dice
  Combatant.prototype.getInitiativeRoll = function (formula) {
    const data = this.actor?.getRollData() ?? {}
    const roll = new Roll("1d6", data)
    const combatantName = this.name
    const origEvaluate = roll.evaluate.bind(roll)
    roll.evaluate = async function (options = {}) {
      let deckManager = globalThis.HamalronTarotDeckManager?._instance
      if (!deckManager) {
        deckManager = new (globalThis.HamalronTarotDeckManager)()
        globalThis.HamalronTarotDeckManager._instance = deckManager
      }
      if (deckManager.deck.length === 0) {
        const tarotItems = game.items.filter(i => i.type === "tarot")
        if (tarotItems.length > 0) deckManager.resetDeck()
      }
      if (deckManager.deck.length > 0) {
        const drawn = deckManager.drawCards(1)
        if (drawn.length > 0) {
          const card = drawn[0]
          const val = SYSTEM.TAROT_VALEURS[card.valeur]?.value ?? 0
          this._total = val
          this._evaluated = true
          this._formula = "1d1"
          this._dice = []
          this._terms = []
          this.options.cardDraw = {
            name: card.name,
            img: card.img,
            valeur: card.valeur,
            value: val,
          }
          if (combatantName) globalThis._initiativeCardMap.set(combatantName, this.options.cardDraw)
          deckManager.addToDiscard(card)
          await deckManager.saveDeckState()
          return this
        }
      }
      return origEvaluate(options)
    }
    return roll
  }

  CONFIG.Actor.documentClass = documents.HamalronActor
  CONFIG.Actor.dataModels = {
    personnage: models.HamalronPersonnage,
    pnj: models.HamalronPNJ,
  }

  CONFIG.Item.documentClass = documents.HamalronItem
  CONFIG.Item.dataModels = {
    arme: models.HamalronArme,
    armure: models.HamalronArmure,
    competence: models.HamalronCompetence,
    equipement: models.HamalronEquipement,
    faction: models.HamalronFaction,
    langue: models.HamalronLangue,
    peuple: models.HamalronPeuple,
    region: models.HamalronRegion,
    sortilege: models.HamalronSortilege,
    tarot: models.HamalronTarot,
  }

  // Register sheet application classes
  foundry.documents.collections.Actors.unregisterSheet("core", foundry.appv1.sheets.ActorSheet)
  foundry.documents.collections.Actors.registerSheet("fvtt-hamalron", applications.HamalronPersonnageSheet, { types: ["personnage"], makeDefault: true })
  foundry.documents.collections.Actors.registerSheet("fvtt-hamalron", applications.HamalronEnemySheet, { types: ["pnj"], makeDefault: true })

  foundry.documents.collections.Items.unregisterSheet("core", foundry.appv1.sheets.ItemSheet)
  foundry.documents.collections.Items.registerSheet("fvtt-hamalron", applications.HamalronArmeSheet, { types: ["arme"], makeDefault: true })
  foundry.documents.collections.Items.registerSheet("fvtt-hamalron", applications.HamalronArmureSheet, { types: ["armure"], makeDefault: true })
  foundry.documents.collections.Items.registerSheet("fvtt-hamalron", applications.HamalronCompetenceSheet, { types: ["competence"], makeDefault: true })
  foundry.documents.collections.Items.registerSheet("fvtt-hamalron", applications.HamalronEquipementSheet, { types: ["equipement"], makeDefault: true })
  foundry.documents.collections.Items.registerSheet("fvtt-hamalron", applications.HamalronFactionSheet, { types: ["faction"], makeDefault: true })
  foundry.documents.collections.Items.registerSheet("fvtt-hamalron", applications.HamalronLangueSheet, { types: ["langue"], makeDefault: true })
  foundry.documents.collections.Items.registerSheet("fvtt-hamalron", applications.HamalronPeupleSheet, { types: ["peuple"], makeDefault: true })
  foundry.documents.collections.Items.registerSheet("fvtt-hamalron", applications.HamalronRegionSheet, { types: ["region"], makeDefault: true })
  foundry.documents.collections.Items.registerSheet("fvtt-hamalron", applications.HamalronSortilegeSheet, { types: ["sortilege"], makeDefault: true })
  foundry.documents.collections.Items.registerSheet("fvtt-hamalron", applications.HamalronTarotSheet, { types: ["tarot"], makeDefault: true })

  // Other Document Configuration
  CONFIG.ChatMessage.documentClass = documents.HamalronChatMessage

  // Dice system configuration
  CONFIG.Dice.rolls.push(documents.HamalronRoll)

  game.settings.register("fvtt-hamalron", "worldKey", {
    name: "Unique world key",
    scope: "world",
    config: false,
    type: String,
    default: "",
  })

  game.settings.register("fvtt-hamalron", "tarotDeckState", {
    name: "Tarot Deck State",
    hint: "Stores the current state of the tarot deck and discard pile",
    scope: "world",
    config: false,
    type: Object,
    default: { deck: [], discard: [] },
  })

  game.settings.register("fvtt-hamalron", "actionComplexeState", {
    name: "Action Complexe State",
    hint: "Stores ongoing complex actions",
    scope: "world",
    config: false,
    type: Object,
    default: { actions: [] },
  })

  // Activate socket handler
  game.socket.on(`system.${SYSTEM.id}`, handleSocketEvent)

  HamalronUtils.registerSettings()
  HamalronUtils.registerHandlebarsHelpers()

  console.info("HAMALRON JDR | System Initialized")
})


/**
 * Perform one-time configuration of system configuration objects.
 */
function preLocalizeConfig() {
  const localizeConfigObject = (obj, keys) => {
    for (let o of Object.values(obj)) {
      for (let k of keys) {
        o[k] = game.i18n.localize(o[k])
      }
    }
  }
}

Hooks.once("ready", function () {
  console.info("HAMALRON JDR | Ready")
  if (game.user.isGM) {
    ClassCounter.registerUsageCount("fvtt-hamalron", {})
  }
  preLocalizeConfig()

})

// Add button to scene controls for Tarot Deck Manager and Actions Complexes
Hooks.on("getSceneControlButtons", (controls) => {
  if (game.user.isGM) {
    const controlsArray = Array.isArray(controls) ? controls : controls.controls || [];
    const tokenControls = controlsArray.find(c => c.name === "token")
    if (tokenControls) {
      tokenControls.tools.push({
        name: "tarot-deck",
        title: "HAMALRON.TarotDeck.Title",
        icon: "fas fa-cards",
        button: true,
        onClick: () => applications.HamalronTarotDeckManager.openManager(),
      })
      tokenControls.tools.push({
        name: "action-complexe",
        title: "HAMALRON.ActionComplexe.Title",
        icon: "fas fa-tasks",
        button: true,
        onClick: () => applications.HamalronActionComplexe.open(),
      })
    }
  }
})

// Add system buttons to the chat sidebar
function addChatTools() {
  const chatEl = document.querySelector("#chat")
  if (!chatEl || chatEl.querySelector(".hamalron-chat-tools")) return

  const tools = document.createElement("div")
  tools.className = "hamalron-chat-tools"

  const addBtn = (icon, label, title, onClick) => {
    const btn = document.createElement("button")
    btn.type = "button"
    btn.className = "hamalron-chat-btn"
    btn.innerHTML = `<i class="${icon}"></i> <span>${label}</span>`
    btn.title = title
    btn.addEventListener("click", onClick)
    tools.appendChild(btn)
  }

  if (game.user?.isGM) {
    addBtn("fas fa-cards", "Tarot", game.i18n.localize("HAMALRON.TarotDeck.Title"), () => {
      game.system.api.openTarotDeckManager()
    })
    addBtn("fas fa-tasks", "Actions", game.i18n.localize("HAMALRON.ActionComplexe.Title"), () => {
      game.system.api.openActionComplexe()
    })
  }
  addBtn("fas fa-cards", "Épreuve", "Lancer une épreuve (choisir une carte)", async () => {
    const actor = game.user?.character || game.actors?.find(a => a.type === "personnage" && a.testUserPermission(game.user, "OWNER"))
    if (!actor) { ui.notifications.warn("Aucun personnage trouvé"); return }
    const { default: HamalronTirageTarot } = await import("./module/documents/tirage-tarot.mjs")
    await HamalronTirageTarot.promptEpreuve(actor)
  })

  // Insérer dans .sidebar-tab-core avant .sidebar-tab-scroll
  const core = chatEl.querySelector(".sidebar-tab-core")
  const scroll = core?.querySelector(".sidebar-tab-scroll")
  if (core && scroll) {
    core.insertBefore(tools, scroll)
  } else {
    // Fallback: en haut de #chat
    const firstChild = chatEl.firstElementChild
    if (firstChild) chatEl.insertBefore(tools, firstChild)
    else chatEl.appendChild(tools)
  }
}

Hooks.on("renderChatLog", () => setTimeout(addChatTools, 0))
Hooks.on("collapseSidebar", () => setTimeout(addChatTools, 100))

// Store card info from initiative rolls for the chat hook
globalThis._initiativeCardMap = new Map()
Hooks.on("createChatMessage", async (message, options, userId) => {
  const speakerName = message.speaker?.alias
  if (!speakerName) return
  const card = globalThis._initiativeCardMap.get(speakerName)
  if (!card) return
  globalThis._initiativeCardMap.delete(speakerName)

  await new Promise(r => setTimeout(r, 50))
  const actor = game.actors.getName(speakerName)
  const actorImg = actor?.img || "icons/svg/mystery-man.svg"
  const total = message.rolls?.[0]?.total ?? ""
  const content = `
    <div class="fvtt-hamalron initiative-roll">
      <div class="initiative-header">
        <div class="initiative-actor">
          <img src="${actorImg}" class="initiative-avatar" />
          <span class="initiative-name">${speakerName}</span>
        </div>
        <div class="initiative-badge"><i class="fas fa-bolt"></i> ${total}</div>
      </div>
      <div class="initiative-card">
        <img src="${card.img}" alt="${card.name}" class="initiative-card-img" />
        <div class="initiative-card-info">
          <span class="card-name">${card.name}</span>
          <span class="card-value">${game.i18n.localize("HAMALRON.Initiative.Value")} : ${card.value}</span>
        </div>
      </div>
      <div class="initiative-footer"><i class="fas fa-cards"></i> ${game.i18n.localize("HAMALRON.Initiative.Title")}</div>
    </div>`
  await message.update({ content })
})


// Helper: ensure deck manager is initialized and has cards
async function ensureDeck() {
  let dm = globalThis.HamalronTarotDeckManager?._instance
  if (!dm) {
    const DM = game.system.api.applications.HamalronTarotDeckManager
    dm = new DM()
    DM._instance = dm
    await dm.loadDeckState()
  }
  if (dm.deck.length === 0) {
    await dm.resetDeck()
  }
  if (dm.deck.length === 0) {
    ui.notifications.warn(game.i18n.localize("HAMALRON.Notifications.deckEmpty"))
    return null
  }
  return dm
}

// Chat action buttons (Sous tension / Opposé)
$(document).on("click", "[data-action='sousTension']", async function () {
  const msgEl = $(this).closest(".chat-message")
  const msgId = msgEl?.data("messageId")
  const msg = game.messages?.get(msgId)
  if (!msg) return

  const totalText = msgEl.find(".calc-total")?.text()?.trim()
  const totalJoueur = Number(totalText) || 0
  const actorName = msg.speaker?.alias || "Inconnu"

  const deckManager = await ensureDeck()
  if (!deckManager) return

  const drawn = deckManager.drawCards(1)
  if (!drawn.length) return
  const card = drawn[0]
  const valData = SYSTEM.TAROT_VALEURS[card.valeur]
  const valeurMJ = valData?.value ?? 0
  deckManager.addToDiscard(card)
  await deckManager.saveDeckState()

  const successA = totalJoueur >= valeurMJ
  const content = await foundry.applications.handlebars.renderTemplate(
    "systems/fvtt-hamalron/templates/chat-tension.hbs",
    { cssClass: "fvtt-hamalron tension-roll", icon: "fa-bolt", label: game.i18n.localize("HAMALRON.Label.sousTension"),
      joueurName: actorName, joueurScore: totalJoueur, mjCard: `${card.name} (${valeurMJ})`, mjScore: valeurMJ,
      isSuccess: successA, isOpponentWinning: totalJoueur < valeurMJ, isSousTension: true })
  ChatMessage.create({ content, style: CONST.CHAT_MESSAGE_STYLES.OTHER })
})

$(document).on("click", "[data-action='oppose']", async function () {
  const msgEl = $(this).closest(".chat-message")
  const msgId = msgEl?.data("messageId")
  const msg = game.messages?.get(msgId)
  if (!msg) return

  const totalText = msgEl.find(".calc-total")?.text()?.trim()
  const totalJoueur = Number(totalText) || 0
  const actorName = msg.speaker?.alias || "Inconnu"

  const deckManager = await ensureDeck()
  if (!deckManager) return

  const drawn = deckManager.drawCards(1)
  if (!drawn.length) return
  const card = drawn[0]
  const valData = SYSTEM.TAROT_VALEURS[card.valeur]
  const valeurOpposant = valData?.value ?? 0
  deckManager.addToDiscard(card)
  await deckManager.saveDeckState()

  const successB = totalJoueur >= valeurOpposant
  const content = await foundry.applications.handlebars.renderTemplate(
    "systems/fvtt-hamalron/templates/chat-tension.hbs",
    { cssClass: "fvtt-hamalron tension-roll", icon: "fa-shield-halved", label: game.i18n.localize("HAMALRON.Label.oppose"),
      joueurName: actorName, joueurScore: totalJoueur, mjCard: `${card.name} (${valeurOpposant})`, mjScore: valeurOpposant,
      isSuccess: successB, isOpponentWinning: totalJoueur < valeurOpposant, isSousTension: false })
  ChatMessage.create({ content, style: CONST.CHAT_MESSAGE_STYLES.OTHER })
})

Hooks.on("hotbarDrop", (bar, data, slot) => {
  if (data.type === "Actor") {
    const actor = fromUuidSync(data.uuid)
    if (!actor) return false
    Macro.create({
      name: actor.name,
      type: "script",
      img: actor.img,
      command: `game.actors.get("${actor.id}")?.sheet?.render(true)`,
      scope: "global",
    }).then(macro => bar.assignMacro(macro, slot))
    return false
  }
  if (data.type === "Item") {
    const item = fromUuidSync(data.uuid)
    if (!item) return false
    const actor = item.parent
    let command = ""
    if (item.type === "competence") {
      command = `const a = game.actors.get("${actor?.id}"); const i = a?.items?.get("${item.id}"); if (i) a?.system?.roll?.("competence", i)`
    } else if (item.type === "sortilege") {
      command = `const { default: Cast } = await import("${game.system.id}/module/applications/sortilege-casting.mjs"); const a = game.actors.get("${actor?.id}"); const i = a?.items?.get("${item.id}"); if (i) Cast.prompt(i, a)`
    } else if (item.type === "arme") {
      command = `const a = game.actors.get("${actor?.id}"); const i = a?.items?.get("${item.id}"); if (i) a?.system?.roll?.("weapon", i)`
    } else {
      command = `const a = game.actors.get("${actor?.id}"); a?.items?.get("${item.id}")?.sheet?.render(true)`
    }
    if (command) {
      Macro.create({
        name: item.name,
        type: "script",
        img: item.img,
        command,
        scope: "actor",
      }).then(macro => bar.assignMacro(macro, slot))
    }
    return false
  }
})
