/* ============================================================
   App composition + render + page interactions.
   ============================================================ */

/* ---- Analytics helper (wraps Vercel Analytics window.va) ---- */
window.alfiaTrack = function(name, props) {
  try { if (window.va) window.va("event", Object.assign({ name: name }, props || {})); } catch(e) {}
};
const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "accent": "#1A53A0",
  "titleFont": "Geist",
  "heroTheme": "dark",
  "animateFeed": true,
  "feedSpeed": 1
}/*EDITMODE-END*/;

const FONT_STACKS = {
  "Geist": "'Geist', ui-sans-serif, system-ui, sans-serif",
  "Open Sans": "'Open Sans', ui-sans-serif, system-ui, sans-serif",
  "Space Grotesk": "'Space Grotesk', ui-sans-serif, sans-serif",
  "Archivo": "'Archivo', ui-sans-serif, sans-serif",
  "Sora": "'Sora', ui-sans-serif, sans-serif"
};

const ACCENTS = ["#1A53A0", "#3C78EF", "#3273C8", "#0E2856"];

function App() {
  const [t, setTweak] = useTweaks(TWEAK_DEFAULTS);
  const root = document.documentElement;

  React.useEffect(() => {
    root.style.setProperty("--font-display", FONT_STACKS[t.titleFont] || FONT_STACKS.Geist);
  }, [t.titleFont]);

  React.useEffect(() => {
    root.style.setProperty("--color-primary", t.accent);
    root.style.setProperty("--color-primary-hover", "color-mix(in oklab, " + t.accent + " 84%, black)");
    root.style.setProperty("--brand-bright", t.accent);
  }, [t.accent]);

  React.useEffect(() => {
    const reduce = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
    const run = t.animateFeed && !reduce;
    window.__heroDesired = Object.assign({}, window.__heroDesired, { run });
    if (window.__heroFeed) window.__heroFeed.setRun(run);
  }, [t.animateFeed]);

  React.useEffect(() => {
    window.__heroDesired = Object.assign({}, window.__heroDesired, { speed: t.feedSpeed });
    if (window.__heroFeed) window.__heroFeed.setSpeed(t.feedSpeed);
  }, [t.feedSpeed]);

  React.useEffect(() => {
    const hero = document.querySelector(".hero");
    if (hero) hero.classList.toggle("hero--dark", t.heroTheme === "dark");
  }, [t.heroTheme]);

  const { TweaksPanel, TweakSection, TweakColor, TweakSelect, TweakToggle, TweakSlider, TweakRadio } = window;

  return (
    <React.Fragment>
      <Nav />
      <main id="top">
        <Hero />
        <Capabilities />
        {/* <Metrics /> — "By the numbers" section hidden; restore when ready */}
        <Testimonials />
        {/* <UseCases /> — "More than order entry" cards moved up into the Platform section */}
        {/* <Exceptions /> — hidden for the lean page; restore when ready */}
        {/* <Integrations /> — hidden for now; restore when ready */}
        {/* <FAQ /> — hidden for the lean page; restore when ready */}
        <CTA />
      </main>
      <Footer />

      <TweaksPanel>
        <TweakSection label="Brand" />
        <TweakColor label="Accent" value={t.accent} options={ACCENTS}
          onChange={(v) => setTweak("accent", v)} />
        <TweakSelect label="Title font" value={t.titleFont} options={Object.keys(FONT_STACKS)}
          onChange={(v) => setTweak("titleFont", v)} />
        <TweakSection label="Hero stage" />
        <TweakRadio label="Hero theme" value={t.heroTheme} options={["light", "dark"]}
          onChange={(v) => setTweak("heroTheme", v)} />
        <TweakToggle label="Animate agent feed" value={t.animateFeed}
          onChange={(v) => setTweak("animateFeed", v)} />
        <TweakSlider label="Feed speed" value={t.feedSpeed} min={0.5} max={2} step={0.1} unit="×"
          onChange={(v) => setTweak("feedSpeed", v)} />
      </TweaksPanel>
    </React.Fragment>
  );
}

ReactDOM.createRoot(document.getElementById("root")).render(<App />);

/* ---- Page interactions (run after first paint) ---- */
function initInteractions() {
  "use strict";
  const reduce = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
  const html = document.documentElement;

  const nav = document.getElementById("nav");
  const hero = document.querySelector(".hero");
  const navDemoBtn = nav ? nav.querySelector(".nav-demo-btn") : null;
  const NAV_H = 80;
  const FADE_PX = 160; // fade in over this many px as hero exits

  function onScroll() {
    if (!nav) return;
    nav.classList.toggle("scrolled", window.scrollY > 8);
    if (navDemoBtn && hero) {
      const heroBottom = hero.getBoundingClientRect().bottom;
      const progress = Math.max(0, Math.min(1, (NAV_H + FADE_PX - heroBottom) / FADE_PX));
      navDemoBtn.style.opacity = progress;
      navDemoBtn.style.pointerEvents = progress > 0.1 ? "auto" : "none";
    }
  }
  window.addEventListener("scroll", onScroll, { passive: true });
  onScroll();

  const animate = html.classList.contains("anim");
  if (animate && "IntersectionObserver" in window) {
    const reveals = Array.prototype.slice.call(document.querySelectorAll(".reveal"));
    const io = new IntersectionObserver((entries) => {
      entries.forEach((e) => {
        if (e.isIntersecting) {
          const el = e.target;
          const sibs = el.parentElement ? el.parentElement.querySelectorAll(":scope > .reveal") : [el];
          const idx = Array.prototype.indexOf.call(sibs, el);
          el.style.transitionDelay = Math.min(idx, 5) * 70 + "ms";
          el.classList.add("in");
          io.unobserve(el);
        }
      });
    }, { threshold: 0.1, rootMargin: "0px 0px -6% 0px" });
    const vh = window.innerHeight;
    reveals.forEach((el) => {
      const r = el.getBoundingClientRect();
      if (r.top < vh * 0.95) el.classList.add("in");
      else io.observe(el);
    });
    /* Failsafe: never leave content invisible (e.g. throttled tab).
       Dropping `anim` removes the hidden state; killing any in-flight
       transition forces the final value to resolve immediately. */
    setTimeout(() => {
      html.classList.remove("anim");
      document.querySelectorAll(".reveal").forEach((el) => {
        el.style.transition = "none";
        el.classList.add("in");
      });
    }, 2600);
  } else {
    html.classList.remove("anim");
  }

  document.querySelectorAll('a[href^="#"]').forEach((a) => {
    a.addEventListener("click", (ev) => {
      const id = a.getAttribute("href");
      if (id.length < 2) return;
      const target = document.querySelector(id);
      if (!target) return;
      ev.preventDefault();
      const y = target.getBoundingClientRect().top + window.scrollY - 76;
      window.scrollTo({ top: y, behavior: reduce ? "auto" : "smooth" });
    });
  });

  /* ---- Click event tracking ---- */
  var track = window.alfiaTrack;

  // Nav "Request demo" button
  var navDemoLink = nav ? nav.querySelector(".nav-demo-btn") : null;
  if (navDemoLink) navDemoLink.addEventListener("click", function() { track("demo_requested", { trigger: "nav_btn" }); });

  // Hero buttons
  document.querySelectorAll(".hero-cta a").forEach(function(a) {
    var href = a.getAttribute("href") || "";
    if (href.indexOf("calendly") !== -1) {
      a.addEventListener("click", function() { track("demo_requested", { trigger: "hero_btn" }); });
    } else if (href === "#platform") {
      a.addEventListener("click", function() { track("see_how_it_works", {}); });
    }
  });

  initHeroFeed(reduce);
}

/* ---- Hero agent-fleet live feed ---- */
function initHeroFeed(reduce) {
  const orbit = document.getElementById("orbit");
  const feed = document.getElementById("feed");
  if (!orbit || !feed) return;
  const agents = Array.prototype.slice.call(orbit.querySelectorAll(".agent"));
  const SCRIPT = [
    { a: 0, c: "#1A53A0", n: "receiving", t: "09:14:02", m: 'ASN matched · <span class="hi">48 cases received</span>' },
    { a: 2, c: "#3273C8", n: "putaway",   t: "09:14:08", m: 'putaway done · dock-to-stock <span class="ok">22 min</span>' },
    { a: 3, c: "#1E8A5B", n: "shipping",  t: "09:14:11", m: 'BOL confirmed · <span class="ok">FedEx Ground</span>' },
    { a: 4, c: "#C77A12", n: "picking",   t: "09:14:15", m: 'wave released · <span class="ok">23 orders</span>' },
    { a: 5, c: "#C73E3E", n: "audit",     t: "09:14:18", m: 'overbill caught · <span class="warn">disputed</span>' },
    { a: 1, c: "#3C78EF", n: "invoicing", t: "09:14:22", m: 'invoice sent · <span class="ok">on time</span>' },
    { a: 6, c: "#0E8C9B", n: "dock",      t: "09:14:26", m: 'dock appt confirmed · <span class="hi">Tue 06:00</span>' },
    { a: 0, c: "#1A53A0", n: "receiving", t: "09:14:30", m: 'receiving exception · PO #48213 · <span class="warn">short 8 units</span>' },
  ];
  function nowStr() {
    const d = new Date();
    return d.getHours().toString().padStart(2,"0") + ":" +
           d.getMinutes().toString().padStart(2,"0") + ":" +
           d.getSeconds().toString().padStart(2,"0");
  }
  const maxLines = window.innerWidth < 760 ? 2 : 5;
  function render(l) {
    const el = document.createElement("div");
    el.className = "line";
    el.innerHTML =
      '<span class="ftime">' + nowStr() + '</span>' +
      '<span class="ftag" style="color:' + l.c + '">' + l.n + '</span>' +
      '<span class="fmsg">' + l.m + '</span>';
    feed.appendChild(el);
    while (feed.children.length > maxLines) feed.removeChild(feed.firstChild);
  }
  function spotlight(i) {
    agents.forEach((a) => a.classList.remove("active"));
    if (agents[i]) agents[i].classList.add("active");
  }
  function paintStatic() {
    feed.innerHTML = "";
    SCRIPT.slice(0, 5).forEach(render);
    spotlight(SCRIPT[4].a);
  }

  const desired = window.__heroDesired || {};
  let running = (desired.run !== undefined) ? desired.run : !reduce;
  let speedMult = desired.speed || 1;
  let i = 0;
  let timer = null;

  function step() {
    const l = SCRIPT[i % SCRIPT.length];
    spotlight(l.a); render(l); i++;
  }
  function schedule() {
    if (!running) return;
    timer = setTimeout(() => { step(); schedule(); }, (1200 + Math.random() * 600) / speedMult);
  }
  function start() { if (running) { step(); schedule(); } else { paintStatic(); } }

  window.__heroFeed = {
    setSpeed(v) { speedMult = v || 1; },
    setRun(v) {
      if (v && !running) { running = true; feed.innerHTML = ""; i = 0; schedule(); }
      else if (!v && running) { running = false; if (timer) clearTimeout(timer); paintStatic(); }
    }
  };

  start();
}

/* Wait until React has committed the hero DOM before wiring interactions,
   so initHeroFeed never races ahead of the render and no-ops. */
function whenHeroReady(fn) {
  let tries = 0;
  (function check() {
    if (document.getElementById("orbit") && document.getElementById("feed")) { fn(); return; }
    if (tries++ > 180) { fn(); return; } /* ~3s safety net — run anyway */
    requestAnimationFrame(check);
  })();
}
whenHeroReady(initInteractions);
