// app.jsx — main entry, tweaks, scroll observers, heavy/moderate modes
const { useEffect: uE, useState: uS, useRef: uR } = React;

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "interactivity": "heavy",
  "palette": "default",
  "typography": "default",
  "density": "regular",
  "showMarquee": true
}/*EDITMODE-END*/;

// Palettes — all stay on-brand (GW Blue + Buff + accents)
const PALETTES = {
  default: {
    "--gw-blue": "#033C5A",
    "--navy": "#00223E",
    "--gw-buff": "#D6BF91",
    "--paper": "#FBF8F1",
    "--parchment": "#F6F1E8",
    "--potomac": "#0075C8",
  },
  navy: {
    "--gw-blue": "#00223E",
    "--navy": "#000D1F",
    "--gw-buff": "#D6BF91",
    "--paper": "#FBF8F1",
    "--parchment": "#F6F1E8",
    "--potomac": "#3391D3",
  },
  buffForward: {
    "--gw-blue": "#033C5A",
    "--navy": "#00223E",
    "--gw-buff": "#C9A968",
    "--paper": "#F2E9D2",
    "--parchment": "#E8DDC6",
    "--potomac": "#0075C8",
  },
};

const TYPOGRAPHIES = {
  default: {
    "--display": '"Oswald", Impact, sans-serif',
    "--sans": '"DM Sans", system-ui, sans-serif',
    "--serif": '"Source Serif 4", Georgia, serif',
  },
  classicSerif: {
    "--display": '"Bodoni Moda", "Source Serif 4", serif',
    "--sans": '"DM Sans", system-ui, sans-serif',
    "--serif": '"Source Serif 4", Georgia, serif',
  },
  modernSans: {
    "--display": '"Anton", Impact, sans-serif',
    "--sans": '"Inter", system-ui, sans-serif',
    "--serif": '"Source Serif 4", Georgia, serif',
  },
};

const DENSITY = {
  compact:  { "--density": "0.78" },
  regular:  { "--density": "1" },
  spacious: { "--density": "1.22" },
};

function applyVars(map) {
  if (!map) return;
  Object.entries(map).forEach(([k, v]) => document.documentElement.style.setProperty(k, v));
}

/* ── Scroll reveal observer (one shot) ──────────────────── */
function useReveals() {
  uE(() => {
    const els = document.querySelectorAll(".reveal");
    const io = new IntersectionObserver((entries) => {
      entries.forEach(e => {
        if (e.isIntersecting) {
          e.target.classList.add("in");
          io.unobserve(e.target);
        }
      });
    }, { threshold: 0.15, rootMargin: "0px 0px -8% 0px" });
    els.forEach(el => io.observe(el));
    return () => io.disconnect();
  });
}

/* ── Heavy: magnetic cursor ─────────────────────────────── */
function MagneticCursor() {
  const dotRef = uR(null);
  uE(() => {
    const dot = dotRef.current; if (!dot) return;
    let tx = -100, ty = -100, x = -100, y = -100;
    let raf = 0;
    const move = (e) => { tx = e.clientX; ty = e.clientY; };
    const enter = () => dot.classList.add("expand");
    const leave = () => dot.classList.remove("expand");
    const tick = () => {
      x += (tx - x) * 0.22;
      y += (ty - y) * 0.22;
      dot.style.left = x + "px";
      dot.style.top  = y + "px";
      raf = requestAnimationFrame(tick);
    };
    window.addEventListener("mousemove", move);
    const interactive = document.querySelectorAll("a, button, .project-card, .pillar, .reel-item, .faq-item, .partner, .region-tab, .filter-btn");
    interactive.forEach(el => { el.addEventListener("mouseenter", enter); el.addEventListener("mouseleave", leave); });
    raf = requestAnimationFrame(tick);
    return () => {
      window.removeEventListener("mousemove", move);
      interactive.forEach(el => { el.removeEventListener("mouseenter", enter); el.removeEventListener("mouseleave", leave); });
      cancelAnimationFrame(raf);
    };
  });
  return <div ref={dotRef} className="magnetic-dot" />;
}

/* ── Heavy: section rail ────────────────────────────────── */
function SectionRail() {
  const [active, setActive] = uS("top");
  const [show, setShow] = uS(false);
  const items = [
    { id: "top",       label: "Top" },
    { id: "metrics",   label: "Numbers" },
    { id: "overview",  label: "Program" },
    { id: "map",       label: "Map" },
    { id: "projects",  label: "Projects" },
    { id: "reel",      label: "Reel" },
    { id: "voices",    label: "Voices" },
    { id: "advisors",  label: "Faculty" },
    { id: "timeline",  label: "Year" },
    { id: "partners",  label: "Clients" },
    { id: "faq",       label: "FAQ" },
    { id: "apply",     label: "Apply" },
  ];
  uE(() => {
    const onScroll = () => setShow(window.scrollY > 400);
    onScroll();
    window.addEventListener("scroll", onScroll, { passive: true });

    const io = new IntersectionObserver((entries) => {
      entries.forEach(e => { if (e.isIntersecting) setActive(e.target.id); });
    }, { rootMargin: "-40% 0px -55% 0px" });
    items.forEach(it => { const el = document.getElementById(it.id); if (el) io.observe(el); });
    return () => { window.removeEventListener("scroll", onScroll); io.disconnect(); };
  });
  return (
    <div className={`section-rail ${show ? "show" : ""}`} aria-hidden="true">
      {items.map(it => (
        <a key={it.id} href={`#${it.id}`} className={`dot ${active === it.id ? "active" : ""}`} data-label={it.label}></a>
      ))}
    </div>
  );
}

/* ── App ────────────────────────────────────────────────── */
function App() {
  const [t, setTweak] = useTweaks(TWEAK_DEFAULTS);
  const heavy = t.interactivity === "heavy";

  uE(() => { applyVars(PALETTES[t.palette]); }, [t.palette]);
  uE(() => { applyVars(TYPOGRAPHIES[t.typography]); }, [t.typography]);
  uE(() => { applyVars(DENSITY[t.density]); }, [t.density]);
  uE(() => {
    document.documentElement.style.setProperty("--motion", heavy ? "1" : "1.15");
  }, [heavy]);

  useReveals();

  return (
    <GWChrome heavy={heavy}>
      <Hero heavy={heavy} />

      <div className="marquee">
        <div className="marquee-track" style={{display: t.showMarquee ? "flex" : "none"}}>
          {[0, 1].map(k => (
            <React.Fragment key={k}>
              {ALL_CLIENTS.map((c, i) => <span key={k + "-" + i}>{c}</span>)}
            </React.Fragment>
          ))}
        </div>
      </div>

      <MetricsStrip heavy={heavy} />
      <Overview />
      <WorldMap />
      <Projects />
      <VideoReel />
      <Testimonials heavy={heavy} />
      <Advisors heavy={heavy} />
      <Timeline />
      <PartnersSection />
      <FAQSection />
      <CTA />

      {heavy && <MagneticCursor />}
      {heavy && <SectionRail />}

      <TweaksPanel title="Tweaks">
        <TweakSection label="Interactivity" />
        <TweakRadio
          label="Level"
          value={t.interactivity}
          options={["moderate", "heavy"]}
          onChange={v => setTweak("interactivity", v)}
        />
        <p style={{
          fontFamily: "var(--sans)", fontSize: 11,
          color: "var(--slate)", margin: "4px 0 0", lineHeight: 1.5,
          letterSpacing: 0.2
        }}>
          <b style={{color: "var(--gw-blue)"}}>Moderate:</b> hover states, smooth scroll reveals, counters.
          <br />
          <b style={{color: "var(--gw-blue)"}}>Heavy:</b> adds magnetic cursor, section rail, auto-rotating quotes, scroll-driven pull-quotes.
        </p>

        <TweakSection label="Color" />
        <div style={{display: "flex", flexDirection: "column", gap: 8, padding: "4px 0"}}>
          <div style={{
            fontFamily: "var(--sans)", fontSize: 11, fontWeight: 600,
            letterSpacing: 0.6, textTransform: "uppercase", color: "#555"
          }}>Palette</div>
          <div style={{display: "grid", gridTemplateColumns: "1fr 1fr 1fr", gap: 8}}>
            {[
              { key: "default", label: "Classic", swatches: ["#033C5A", "#D6BF91", "#0075C8"] },
              { key: "navy",    label: "Deep",    swatches: ["#00223E", "#D6BF91", "#3391D3"] },
              { key: "buffForward", label: "Buff", swatches: ["#033C5A", "#C9A968", "#E8DDC6"] },
            ].map(opt => (
              <button key={opt.key}
                onClick={() => setTweak("palette", opt.key)}
                style={{
                  border: t.palette === opt.key ? "2px solid #033C5A" : "1px solid rgba(0,0,0,0.15)",
                  background: "white", padding: 8, cursor: "pointer",
                  display: "flex", flexDirection: "column", gap: 6, alignItems: "stretch"
                }}
              >
                <div style={{display: "flex", height: 22, gap: 2}}>
                  {opt.swatches.map((c, i) => <div key={i} style={{flex: 1, background: c}} />)}
                </div>
                <div style={{
                  fontFamily: "var(--sans)", fontSize: 10, fontWeight: 600,
                  letterSpacing: 0.6, textTransform: "uppercase",
                  color: t.palette === opt.key ? "#033C5A" : "#666"
                }}>{opt.label}</div>
              </button>
            ))}
          </div>
        </div>

        <TweakSection label="Typography" />
        <TweakRadio
          label="Display"
          value={t.typography}
          options={["default", "classicSerif", "modernSans"]}
          onChange={v => setTweak("typography", v)}
        />

        <TweakSection label="Layout" />
        <TweakRadio
          label="Density"
          value={t.density}
          options={["compact", "regular", "spacious"]}
          onChange={v => setTweak("density", v)}
        />
        <TweakToggle
          label="Show marquee"
          value={t.showMarquee}
          onChange={v => setTweak("showMarquee", v)}
        />
      </TweaksPanel>
    </GWChrome>
  );
}

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