import { SYSTEM } from "../config/system.mjs"
export { log } from "./helpers.mjs"

export function hasD30Reroll(d30Message) {
  return d30Message?.type === "mulligan"
}

/**
 * Process D30 bonus dice for attack or defense.
 * Rolls and applies bonus dice BEFORE grit/luck/shield decisions.
 * For `choice` type results (D30=20, 30), shows dialog to choose between bonus dice and special effect.
 * For `bonus_dice` type results (D30=27, 2, 3), auto-rolls the dice.
 * @param {Object|null} d30Message The D30 result object
 * @param {"attack"|"defense"} side Whether processing the attack or defense side
 * @param {number|null} naturalRoll The natural D20 roll (for special strike type detection)
 * @param {Object} actor The actor (for dice3d display)
 * @returns {Promise<{modifier: number, specialEffect: string|null, specialName: string|null}>}
 */
export async function processD30BonusDice(d30Message, side, naturalRoll = null, actor = null, canDialog = true) {
  if (!d30Message) return { modifier: 0, specialEffect: null, specialName: null }

  const validTargets = side === "attack" ? ["attack", "spell_attack"] : ["defense", "spell_defense"]

  // ── Simple bonus_dice type ── auto-roll if target matches
  if (d30Message.type === "bonus_dice") {
    if (!validTargets.includes(d30Message.target)) return { modifier: 0, specialEffect: null, specialName: null }
    const modifier = await _rollD30BonusDie(d30Message.dice, actor, !canDialog)
    return { modifier, specialEffect: null, specialName: null }
  }

  // ── Choice type ── auto-roll bonus dice, alert about special effects
  if (d30Message.type === "choice") {
    // Non-controlling client can't roll dice here — the controlling client
    // sends the updated values via socket.
    if (!canDialog) {
      return { modifier: 0, specialEffect: null, specialName: null }
    }

    // Auto-roll bonus dice (like d6E on 27 — no dialog)
    const bonusChoice = d30Message.choices.find(c => c.type === "bonus_dice")
    let modifier = 0
    if (bonusChoice) {
      modifier = await _rollD30BonusDie(bonusChoice.dice, actor)
    }

    // Inform about special strike/defense or other effects (informational only)
    const specialChoice = d30Message.choices.find(c => c.type === "special_strike" || c.type === "special_defense")
    if (specialChoice) {
      return { modifier, specialEffect: "flag", specialName: _buildSpecialName(specialChoice, naturalRoll) }
    }

    // Non-standard choice (spell_calamity, etc.) — report it
    const nonStandardChoice = d30Message.choices.find(c => c.type !== "bonus_dice")
    if (nonStandardChoice) {
      return { modifier, specialEffect: "flag", specialName: _buildSpecialName(nonStandardChoice, naturalRoll) }
    }

    return { modifier, specialEffect: null, specialName: null }
  }

  // ── Combo type (bleed / internal injury) — flag for wound creation
  if (d30Message.type === "combo") {
    const hasBleed = d30Message.effects?.some(e => e.type === "bleed" || e.type === "internal_injury")
    if (hasBleed) {
      return { modifier: 0, specialEffect: "bleed", specialName: "Bleeding/Internal Injury" }
    }
  }

  // ── Bleed type (ranged attacks) — flag for wound creation, same as combo bleed
  if (d30Message.type === "bleed") {
    return { modifier: 0, specialEffect: "bleed", specialName: "Bleeding" }
  }

  // ── Damage multiplier type (2x/3x damage before DR)
  if (d30Message.type === "damage_multiplier") {
    return { modifier: 0, specialEffect: "damageMultiplier", specialName: `x${d30Message.multiplier} Damage`, multiplier: d30Message.multiplier }
  }

  // ── DR multiplier type (2x/3x DR including shield)
  if (d30Message.type === "dr_multiplier") {
    return { modifier: 0, specialEffect: "drMultiplier", specialName: `x${d30Message.multiplier} DR`, multiplier: d30Message.multiplier }
  }

  return { modifier: 0, specialEffect: null, specialName: null }
}

/**
 * Roll a D30 bonus die and show with 3D dice if available.
 * @param {string} formula Dice formula (e.g. "D6", "D12", "D20E")
 * @param {Object} actor Actor for chat message speaker
 * @returns {Promise<number>} The roll total
 */
export async function _rollD30BonusDie(formula, actor, silent = false) {
  const cleaned = formula.replace(/NE$/i, "").replace("E", "")
  const roll = new Roll(cleaned)
  await roll.evaluate()
  if (game?.dice3d) {
    await game.dice3d.showForRoll(roll, game.user, true)
  }
  if (!silent) {
    await ChatMessage.create({
      content: await foundry.applications.handlebars.renderTemplate("systems/fvtt-lethal-fantasy/templates/chat/reaction-message.hbs", {type:"d30BonusRoll", formula: cleaned.toUpperCase(), value: roll.total}),
      speaker: ChatMessage.getSpeaker({ actor })
    })
  }
  return roll.total
}

/**
 * Build the special effect name based on the D30 result and natural roll.
 * @param {Object} specialChoice The choice object with type and options
 * @param {number|null} naturalRoll The natural D20 roll
 * @returns {string} The special effect name
 */
export function _buildSpecialName(specialChoice, naturalRoll) {
  if (specialChoice.type === "special_strike") {
    if (specialChoice.options.includes("lethal")) {
      if (naturalRoll === 20) return "Lethal Strike"
      if (naturalRoll >= 16 && naturalRoll <= 19) return "Vital Strike"
      return "Lethal/Vital Strike"
    }
    if (specialChoice.options.includes("vicious")) return "Vicious Strike"
    return "Special Strike"
  }
  if (specialChoice.type === "special_defense") {
    if (specialChoice.options.includes("perfect_spell")) return "Perfect Spell Defense"
    if (specialChoice.options.includes("flawless")) return "Flawless Defense"
    if (specialChoice.options.includes("legendary")) return "Legendary Defense"
    if (specialChoice.options.includes("perfect")) return "Perfect Defense"
    return "Special Defense"
  }
  return specialChoice.type.replace(/_/g, " ").replace(/\b\w/g, l => l.toUpperCase())
}
