"use client";

import { useEffect, useMemo, useState } from "react";
import { useSearchParams } from "next/navigation";
import { OnlyOfficeAiAgentPanel } from "@/components/onlyoffice/OnlyOfficeAiAgentPanel";
import { rewriteToPublicOrigin } from "@/lib/url/rewritePublicOrigin";

type EditorMode = "view" | "edit";

const MNOTE_AGENT_PLUGIN_GUID = "asc.{F2B9A7B4-3A22-4E0E-8B32-3B0DE7AE8A60}";

const loadScript = (src: string) =>
  new Promise<void>((resolve, reject) => {
    const existing = document.querySelector(`script[src="${src}"]`);
    if (existing) {
      existing.addEventListener("load", () => resolve(), { once: true });
      resolve();
      return;
    }
    const script = document.createElement("script");
    script.src = src;
    script.async = true;
    script.onload = () => resolve();
    script.onerror = () => reject(new Error(`加载 ONLYOFFICE 脚本失败: ${src}`));
    document.body.appendChild(script);
  });

const hashKey = (input: string) => {
  let hash = 0;
  for (let i = 0; i < input.length; i += 1) {
    hash = (hash << 5) - hash + input.charCodeAt(i);
    hash |= 0;
  }
  return Math.abs(hash).toString();
};

const docTypeFromExt = (ext: string) => {
  const word = ["doc", "docx", "odt", "rtf"];
  const slide = ["ppt", "pptx", "odp"];
  const sheet = ["xls", "xlsx", "ods", "csv"];
  const pdf = ["pdf"];
  // 说明：ONLYOFFICE 文档类型使用 word/cell/slide/pdf（旧的 text/spreadsheet/presentation 已逐步弃用）
  if (word.includes(ext)) return "word";
  if (slide.includes(ext)) return "slide";
  if (sheet.includes(ext)) return "cell";
  if (pdf.includes(ext)) return "pdf";
  return "word";
};

export default function OnlyOfficePage() {
  const params = useSearchParams();
  const fileUrl = params.get("fileUrl") ?? "";
  const fileName = params.get("fileName") ?? "未命名文档";
  const fileType = (params.get("fileType") ?? "docx").toLowerCase();
  const mode = (params.get("mode") ?? "edit") as EditorMode;
  const assetId = params.get("assetId") ?? "";
  const [error, setError] = useState<string | null>(null);
  const baseUrl = process.env.NEXT_PUBLIC_ONLYOFFICE_BASE_URL;
  const storageHostOverride =
    process.env.NEXT_PUBLIC_ONLYOFFICE_STORAGE_HOST_OVERRIDE;

  const targetDocType = useMemo(() => docTypeFromExt(fileType), [fileType]);    
  const resolvedFileUrl = useMemo(() => {
    if (!fileUrl) return "";
    // 说明：OnlyOffice 的 document.url 由“文档服务器”拉取（不是浏览器）。
    // 如果我们已经配置了专用回源（storageHostOverride），就不要再把 URL 改写成公网，
    // 否则会把 http://host.docker.internal:18000 错误改成 https://host.docker.internal:18000，
    // 导致 ONLYOFFICE 报 “下载失败（EPROTO wrong version number）”。
    const base = storageHostOverride
      ? fileUrl
      : rewriteToPublicOrigin(fileUrl, process.env.NEXT_PUBLIC_SUPABASE_URL);
    try {
      const u = new URL(base);
      if (!storageHostOverride) return u.toString();

      // 兼容两种写法：hostname 或完整 origin（https://xxx）
      if (/^https?:\/\//i.test(storageHostOverride)) {
        const ov = new URL(storageHostOverride);
        u.protocol = ov.protocol;
        u.host = ov.host;
        return u.toString();
      }

      u.hostname = storageHostOverride;
      return u.toString();
    } catch {
      return base;
    }
  }, [fileUrl, storageHostOverride]);

  useEffect(() => {
    if (!baseUrl) {
      setError("缺少 NEXT_PUBLIC_ONLYOFFICE_BASE_URL 配置，无法加载编辑器。");
      return;
    }
    if (!fileUrl) {
      setError("缺少 fileUrl 参数。");
      return;
    }
    const scriptUrl = `${baseUrl.replace(/\/$/, "")}/web-apps/apps/api/documents/api.js`;
    loadScript(scriptUrl)
      .then(() => {
        // @ts-expect-error ONLYOFFICE 全局对象
        if (!window.DocsAPI) {
          throw new Error("未检测到 DocsAPI，请检查 ONLYOFFICE 版本。");
        }
        // eslint-disable-next-line new-cap,@typescript-eslint/no-explicit-any
        const pluginConfigUrl = `${window.location.origin}/onlyoffice/plugins/agent-tools/config.json`;
        new (window as any).DocsAPI.DocEditor("onlyoffice-frame", {
          width: "100%",
          height: "100%",
          document: {
            fileType,
            title: fileName,
            url: resolvedFileUrl,
            key: hashKey(`${resolvedFileUrl}-${fileName}`),
          },
          documentType: targetDocType,
          editorConfig: {
            mode: mode === "view" ? "view" : "edit",
            lang: "zh-CN",
            customization: {
              feedback: { visible: false },
            },
            plugins: {
              autostart: [MNOTE_AGENT_PLUGIN_GUID],
              pluginsData: [pluginConfigUrl],
            },
          },
        });
      })
      .catch((err: Error) => {
        setError(err.message);
      });
  }, [baseUrl, fileName, fileType, mode, resolvedFileUrl, targetDocType]);

  if (error) {
    return (
      <div className="flex h-screen flex-col items-center justify-center gap-3 bg-slate-50">
        <p className="text-base font-semibold text-red-600">ONLYOFFICE 加载失败</p>
        <p className="text-sm text-gray-600">{error}</p>
      </div>
    );
  }

  return (
    <div className="relative h-screen w-screen bg-slate-50">
      <div id="onlyoffice-frame" className="h-full w-full" />
      <OnlyOfficeAiAgentPanel
        openFile={{
          id: assetId || `onlyoffice_${hashKey(`${resolvedFileUrl}-${fileName}`)}`,
          title: fileName,
          fileUrl: resolvedFileUrl,
          mimeType: null,
        }}
      />
    </div>
  );
}
