"use client";

import { useEffect, useState } from "react";

const LUCKYSHEET_VERSION = "crdt-20251127";

const withVersion = (path: string) => `${path}?v=${LUCKYSHEET_VERSION}`;

export const LUCKYSHEET_RESOURCES = {
  css: [
    withVersion("/luckysheet/css/luckysheet.css"),
    withVersion("/luckysheet/plugins/plugins.css"),
    withVersion("/luckysheet/plugins/css/pluginsCss.css"),
    withVersion("/luckysheet/assets/iconfont/iconfont.css"),
  ],
  js: [
    withVersion("/luckysheet/plugins/js/plugin.js"),
    withVersion("/luckysheet/luckysheet.umd.js"),
  ],
};

let loaderPromise: Promise<void> | null = null;

const appendCssOnce = (href: string) =>
  new Promise<void>((resolve, reject) => {
    if (typeof document === "undefined") {
      resolve();
      return;
    }

    const marker = `link[data-luckysheet-href="${href}"]`;
    const existing = document.querySelector<HTMLLinkElement>(marker);
    if (existing) {
      if (existing.dataset.loaded === "1") {
        resolve();
        return;
      }
      const handleLoad = () => {
        existing.dataset.loaded = "1";
        resolve();
      };
      const handleError = () => {
        reject(new Error(`加载 Luckysheet 样式失败: ${href}`));
      };
      existing.addEventListener("load", handleLoad, { once: true });
      existing.addEventListener("error", handleError, { once: true });
      return;
    }

    const link = document.createElement("link");
    link.rel = "stylesheet";
    link.href = href;
    link.dataset.luckysheetHref = href;
    link.onload = () => {
      link.dataset.loaded = "1";
      resolve();
    };
    link.onerror = () => {
      reject(new Error(`加载 Luckysheet 样式失败: ${href}`));
    };
    document.head.appendChild(link);
  });

const appendScriptOnce = (src: string) =>
  new Promise<void>((resolve, reject) => {
    if (typeof document === "undefined") {
      resolve();
      return;
    }
    const marker = `script[data-luckysheet-src="${src}"]`;
    const existing = document.querySelector<HTMLScriptElement>(marker);
    if (existing) {
      if (existing.dataset.loaded === "1") {
        resolve();
        return;
      }
      const handleLoad = () => {
        existing.dataset.loaded = "1";
        resolve();
      };
      const handleError = () => {
        reject(new Error(`加载 Luckysheet 资源失败: ${src}`));
      };
      existing.addEventListener("load", handleLoad, { once: true });
      existing.addEventListener("error", handleError, { once: true });
      return;
    }
    const script = document.createElement("script");
    script.src = src;
    script.async = true;
    script.dataset.luckysheetSrc = src;
    script.onload = () => {
      script.dataset.loaded = "1";
      resolve();
    };
    script.onerror = () => {
      reject(new Error(`加载 Luckysheet 资源失败: ${src}`));
    };
    document.body.appendChild(script);
  });

export const ensureLuckysheetLoaded = async () => {
  if (typeof window === "undefined") {
    return;
  }
  if (window.luckysheet) {
    return;
  }
  if (loaderPromise) {
    await loaderPromise;
    return;
  }

  loaderPromise = (async () => {
    const cssPromises = LUCKYSHEET_RESOURCES.css.map((href) => appendCssOnce(href));
    for (const src of LUCKYSHEET_RESOURCES.js) {
      await appendScriptOnce(src);
    }
    await Promise.all(cssPromises);

    if (process.env.NODE_ENV !== "production") {
      (window as unknown as { __wolaiLuckysheetResources?: typeof LUCKYSHEET_RESOURCES }).__wolaiLuckysheetResources = LUCKYSHEET_RESOURCES;
      console.log("[LuckysheetLoader] 资源加载完成", LUCKYSHEET_RESOURCES);
    }
  })();

  await loaderPromise;
};

export const useLuckysheetLoader = () => {
  const [isReady, setIsReady] = useState(
    typeof window !== "undefined" && typeof window.luckysheet !== "undefined",
  );

  useEffect(() => {
    let canceled = false;
    if (typeof window === "undefined") {
      return;
    }
    ensureLuckysheetLoaded()
      .then(() => {
        if (!canceled) {
          setIsReady(true);
        }
      })
      .catch((error) => {
        console.error("Luckysheet 资源加载失败", error);
      });
    return () => {
      canceled = true;
    };
  }, []);

  return isReady;
};
