// 说明：该插件用于把 ONLYOFFICE 编辑器“选区读/写”能力暴露给宿主页面（MNOTE）。
// 宿主页面通过 postMessage 下发 oo_* 工具调用；插件执行后再 postMessage 回传结果。
(function () {
  const CHANNEL = "mnote_onlyoffice_agent_tools_v1";
  let readyPulseTimer = null;
  let readyPulseDeadline = 0;

  const safePostToTop = (payload) => {
    try {
      if (typeof window === "undefined") return;
      if (!window.top) return;
      window.top.postMessage({ channel: CHANNEL, ...payload }, "*");
    } catch {
      // ignore
    }
  };

  const isPluginApiReady = () =>
    Boolean(window.Asc && window.Asc.plugin && typeof window.Asc.plugin.executeMethod === "function");

  const stopReadyPulse = () => {
    if (readyPulseTimer) {
      window.clearInterval(readyPulseTimer);
      readyPulseTimer = null;
    }
    readyPulseDeadline = 0;
  };

  const startReadyPulse = () => {
    if (readyPulseTimer) return;
    readyPulseDeadline = Date.now() + 20_000;
    safePostToTop({ type: "ready" });
    readyPulseTimer = window.setInterval(() => {
      if (Date.now() > readyPulseDeadline) {
        stopReadyPulse();
        return;
      }
      safePostToTop({ type: "ready" });
    }, 1000);
  };

  const waitForPluginApiReady = () => {
    if (isPluginApiReady()) {
      startReadyPulse();
      return;
    }

    const deadline = Date.now() + 60_000;
    const timer = window.setInterval(() => {
      if (isPluginApiReady()) {
        window.clearInterval(timer);
        startReadyPulse();
        return;
      }
      if (Date.now() > deadline) {
        window.clearInterval(timer);
        safePostToTop({ type: "result", callId: "bridge_bootstrap", ok: false, error: "ONLYOFFICE 插件 API 长时间未就绪" });
      }
    }, 500);
  };

  const execMethod = (method, args) =>
    new Promise((resolve, reject) => {
      try {
        if (!window.Asc || !window.Asc.plugin) throw new Error("ONLYOFFICE 插件 API 未就绪");
        window.Asc.plugin.executeMethod(method, Array.isArray(args) ? args : [], (res) => resolve(res));
      } catch (e) {
        reject(e instanceof Error ? e : new Error(String(e)));
      }
    });

  const handleTool = async (tool, args) => {
    const a = args && typeof args === "object" ? args : {};
    if (tool === "oo_get_selection") {
      // 说明：先做最基础的“纯文本选区读取”，HTML 可在后续升级（需要更复杂的导出方式）。
      const text = await execMethod("GetSelectedText", []);
      return { format: "text", text: String(text ?? "") };
    }

    if (tool === "oo_replace_selection") {
      const format = String(a.format ?? "text");
      const text = String(a.text ?? "");
      if (format === "html") {
        await execMethod("PasteHtml", [text]);
        return { ok: true, format: "html", length: text.length };
      }
      await execMethod("PasteText", [text]);
      return { ok: true, format: "text", length: text.length };
    }

    if (tool === "oo_insert_text") {
      const text = String(a.text ?? "");
      await execMethod("PasteText", [text]);
      return { ok: true, length: text.length };
    }

    if (tool === "oo_insert_html") {
      const html = String(a.html ?? "");
      await execMethod("PasteHtml", [html]);
      return { ok: true, length: html.length };
    }

    if (tool === "oo_insert_image") {
      // 说明：优先用 HTML 插入 <img>，避免依赖 PutImageDataToSelection 的参数差异。
      const src = String(a.src ?? a.imageData ?? "");
      if (!src) throw new Error("缺少图片数据（src/imageData）");
      const w = Number(a.width ?? 0);
      const h = Number(a.height ?? 0);
      const widthAttr = Number.isFinite(w) && w > 0 ? ` width=\"${Math.floor(w)}\"` : "";
      const heightAttr = Number.isFinite(h) && h > 0 ? ` height=\"${Math.floor(h)}\"` : "";
      const html = `<img src=\"${src}\"${widthAttr}${heightAttr} />`;
      await execMethod("PasteHtml", [html]);
      return { ok: true };
    }

    throw new Error(`未知工具：${tool}`);
  };

  window.Asc = window.Asc || {};
  window.Asc.plugin = window.Asc.plugin || {};

  window.Asc.plugin.init = function () {
    startReadyPulse();
  };

  waitForPluginApiReady();

  window.addEventListener("message", async (ev) => {
    const msg = ev && ev.data ? ev.data : null;
    if (!msg || typeof msg !== "object") return;
    if (msg.channel !== CHANNEL) return;
    if (msg.type !== "call") return;

    stopReadyPulse();

    const callId = String(msg.callId ?? "").trim();
    const tool = String(msg.tool ?? "").trim();
    const args = msg.args && typeof msg.args === "object" ? msg.args : {};
    if (!callId || !tool) return;

    try {
      const result = await handleTool(tool, args);
      safePostToTop({ type: "result", callId, ok: true, result });
    } catch (e) {
      const err = e instanceof Error ? e.message : String(e);
      safePostToTop({ type: "result", callId, ok: false, error: err });
    }
  });
})();
