// Norton-Gauss · App entry · routes + tweaks

const { useState: aUS, useEffect: aUE } = React;

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "theme": "dark",
  "lang": "en",
  "heroVariant": "mesh",
  "splineUrl": ""
}/*EDITMODE-END*/;

// --- URL routing -----------------------------------------------------------
// Give every page a real, deep-linkable URL hash (e.g. #/practices,
// #/careers/lead-agent-eng) instead of everything living at the bare index
// URL. This makes refresh, back/forward, and code handoff resolve to distinct
// routes that map 1:1 onto real server routes (/practices, /case, /careers...).
const ROUTE_SLUG = { home: '', services: 'practices', case: 'case', careers: 'careers', book: 'book' };

function routeFromHash() {
  const raw = (typeof location !== 'undefined' ? location.hash : '').replace(/^#\/?/, '');
  const [slug, id] = raw.split('/');
  if (slug === 'careers' && id) return { route: 'job', jobId: id };
  const match = Object.keys(ROUTE_SLUG).find((r) => ROUTE_SLUG[r] === slug);
  return { route: match || 'home', jobId: null };
}

function hashFromRoute(route, jobId) {
  if (route === 'job') return '#/careers/' + (jobId || '');
  const slug = ROUTE_SLUG[route] || '';
  return slug ? '#/' + slug : '';
}

function App() {
  // Per-page handoff files set window.__NG_INITIAL_ROUTE to boot straight to
  // one page (e.g. practices.html → { route: 'services' }); otherwise the URL
  // hash decides.
  const initial = (typeof window !== 'undefined' && window.__NG_INITIAL_ROUTE) || routeFromHash();
  const [route, setRoute] = aUS(initial.route);
  const [jobId, setJobId] = aUS(initial.jobId);
  const [t, setTweak] = useTweaks(TWEAK_DEFAULTS);

  // Write the active route into the URL hash on every navigation.
  aUE(() => {
    const desired = hashFromRoute(route, jobId);
    if ((desired || '') !== location.hash) {
      if (desired) location.hash = desired;
      else history.replaceState(null, '', location.pathname + location.search);
    }
  }, [route, jobId]);

  // Read the URL back into state on browser back/forward (and manual edits).
  aUE(() => {
    const onHash = () => {
      const next = routeFromHash();
      setRoute(next.route);
      setJobId(next.jobId);
    };
    window.addEventListener('hashchange', onHash);
    return () => window.removeEventListener('hashchange', onHash);
  }, []);

  aUE(() => {
    document.documentElement.setAttribute('data-theme', t.theme);
    document.documentElement.lang = t.lang || 'en';
    // Surface tweak values to vanilla components (e.g. SplineMagnet reads NG.tweaks.splineUrl)
    window.NG = window.NG || {};
    window.NG.tweaks = { ...(window.NG.tweaks || {}), splineUrl: t.splineUrl };
  }, [t.theme, t.lang, t.splineUrl]);

  // Expose a global route helper so any anchor with [data-route] works.
  aUE(() => {
    window.NGRoute = setRoute;
    const onClick = (e) => {
      const a = e.target.closest && e.target.closest('[data-route]');
      if (!a) return;
      e.preventDefault();
      setRoute(a.getAttribute('data-route'));
    };
    document.addEventListener('click', onClick);
    return () => document.removeEventListener('click', onClick);
  }, []);
  aUE(() => {
    window.scrollTo({ top: 0, behavior: 'instant' });
    // Re-run GSAP scroll trigger after route change, plus re-apply motion-v3
    // so the new page's headlines, magnetic CTAs and reveals engage.
    setTimeout(() => {
      if (window.ScrollTrigger) window.ScrollTrigger.refresh();
      if (window.NGMotion && window.NGMotion.refresh) window.NGMotion.refresh();
    }, 400);
  }, [route, jobId]);

  const openJob = (id) => { setJobId(id); setRoute('job'); };

  let Page;
  if (route === 'services') {
    Page = <ServicesPage setRoute={setRoute} />;
  } else if (route === 'case') {
    Page = <CaseStudyPage />;
  } else if (route === 'careers') {
    Page = <CareersPage setRoute={setRoute} openJob={openJob} />;
  } else if (route === 'job') {
    Page = <JobDetailPage jobId={jobId} setRoute={setRoute} />;
  } else if (route === 'book') {
    Page = <BookCallPage setRoute={setRoute} />;
  } else {
    Page = (
      <div className="page-enter">
        <Hero heroVariant={t.heroVariant} />
        <PositioningStrip />
        <ManifestoBanner />
        <CostOfManual />
        <CapabilityPanels setRoute={setRoute} />
        <PracticesDetail setRoute={setRoute} />
        <Framework />
        <Compounding />
        <Roadmaps />
        <WorldMap />
        <ImpactV2 />
        <WhatWeBuild setRoute={setRoute} />
        <Cases setRoute={setRoute} />
        <ExtraCases setRoute={setRoute} />
        <WhyNG />
        <Innovation />
        <Manifesto />
        <FinalCTA />
      </div>
    );
  }

  return (
    <>
      <Nav route={route} setRoute={setRoute} theme={t.theme} lang={t.lang} setTweak={setTweak} />
      {Page}
      <Footer setRoute={setRoute} />

      <TweaksPanel title="Tweaks · Norton-Gauss">
        <TweakSection label="Theme">
          <TweakRadio label="Mode" options={['dark', 'light']} value={t.theme}
            onChange={(v) => setTweak('theme', v)} />
        </TweakSection>
        <TweakSection label="Hero centerpiece">
          <TweakSelect label="Variant" options={[
            { value: 'mesh', label: 'Neural mesh · Three.js (drag to rotate)' },
            { value: 'agent', label: 'Live agent simulation' },
            { value: 'logo', label: 'Logo morph · grey → green' },
            { value: 'kinetic', label: 'Kinetic · type-only' },
          ]} value={t.heroVariant} onChange={(v) => setTweak('heroVariant', v)} />
        </TweakSection>
        <TweakSection label="Innovation · Spline scene">
          <TweakText label="Spline scene URL" value={t.splineUrl}
            onChange={(v) => setTweak('splineUrl', v)} />
        </TweakSection>
      </TweaksPanel>
    </>
  );
}

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