/**
 * Free Dice Tray — injected into the Foundry chat sidebar.
 *
 * Provides a compact bar for GM and players to roll any standard die (d4–d30)
 * or its exploding variant (dXx) without needing an actor sheet.
 * Supports selecting how many dice to roll (1–9).
 */

/** Standard dice available in Lethal Fantasy */
const DICE_TYPES = ["d4", "d6", "d8", "d10", "d12", "d20", "d30"]

/**
 * Inject the dice tray bar into the ChatLog HTML.
 * Called from `Hooks.on("renderChatLog", ...)`.
 *
 * @param {Application} _chatLog
 * @param {HTMLElement|jQuery} html
 */
export function injectDiceTray(_chatLog, html) {
  const el = (html instanceof HTMLElement) ? html : (html[0] ?? html)
  if (!el?.querySelector) return
  if (el.querySelector(".lf-dice-tray")) return

  const bar = document.createElement("div")
  bar.className = "lf-dice-tray"

  const diceButtons = DICE_TYPES.map(d =>
    `<button type="button" class="lf-dt-die-btn" data-die="${d}" title="${d.toUpperCase()}">${d.toUpperCase()}</button>`
  ).join("")

  const countOptions = Array.from({ length: 9 }, (_, i) =>
    `<option value="${i + 1}">${i + 1}</option>`
  ).join("")

  bar.innerHTML = `
    <div class="lf-dt-row">
      <span class="lf-dt-label"><i class="fa-solid fa-dice"></i></span>
      <select class="lf-dt-count" title="${game.i18n.localize("LETHALFANTASY.DiceTray.CountTitle")}">
        ${countOptions}
      </select>
      <div class="lf-dt-dice">${diceButtons}</div>
      <label class="lf-dt-explode-label" title="${game.i18n.localize("LETHALFANTASY.DiceTray.ExplodeTitle")}">
        <input type="checkbox" class="lf-dt-explode" />
        <i class="fa-solid fa-explosion"></i>
      </label>
    </div>
  `

  bar.addEventListener("click", async ev => {
    const btn = ev.target.closest(".lf-dt-die-btn")
    if (!btn) return
    ev.stopPropagation()

    const dieType = btn.dataset.die
    const count = parseInt(bar.querySelector(".lf-dt-count").value) || 1
    const explode = bar.querySelector(".lf-dt-explode").checked

    try {
      await rollFreeDie(dieType, count, explode)
    } catch (err) {
      console.error("Lethal Fantasy | Dice Tray error:", err)
      ui.notifications?.error("Dice Tray roll failed — see console")
    }
  })

  const anchor = el.querySelector(".chat-form")
    ?? el.querySelector(".chat-message-form")
    ?? el.querySelector("form")
  if (anchor) {
    anchor.parentElement.insertBefore(bar, anchor)
  } else {
    el.appendChild(bar)
  }
}

/**
 * Roll one or more dice of the given type and post the result to chat.
 * For exploding dice, follows the Lethal Fantasy rule: each exploded reroll
 * contributes (result − 1) to the total, same as all other system rolls.
 *
 * @param {string}  dieType  Die face, e.g. "d20"
 * @param {number}  count    Number of dice to roll (1–9)
 * @param {boolean} explode  Whether to use the exploding variant (max triggers reroll at −1)
 * @returns {Promise<void>}
 */
export async function rollFreeDie(dieType, count = 1, explode = false) {
  const sides = parseInt(dieType.replace("d", "")) || 20
  const baseFormula = `1d${sides}`
  const label = explode
    ? `${count}${dieType.toUpperCase()}E`
    : `${count}${dieType.toUpperCase()}`

  const dieLabel = dieType.toUpperCase()
  const dieChips = []
  let total = 0

  for (let i = 0; i < count; i++) {
    const r0 = await new Roll(baseFormula).evaluate()
    if (game?.dice3d) await game.dice3d.showForRoll(r0, game.user, true)
    let diceResult = r0.dice[0].results[0].result
    dieChips.push({ label: dieLabel, value: diceResult, exploded: false })
    total += diceResult

    if (explode) {
      while (diceResult === sides) {
        const rx = await new Roll(baseFormula).evaluate()
        if (game?.dice3d) await game.dice3d.showForRoll(rx, game.user, true)
        diceResult = rx.dice[0].results[0].result
        const contrib = diceResult - 1
        dieChips.push({ label: `${dieLabel}-1`, value: contrib, exploded: true })
        total += contrib
      }
    }
  }

  const resultHtml = dieChips.map(chip => {
    const isMax = !chip.exploded && chip.value === sides
    const isMin = chip.value === 1
    const explodeIcon = chip.exploded ? `<i class="fa-solid fa-burst lf-dt-explode-icon"></i>` : ""
    const classes = ["lf-frc-die-chip", isMax ? "lf-frc-max" : "", isMin ? "lf-frc-min" : ""].filter(Boolean).join(" ")
    return `<div class="${classes}">
      <span class="lf-frc-die-type">${chip.label}</span>
      <span class="lf-frc-die-sep">→</span>
      <span class="lf-frc-die-val">${chip.value}${explodeIcon}</span>
    </div>`
  }).join("")

  const totalLabel = game.i18n.localize("LETHALFANTASY.Label.total").toUpperCase()
  const content = `
    <div class="lf-free-roll-card">
      <div class="lf-frc-header">
        <i class="fa-solid fa-dice"></i>
        <span class="lf-frc-title-text">${game.i18n.localize("LETHALFANTASY.DiceTray.ChatTitle")}</span>
        <span class="lf-frc-badge">${label}</span>
      </div>
      <div class="lf-frc-dice">${resultHtml}</div>
      <div class="lf-frc-total-bar">
        <span class="lf-frc-total-label">${totalLabel}</span>
        <span class="lf-frc-total-value">${total}</span>
      </div>
    </div>
  `

  const rollMode = game.settings.get("core", "rollMode")
  // Normalize old-style rollMode keys (v12/v13) to new-style (v14), fallback to "public"
  const modeMap = { publicroll: "public", gmroll: "gm", blindroll: "blind", selfroll: "self" }
  const mode = modeMap[rollMode] ?? rollMode ?? "public"
  const msgData = {
    speaker: ChatMessage.getSpeaker(),
    content,
    sound: CONFIG.sounds.dice,
    mode,
  }
  await ChatMessage.create(msgData)
}
