// Rôle : regroupe les actions métier de création, import/export, lien et édition toolbox.
import {
  compactModuleDataForStorage,
  createGlobalExportPayload,
  createToolboxExportPayload,
  globalModuleKey,
  labelFromFileName,
  normalizeToolbox,
  remapModuleOrderIds,
  uid
} from "./storage/toolboxStorage.js";
import { compressImage } from "../../utils/imageCompression.js";

function downloadJson(payload, filename) {
  const blob = new Blob([JSON.stringify(payload, null, 2)], { type: "application/json" });
  const link = document.createElement("a");
  link.href = URL.createObjectURL(blob);
  link.download = filename;
  link.click();
  URL.revokeObjectURL(link.href);
}

export function useToolboxActions({ store, notify, setConfirmModal, setCreateModal, setLinkModalGameId, setDrawerGameId, setImage }) {
  function createToolbox(name, gameId = "") {
    const now = new Date().toISOString();
    const toolbox = {
      id: uid("tbx"),
      name: name.trim() || "Nouvelle toolbox",
      updatedAt: now,
      modules: [
        { id: uid("mod"), type: "notepad", title: "Notes rapides" },
        { id: uid("mod"), type: "checklist" }
      ]
    };
    if (!store.setToolboxes([toolbox, ...store.toolboxes])) return null;
    if (gameId) store.setLinks({ ...store.links, [gameId]: toolbox.id });
    return toolbox;
  }

  function updateToolbox(nextToolbox) {
    store.setToolboxes(store.toolboxes.map((toolbox) => toolbox.id === nextToolbox.id
      ? { ...nextToolbox, updatedAt: new Date().toISOString() }
      : toolbox));
  }

  function deleteToolbox(id) {
    const toolbox = store.toolboxes.find((item) => item.id === id);
    store.removeToolboxModuleData(toolbox);
    store.setToolboxes(store.toolboxes.filter((item) => item.id !== id));
    const nextLinks = { ...store.links };
    Object.entries(nextLinks).forEach(([gameId, toolboxId]) => {
      if (toolboxId === id) delete nextLinks[gameId];
    });
    store.setLinks(nextLinks);
  }

  function linkToolboxToGame(gameId, toolboxId) {
    const previousToolboxId = store.links[gameId] || "";
    const nextLinks = { ...store.links };
    if (toolboxId) nextLinks[gameId] = toolboxId;
    else delete nextLinks[gameId];
    store.setLinks(nextLinks);
    const touched = new Set([previousToolboxId, toolboxId].filter(Boolean));
    store.setToolboxes(store.toolboxes.map((toolbox) => touched.has(toolbox.id)
      ? { ...toolbox, updatedAt: new Date().toISOString() }
      : toolbox));
  }

  async function addImageFiles(toolboxId, moduleId, files) {
    const imageFiles = [...files].filter((file) => file?.type?.startsWith("image/"));
    if (!imageFiles.length) return false;
    const data = store.getModuleData(toolboxId, moduleId, { images: [] });
    for (const file of imageFiles) {
      const image = { id: uid("image"), dataUrl: await compressImage(file) };
      const label = labelFromFileName(file.name);
      if (label) image.label = label;
      data.images.unshift(image);
    }
    return store.updateModuleData(toolboxId, moduleId, data);
  }

  function createChecklistFromList(gameId, list) {
    const toolboxId = store.links[gameId] || "";
    const toolbox = store.toolboxes.find((item) => item.id === toolboxId);
    if (!toolbox || !list) return false;

    const moduleId = uid("mod");
    const sections = (list.categories || []).map((category) => ({
      id: uid("section"),
      title: category.title || "",
      items: (category.items || []).map((item) => ({
        id: uid("item"),
        label: item.name,
        qtyTarget: Math.max(1, Number.parseInt(item.quantity, 10) || 1),
        qtyCurrent: 0
      })).filter((item) => item.label)
    })).filter((section) => section.items.length);

    if (!sections.length) return false;

    setConfirmModal({
      title: "Créer une checklist",
      message: `Créer la checklist "${list.title || "Checklist"}" dans la toolbox "${toolbox.name}" ?`,
      confirmLabel: "Créer",
      onResolve: (confirmed) => {
        if (!confirmed) return;
        store.setToolboxes(store.toolboxes.map((item) => item.id === toolboxId
          ? { ...item, modules: [...item.modules, { id: moduleId, type: "checklist", title: list.title || "Checklist" }], updatedAt: new Date().toISOString() }
          : item));
        store.updateModuleData(toolboxId, moduleId, { sections }, "checklist");
        notify("Checklist créée dans la toolbox associée.");
      }
    });
    return true;
  }

  async function importToolboxPayload(file, gameId = "") {
    const payload = JSON.parse(await file.text());
    if (!payload.toolbox?.modules) throw new Error("Format d'outils invalide");
    const imported = normalizeToolbox({ ...payload.toolbox, id: uid("tbx"), updatedAt: new Date().toISOString() });
    const moduleIdMap = new Map();
    imported.modules = imported.modules.map((module) => {
      const nextId = uid("mod");
      moduleIdMap.set(module.id, nextId);
      return { ...module, id: nextId };
    });
    imported.moduleOrder = remapModuleOrderIds(imported.moduleOrder, moduleIdMap);
    const normalizedImport = normalizeToolbox(imported);
    if (!store.setToolboxes([normalizedImport, ...store.toolboxes])) return null;
    Object.entries(payload.modules || {}).forEach(([oldId, data]) => {
      const nextId = moduleIdMap.get(oldId);
      const module = normalizedImport.modules.find((item) => item.id === nextId);
      if (nextId) store.updateModuleData(normalizedImport.id, nextId, data, module?.type);
    });
    if (gameId) linkToolboxToGame(gameId, normalizedImport.id);
    return normalizedImport;
  }

  async function importAllToolboxesPayload(file) {
    const payload = JSON.parse(await file.text());
    if (!Array.isArray(payload.toolboxes) || !payload.modules || typeof payload.modules !== "object") {
      throw new Error("Format d'import global invalide");
    }
    const toolboxIdMap = new Map();
    const moduleIdMap = new Map();
    const importedToolboxes = payload.toolboxes.map((toolbox) => {
      const nextToolboxId = uid("tbx");
      toolboxIdMap.set(toolbox.id, nextToolboxId);
      const localModuleIdMap = new Map();
      const modules = (toolbox.modules || []).map((module) => {
        const nextModuleId = uid("mod");
        moduleIdMap.set(globalModuleKey(toolbox.id, module.id), nextModuleId);
        localModuleIdMap.set(module.id, nextModuleId);
        return { ...module, id: nextModuleId };
      });
      const moduleOrder = remapModuleOrderIds(toolbox.moduleOrder, localModuleIdMap);
      return normalizeToolbox({ ...toolbox, id: nextToolboxId, name: `${toolbox.name || "Toolbox"} (import)`, modules, moduleOrder, updatedAt: new Date().toISOString() });
    });
    const nextLinks = { ...store.links };
    Object.entries(payload.links || {}).forEach(([gameId, oldToolboxId]) => {
      const nextToolboxId = toolboxIdMap.get(oldToolboxId);
      if (nextToolboxId) nextLinks[gameId] = nextToolboxId;
    });
    Object.entries(payload.modules).forEach(([key, data]) => {
      const [oldToolboxId] = key.split(":");
      const nextToolboxId = toolboxIdMap.get(oldToolboxId);
      const nextModuleId = moduleIdMap.get(key);
      const toolbox = importedToolboxes.find((item) => item.id === nextToolboxId);
      const module = toolbox?.modules.find((item) => item.id === nextModuleId);
      const compact = compactModuleDataForStorage(module?.type, data);
      if (nextToolboxId && nextModuleId && compact) store.updateModuleData(nextToolboxId, nextModuleId, compact, module?.type);
    });
    store.setToolboxes([...importedToolboxes, ...store.toolboxes]);
    store.setLinks(nextLinks);
    store.refreshQuota();
  }

  return {
    createToolbox,
    updateToolbox,
    deleteToolbox,
    linkToolboxToGame,
    setCreateModal,
    setConfirmModal,
    setLinkModalGameId,
    setDrawerGameId,
    setImage,
    createChecklistFromList,
    addImageFiles,
    notify,
    removeModuleData: store.removeModuleData,
    updateModuleData: store.updateModuleData,
    updateToolboxOrder: (orderedIds) => {
      const order = new Map(orderedIds.map((id, index) => [id, index]));
      store.setToolboxes([...store.toolboxes].sort((a, b) => (order.get(a.id) ?? 9999) - (order.get(b.id) ?? 9999)));
    },
    importToolbox: async (file, gameId = "") => {
      try {
        const toolbox = await importToolboxPayload(file, gameId);
        if (toolbox) notify("Toolbox importée.");
        return toolbox;
      } catch (error) {
        setConfirmModal({
          title: "Import impossible",
          message: error.message,
          confirmLabel: "Compris",
          cancelLabel: "Fermer",
          danger: true
        });
        return null;
      }
    },
    importAllToolboxes: async (file) => {
      try {
        await importAllToolboxesPayload(file);
        notify("Import global terminé.");
        return true;
      } catch (error) {
        setConfirmModal({
          title: "Import global impossible",
          message: error.message,
          confirmLabel: "Compris",
          cancelLabel: "Fermer",
          danger: true
        });
        return false;
      }
    },
    exportToolbox: (id) => {
      const toolbox = normalizeToolbox(store.toolboxes.find((item) => item.id === id));
      if (!toolbox) return;
      downloadJson(createToolboxExportPayload(toolbox, store.moduleData), `${toolbox.name.toLowerCase().replace(/[^a-z0-9]+/gi, "-")}.sokkog.json`);
      notify("Export de la toolbox lancé.");
    },
    exportAllToolboxes: () => {
      downloadJson(createGlobalExportPayload(store.toolboxes, store.links, store.moduleData), `sokkog-global-${new Date().toISOString().slice(0, 10)}.json`);
      notify("Export global lancé.");
    }
  };
}
