export function runtimeBootstrapScript(basePath = "") {
    return `(() => {
    const runtime = {
      basePath: ${JSON.stringify(basePath)},
      hooks: {},
      mounts: {},
      registerMount(pluginId, hookName, mountId, mountFn) {
        const key = pluginId + ':' + hookName + ':' + mountId;
        this.mounts[key] = mountFn;
      },
      async loadScript(url) {
        if (document.querySelector('script[data-runtime-src="' + url + '"]')) return;
        await new Promise((resolve, reject) => {
          const script = document.createElement('script');
          script.src = url;
          script.async = true;
          script.dataset.runtimeSrc = url;
          script.onload = () => resolve();
          script.onerror = reject;
          document.head.appendChild(script);
        });
      },
      ensureCss(url) {
        if (!url || document.querySelector('link[data-runtime-css="' + url + '"]')) return;
        const link = document.createElement('link');
        link.rel = 'stylesheet';
        link.href = url;
        link.dataset.runtimeCss = url;
        document.head.appendChild(link);
      },
      async fetchHooks() {
        const res = await fetch(this.basePath + '/api/runtime/hooks', { credentials: 'include' });
        if (!res.ok) throw new Error('hook fetch failed: ' + res.status);
        const data = await res.json();
        this.hooks = data.hooks || {};
        return data;
      },
      toolbarAnchor() {
        return document.querySelector('[data-mailcow-plugin-hook="mail.compose.toolbar"]')
          || document.querySelector('.compose-toolbar')
          || document.querySelector('[role="toolbar"]')
          || document.body;
      },
      attachmentsAnchor() {
        return document.querySelector('[data-mailcow-plugin-hook="mail.compose.attachments"]')
          || document.querySelector('.compose-attachments')
          || document.querySelector('[data-attachments]')
          || document.body;
      },
      async mountContribution(contribution) {
        if (contribution.cssUrl) this.ensureCss(contribution.cssUrl);
        if (contribution.mountUrl) await this.loadScript(contribution.mountUrl);
        const key = contribution.pluginId + ':' + contribution.hook + ':' + contribution.id;
        const mountFn = this.mounts[key];
        if (!mountFn) return;
        const parent = contribution.hook === 'mail.compose.attachments' ? this.attachmentsAnchor() : this.toolbarAnchor();
        let target = parent.querySelector('[data-plugin-target="' + key + '"]');
        if (!target) {
          target = document.createElement('div');
          target.dataset.pluginTarget = key;
          target.className = 'mailcow-plugin-target';
          parent.appendChild(target);
        }
        const context = {
          basePath: this.basePath,
          contribution,
          hooks: this.hooks,
          apiBase: contribution.apiBase,
          uiBase: contribution.uiBase,
          user: window.MAILCOW_USER || null,
        };
        await mountFn(target, context);
      },
      async renderHook(hookName) {
        const list = this.hooks[hookName] || [];
        for (const contribution of list) {
          try {
            await this.mountContribution(contribution);
          } catch (error) {
            console.error('Failed to mount contribution', contribution, error);
          }
        }
      },
      async init() {
        window.MAILCOW_PLUGIN_RUNTIME = this;
        await this.fetchHooks();
        await this.renderHook('mail.compose.toolbar');
        await this.renderHook('mail.compose.attachments');
      }
    };
    const start = () => runtime.init().catch((err) => console.error('Mailcow plugin runtime bootstrap failed', err));
    if (document.readyState === 'loading') {
      document.addEventListener('DOMContentLoaded', start, { once: true });
    } else {
      start();
    }
  })();`;
}
