// Loads the product's own files and publishes window.LodestayApp.
//
// Four hard-won details, three of them kept from the other templates in this
// system and the fourth belonging to this one:
//   1. The global is published SYNCHRONOUSLY, on the first line, as a stub that
//      re-renders itself when the real App lands. <x-import
//      component-from-global-scope="LodestayApp"> resolves the global with a
//      bounded wait, and on a cold cache the load below takes longer than that
//      window — the placeholder never retries, so the first person to open the
//      template would otherwise see a blank page for good.
//   2. React, ReactDOM and Babel are NOT fetched here when the page is a Design
//      Component — the DC runtime puts its own copies on window, and a second
//      React breaks every hook ("Invalid hook call"). We wait for them and only
//      fall back to the CDN if nothing else provides them.
//   3. Each file is evaluated in its own function scope rather than appended as
//      a <script>. The DC runtime can re-run this loader against a rebuilt
//      document, and script tags in a replaced <head> either vanish mid-flight
//      or re-declare every top-level const. Everything files need from each
//      other is on window already, so function scope costs nothing.
//   4. Leaflet and its stylesheet are loaded HERE, before any screen renders,
//      so no map component ever races the library. Without leaflet.css the
//      tiles render scrambled, so the link is not optional.
//
// Load order matters in one place: metrics.js is evaluated before fixtures.js,
// because the fixtures build every booking's payment rows by calling quoteFor
// and paymentPlan rather than typing amounts that would have to be kept in step.
(() => {
  const base = new URL(".", document.currentScript.src).href;

  /* --- 1. the stub, published before anything is fetched ----------------- */
  const READY = "lodestay:ready";
  if (!window.LodestayApp) {
    window.LodestayApp = function LodestayAppStub(props) {
      const [, bump] = window.React.useState(0);
      window.React.useEffect(() => {
        if (window.__lodestayReal) return undefined;
        const on = () => bump((n) => n + 1);
        window.addEventListener(READY, on);
        return () => window.removeEventListener(READY, on);
      }, []);
      const Real = window.__lodestayReal;
      return Real ? window.React.createElement(Real, props) : null;
    };
  }

  /* --- 2. the load ------------------------------------------------------- */
  const load = (src, integrity) => new Promise((res, rej) => { const s = document.createElement("script"); s.src = src; if (integrity) s.integrity = integrity; s.crossOrigin = "anonymous"; s.onload = res; s.onerror = () => rej(new Error("failed to load " + src)); document.head.appendChild(s); });
  const style = (href, integrity) => { const l = document.createElement("link"); l.rel = "stylesheet"; l.href = href; if (integrity) { l.integrity = integrity; l.crossOrigin = "anonymous"; } document.head.appendChild(l); };
  const wait = async (test, ms) => { for (let i = 0; i < ms / 25; i++) { if (test()) return true; await new Promise((r) => setTimeout(r, 25)); } return !!test(); };
  const FILES = [
    "lib/contracts.js", "enums.js", "nav.js", "metrics.js", "fixtures.js",
    "lib/ui-runtime.js", "lib/command-palette.js", "lib/template-menu.js",
    "LodestayParts.jsx", "MapView.jsx", "LodestayShell.jsx",
    "SearchScreen.jsx", "StayScreen.jsx", "CheckoutScreen.jsx",
    "TripsScreen.jsx", "ReceiptScreen.jsx", "TripScreen.jsx", "SavedScreen.jsx", "InboxScreen.jsx",
    "LodestayAccountScreens.jsx", "LodestayAuthScreens.jsx", "HostScreen.jsx",
    "App.jsx",
  ];
  (async () => {
    /* Every file is fetched at once — the sequential round-trips were most of
       the cold-start latency. Only the transpile-and-run is ordered. */
    const sources = FILES.map((f) => fetch(base + f).then((r) => r.text()));
    if (!window.L) style("https://unpkg.com/leaflet@1.9.4/dist/leaflet.css", "sha384-sHL9NAb7lN7rfvG5lfHpm643Xkcjzp4jFvuavGOndn6pjVqS6ny56CAt3nsEVT4H");
    if (!window.React || !window.ReactDOM) {
      if (!(await wait(() => window.React && window.ReactDOM, 1500))) {
        if (!window.React) await load("https://unpkg.com/react@18.3.1/umd/react.development.js");
        if (!window.ReactDOM) await load("https://unpkg.com/react-dom@18.3.1/umd/react-dom.development.js");
      }
    }
    if (!window.Babel) await load("https://unpkg.com/@babel/standalone@7.29.0/babel.min.js");
    if (!window.lucide) await load("https://unpkg.com/lucide@0.544.0/dist/umd/lucide.min.js");
    if (!window.L) await load("https://unpkg.com/leaflet@1.9.4/dist/leaflet.js", "sha384-cxOPjt7s7Iz04uaHJceBmS+qpjv2JkIHNVcuOrM+YHwZOmJGBXI00mdUXEq65HTH");
    await wait(() => Object.keys(window).some((k) => k.indexOf("OriginDesignSystem") === 0), 10000);
    for (let i = 0; i < FILES.length; i++) {
      const src = await sources[i];
      const out = window.Babel.transform(src, { presets: ["react"], filename: FILES[i] }).code;
      try { new Function(out)(); } catch (e) { console.error("boot.js: " + FILES[i], e); throw e; }
    }
    /* App.jsx assigns window.__lodestayReal; wake the stub. */
    window.dispatchEvent(new Event(READY));
  })().catch((e) => console.error("boot.js:", e));
})();
