import { CharacterDataModel, SkillDataModel, GearDataModel, WeaponDataModel, StrangenessDataModel, StressAfflictionDataModel, SpellDataModel, AvatarChannelDataModel } from "./module/data-models.mjs";
import { UA2eActor, UA2eItem } from "./module/documents.mjs";
import { UA2eCharacterSheet, UA2eSkillSheet, UA2eGearSheet, UA2eStrangenessSheet, UA2eStressAfflictionSheet, UA2eSpellSheet, UA2eAvatarChannelSheet } from "./module/sheets.mjs";

/* -------------------------------------------- */
/*  Initialisation Hook                         */
/* -------------------------------------------- */

Hooks.once("init", () => {
  console.log("unknown-armies-v2 | Initialising Unknown Armies 2nd Edition");

  // ---- Custom document classes ----
  CONFIG.Actor.documentClass = UA2eActor;
  CONFIG.Item.documentClass  = UA2eItem;

  // ---- Data models ----
  CONFIG.Actor.dataModels = {
    character: CharacterDataModel
  };
  CONFIG.Item.dataModels = {
    skill:            SkillDataModel,
    gear:             GearDataModel,
    weapon:           WeaponDataModel,
    strangeness:      StrangenessDataModel,
    stressAffliction: StressAfflictionDataModel,
    spell:            SpellDataModel,
    avatarChannel:    AvatarChannelDataModel
  };

  // ---- Register actor sheets ----
  DocumentSheetConfig.registerSheet(Actor, "unknown-armies-v2", UA2eCharacterSheet, {
    types:       ["character"],
    makeDefault: true,
    label:       "UA2E.Sheets.Character"
  });

  // ---- Register item sheets ----
  DocumentSheetConfig.registerSheet(Item, "unknown-armies-v2", UA2eSkillSheet, {
    types:       ["skill"],
    makeDefault: true,
    label:       "UA2E.Sheets.Skill"
  });
  DocumentSheetConfig.registerSheet(Item, "unknown-armies-v2", UA2eGearSheet, {
    types:       ["gear", "weapon"],
    makeDefault: true,
    label:       "UA2E.Sheets.Item"
  });
  DocumentSheetConfig.registerSheet(Item, "unknown-armies-v2", UA2eStrangenessSheet, {
    types:       ["strangeness"],
    makeDefault: true,
    label:       "UA2E.Sheets.Strangeness"
  });
  DocumentSheetConfig.registerSheet(Item, "unknown-armies-v2", UA2eStressAfflictionSheet, {
    types:       ["stressAffliction"],
    makeDefault: true,
    label:       "UA2E.Sheets.StressAffliction"
  });
  DocumentSheetConfig.registerSheet(Item, "unknown-armies-v2", UA2eSpellSheet, {
    types:       ["spell"],
    makeDefault: true,
    label:       "UA2E.Sheets.Spell"
  });
  DocumentSheetConfig.registerSheet(Item, "unknown-armies-v2", UA2eAvatarChannelSheet, {
    types:       ["avatarChannel"],
    makeDefault: true,
    label:       "UA2E.Sheets.AvatarChannel"
  });

  // ---- Trackable token attributes ----
  CONFIG.Actor.trackableAttributes = {
    character: {
      bar:   ["woundPoints"],
      value: []
    }
  };

  // ---- Register Handlebars helpers ----
  _registerHandlebarsHelpers();
});

/* -------------------------------------------- */
/*  Handlebars Helpers                          */
/* -------------------------------------------- */

function _registerHandlebarsHelpers() {
  // Repeat a block N times
  Handlebars.registerHelper("times", (n, block) => {
    let res = "";
    for (let i = 0; i < n; i++) res += block.fn(i);
    return res;
  });

  // Capitalise first letter
  Handlebars.registerHelper("capitalize", str =>
    typeof str === "string" ? str.charAt(0).toUpperCase() + str.slice(1) : str
  );

  // Percentage bar width
  Handlebars.registerHelper("pct", (val, max) =>
    max > 0 ? Math.round((val / max) * 100) : 0
  );

  // Check equality
  Handlebars.registerHelper("eq", (a, b) => a === b);

  // Logical AND for simple template guards
  Handlebars.registerHelper("and", (...args) => args.slice(0, -1).every(Boolean));

  // Tab active class helper
  Handlebars.registerHelper("activeTab", (tab, active) =>
    tab === active ? "active" : ""
  );

  // Range array helper (0 to n-1)
  Handlebars.registerHelper("range", n => Array.from({ length: n }, (_, i) => i));

  // Concatenate strings
  Handlebars.registerHelper("concat", (...args) => args.slice(0, -1).join(""));

  // Localise with fallback
  Handlebars.registerHelper("locOr", (key, fallback) => {
    const localised = game.i18n.localize(key);
    return localised === key ? fallback : localised;
  });
}
