interface PluginInfo {
  options?: unknown;
}

interface PluginRuntime {
  info?: PluginInfo;
  init?: (...args: unknown[]) => void;
}

interface AscRuntime {
  plugin?: PluginRuntime;
}

function hasRuntimeOptions(options: unknown): boolean {
  return (typeof options === 'object' && options !== null)
    || (typeof options === 'string' && options.trim().length > 0);
}

/**
 * OnlyOffice 在调用 plugin.init 时才会将 editorConfig.plugins.options 注入 iframe。
 * 不能在 Vue mounted 时抢先读取，否则自动启动插件会拿到空上下文。
 */
export function bindPluginReady(asc: AscRuntime | undefined, onReady: () => void): () => void {
  const plugin = asc?.plugin;
  let initialized = false;
  const initialize = () => {
    if (initialized) return;
    initialized = true;
    onReady();
  };

  if (!plugin) {
    initialize();
    return () => undefined;
  }

  const originalInit = plugin.init;
  const init = (...args: unknown[]) => {
    originalInit?.(...args);
    initialize();
  };
  plugin.init = init;

  // Vite HMR 或手动再次打开插件时，options 可能已经可用而 init 不会再触发。
  if (hasRuntimeOptions(plugin.info?.options)) initialize();

  return () => {
    if (plugin.init === init) plugin.init = originalInit;
  };
}
