// app.jsx — root app: router, nav, footer, tweaks, inline edit
const { useEffect: appUseEffect, useRef: appUseRef, useState: appUseState } = React;

// ---------- Hash router ----------
function useHashRoute() {
  const [route, setRoute] = appUseState(() => parseHash(location.hash));
  appUseEffect(() => {
    const upd = () => setRoute(parseHash(location.hash));
    window.addEventListener("hashchange", upd);
    return () => window.removeEventListener("hashchange", upd);
  }, []);
  const go = (path) => {
    location.hash = "#" + path;
    setTimeout(() => window.ScrollFX?.scrollToTop(), 50);
  };
  return [route, go];
}
function parseHash(h) {
  const path = (h || "").replace(/^#/, "") || "/";
  const parts = path.split("/").filter(Boolean);
  return { path, parts };
}

// ---------- Footer ----------
function Footer({ onGo }) {
  const ref = appUseRef(null);
  appUseEffect(() => {
    if (!window.gsap || !window.ScrollTrigger) return;
    window.ScrollFX.splitText(ref.current.querySelector("[data-split]"));
    const chars = ref.current.querySelectorAll(".split-char");
    window.gsap.set(chars, { yPercent: 110 });
    window.ScrollTrigger.create({
      trigger: ref.current, start: "top 75%",
      onEnter: () => window.gsap.to(chars, { yPercent: 0, duration: 1.2, ease: "power4.out", stagger: { each: 0.02, from: "random" } })
    });
  }, []);
  return (
    <footer className="foot" ref={ref}>
      <div className="wrap">
        <div className="foot__big">
          <span data-split>let&apos;s ship.</span>
        </div>
        <div className="foot__cols">
          <div>
            <h5>Studio</h5>
            <p style={{fontSize:"14px", color:"var(--fg-2)", lineHeight:1.6, marginTop:"-4px"}}>A two-person studio shipping production scripts for AE, Blender and Unreal.</p>
            <p style={{fontSize:"12px", color:"var(--fg-3)", letterSpacing:"0.1em", textTransform:"uppercase", marginTop:"16px"}}>hi@scripts.studio</p>
          </div>
          <div>
            <h5>Browse</h5>
            <a href="#/scripts" onClick={(e)=>{e.preventDefault(); onGo("/scripts");}} data-cursor="text">All scripts</a>
            <a href="#/scripts" onClick={(e)=>{e.preventDefault(); onGo("/scripts");}} data-cursor="text">After Effects</a>
            <a href="#/scripts" onClick={(e)=>{e.preventDefault(); onGo("/scripts");}} data-cursor="text">Blender</a>
            <a href="#/scripts" onClick={(e)=>{e.preventDefault(); onGo("/scripts");}} data-cursor="text">Unreal</a>
          </div>
          <div>
            <h5>Account</h5>
            <a href="#/membership" onClick={(e)=>{e.preventDefault(); onGo("/membership");}} data-cursor="text">Membership</a>
            <a href="#/cart" onClick={(e)=>{e.preventDefault(); onGo("/cart");}} data-cursor="text">Cart</a>
            <a href="#/login" onClick={(e)=>{e.preventDefault(); onGo("/login");}} data-cursor="text">Sign in</a>
            <a href="#/account" onClick={(e)=>{e.preventDefault(); onGo("/account");}} data-cursor="text">Account</a>
          </div>
          <div>
            <h5>Index</h5>
            <a href="#" onClick={(e)=>e.preventDefault()} data-cursor="text">Licence</a>
            <a href="#" onClick={(e)=>e.preventDefault()} data-cursor="text">Refunds</a>
            <a href="#" onClick={(e)=>e.preventDefault()} data-cursor="text">Changelog</a>
            <a href="#/admin" onClick={(e)=>{e.preventDefault(); onGo("/admin");}} data-cursor="text">Admin</a>
          </div>
        </div>
        <div className="foot__bottom">
          <span>© SCRIPTS.STUDIO · MMXXVI</span>
          <span>Berlin ↔ Shenzhen</span>
          <span>Built with GSAP · Lenis · Three.js</span>
        </div>
      </div>
    </footer>
  );
}

// ---------- Nav ----------
function Nav({ onGo, route }) {
  const [cartCount, setCartCount] = appUseState(() => window.AppData.getCart().length);
  const [user, setUser] = appUseState(() => window.AppData.currentUser());
  const [menuOpen, setMenuOpen] = appUseState(false);
  const menuTimer = appUseRef(null);
  const megaRef = appUseRef(null);
  appUseEffect(() => {
    const upd = () => setCartCount(window.AppData.getCart().length);
    const usrUpd = () => setUser(window.AppData.currentUser());
    window.addEventListener("pa:cart", upd);
    window.addEventListener("pa:session", usrUpd);
    return () => { window.removeEventListener("pa:cart", upd); window.removeEventListener("pa:session", usrUpd); };
  }, []);
  // Drive mega opacity/transform via gsap to avoid CSS-transition timing bugs
  appUseEffect(() => {
    if (!megaRef.current || !window.gsap) return;
    if (menuOpen) {
      window.gsap.to(megaRef.current, { opacity: 1, y: 0, duration: 0.32, ease: "power2.out", pointerEvents: "auto", overwrite: true });
    } else {
      window.gsap.to(megaRef.current, { opacity: 0, y: -12, duration: 0.24, ease: "power2.in", pointerEvents: "none", overwrite: true });
    }
  }, [menuOpen]);
  const active = (p) => route.path.startsWith(p) ? "is-active" : "";

  const openMenu = () => { clearTimeout(menuTimer.current); setMenuOpen(true); };
  const closeMenu = () => { clearTimeout(menuTimer.current); menuTimer.current = setTimeout(() => setMenuOpen(false), 140); };

  const goWithFilter = (soft) => {
    setMenuOpen(false);
    sessionStorage.setItem("pa_filter", soft);
    onGo("/scripts");
  };

  const softwareItems = [
    { id: "AE", name: "After Effects", desc: "Kinetic type, glitch, reveals", count: 4, glyph: "Ae" },
    { id: "Blender", name: "Blender", desc: "Geo nodes, sims, procedural worlds", count: 3, glyph: "Bl" },
    { id: "UE5", name: "Unreal Engine 5", desc: "Niagara, volumetrics, grooms", count: 3, glyph: "UE5" },
    { id: "All", name: "Browse everything", desc: "The full index, all software", count: null, glyph: "↗" }
  ];

  return (
    <React.Fragment>
      <nav className="nav">
        <a href="#/" className="nav__logo" onClick={(e)=>{e.preventDefault(); onGo("/");}} data-cursor="text">scripts<b>.</b>studio</a>
        <div className="nav__links">
          <div className="nav__menu-trigger" onMouseEnter={openMenu} onMouseLeave={closeMenu}>
            <a href="#/scripts" className={active("/scripts") + (menuOpen ? " is-open" : "")} onClick={(e)=>{e.preventDefault(); onGo("/scripts");}} data-cursor="text">
              Scripts <span className="nav__chev">▾</span>
            </a>
          </div>
          <a href="#/membership" className={active("/membership")} onClick={(e)=>{e.preventDefault(); onGo("/membership");}} data-cursor="text">Membership</a>
        </div>
        <div className="nav__right">
          {user ? (
            <a href={user.role === "admin" ? "#/admin" : "#/account"} onClick={(e)=>{e.preventDefault(); onGo(user.role === "admin" ? "/admin" : "/account");}} data-cursor="text" style={{fontSize:"12px", textTransform:"uppercase", letterSpacing:"0.12em"}}>
              {user.name}
            </a>
          ) : (
            <a href="#/login" onClick={(e)=>{e.preventDefault(); onGo("/login");}} data-cursor="text" style={{fontSize:"12px", textTransform:"uppercase", letterSpacing:"0.12em"}}>Sign in</a>
          )}
          <a href="#/cart" className="nav__cart" onClick={(e)=>{e.preventDefault(); onGo("/cart");}} data-cursor="text">
            Cart {cartCount > 0 && <span className="nav__cart-count">{cartCount}</span>}
          </a>
        </div>
      </nav>

      {/* Mega menu — Apple style */}
      <div ref={megaRef} className="mega" onMouseEnter={openMenu} onMouseLeave={closeMenu} style={{opacity:0, transform:"translateY(-12px)", pointerEvents:"none"}}>
        <div className="mega__inner">
          <div className="mega__head">
            <div className="mega__eyebrow"><span className="dot">●</span><span>Browse by software</span></div>
            <div className="mega__count">{window.AppData.getScripts().length} scripts shipped</div>
          </div>
          <div className="mega__grid">
            {softwareItems.map(s => (
              <button key={s.id} className="mega__item" onClick={() => goWithFilter(s.id)} data-cursor="ring" data-cursor-label="Open">
                <div className="mega__item-glyph display">{s.glyph}</div>
                <div className="mega__item-body">
                  <div className="mega__item-title">{s.name}</div>
                  <div className="mega__item-desc">{s.desc}</div>
                </div>
                {s.count != null ? <div className="mega__item-count">{String(s.count).padStart(2, "0")}</div> : <div className="mega__item-arrow">→</div>}
              </button>
            ))}
          </div>
          <div className="mega__foot">
            <a href="#/membership" onClick={(e)=>{e.preventDefault(); setMenuOpen(false); onGo("/membership");}} data-cursor="text">
              <span style={{color:"var(--accent)"}}>↘</span> Or unlock everything with membership — from $20/month
            </a>
          </div>
        </div>
      </div>
      {menuOpen && <div className="mega__scrim" onClick={() => setMenuOpen(false)}></div>}
    </React.Fragment>
  );
}

// ---------- Inline edit mode ----------
function InlineEditBadge({ onExit }) {
  return (
    <div className="inline-edit-badge">
      <span>● Inline edit mode</span>
      <button onClick={onExit}>Exit</button>
    </div>
  );
}

function InlineEditController({ active }) {
  appUseEffect(() => {
    if (!active) return;
    const targets = document.querySelectorAll("[data-inline]");
    const handlers = [];
    targets.forEach(el => {
      el.classList.add("inline-editable");
      el.setAttribute("contenteditable", "true");
      const onBlur = () => {
        const key = el.getAttribute("data-inline");
        const [type, id, field] = key.split(":");
        if (type === "script") {
          const val = field === "price" ? parseFloat(el.textContent.replace(/[^\d.]/g, "")) : el.textContent.trim();
          window.AppData.updateScript(id, { [field]: val });
        }
      };
      el.addEventListener("blur", onBlur);
      handlers.push([el, onBlur]);
    });
    return () => {
      handlers.forEach(([el, onBlur]) => {
        el.removeEventListener("blur", onBlur);
        el.classList.remove("inline-editable");
        el.removeAttribute("contenteditable");
      });
    };
  }, [active]);
  return null;
}

// ---------- Home ----------
function Home({ onGo, variant, videoUrl }) {
  const { HeroParticles, HeroType, HeroGrid, HeroVideo } = window.Hero;
  const Hero =
    variant === "type" ? HeroType :
    variant === "grid" ? HeroGrid :
    variant === "video" ? HeroVideo :
    HeroParticles;
  return (
    <main>
      <Hero onGo={onGo} videoUrl={videoUrl} key={variant} />
    </main>
  );
}

// ---------- Root App ----------
const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "heroVariant": "video",
  "videoUrl": "",
  "accent": "#ff3366",
  "noise": true
}/*EDITMODE-END*/;

function App() {
  const [route, go] = useHashRoute();
  const [authReturn, setAuthReturn] = appUseState(null);
  const [inlineEdit, setInlineEdit] = appUseState(false);
  const [t, setTweak] = window.useTweaks ? window.useTweaks(TWEAK_DEFAULTS) : [TWEAK_DEFAULTS, () => {}];

  // Apply accent variable
  appUseEffect(() => {
    document.documentElement.style.setProperty("--accent", t.accent);
  }, [t.accent]);

  // Init scroll — also called at module level before render for early triggers
  appUseEffect(() => {
    if (!window.ScrollFX?.lenis) window.ScrollFX?.initScroll();
  }, []);

  // Refresh ScrollTrigger when route changes
  appUseEffect(() => {
    const id = setTimeout(() => { window.ScrollFX?.refreshTriggers(); window.ScrollFX?.scrollToTop(); }, 100);
    return () => clearTimeout(id);
  }, [route.path]);

  const openAuth = (returnTo) => { setAuthReturn(returnTo); go("/login"); };
  const onGo = (p) => { setAuthReturn(null); go(p); };

  // Route dispatch
  let page;
  const { Catalog, Detail, Cart, Success } = window.ShopPages;
  const { Membership, Auth, Account, Admin } = window.AccountPages;
  const p = route.parts;

  if (route.path === "/" || route.path === "") {
    page = <Home onGo={onGo} variant={t.heroVariant} videoUrl={t.videoUrl} />;
  } else if (p[0] === "scripts" && p.length === 1) {
    page = <Catalog onOpen={(id)=>onGo("/scripts/"+id)} />;
  } else if (p[0] === "scripts" && p[1]) {
    page = <Catalog onOpen={(id)=>onGo("/scripts/"+id)} key="cat" />;
    page = <Detail id={p[1]} onGo={onGo} openAuth={openAuth} />;
  } else if (p[0] === "cart") {
    page = <Cart onGo={onGo} openAuth={openAuth} />;
  } else if (p[0] === "success") {
    page = <Success onGo={onGo} />;
  } else if (p[0] === "membership") {
    page = <Membership onGo={onGo} openAuth={openAuth} />;
  } else if (p[0] === "login") {
    page = <Auth onGo={onGo} returnTo={authReturn} />;
  } else if (p[0] === "account") {
    page = <Account onGo={onGo} />;
  } else if (p[0] === "admin") {
    if (p[1] === "inline") {
      // Activate inline edit and bounce home
      setTimeout(() => { setInlineEdit(true); go("/"); }, 0);
      page = null;
    } else {
      page = <Admin onGo={onGo} />;
    }
  } else {
    page = <main className="wrap" style={{padding:"160px 0", textAlign:"center"}}>
      <h1 className="display" style={{fontSize:"96px"}}>404</h1>
      <p style={{color:"var(--fg-3)", marginTop:"16px"}}>This page doesn't exist.</p>
      <a className="btn" href="#/" style={{marginTop:"32px", display:"inline-flex"}} onClick={(e)=>{e.preventDefault(); onGo("/");}} data-cursor="button">Back home</a>
    </main>;
  }

  // Render tweaks panel
  const TweaksPanel = window.TweaksPanel;
  const TweakSection = window.TweakSection;
  const TweakRadio = window.TweakRadio;
  const TweakSelect = window.TweakSelect;
  const TweakColor = window.TweakColor;
  const TweakToggle = window.TweakToggle;
  const TweakText = window.TweakText;

  return (
    <React.Fragment>
      {t.noise && <div className="noise"></div>}
      <window.Cursor />
      <Nav onGo={onGo} route={route} />
      {page}
      {!["/login", "/admin"].includes(route.path) && route.path !== "/cart" && !route.path.startsWith("/admin") && route.path !== "/" && <Footer onGo={onGo} />}
      <InlineEditController active={inlineEdit} />
      {inlineEdit && <InlineEditBadge onExit={() => setInlineEdit(false)} />}
      {TweaksPanel && (
        <TweaksPanel title="Tweaks">
          <TweakSection label="Hero">
            <TweakSelect
              label="Variant"
              value={t.heroVariant}
              onChange={(v)=>setTweak("heroVariant", v)}
              options={[
                { value: "video", label: "Video Scrub (scroll-driven)" },
                { value: "particles", label: "Particles (Three.js)" },
                { value: "type", label: "Big Type" },
                { value: "grid", label: "Tile Grid" }
              ]}
            />
            {t.heroVariant === "video" && (
              <TweakText label="Video URL" value={t.videoUrl} onChange={(v)=>setTweak("videoUrl", v)} placeholder="https://…" />
            )}
          </TweakSection>
          <TweakSection label="Theme">
            <TweakColor label="Accent" value={t.accent} onChange={(v)=>setTweak("accent", v)} options={["#ff3366", "#ff7a3d", "#1eff8d", "#3d7aff"]} />
            <TweakToggle label="Noise overlay" value={t.noise} onChange={(v)=>setTweak("noise", v)} />
          </TweakSection>
          <TweakSection label="Admin">
            <TweakToggle label="Inline edit mode" value={inlineEdit} onChange={setInlineEdit} />
          </TweakSection>
        </TweaksPanel>
      )}
    </React.Fragment>
  );
}

// Mount
window.ScrollFX?.initScroll();
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<App />);
