/**
 * fvtt-celestopol.mjs — Point d'entrée principal du système Célestopol 1922
 * FoundryVTT v13+ / DataModels / ApplicationV2
 */

import { SYSTEM, SYSTEM_ID, ASCII } from "./module/config/system.mjs"
import {
  CelestopolCharacter,
  CelestopolNPC,
  CelestopolAnomaly,
  CelestopolAspect,
  CelestopolAttribute,
  CelestopolEquipment,
} from "./module/models/_module.mjs"
import {
  CelestopolActor,
  CelestopolItem,
  CelestopolChatMessage,
  CelestopolRoll,
} from "./module/documents/_module.mjs"
import {
  CelestopolCharacterSheet,
  CelestopolNPCSheet,
  CelestopolAnomalySheet,
  CelestopolAspectSheet,
  CelestopolAttributeSheet,
  CelestopolEquipmentSheet,
} from "./module/applications/_module.mjs"

/* ─── Init hook ──────────────────────────────────────────────────────────── */

Hooks.once("init", () => {
  console.log(ASCII)
  console.log(`${SYSTEM_ID} | Initializing Célestopol 1922 system`)

  // Expose SYSTEM constants in game.system namespace
  game.celestopol = { SYSTEM }

  // ── DataModels ──────────────────────────────────────────────────────────
  CONFIG.Actor.dataModels.character = CelestopolCharacter
  CONFIG.Actor.dataModels.npc       = CelestopolNPC

  CONFIG.Item.dataModels.anomaly   = CelestopolAnomaly
  CONFIG.Item.dataModels.aspect    = CelestopolAspect
  CONFIG.Item.dataModels.attribute = CelestopolAttribute
  CONFIG.Item.dataModels.equipment = CelestopolEquipment

  // ── Document classes ────────────────────────────────────────────────────
  CONFIG.Actor.documentClass       = CelestopolActor
  CONFIG.Item.documentClass        = CelestopolItem
  CONFIG.ChatMessage.documentClass = CelestopolChatMessage
  CONFIG.Dice.rolls.push(CelestopolRoll)

  // ── Token display defaults ───────────────────────────────────────────────
  CONFIG.Actor.trackableAttributes = {
    character: {
      bar:   ["blessures.lvl"],
      value: ["initiative", "anomaly.level"],
    },
    npc: {
      bar:   ["blessures.lvl"],
      value: ["initiative"],
    },
  }

  // ── Sheets: unregister core, register system sheets ─────────────────────
  foundry.applications.sheets.ActorSheetV2.unregisterSheet?.("core", "Actor", { types: ["character", "npc"] })
  foundry.documents.collections.Actors.unregisterSheet("core", ActorSheet)
  foundry.documents.collections.Actors.registerSheet(SYSTEM_ID, CelestopolCharacterSheet, {
    types: ["character"],
    makeDefault: true,
    label: "CELESTOPOL.Sheet.character",
  })
  foundry.documents.collections.Actors.registerSheet(SYSTEM_ID, CelestopolNPCSheet, {
    types: ["npc"],
    makeDefault: true,
    label: "CELESTOPOL.Sheet.npc",
  })

  foundry.documents.collections.Items.unregisterSheet("core", ItemSheet)
  foundry.documents.collections.Items.registerSheet(SYSTEM_ID, CelestopolAnomalySheet, {
    types: ["anomaly"],
    makeDefault: true,
    label: "CELESTOPOL.Sheet.anomaly",
  })
  foundry.documents.collections.Items.registerSheet(SYSTEM_ID, CelestopolAspectSheet, {
    types: ["aspect"],
    makeDefault: true,
    label: "CELESTOPOL.Sheet.aspect",
  })
  foundry.documents.collections.Items.registerSheet(SYSTEM_ID, CelestopolAttributeSheet, {
    types: ["attribute"],
    makeDefault: true,
    label: "CELESTOPOL.Sheet.attribute",
  })
  foundry.documents.collections.Items.registerSheet(SYSTEM_ID, CelestopolEquipmentSheet, {
    types: ["equipment"],
    makeDefault: true,
    label: "CELESTOPOL.Sheet.equipment",
  })

  // ── Handlebars helpers ───────────────────────────────────────────────────
  _registerHandlebarsHelpers()

  // ── Game settings ────────────────────────────────────────────────────────
  _registerSettings()

  // ── Pre-load templates ───────────────────────────────────────────────────
  _preloadTemplates()
})

/* ─── Ready hook ─────────────────────────────────────────────────────────── */

Hooks.once("ready", () => {
  console.log(`${SYSTEM_ID} | System ready`)

  // Socket handler for GM-only operations (e.g. wound application)
  if (game.socket) {
    game.socket.on(`system.${SYSTEM_ID}`, _onSocketMessage)
  }
})

/* ─── Handlebars helpers ─────────────────────────────────────────────────── */

function _registerHandlebarsHelpers() {
  // Helper : concat strings
  Handlebars.registerHelper("concat", (...args) => args.slice(0, -1).join(""))

  // Helper : strict equality
  Handlebars.registerHelper("eq", (a, b) => a === b)

  // Helper : greater than
  Handlebars.registerHelper("gt", (a, b) => a > b)

  // Helper : less than or equal
  Handlebars.registerHelper("lte", (a, b) => a <= b)

  // Helper : greater than or equal
  Handlebars.registerHelper("gte", (a, b) => a >= b)

  // Helper : less than
  Handlebars.registerHelper("lt", (a, b) => a < b)

  // Helper : logical OR
  Handlebars.registerHelper("or", (...args) => args.slice(0, -1).some(Boolean))

  // Helper : build array from args (Handlebars doesn't have arrays natively)
  Handlebars.registerHelper("array", (...args) => args.slice(0, -1))

  // Helper : nested object lookup with dot path or multiple keys
  Handlebars.registerHelper("lookup", (obj, ...args) => {
    const options = args.pop() // last arg is Handlebars options hash
    return args.reduce((acc, key) => (acc && acc[key] !== undefined ? acc[key] : undefined), obj)
  })

  // Helper : negate a number (abs value helper)
  Handlebars.registerHelper("neg", n => -n)

  // Helper : absolute value
  Handlebars.registerHelper("abs", n => Math.abs(n))

  // Helper : add two numbers
  Handlebars.registerHelper("add", (a, b) => a + b)

  Handlebars.registerHelper("let", function(value, options) {
    return options.fn({ value })
  })
}

/* ─── Settings ───────────────────────────────────────────────────────────── */

function _registerSettings() {
  game.settings.register(SYSTEM_ID, "rollMoonDieByDefault", {
    name: "CELESTOPOL.Setting.rollMoonDieByDefault.name",
    hint: "CELESTOPOL.Setting.rollMoonDieByDefault.hint",
    scope: "world",
    config: true,
    type: Boolean,
    default: false,
  })

  game.settings.register(SYSTEM_ID, "autoWounds", {
    name: "CELESTOPOL.Setting.autoWounds.name",
    hint: "CELESTOPOL.Setting.autoWounds.hint",
    scope: "world",
    config: true,
    type: Boolean,
    default: false,
  })
}

/* ─── Template preload ───────────────────────────────────────────────────── */

function _preloadTemplates() {
  const base = `systems/${SYSTEM_ID}/templates`
  loadTemplates([
    `${base}/character-main.hbs`,
    `${base}/character-competences.hbs`,
    `${base}/character-blessures.hbs`,
    `${base}/character-factions.hbs`,
    `${base}/character-biography.hbs`,
    `${base}/npc-main.hbs`,
    `${base}/npc-competences.hbs`,
    `${base}/npc-blessures.hbs`,
    `${base}/anomaly.hbs`,
    `${base}/aspect.hbs`,
    `${base}/attribute.hbs`,
    `${base}/equipment.hbs`,
    `${base}/roll-dialog.hbs`,
    `${base}/chat-message.hbs`,
    `${base}/partials/item-scores.hbs`,
  ])
}

/* ─── Socket handler ─────────────────────────────────────────────────────── */

function _onSocketMessage(data) {
  if (!game.user.isGM) return
  switch (data.type) {
    case "applyWound": {
      const actor = game.actors.get(data.actorId)
      if (actor) actor.update({ "system.blessures.lvl": data.level })
      break
    }
  }
}
