/**
 * Divi Builder Content Bridge
 *
 * Extracts live content from the Divi Visual Builder (frontend VB)
 * and Backend Builder (BFB) for SEO analysis.
 *
 * Supports Divi 4 (shortcode-based) and Divi 5 (JSON block-based).
 */

/**
 * Get the Divi builder iframe element.
 * Checks for VB (frontend), BFB (backend), and Divi 5 VB.
 */
const getDiviIframe = () =>
  document.getElementById('et-fb-app-frame') ||
  document.getElementById('et-bfb-app-frame') ||
  document.getElementById('et-vb-app-frame');

/**
 * Check if we're inside an *active* Divi Builder session.
 *
 * ETBuilderBackend alone is not sufficient — Divi may expose the global
 * on normal post.php screens for configuration purposes.  We require an
 * additional signal (iframe mounted, body class, or Divi 5 API) to confirm
 * the builder is actually open.
 */
export const isDiviEditor = () => {
  // Divi 5 VB — API object only exists during an active VB session
  if (window.ET_Builder?.API) return true;

  // VB body class — set only while the frontend Visual Builder is running
  if (document.body?.classList?.contains('et_fb')) return true;

  // BFB / VB: ETBuilderBackend paired with an actual builder iframe
  if (window.ETBuilderBackend && getDiviIframe()) return true;

  return false;
};

/**
 * Extract rendered HTML from Divi's builder iframe.
 */
export const getDiviContent = () => {
  try {
    const iframe = getDiviIframe();
    if (!iframe?.contentDocument) return '';

    const doc = iframe.contentDocument;

    // Divi 4 & 5: main content area
    const contentEl =
      doc.querySelector('#et-main-area') ||
      doc.querySelector('#et_builder_outer_content') ||
      doc.querySelector('.et_pb_section');

    if (!contentEl) return '';

    return contentEl.innerHTML;
  } catch {
    // Cross-origin or not yet loaded
    return '';
  }
};

/**
 * Get the post title from Divi's builder config.
 */
export const getDiviTitle = () => {
  try {
    // ETBuilderBackend is the primary config object in Divi 4 & 5
    if (window.ETBuilderBackend?.postTitle) {
      return window.ETBuilderBackend.postTitle;
    }

    // Divi 5: check data registry inside iframe
    const iframe = getDiviIframe();
    if (iframe?.contentWindow?.divi?.data) {
      const store = iframe.contentWindow.divi.data.select?.('divi/edit-post');
      if (store?.getPostTitle) return store.getPostTitle() || '';
    }

    return '';
  } catch {
    return '';
  }
};

/**
 * Get the live permalink from Divi's context.
 * Derives from the current URL (VB) or the post ID (BFB).
 */
export const getDiviPermalink = () => {
  try {
    // In the frontend VB, the page URL IS the permalink (minus query params)
    const url = new URL(window.location.href);
    const etFb = url.searchParams.get('et_fb');
    if (etFb) {
      // Strip Divi builder query params to get the clean permalink
      url.searchParams.delete('et_fb');
      url.searchParams.delete('et_bfb');
      url.searchParams.delete('PageSpeed');
      const clean = url.toString();
      // Remove trailing ? if no params remain
      return clean.replace(/\?$/, '');
    }

    // BFB: derive from post ID via ETBuilderBackend
    const postId = window.ETBuilderBackend?.postId;
    if (postId) {
      // Try wp.data if available (Gutenberg stores may be registered)
      const editor = window.wp?.data?.select?.('core/editor');
      if (editor?.getPermalink) return editor.getPermalink() || '';
      if (editor?.getCurrentPost?.()?.link) return editor.getCurrentPost().link;
    }

    return '';
  } catch {
    return '';
  }
};

/**
 * Subscribe to Divi content changes.
 * Returns an unsubscribe function.
 */
export const subscribeToDiviChanges = (callback) => {
  const cleanups = [];
  const $ = window.jQuery;

  // Divi events fire on window via jQuery
  if ($) {
    // Module settings changed (real-time edits)
    try {
      $(window).on('et_fb_module_settings_changed.prorankSeo', callback);
      cleanups.push(() => $(window).off('et_fb_module_settings_changed.prorankSeo'));
    } catch { /* ignore */ }

    // Page finished rendering in canvas
    try {
      $(window).on('et_fb_page_loaded.prorankSeo', callback);
      cleanups.push(() => $(window).off('et_fb_page_loaded.prorankSeo'));
    } catch { /* ignore */ }

    // After save
    try {
      $(window).on('et_builder_after_save.prorankSeo', callback);
      cleanups.push(() => $(window).off('et_builder_after_save.prorankSeo'));
    } catch { /* ignore */ }

    // Module init (inserted/reordered)
    try {
      $(window).on('et_fb_module_init.prorankSeo', callback);
      cleanups.push(() => $(window).off('et_fb_module_init.prorankSeo'));
    } catch { /* ignore */ }
  }

  // Iframe load event
  try {
    const iframe = getDiviIframe();
    if (iframe) {
      const onLoad = () => callback();
      iframe.addEventListener('load', onLoad);
      cleanups.push(() => iframe.removeEventListener('load', onLoad));
    }
  } catch { /* ignore */ }

  // Polling fallback — covers edge cases not caught by events
  const intervalId = window.setInterval(callback, 2000);
  cleanups.push(() => window.clearInterval(intervalId));

  return () => cleanups.forEach((fn) => fn());
};
