/* eslint-disable */
// App entry, router + Tweaks wiring

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "darkCta": true,
  "heroAccent": "underline",
  "accentTone": "blue",
  "density": "regular",
  "journeyStyle": "pinned",
  "teamCard": "current",
  "builtWith": "navy",
  "caseLayout": "current",
  "toolCard": "current",
  "whatWeAre": "A current",
  "homeEnd": "current",
  "homeAlign": "aligned",
  "heroFigure": "B5e dashed",
  "wwbClose": "rule",
  "contactLayout": "standard",
  "workMotion": "fan",
  "workMotionNonce": 0,
  "showDecisions": true,
  "belowHero": "marquee",
  "thesisVoice": "current",
  "doorColour": "teal + navy",
  "doorStyle": "solid",
  "heroScatter": "corners",
  "homeHero": "photo",
  "heroLength": "doors visible",
  "accVersion": "B brief rebuild",
  "accStories": "reveal",
  "accAfter": "cards",
  "accStatement": "cycling shape"
}/*EDITMODE-END*/;

// V2 Website.html ships without data-hero — it keeps the dark slab build.
if (document.documentElement.getAttribute("data-hero") !== "photo") TWEAK_DEFAULTS.homeHero = "slab";
// V5 ships the statement hero only: dark or light.
const STATEMENT_ONLY = document.documentElement.getAttribute("data-heroset") === "statement";
if (STATEMENT_ONLY) { TWEAK_DEFAULTS.homeHero = "dark"; TWEAK_DEFAULTS.snapScroll = false; }
// MVP build: fewer pages, no client-logo marquee, no recent work, softer doors.
const MVP_BUILD = document.documentElement.getAttribute("data-mvp") === "on";
if (MVP_BUILD) {
  TWEAK_DEFAULTS.homeHero = "dark";
  TWEAK_DEFAULTS.doorColour = "pale + navy";
  TWEAK_DEFAULTS.doorStyle = "question card";
  TWEAK_DEFAULTS.homeEnd = "statement + awards";
}

function parseHash() {
  const parts = window.location.hash.replace(/^#/, "").split("/");
  return { screen: parts[0] || "home", sub: parts[1] || "" };
}

function App() {
  const [route, setRoute] = React.useState(parseHash);
  const screen = route.screen;
  const [t, setTweak] = useTweaks(TWEAK_DEFAULTS);

  const go = React.useCallback((s) => {
    window.location.hash = s;
    setRoute(parseHash());
    requestAnimationFrame(() => window.scrollTo({ top: 0, behavior: "instant" }));
  }, []);

  React.useEffect(() => {
    const onHash = () => setRoute(parseHash());
    window.addEventListener("hashchange", onHash);
    return () => window.removeEventListener("hashchange", onHash);
  }, []);

  React.useEffect(() => {
    if (window.lucide) window.lucide.createIcons();
  }, [screen, route.sub, t]);

  // Scroll reveal, used deliberately rather than everywhere: the first screen of a
  // page gets an entrance, and below that only elements marked data-reveal. A reveal
  // that fires on every block carries no information about what matters.
  React.useEffect(() => {
    if (window.matchMedia("(prefers-reduced-motion: reduce)").matches) return;
    const vh = window.innerHeight || 800;
    const set = new Set();
    document.querySelectorAll(".section > .container > *, .doors > *").forEach((el) => {
      // The observer fires at 4% visibility, which a very tall block can never
      // reach -- 4% of a 20,000px legal document is more than a phone screen, so
      // it would sit at opacity 0 forever. Such blocks opt out explicitly.
      if (el.hasAttribute("data-no-reveal")) return;
      if (el.getBoundingClientRect().top + window.scrollY < vh * 1.05) set.add(el);
    });
    document.querySelectorAll("[data-reveal]").forEach((el) => set.add(el));
    const targets = Array.from(set);
    if (!targets.length) return;
    targets.forEach((el) => {
      // A group resolves as one gesture: children stagger off the parent's trigger.
      if (el.getAttribute("data-reveal") === "group") {
        Array.from(el.children).forEach((c, i) => { c.classList.add("reveal"); c.style.transitionDelay = `${i * 70}ms`; });
      } else {
        el.classList.add("reveal");
      }
    });
    const io = new IntersectionObserver((entries) => {
      entries.forEach((e) => {
        if (!e.isIntersecting) return;
        if (e.target.getAttribute("data-reveal") === "group") {
          Array.from(e.target.children).forEach((c) => c.classList.add("reveal--in"));
        } else {
          e.target.classList.add("reveal--in");
        }
        io.unobserve(e.target);
      });
    }, { rootMargin: "0px 0px -8% 0px", threshold: 0.04 });
    targets.forEach((el) => io.observe(el));
    return () => io.disconnect();
  }, [screen, route.sub]);

  // Apply tweak-driven body class for density / accent
  React.useEffect(() => {
    document.documentElement.dataset.accent = t.accentTone;
    document.documentElement.dataset.density = t.density;
    document.documentElement.dataset.heroAccent = t.heroAccent;
    document.documentElement.dataset.wwbclose = t.wwbClose;
    document.documentElement.dataset.decisions = t.showDecisions ? "on" : "off";
    document.documentElement.dataset.homealign = t.homeAlign || "aligned";
    const hb = t.homeHero || "photo";
    document.documentElement.dataset.hero = hb === "slab" ? "slab" : "photo";
    document.documentElement.dataset.homehero = hb;
    document.documentElement.dataset.snap = (t.snapScroll && screen === "home") ? "on" : "off";
    document.documentElement.dataset.photohome = (hb !== "slab" && screen === "home") ? "on" : "off";
  }, [t.accentTone, t.density, t.heroAccent, t.wwbClose, t.showDecisions, t.homeAlign, t.homeHero, t.snapScroll, screen]);

  const screens = {
    "home":          <HomeV2Screen        go={go} t={t} />,
    "ai-foundations":<AiFoundationsScreen go={go} t={t} />,
    "accelerators":  (t.accVersion === "A current" ? <AcceleratorsScreen go={go} t={t} /> : <AcceleratorsBScreen go={go} t={t} />),
    "accelerators-a":<AcceleratorsScreen  go={go} t={t} />,
    "accelerators-b":<AcceleratorsBScreen go={go} t={t} />,
    "decisions":     <DecisionsScreen     go={go} t={t} />,
    "services":      <ServicesScreen      go={go} t={t} />,
    "blueprint":     <BlueprintScreen     go={go} t={t} />,
    "foundations":   <FoundationsScreen   go={go} t={t} />,
    "literacy":      <LiteracyScreen      go={go} t={t} />,
    "ai-setup":      <AiSetupScreen       go={go} t={t} />,
    "governance":    <GovernanceScreen    go={go} t={t} />,
    "build":         <BuildScreen         go={go} t={t} />,
    "quick-wins":    <QuickWinsScreen     go={go} t={t} />,
    "custom-builds": <CustomBuildsScreen  go={go} t={t} />,
    "how-we-work":   <HowWeWorkV2Screen   go={go} t={t} />,
    "how-we-work-v1":<HowWeWorkScreen     go={go} t={t} />,
    "toolbox":       <ToolboxScreen       go={go} t={t} />,
    "tool":          <ToolDetailScreen    go={go} slug={route.sub} />,
    "resources":     <ResourcesScreen     go={go} t={t} />,
    "post":          <PostScreen          go={go} t={t} slug={route.sub} />,
    "work":          <WorkV2Screen        go={go} t={t} sub={route.sub} />,
    "work-v1":       <WorkScreen          go={go} t={t} />,
    "about":         <AboutV2Screen       go={go} t={t} />,
    "about-v1":      <AboutScreen         go={go} t={t} />,
    "about-pmv":     <PurposeMissionValuesScreen go={go} t={t} />,
    "contact":       <ContactV2Screen     go={go} t={t} />,
    "contact-v1":    <ContactScreen       go={go} t={t} />,
    "faqs":          <FaqsScreen          go={go} t={t} />,
    "terms":         <TermsScreen         go={go} />,
    "privacy":       <PrivacyScreen       go={go} />,
  };
  if (!MVP_BUILD) {
    screens["home-v1"] = <HomeScreen go={go} t={t} />;
  } else {
    // MVP drops the Toolbox, Blog and Our Work sections entirely.
    ["toolbox", "tool", "resources", "post", "work", "work-v1"].forEach((k) => { delete screens[k]; });
  }

  return (
    <>
      <Nav current={screen} go={go} />
      <main>{screens[screen] || screens["home"]}</main>
      {/* Contact form lives on the Contact page only. */}
      <Footer go={go} />

      <TweaksPanel title="Tweaks">
        <TweakSection label="Hero" />
        {STATEMENT_ONLY && (
        <>
        <TweakRadio
          label="Hero length"
          value={t.heroLength}
          options={["doors visible", "full bleed"]}
          onChange={(v) => setTweak("heroLength", v)}
        />
        <TweakToggle
          label="Snap to sections"
          value={t.snapScroll}
          onChange={(v) => setTweak("snapScroll", v)}
        />
        </>
        )}

        <TweakSection label="Home doors" />
        <TweakRadio
          label="Two doors"
          value={t.doorStyle}
          options={["cards", "question ruled", "question rows", "question card"]}
          onChange={(v) => setTweak("doorStyle", v)}
        />

        <TweakRadio
          label="Page ending"
          value={t.homeEnd}
          options={["current", "statement + awards", "closer in footer"]}
          onChange={(v) => setTweak("homeEnd", v)}
        />

        <TweakSection label="CTA strips" />
        <TweakToggle
          label="Dark inverted CTAs"
          value={t.darkCta}
          onChange={(v) => setTweak("darkCta", v)}
        />

        <TweakSection label="Style" />
        <TweakRadio
          label="Accent"
          value={t.accentTone}
          options={["blue", "cyan"]}
          onChange={(v) => setTweak("accentTone", v)}
        />
        <TweakRadio
          label="Density"
          value={t.density}
          options={["compact", "regular", "airy"]}
          onChange={(v) => setTweak("density", v)}
        />
        <TweakSection label="About" />
        <TweakRadio
          label="Contact page layout"
          value={t.contactLayout}
          options={["standard", "glance card", "editorial"]}
          onChange={(v) => setTweak("contactLayout", v)}
        />
        <TweakRadio
          label="Built with strip"
          value={t.builtWith}
          options={["band", "navy", "card"]}
          onChange={(v) => setTweak("builtWith", v)}
        />
        <TweakRadio
          label="People cards"
          value={t.teamCard}
          options={["current", "portraits", "tiles"]}
          onChange={(v) => setTweak("teamCard", v)}
        />
        <TweakSection label="Our Work" />
        <TweakRadio
          label="Case study page"
          value={t.caseLayout}
          options={["current", "A before/after", "B how it runs", "C spec sheet"]}
          onChange={(v) => setTweak("caseLayout", v)}
        />
        <TweakSection label="AI Toolbox" />
        <TweakRadio
          label="Tool cards"
          value={t.toolCard}
          options={["current", "plate"]}
          onChange={(v) => setTweak("toolCard", v)}
        />
        <TweakSection label="AI Accelerators" />
        <TweakRadio
          label="Page version"
          value={t.accVersion}
          options={["A current", "B brief rebuild"]}
          onChange={(v) => setTweak("accVersion", v)}
        />
        <TweakRadio
          label="After the build"
          value={t.accAfter}
          options={["cards", "ruled columns"]}
          onChange={(v) => setTweak("accAfter", v)}
        />
        <TweakRadio
          label="Statement animation"
          value={t.accStatement}
          options={["cycling shape", "typewriter", "emphasis last"]}
          onChange={(v) => setTweak("accStatement", v)}
        />
        <TweakRadio
          label="Build stories"
          value={t.accStories}
          options={["cards", "spotlight", "fanned deck", "reveal", "wide tiles"]}
          onChange={(v) => setTweak("accStories", v)}
        />
        <TweakRadio
          label="Closing statement"
          value={t.wwbClose}
          options={["rule", "hairline", "card", "navy", "right", "tick"]}
          onChange={(v) => setTweak("wwbClose", v)}
        />
        <TweakSection label="How we work" />
        <TweakRadio
          label="The journey"
          value={t.journeyStyle}
          options={["rail", "pinned", "editorial"]}
          onChange={(v) => setTweak("journeyStyle", v)}
        />
      </TweaksPanel>
    </>
  );
}

// Apply hero accent via dynamic stylesheet
const __dynamicStyle = document.createElement("style");
__dynamicStyle.textContent = `
  html[data-hero-accent="plain"]  .h-display em { background: none; padding: 0; color: var(--ink); }
  html[data-hero-accent="color"]  .h-display em { background: none; padding: 0; color: var(--ia-blue); }
  html[data-accent="cyan"]        .eyebrow, html[data-accent="cyan"] .linkout { color: var(--ia-dark-blue); }
  html[data-decisions="off"]      .decision, html[data-decisions="off"] .status-flag { display: none; }
  html[data-density="compact"]    .section { padding: 64px 0; }
  html[data-density="airy"]       .section { padding: 128px 0; }
  html[data-density="airy"]       .section--tight { padding: 80px 0; }
  html[data-density="airy"]       .hero { padding: 112px 0 128px; }
  html[data-density="airy"]       .container { padding: 0 36px; }
  html[data-density="airy"]       .section-head { margin-bottom: 72px; }
  html[data-density="airy"]       .card { padding: 32px; }
  html[data-density="airy"]       .grid { gap: 24px; }
  html[data-density="airy"]       .acc-strip { gap: 16px; }
  html[data-density="airy"]       .acc-strip-wrap { padding: 36px; }
  html[data-density="airy"]       .acc-tile { padding: 24px; min-height: 180px; }
  html[data-density="airy"]       .stepper { gap: 24px; }
  html[data-density="airy"]       .cta-strip { padding: 72px; }
  html[data-density="airy"]       .case-feature-body { padding: 56px; }
  html[data-density="airy"]       .phase-row { padding: 36px 0; }
`;
document.head.appendChild(__dynamicStyle);

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