import { SYSTEM, STATUS_EFFECTS } from "./module/config/system.mjs"
globalThis.SYSTEM = SYSTEM

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 OathHammerUtils from "./module/utils.mjs"
import OathHammerWeaponDialog from "./module/applications/weapon-dialog.mjs"
import OathHammerCombat from "./module/combat.mjs"
import { rollWeaponDamage } from "./module/rolls.mjs"
import { rollPostRollLuck } from "./module/rolls.mjs"
import { injectFreeRollBar } from "./module/applications/free-roll.mjs"
import OathHammerLuckRollDialog from "./module/applications/luck-roll-dialog.mjs"

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

  globalThis.oathHammer = game.system
  game.system.CONST = SYSTEM

  game.system.api = { applications, models, documents }

  CONFIG.Actor.documentClass = documents.OathHammerActor
  CONFIG.Combat.documentClass = OathHammerCombat
  CONFIG.Actor.dataModels = {
    character: models.OathHammerCharacter,
    npc:       models.OathHammerNPC,
    settlement: models.OathHammerSettlement,
    regiment:  models.OathHammerRegiment,
    party:     models.OathHammerParty,
    army:      models.OathHammerArmy,
  }

  CONFIG.Item.documentClass = documents.OathHammerItem
  CONFIG.Item.dataModels = {
    weapon: models.OathHammerWeapon,
    armor: models.OathHammerArmor,
    ammunition: models.OathHammerAmmunition,
    equipment: models.OathHammerEquipment,
    spell: models.OathHammerSpell,
    miracle: models.OathHammerMiracle,
    "magic-item": models.OathHammerMagicItem,
    trait: models.OathHammerTrait,
    oath: models.OathHammerOath,
    "class": models.OathHammerClass,
    building: models.OathHammerBuilding,
    skillnpc: models.OathHammerSkillNPC,
    npcattack: models.OathHammerNpcAttack,
  }

  foundry.documents.collections.Actors.unregisterSheet("core", foundry.appv1.sheets.ActorSheet)
  foundry.documents.collections.Actors.registerSheet("fvtt-oath-hammer", applications.OathHammerCharacterSheet, {
    types: ["character"],
    makeDefault: true,
    label: "OATHHAMMER.Sheet.Character"
  })
  foundry.documents.collections.Actors.registerSheet("fvtt-oath-hammer", applications.OathHammerNPCSheet, {
    types: ["npc"],
    makeDefault: true,
    label: "OATHHAMMER.Sheet.NPC"
  })
  foundry.documents.collections.Actors.registerSheet("fvtt-oath-hammer", applications.OathHammerSettlementSheet, {
    types: ["settlement"],
    makeDefault: true,
    label: "OATHHAMMER.Sheet.Settlement"
  })
  foundry.documents.collections.Actors.registerSheet("fvtt-oath-hammer", applications.OathHammerRegimentSheet, {
    types: ["regiment"],
    makeDefault: true,
    label: "OATHHAMMER.Sheet.Regiment"
  })
  foundry.documents.collections.Actors.registerSheet("fvtt-oath-hammer", applications.OathHammerPartySheet, {
    types: ["party"],
    makeDefault: true,
    label: "OATHHAMMER.Sheet.Party"
  })
  foundry.documents.collections.Actors.registerSheet("fvtt-oath-hammer", applications.OathHammerArmySheet, {
    types: ["army"],
    makeDefault: true,
    label: "OATHHAMMER.Sheet.Army"
  })

  foundry.documents.collections.Items.unregisterSheet("core", foundry.appv1.sheets.ItemSheet)
  foundry.documents.collections.Items.registerSheet("fvtt-oath-hammer", applications.OathHammerWeaponSheet, { types: ["weapon"], makeDefault: true, label: "OATHHAMMER.Sheet.Weapon" })
  foundry.documents.collections.Items.registerSheet("fvtt-oath-hammer", applications.OathHammerArmorSheet, { types: ["armor"], makeDefault: true, label: "OATHHAMMER.Sheet.Armor" })
  foundry.documents.collections.Items.registerSheet("fvtt-oath-hammer", applications.OathHammerAmmunitionSheet, { types: ["ammunition"], makeDefault: true, label: "OATHHAMMER.Sheet.Ammunition" })
  foundry.documents.collections.Items.registerSheet("fvtt-oath-hammer", applications.OathHammerEquipmentSheet, { types: ["equipment"], makeDefault: true, label: "OATHHAMMER.Sheet.Equipment" })
  foundry.documents.collections.Items.registerSheet("fvtt-oath-hammer", applications.OathHammerSpellSheet, { types: ["spell"], makeDefault: true, label: "OATHHAMMER.Sheet.Spell" })
  foundry.documents.collections.Items.registerSheet("fvtt-oath-hammer", applications.OathHammerMiracleSheet, { types: ["miracle"], makeDefault: true, label: "OATHHAMMER.Sheet.Miracle" })
  foundry.documents.collections.Items.registerSheet("fvtt-oath-hammer", applications.OathHammerMagicItemSheet, { types: ["magic-item"], makeDefault: true, label: "OATHHAMMER.Sheet.MagicItem" })
  foundry.documents.collections.Items.registerSheet("fvtt-oath-hammer", applications.OathHammerTraitSheet, { types: ["trait"], makeDefault: true, label: "OATHHAMMER.Sheet.Trait" })
  foundry.documents.collections.Items.registerSheet("fvtt-oath-hammer", applications.OathHammerOathSheet, { types: ["oath"], makeDefault: true, label: "OATHHAMMER.Sheet.Oath" })
  foundry.documents.collections.Items.registerSheet("fvtt-oath-hammer", applications.OathHammerClassSheet, { types: ["class"], makeDefault: true, label: "OATHHAMMER.Sheet.Class" })
  foundry.documents.collections.Items.registerSheet("fvtt-oath-hammer", applications.OathHammerBuildingSheet, { types: ["building"], makeDefault: true, label: "OATHHAMMER.Sheet.Building" })
  foundry.documents.collections.Items.registerSheet("fvtt-oath-hammer", applications.OathHammerSkillNPCSheet, { types: ["skillnpc"], makeDefault: true, label: "OATHHAMMER.Sheet.SkillNPC" })
  foundry.documents.collections.Items.registerSheet("fvtt-oath-hammer", applications.OathHammerNpcAttackSheet, { types: ["npcattack"], makeDefault: true, label: "OATHHAMMER.Sheet.NpcAttack" })

  CONFIG.statusEffects = STATUS_EFFECTS

  OathHammerUtils.registerHandlebarsHelpers()

  // Pre-register Handlebars partials so {{> "path"}} works in item templates
  foundry.applications.handlebars.loadTemplates([
    "systems/fvtt-oath-hammer/templates/item/rune-zone.hbs",
  ])

  console.info("Oath Hammer | System Initialized")
})

Hooks.once("ready", async function () {
  console.info("Oath Hammer | System Ready")

  // Migration: remove orphaned items with removed types (lineage → actor field, ability → trait, regiment → actor type)
  const removedTypes = new Set(["lineage", "ability", "regiment"])
  for (const actor of game.actors) {
    const toDelete = []

    // Catch items that failed validation and landed in invalidDocumentIds
    for (const id of (actor.items.invalidDocumentIds ?? [])) {
      const raw = actor.items.getInvalid(id)
      if (raw && removedTypes.has(raw._source?.type)) toDelete.push(id)
    }

    // Also catch any that slipped through in _source (belt-and-suspenders)
    for (const src of (actor._source.items ?? [])) {
      if (removedTypes.has(src.type) && !toDelete.includes(src._id)) toDelete.push(src._id)
    }

    if (toDelete.length) {
      console.info(`Oath Hammer | Migrating ${actor.name}: removing ${toDelete.length} obsolete item(s)`)
      await actor.deleteEmbeddedDocuments("Item", toDelete)
    }
  }

  // Purge invalid world items of removed types
  for (const id of game.items.invalidDocumentIds) {
    const item = game.items.getInvalid(id)
    if (item && removedTypes.has(item._source?.type)) {
      console.info(`Oath Hammer | Deleting world item: ${item._source.name} (${item._source.type})`)
      await item.delete()
    }
  }

  // Auto-import the welcome scene if GM and not already present
  if (game.user.isGM) await _importWelcomeScene()
})

// Auto-link regiment (and army) actor tokens so they can be added to garrisons/armies
Hooks.on("preCreateActor", (actor, _data, _options, _userId) => {
  if (actor.type === "regiment" || actor.type === "army") {
    actor.updateSource({ "prototypeToken.actorLink": true })
  }
})

// Handle "Roll Damage" button in weapon attack chat cards
Hooks.on("renderChatMessageHTML", async (message, html) => {
  // Weapon damage button
  const btn = html.querySelector("[data-action=\"rollWeaponDamage\"]")
  if (btn) {
    btn.addEventListener("click", async () => {
      const flagData = message.getFlag("fvtt-oath-hammer", "weaponAttack")
      if (!flagData) return
      const { actorUuid, weaponUuid, attackSuccesses } = flagData
      const actor  = await fromUuid(actorUuid)
      const weapon = await fromUuid(weaponUuid)
      if (!actor || !weapon) return ui.notifications.warn(game.i18n.localize("OATHHAMMER.Roll.NoActor"))
      const opts = await OathHammerWeaponDialog.promptDamage(actor, weapon, attackSuccesses ?? 0)
      if (opts) await rollWeaponDamage(actor, weapon, opts)
    })
  }

  // Luck post-roll button
  const luckFlag = message.getFlag("fvtt-oath-hammer", "luckRoll")
  if (!luckFlag) return

  const resultDiv = html.querySelector(".oh-roll-result")
  if (!resultDiv) return

  if (luckFlag.used) {
    // Show luck result section
    const bonusLabel = luckFlag.bonusSuccesses > 0
      ? `+${luckFlag.bonusSuccesses} ${game.i18n.localize("OATHHAMMER.Roll.Successes")}`
      : game.i18n.localize("OATHHAMMER.Roll.NoBonus")
    const resultHtml = `
      <div class="oh-luck-result">
        <span class="oh-luck-result-icon">🍀</span>
        <span>${game.i18n.localize("OATHHAMMER.Roll.LuckResult")} ${bonusLabel}</span>
        <span class="oh-luck-dice">${luckFlag.luckDiceHtml ?? ""}</span>
      </div>`
    resultDiv.insertAdjacentHTML("afterend", resultHtml)
  } else {
    // Show "Spend Luck" button if actor owns the message and has luck left
    const actor = await fromUuid(luckFlag.actorUuid).catch(() => null)
    if (!actor?.isOwner) return
    const availableLuck = actor.system.luck?.value ?? 0
    if (availableLuck <= 0) return

    const btnHtml = `
      <div class="oh-luck-btn-row">
        <button type="button" class="oh-post-luck-btn" data-action="postRollLuck">
          🍀 ${game.i18n.localize("OATHHAMMER.Roll.LuckRollPost")}
        </button>
      </div>`
    resultDiv.insertAdjacentHTML("afterend", btnHtml)

    html.querySelector("[data-action=\"postRollLuck\"]")?.addEventListener("click", async () => {
      const actor = await fromUuid(luckFlag.actorUuid).catch(() => null)
      if (!actor) return
      const opts = await OathHammerLuckRollDialog.prompt(actor)
      if (!opts) return
      await rollPostRollLuck(message, opts.luckSpend, opts.luckIsHuman)
    })
  }
})

// Inject Free Roll bar into the chat sidebar
Hooks.on("renderChatLog", (_chatLog, html) => injectFreeRollBar(_chatLog, html))


// ============================================================
// WELCOME SCENE — auto-create on first world load (GM only)
// ============================================================
const WELCOME_SCENE_NAME = "Oath Hammer"
const WELCOME_SCENE_MAP  = "systems/fvtt-oath-hammer/assets/images/oathhammer_map.webp"

/** Scene data for the welcome map (3600×5400 px, no grid — world map). */
function _welcomeSceneData() {
  return {
    name: WELCOME_SCENE_NAME,
    background: { src: WELCOME_SCENE_MAP },
    width: 3600,
    height: 5400,
    grid: { type: 0, size: 100 },  // gridless
    padding: 0,
    initial: { x: 1800, y: 2700, scale: 0.25 },
    tokenVision: false,
    flags: { "fvtt-oath-hammer": { welcomeScene: true } },
  }
}

async function _importWelcomeScene() {
  // Skip if the scene already exists in the world
  if (game.scenes.find(s => s.name === WELCOME_SCENE_NAME)) return
  console.info("Oath Hammer | Creating welcome scene…")
  const scene = await Scene.create(_welcomeSceneData())
  await scene.activate()
  console.info("Oath Hammer | Welcome scene created and activated.")
}
