/**
 * Chroniques de l'Étrange — Système FoundryVTT
 *
 * Chroniques de l'Étrange est un jeu de rôle édité par Antre-Monde Éditions.
 * Ce système FoundryVTT est une implémentation indépendante et n'est pas
 * affilié à Antre-Monde Éditions,
 * mais a été réalisé avec l'autorisation d'Antre-Monde Éditions.
 *
 * @author    LeRatierBretonnien
 * @copyright 2024–2026 LeRatierBretonnien
 * @license   CC BY-NC-SA 4.0 – https://creativecommons.org/licenses/by-nc-sa/4.0/
 */

/**
 * Post-roll interactive action buttons injected into dice result chat messages.
 * Allows players to pull dice from the Loksyu (as Successes or dés-fastes)
 * and allows the GM to spend Tin Ji to intervene.
 *
 * After a draw, the originating roll result message is updated in-place
 * with the new counts, without creating noise.
 */

import { getLoksyuData, setLoksyuData, getTinjiValue, setTinjiValue, requestLoksyuDraw, requestTinjiSpend } from "./apps/singletons.js"
import { SYSTEM_ID, WU_XING_CYCLE, ASPECT_LABELS, ASPECT_ICONS } from "../config/constants.js"

const RESULT_TEMPLATE = "systems/fvtt-chroniques-de-l-etrange/templates/form/cde-dice-result.html"

/**
 * Inject or refresh post-roll action buttons in the given chat message HTML element.
 * Called from renderChatMessageHTML hook.
 * @param {ChatMessage} message
 * @param {HTMLElement} html - the chat message HTML element (li.chat-message)
 */
export function injectRollActions(message, html) {
  const rollCard = html.querySelector(".cde-roll-result")
  if (!rollCard) return
  const aspect = rollCard.dataset.aspect
  if (!aspect || !WU_XING_CYCLE[aspect]) return
  refreshRollActions(rollCard, aspect, message)
}

/**
 * Re-render the action buttons section based on current Loksyu / TinJi state.
 */
function refreshRollActions(rollCard, aspect, message) {
  rollCard.querySelector(".cde-roll-actions")?.remove()

  const cycle       = WU_XING_CYCLE[aspect]
  const fasteAspect = cycle[1]

  const loksyu = getLoksyuData()
  const tinji  = getTinjiValue()

  const successAvail = (loksyu[aspect]?.yin ?? 0) + (loksyu[aspect]?.yang ?? 0)
  const fasteAvail   = (loksyu[fasteAspect]?.yin ?? 0) + (loksyu[fasteAspect]?.yang ?? 0)

  const hasSomething = successAvail > 0 || fasteAvail > 0 || tinji > 0
  if (!hasSomething) return

  const aspLabel   = game.i18n.localize(ASPECT_LABELS[aspect])
  const fasteLabel = game.i18n.localize(ASPECT_LABELS[fasteAspect])

  let btns = ""

  if (successAvail > 0) {
    btns += `<button class="cde-roll-action-btn cde-roll-action--success" data-action="loksyu-success">
      <img src="${ASPECT_ICONS[aspect]}" class="cde-roll-action-icon" alt="${aspLabel}"/>
      <span class="cde-roll-action-label">+1 ${game.i18n.localize("CDE.Successes")}</span>
      <span class="cde-roll-action-count">${successAvail}</span>
    </button>`
  }

  if (fasteAvail > 0) {
    btns += `<button class="cde-roll-action-btn cde-roll-action--faste" data-action="loksyu-faste">
      <img src="${ASPECT_ICONS[fasteAspect]}" class="cde-roll-action-icon" alt="${fasteLabel}"/>
      <span class="cde-roll-action-label">+1 ${game.i18n.localize("CDE.AuspiciousDie")}</span>
      <span class="cde-roll-action-count">${fasteAvail}</span>
    </button>`
  }

  if (tinji > 0) {
    btns += `<button class="cde-roll-action-btn cde-roll-action--tinji" data-action="tinji">
      <span class="cde-roll-action-tinji-char">天</span>
      <span class="cde-roll-action-label">${game.i18n.localize("CDE.TinJi2")}</span>
      <span class="cde-roll-action-count">${tinji}</span>
    </button>`
  }

  const wrapper = document.createElement("div")
  wrapper.className = "cde-roll-actions"
  wrapper.innerHTML = `
    <div class="cde-roll-actions-title">
      <i class="fas fa-yin-yang"></i>
      ${game.i18n.localize("CDE.PostRollActions")}
    </div>
    <div class="cde-roll-actions-btns">${btns}</div>
  `
  rollCard.appendChild(wrapper)

  wrapper.addEventListener("click", async ev => {
    const btn = ev.target.closest("[data-action]")
    if (!btn || btn.disabled) return
    const action = btn.dataset.action
    if (action === "loksyu-success") {
      await _drawFromLoksyu(message, aspect, "success", aspLabel)
    } else if (action === "loksyu-faste") {
      await _drawFromLoksyu(message, fasteAspect, "faste", fasteLabel)
    } else if (action === "tinji") {
      await _spendTinjiPostRoll()
    }
    // Buttons will be re-injected automatically via renderChatMessageHTML
    // after message.update(). For tinji (no message update), refresh manually.
    if (action === "tinji") refreshRollActions(rollCard, aspect, message)
  })
}

/**
 * Pull one die from a given Loksyu aspect slot, update Loksyu settings,
 * and update the originating roll-result message in-place.
 *
 * @param {ChatMessage} message - the roll result chat message to update
 * @param {string} aspect       - which Loksyu aspect slot to draw from
 * @param {"success"|"faste"} type
 * @param {string} aspectLabel  - localised aspect name for the notification
 */
async function _drawFromLoksyu(message, aspect, type, aspectLabel) {
  const data  = getLoksyuData()
  const entry = data[aspect] ?? { yin: 0, yang: 0 }
  const total = entry.yin + entry.yang
  if (total <= 0) {
    ui.notifications.warn(game.i18n.localize("CDE.LoksyuEmpty"))
    return
  }

  // Remove 1 die according to the consumption order setting
  const order = game.settings.get(SYSTEM_ID, "loksyuConsumptionOrder")
  if (order === "yin-first") {
    if (entry.yin > 0) entry.yin--
    else entry.yang--
  } else if (order === "balanced") {
    if (entry.yin > entry.yang) entry.yin--
    else if (entry.yang > entry.yin) entry.yang--
    else if (entry.yang > 0) entry.yang--
    else entry.yin--
  } else {
    // yang-first (default)
    if (entry.yang > 0) entry.yang--
    else entry.yin--
  }
  data[aspect] = entry
  if (game.user.isGM) {
    await setLoksyuData(data)
  } else {
    requestLoksyuDraw(aspect, order)
  }

  // Update the roll-result message in-place if it has stored flags
  const flags = message?.flags?.[SYSTEM_ID]
  if (flags?.rollResult && message.isOwner) {
    const updated = foundry.utils.deepClone(flags.rollResult)
    if (type === "success") {
      updated.successesdice    = (updated.successesdice ?? 0) + 1
      updated.loksyuBonusSuc   = (updated.loksyuBonusSuc ?? 0) + 1
      // Recalculate weapon damage if applicable
      if (updated.damageBase != null) updated.totalDamage = updated.damageBase + (updated.damageAspectValue ?? 0)
    } else {
      updated.auspiciousdice  = (updated.auspiciousdice ?? 0) + 1
      updated.loksyuBonusFaste = (updated.loksyuBonusFaste ?? 0) + 1
    }
    const newHtml = await foundry.applications.handlebars.renderTemplate(RESULT_TEMPLATE, updated)
    await message.update({
      content: newHtml,
      [`flags.${SYSTEM_ID}.rollResult`]: updated,
    })
    // renderChatMessageHTML hook fires automatically → buttons re-injected
  }

  const remain    = entry.yin + entry.yang
  const typeLabel = type === "success"
    ? game.i18n.localize("CDE.Successes")
    : game.i18n.localize("CDE.AuspiciousDie")

  await ChatMessage.create({
    user:    game.user.id,
    content: `<div class="cde-loksyu-draw-msg">
      <div class="cde-loksyu-draw-header">
        <img src="${ASPECT_ICONS[aspect]}" class="cde-loksyu-draw-aspect-icon" alt="${aspectLabel}"/>
        <span class="cde-loksyu-draw-user">${game.user.name}</span>
        <span class="cde-loksyu-draw-action">${game.i18n.localize("CDE.LoksyuDrawsA")}</span>
        <span class="cde-loksyu-draw-type">${typeLabel}</span>
        <span class="cde-loksyu-draw-from">${game.i18n.localize("CDE.LoksyuFromAspect")} <em>${aspectLabel}</em></span>
      </div>
      <div class="cde-loksyu-draw-footer">
        <i class="fas fa-yin-yang"></i>
        <span>${game.i18n.localize("CDE.Loksyu")} ${aspectLabel} : </span>
        <strong class="cde-loksyu-remain">${remain} ${game.i18n.localize("CDE.LoksyuRemaining")}</strong>
      </div>
    </div>`,
  })
}

/**
 * Spend 1 Tin Ji point (GM only) and post a notification.
 */
async function _spendTinjiPostRoll() {
  const current = getTinjiValue()
  if (current <= 0) {
    ui.notifications.warn(game.i18n.localize("CDE.TinjiEmpty"))
    return
  }
  if (game.user.isGM) {
    await setTinjiValue(current - 1)
  } else {
    requestTinjiSpend()
  }
  await ChatMessage.create({
    user:    game.user.id,
    content: `<div class="cde-tinji-spend-msg">
      <span class="cde-tinji-icon">天</span>
      <span class="cde-tinji-text">
        <strong>${game.user.name}</strong> ${game.i18n.localize("CDE.TinjiSpent").replace("{name}", game.user.name)}
      </span>
      <span class="cde-tinji-remain">(${current - 1} ${game.i18n.localize("CDE.TinjiRemaining")})</span>
    </div>`,
  })
}

/**
 * Refresh all visible roll-result buttons when Loksyu or TinJi settings change.
 * Wired up via Hooks.on("updateSetting", ...) in system.js.
 */
export function refreshAllRollActions() {
  document.querySelectorAll(".chat-message .cde-roll-result[data-aspect]").forEach(card => {
    const aspect = card.dataset.aspect
    if (!aspect || !WU_XING_CYCLE[aspect]) return
    // Find the ChatMessage document from the ancestor element's data-message-id
    const msgEl = card.closest("[data-message-id]")
    const msgId = msgEl?.dataset?.messageId
    const message = msgId ? game.messages.get(msgId) : null
    refreshRollActions(card, aspect, message)
  })
}

