/**
 * Donjon & Cie - Systeme FoundryVTT
 *
 * Donjon & Cie est un jeu de role edite par John Doe.
 * Ce systeme FoundryVTT est une implementation independante et n'est pas
 * affilie a John Doe.
 *
 * @author    LeRatierBretonnien
 * @copyright 2025–2026 LeRatierBretonnien
 * @license   CC BY-NC-SA 4.0 – https://creativecommons.org/licenses/by-nc-sa/4.0/
 */

import { DONJON_ET_CIE } from "./donjon-et-cie-config.mjs";
import { DonjonEtCieUtility } from "./donjon-et-cie-utility.mjs";

import { DonjonEtCieActor } from "./donjon-et-cie-actor.mjs";
import { DonjonEtCieItem } from "./donjon-et-cie-item.mjs";
import * as models from "./models/index.mjs";
import * as sheets from "./applications/sheets/_module.mjs";
import { DonjonEtCieRollDialog } from "./applications/donjon-et-cie-roll-dialog.mjs";
import { DonjonEtCieEmployesDialog } from "./applications/donjon-et-cie-employes-dialog.mjs";
import { DonjonEtCieRolls } from "./donjon-et-cie-rolls.mjs";
import { DonjonEtCieMacros } from "./donjon-et-cie-macros.mjs";

const WELCOME_MESSAGE_SETTING = "welcomeMessageVersion";

function injectActorDirectoryMissionPackButton(app, element) {
  if (!game.user.isGM) return;

  const root = app?.element ?? element?.[0] ?? element;
  if (!(root instanceof HTMLElement)) return;

  const headerActions = root.querySelector(".directory-header .header-actions");
  if (!(headerActions instanceof HTMLElement)) return;
  if (headerActions.querySelector(".dnc-mission-pack-button")) return;

  const button = document.createElement("button");
  button.type = "button";
  button.className = "dnc-mission-pack-button";
  button.title = game.i18n.localize("DNC.Macro.MissionPack.SidebarButton");
  button.setAttribute("aria-label", game.i18n.localize("DNC.Macro.MissionPack.SidebarButton"));
  button.innerHTML = `<i class="fa-solid fa-box-open" inert></i><span>${game.i18n.localize("DNC.Macro.MissionPack.SidebarButton")}</span>`;
  button.addEventListener("click", () => {
    void game.system.donjonEtCie.macros.openMissionPackDialog();
  });
  headerActions.append(button);

  // Bouton "Employés / Clients"
  const empButton = document.createElement("button");
  empButton.type = "button";
  empButton.className = "dnc-employes-button";
  empButton.title = game.i18n.localize("DNC.Dialog.EmployeesTitle");
  empButton.setAttribute("aria-label", game.i18n.localize("DNC.Dialog.EmployeesTitle"));
  empButton.innerHTML = `<i class="fa-solid fa-hard-hat" inert></i><span>${game.i18n.localize("DNC.Dialog.EmployeesTitle")}</span>`;
  empButton.addEventListener("click", () => {
    void DonjonEtCieEmployesDialog.open();
  });
  headerActions.append(empButton);
}

function onChatActionClick(event) {
  const button = event.target.closest("[data-action='rollChatDamage'], [data-action='rollSpellChaos'], [data-action='applyDamage'], [data-action='rollAmmoUsage'], [data-action='rollDamageUsage']");
  if (!(button instanceof HTMLElement)) return;

  event.preventDefault();

  void (async () => {
    if (button.dataset.action === "rollSpellChaos") {
      const actorUuid = button.dataset.actorUuid;
      const itemUuid = button.dataset.itemUuid;
      if (!actorUuid || !itemUuid) return;
      const [actor, item] = await Promise.all([fromUuid(actorUuid), fromUuid(itemUuid)]);
      return DonjonEtCieRolls.rollSpellChaos(actor, item);
    }

    if (button.dataset.action === "applyDamage") {
      const card = button.closest(".dnc-chat-card-damage");
      const select = card?.querySelector("[data-role='damage-target']");
      const targetUuid = select instanceof HTMLSelectElement ? select.value : "";
      if (!targetUuid) {
        ui.notifications.warn(game.i18n.localize("DNC.Chat.SelectTarget"));
        return null;
      }

      const target = await fromUuid(targetUuid);
      if (!target) {
        ui.notifications.warn(game.i18n.localize("DNC.Chat.TargetUnavailable"));
        return null;
      }

      return DonjonEtCieRolls.applyDamage(target, {
        damage: Number(button.dataset.damage ?? 0),
        useArmor: button.dataset.useArmor === "true",
        sourceLabel: button.dataset.sourceLabel ?? ""
      });
    }

    const itemUuid = button.dataset.itemUuid;
    if (!itemUuid) return;
    const item = await fromUuid(itemUuid);
    if (button.dataset.action === "rollAmmoUsage") {
      return item?.rollAmmoUsage?.();
    }
    if (button.dataset.action === "rollDamageUsage") {
      return item?.rollDamageUsage?.();
    }
    return item?.rollDamage?.();
  })();
}

function registerSystemSettings() {
  game.settings.register("fvtt-donjon-et-cie", WELCOME_MESSAGE_SETTING, {
    name: "Version du message de bienvenue",
    hint: "Usage interne pour eviter de republier le message de bienvenue a chaque chargement.",
    scope: "world",
    config: false,
    type: String,
    default: ""
  });

  game.settings.register("fvtt-donjon-et-cie", DonjonEtCieMacros.MISSION_PACK_MODE_SETTING, {
    name: "Mode de paquetage de mission",
    hint: "Choisit entre le tirage classique rapide et la regle optionnelle de campagne avec allocation des des par les joueurs.",
    scope: "world",
    config: true,
    type: String,
    default: "classic",
    choices: {
      classic: "Classique",
      campaign: "Campagne"
    }
  });
}

async function getHelpJournalLink() {
  const pack = [...game.packs.values()].find((candidate) => candidate.metadata.name === "system-help");
  if (!pack) return null;

  const index = await pack.getIndex();
  const entry = index.find((document) => document.name === "Aide du systeme");
  if (!entry?._id) return null;

  const journal = await pack.getDocument(entry._id);
  if (!journal?.uuid) return null;

  return `@UUID[${journal.uuid}]{${game.i18n.localize("DNC.Welcome.HelpLinkLabel")}}`;
}

async function maybeCreateWelcomeMessage() {
  if (!game.user.isGM) return;

  const currentVersion = String(game.system.version ?? "");
  const shownVersion = String(game.settings.get("fvtt-donjon-et-cie", WELCOME_MESSAGE_SETTING) ?? "");
  if (shownVersion === currentVersion) return;

  const helpJournalLink = await getHelpJournalLink();
  const content = await foundry.applications.handlebars.renderTemplate(
    "systems/fvtt-donjon-et-cie/templates/chat/welcome-card.hbs",
    {
      title: game.i18n.localize("DNC.Welcome.Title"),
      subtitle: game.i18n.format("DNC.Welcome.Subtitle", { version: currentVersion }),
      intro: game.i18n.localize("DNC.Welcome.Intro"),
      bullets: [
        game.i18n.localize("DNC.Welcome.BulletActors"),
        game.i18n.localize("DNC.Welcome.BulletItems"),
        game.i18n.localize("DNC.Welcome.BulletMissionPack")
      ],
      helpLabel: game.i18n.localize("DNC.Welcome.HelpLabel"),
      helpLink: helpJournalLink,
      helpFallback: game.i18n.localize("DNC.Welcome.HelpFallback"),
      footer: game.i18n.localize("DNC.Welcome.Footer"),
      creditsLabel: game.i18n.localize("DNC.Welcome.CreditsLabel"),
      creditsText: game.i18n.localize("DNC.Welcome.CreditsText"),
      officialLabel: game.i18n.localize("DNC.Welcome.OfficialLabel"),
      officialUrl: "https://johndoe-rpg.com/catalogue/donjon-cie/",
      officialLinkText: game.i18n.localize("DNC.Welcome.OfficialLinkText")
    }
  );

  await ChatMessage.create({
    speaker: {
      alias: game.system.title
    },
    user: game.user.id,
    content: await TextEditor.enrichHTML(content, { async: true })
  });

  await game.settings.set("fvtt-donjon-et-cie", WELCOME_MESSAGE_SETTING, currentVersion);
}

Hooks.once("init", async () => {
  const startupBanner =
    `▗▄▄▄   ▗▄▖ ▗▖  ▗▖   ▗▖ ▗▄▖ ▗▖  ▗▖    ▗▄▄▄▖▗▄▄▄▖     ▗▄▄▖▗▄▄▄▖▗▞▀▚▖
▐▌  █ ▐▌ ▐▌▐▛▚▖▐▌   ▐▌▐▌ ▐▌▐▛▚▖▐▌    ▐▌     █      ▐▌     █  ▐▛▀▀▘
▐▌  █ ▐▌ ▐▌▐▌ ▝▜▌   ▐▌▐▌ ▐▌▐▌ ▝▜▌    ▐▛▀▀▘  █      ▐▌     █  ▝▚▄▄▖
▐▙▄▄▀ ▝▚▄▞▘▐▌  ▐▌▗▄▄▞▘▝▚▄▞▘▐▌  ▐▌    ▐▙▄▄▖  █      ▝▚▄▄▖▗▄█▄▖
`;

  console.log(`%c${startupBanner}`, "font-family: monospace; white-space: pre; line-height: 1.1;");
  console.log("Initialisation du systeme Donjon & Cie");

  registerSystemSettings();
  await DonjonEtCieUtility.preloadHandlebarsTemplates();

  CONFIG.Combat.initiative = {
    formula: "1d20 + @system.caracteristiques.dexterite.value + @system.combat.initiativeBonus",
    decimals: 0
  };

  CONFIG.Actor.documentClass = DonjonEtCieActor;
  CONFIG.Actor.dataModels = {
    employe: models.EmployeDataModel,
    pnj: models.PnjDataModel
  };

  CONFIG.Item.documentClass = DonjonEtCieItem;
  CONFIG.Item.dataModels = {
    trait: models.TraitDataModel,
    langue: models.LangueDataModel,
    capacite: models.CapaciteDataModel,
    sortilege: models.SortilegeDataModel,
    arme: models.ArmeDataModel,
    armure: models.ArmureDataModel,
    equipement: models.EquipementDataModel,
    consommable: models.ConsommableDataModel,
    entrainement: models.EntrainementDataModel
  };

  game.system.donjonEtCie = {
    config: DONJON_ET_CIE,
    models,
    sheets,
    rolls: DonjonEtCieRolls,
    dialogs: DonjonEtCieRollDialog,
    utility: DonjonEtCieUtility,
    macros: DonjonEtCieMacros
  };

  foundry.documents.collections.Actors.unregisterSheet("core", foundry.appv1.sheets.ActorSheet);
  foundry.documents.collections.Actors.registerSheet("fvtt-donjon-et-cie", sheets.DonjonEtCieEmployeSheet, { types: ["employe"], makeDefault: true });
  foundry.documents.collections.Actors.registerSheet("fvtt-donjon-et-cie", sheets.DonjonEtCiePNJSheet, { types: ["pnj"], makeDefault: true });

  foundry.documents.collections.Items.unregisterSheet("core", foundry.appv1.sheets.ItemSheet);
  for (const type of ["trait", "langue", "capacite", "sortilege", "arme", "armure", "equipement", "consommable", "entrainement"]) {
    foundry.documents.collections.Items.registerSheet("fvtt-donjon-et-cie", sheets.DonjonEtCieItemSheet, { types: [type], makeDefault: true });
  }
});

// Gestion de la commande /employes
// Enregistrement officiel via ChatLogV2.CHAT_COMMANDS (comme mgt2-compendium-amiral-denisov)
function registerEmployesCommand() {
  const ChatLogV2 = foundry.applications.sidebar.tabs.ChatLog;
  
  if (ChatLogV2?.CHAT_COMMANDS) {
    ChatLogV2.CHAT_COMMANDS.employes = {
      rgx: /^\/employes(?:\s+(.*))?$/i,
      fn: () => {
        DonjonEtCieEmployesDialog.open();
        return false;
      },
    };
    console.log("DNC | Commande /employes enregistrée via ChatLog.CHAT_COMMANDS");
  } else {
    console.warn("DNC | ChatLog.CHAT_COMMANDS indisponible, utilisation des hooks de fallback");
  }
}

Hooks.once("init", () => {
  registerEmployesCommand();
});

Hooks.once("ready", () => {
  DonjonEtCieMacros.registerSocketListeners();
  document.addEventListener("click", onChatActionClick);
  void maybeCreateWelcomeMessage();

  // Hooks de fallback pour compatibilité
  Hooks.on("preCreateChatMessage", (message, data, options, userId) => {
    const content = data.content?.trim()?.toLowerCase();
    if (content === "/employes" || content?.startsWith("/employes ")) {
      DonjonEtCieEmployesDialog.open();
      return false;
    }
    return true;
  });

  Hooks.on("chatMessage", (...args) => {
    // Gestion compatibilité v13/v14
    let message;
    if (args[0]?.content !== undefined) {
      message = args[0].content; // v14
    } else if (typeof args[1] === "string") {
      message = args[1]; // v13
    } else {
      return true;
    }
    
    const trimmed = message?.trim()?.toLowerCase();
    if (trimmed === "/employes" || trimmed?.startsWith("/employes ")) {
      DonjonEtCieEmployesDialog.open();
      return false;
    }
    return true;
  });
});

Hooks.on("renderActorDirectory", (app, element) => {
  injectActorDirectoryMissionPackButton(app, element);
});
