(function () {
  'use strict';

  // Idempotency guard: bail if embed.js has already executed on this page.
  // Loading it twice causes duplicate <script>/<link> injection and (under
  // deploy races) a second main bundle, which produces a React render loop.
  if (window.__diqEmbedLoaded) {
    console.warn(
      '[DemandIQ] embed.js was loaded more than once on this page. ' +
        'Remove the duplicate <script src=".../embed.js"> tag — ' +
        'including it twice can cause the journey to render in a loop.'
    );
    return;
  }
  window.__diqEmbedLoaded = true;

  // Performance telemetry — collect timing marks before React loads
  window.__diq_perf = [];
  window.__diq_perf.push({ name: 'diq:embed_start', startTime: performance.now() });

  // Detect base URL from script src
  var scriptEl = document.currentScript;
  var baseUrl = '';

  if (scriptEl && scriptEl.src) {
    // Extract base URL from the embed.js script location
    // e.g., https://journey.demand-iq.com/embed.js -> https://journey.demand-iq.com/
    baseUrl = scriptEl.src.replace(/embed\.js(\?.*)?$/, '');
  }

  // Fallback for browsers that don't support currentScript or async scenarios
  if (!baseUrl) {
    var scripts = document.getElementsByTagName('script');
    for (var i = 0; i < scripts.length; i++) {
      if (scripts[i].src && scripts[i].src.indexOf('embed.js') !== -1) {
        baseUrl = scripts[i].src.replace(/embed\.js(\?.*)?$/, '');
        break;
      }
    }
  }

  // Default to production if detection fails
  if (!baseUrl) {
    baseUrl = 'https://journey.demand-iq.com/';
  }

  // --- ENG-1009: escape site-builder srcdoc sandboxes -----------------------
  // Some site builders (GoDaddy) wrap pasted embed code in a sandboxed
  // <iframe srcdoc="...">, so this script runs in an `about:srcdoc` document:
  // wrong referrer for the Places API key check, `X-EMBEDDED-URL: about:srcdoc`
  // to the backend, empty UTMs, broken deep links. When the sandbox grants
  // allow-same-origin, we escape: move the container div(s) into the parent
  // document next to the hosting iframe, hide the iframe, inject a fresh
  // embed.js into the parent, and stop this copy. The app then runs natively
  // in the real page. The parent copy sees a real location.href, so it can
  // never try to escape again.

  function detectSrcdocSandbox() {
    // Exact match on the spec'd srcdoc URL — never true for real pages,
    // customers who deliberately iframe the embed with a real URL, or
    // about:blank widget loaders. Own-document location reads never throw,
    // even on an opaque origin.
    if (window.location.href !== 'about:srcdoc') {
      return { inSrcdoc: false, parentReachable: false };
    }
    var frameEl = null;
    try {
      // null when the sandbox lacks allow-same-origin (opaque origin fails
      // the same-origin-domain check). try/catch in case an engine throws
      // instead.
      frameEl = window.frameElement;
    } catch (e) {
      frameEl = null;
    }
    if (!frameEl) {
      return { inSrcdoc: true, parentReachable: false };
    }
    try {
      var parentDoc = frameEl.ownerDocument;
      var reachable = !!(parentDoc && parentDoc.defaultView && frameEl.parentNode);
      return { inSrcdoc: true, parentReachable: reachable, frameEl: reachable ? frameEl : undefined };
    } catch (e) {
      return { inSrcdoc: true, parentReachable: false };
    }
  }

  function trySandboxEscape() {
    var detection = detectSrcdocSandbox();
    if (!detection.inSrcdoc) {
      return false;
    }
    if (!detection.parentReachable) {
      // Locked-down sandbox — nothing we can do. Log, flag for telemetry
      // (this copy's bundle still boots below), and degrade in place.
      console.error(
        '[DemandIQ] embed.js is running inside a sandboxed srcdoc iframe ' +
          "(commonly a site builder's code-embed widget) that does not grant " +
          'access to the parent page (sandbox is missing allow-same-origin). ' +
          'The journey may render with degraded behavior (address autocomplete, ' +
          'deep links, lead-cert tracking). Enable allow-same-origin on the ' +
          'embed sandbox, or move the embed code outside the code-embed widget.'
      );
      window.dispatchEvent(
        new CustomEvent('demand-iq-load-error', {
          detail: new Error('Sandboxed srcdoc iframe: parent document unreachable'),
        })
      );
      window.__diqSandboxEscape = { attempted: true, escaped: false, reason: 'locked-down-sandbox' };
      return false;
    }

    var frameEl = detection.frameEl;
    var parentDoc = frameEl.ownerDocument;
    var parentWin = parentDoc.defaultView;

    // Same container selector as main.tsx forceStartup(). Scoped to THIS
    // sandboxed document, so sibling srcdoc iframes never cross-talk.
    var containers = document.querySelectorAll('[data-journey-id], [id=demand-iq-journey], [id^="demand-iq-journey-"]');
    if (containers.length === 0) {
      // Script-only paste with no container — nothing to move; the normal
      // flow below just idles, same as today.
      return false;
    }
    for (var c = 0; c < containers.length; c++) {
      // importNode deep-clones into the parent document's ownership,
      // including every data-* attribute (api-key, journey-id, …).
      var clone = parentDoc.importNode(containers[c], true);
      frameEl.parentNode.insertBefore(clone, frameEl);
    }

    // Hide rather than remove: site-builder re-render passes can resurrect
    // nodes they own, and display:none leaves no blank gap even when the
    // builder gave the iframe fixed dimensions.
    frameEl.style.setProperty('display', 'none', 'important');
    frameEl.setAttribute('data-demand-iq-escaped', 'true');

    window.__diq_perf.push({ name: 'diq:sandbox_escape', startTime: performance.now() });

    if (parentWin.__diqEmbedLoaded || parentWin.__diqEmbedInjected) {
      // The parent already has an embed.js — either the owner also pasted one
      // at top level (__diqEmbedLoaded) or a sibling srcdoc iframe escaped
      // first and injected one that may not have executed yet
      // (__diqEmbedInjected). Don't inject a second copy. If the parent
      // bundle is already running, its 10s startup poll may have elapsed —
      // nudge it to pick up the moved container(s) now; a not-yet-executed
      // copy will find them on its own.
      parentWin.__diqSandboxEscape = { attempted: true, escaped: true, reason: 'moved-to-existing-parent-embed' };
      if (parentWin.DemandIQJourney && typeof parentWin.DemandIQJourney.forceStartup === 'function') {
        parentWin.DemandIQJourney.forceStartup();
      }
      return true;
    }

    // NOTE: do NOT set parentWin.__diqEmbedLoaded here — the injected copy's
    // own top-of-file guard would see it and bail. __diqEmbedInjected is a
    // separate marker that only dedupes escape-driven injection; the injected
    // copy claims __diqEmbedLoaded itself when it runs.
    parentWin.__diqEmbedInjected = true;
    parentWin.__diqSandboxEscape = { attempted: true, escaped: true, reason: 'escaped-fresh-embed' };
    var parentScript = parentDoc.createElement('script');
    parentScript.src = scriptEl && scriptEl.src ? scriptEl.src : baseUrl + 'embed.js';
    parentScript.async = true;
    parentScript.setAttribute('data-demand-iq', 'true');
    (parentDoc.head || parentDoc.documentElement).appendChild(parentScript);
    return true;
  }

  if (trySandboxEscape()) {
    // Everything now lives in the parent document; this sandboxed copy is done.
    return;
  }
  // --------------------------------------------------------------------------

  // Fetch manifest with cache-busting timestamp
  var manifestUrl = baseUrl + 'manifest.json?_=' + Date.now();

  window.__diq_perf.push({ name: 'diq:manifest_fetch_start', startTime: performance.now() });

  fetch(manifestUrl)
    .then(function (response) {
      if (!response.ok) {
        throw new Error('Manifest fetch failed: ' + response.status);
      }
      return response.json();
    })
    .then(function (manifest) {
      window.__diq_perf.push({ name: 'diq:manifest_fetch_end', startTime: performance.now() });

      // ENG-920: stash the manifest (carries buildHash) so the app bundle can
      // detect, at chunk-load-failure time, whether a newer deploy has since
      // replaced the assets this page loaded (see src/utils/chunkRecovery.ts).
      // Set before the entry <script> is injected, so it's always available.
      window.__diqManifest = manifest;

      // Warm TLS/DNS for the API + posthog origins before the bundle starts firing
      // the session/workflow/step and /flags requests.
      if (manifest.preconnect && manifest.preconnect.length) {
        manifest.preconnect.forEach(function (origin) {
          var pre = document.createElement('link');
          pre.rel = 'preconnect';
          pre.href = origin;
          pre.crossOrigin = 'anonymous';
          pre.setAttribute('data-demand-iq', 'true');
          document.head.appendChild(pre);
        });
      }

      // Preload the entry's eager vendor chunks so they download in parallel with
      // index-*.js instead of being discovered one round-trip later (waterfall).
      if (manifest.assets && manifest.assets.modulepreload) {
        manifest.assets.modulepreload.forEach(function (file) {
          var preload = document.createElement('link');
          preload.rel = 'modulepreload';
          preload.href = baseUrl + file;
          preload.setAttribute('data-demand-iq', 'true');
          document.head.appendChild(preload);
        });
      }

      // Load JS files
      if (manifest.assets && manifest.assets.js) {
        manifest.assets.js.forEach(function (file) {
          var scriptEle = document.createElement('script');
          scriptEle.src = baseUrl + file;
          scriptEle.async = true;
          scriptEle.type = 'module';
          scriptEle.setAttribute('data-demand-iq', 'true');
          document.head.appendChild(scriptEle);
        });
      }

      window.__diq_perf.push({ name: 'diq:assets_inject', startTime: performance.now() });

      // Load CSS files
      if (manifest.assets && manifest.assets.css) {
        manifest.assets.css.forEach(function (file) {
          var linkEle = document.createElement('link');
          linkEle.rel = 'stylesheet';
          linkEle.href = baseUrl + file;
          linkEle.setAttribute('data-demand-iq', 'true');
          document.head.appendChild(linkEle);
        });
      }

      // NOTE: feature-flag resolution is intentionally NOT done here anymore. The
      // early /flags fetch fired on every page load (even loads that never opened a
      // journey), which was ~99% of our billed PostHog flag requests. The main
      // bundle now resolves flags lazily at journey entry, cached 24h in
      // localStorage (utils/posthog.ts ensureFeatureFlags). Do NOT re-add a /flags
      // fetch here.
    })
    .catch(function (error) {
      console.error('[DemandIQ] Failed to load journey assets:', error);
      // Dispatch custom event for client-side error tracking
      window.dispatchEvent(new CustomEvent('demand-iq-load-error', { detail: error }));
    });
})();
