/* ============ chethan — main app ============ */

const DEFAULTS = /*EDITMODE-BEGIN*/{
  "titleVariant": "classic",
  "worksLayout": "list",
  "grain": 0.06,
  "showCursor": true,
  "showStatus": true,
  "spinningMark": true,
  "marqueeSpeed": 38
}/*EDITMODE-END*/;

function useClock() {
  const fmt = () => {
    const d = new Date();
    try { return new Intl.DateTimeFormat("en-GB", { hour:"2-digit", minute:"2-digit", timeZone:"Asia/Kolkata" }).format(d) + " IST"; }
    catch { return d.toLocaleTimeString().slice(0,5) + " IST"; }
  };
  const [t, setT] = React.useState(fmt);
  React.useEffect(() => { const id = setInterval(() => setT(fmt()), 30000); return () => clearInterval(id); }, []);
  return t;
}

function useIsTouch() {
  const [touch, setTouch] = React.useState(false);
  React.useEffect(() => {
    const check = () => {
      const t = matchMedia("(hover: none)").matches || "ontouchstart" in window;
      setTouch(t);
    };
    check();
    window.addEventListener("resize", check);
    return () => window.removeEventListener("resize", check);
  }, []);
  return touch;
}

function App() {
  const [tweaks, setTweak] = useTweaks(DEFAULTS);
  const [loaded, setLoaded] = React.useState(false);
  const [menuOpen, setMenuOpen] = React.useState(false);
  const [openProject, setOpenProject] = React.useState(null);
  const [activeSec, setActiveSec] = React.useState("works");
  const [inverted, setInverted] = React.useState(false);
  const time = useClock();
  const touch = useIsTouch();
  useReveal();

  /* apply live tweaks */
  React.useEffect(() => {
    document.documentElement.style.setProperty("--grain", tweaks.grain);
    document.querySelectorAll(".marquee").forEach(m => m.style.setProperty("--speed", tweaks.marqueeSpeed + "s"));
  }, [tweaks.grain, tweaks.marqueeSpeed]);

  /* invert easter egg (Konami: ↑↑↓↓←→←→BA or just type "invert") */
  React.useEffect(() => {
    document.body.classList.toggle("is-inverted", inverted);
  }, [inverted]);
  React.useEffect(() => {
    const keys = ["ArrowUp","ArrowUp","ArrowDown","ArrowDown","ArrowLeft","ArrowRight","ArrowLeft","ArrowRight","b","a"];
    let i = 0;
    const onKey = (e) => {
      if ((e.key + "").toLowerCase() === keys[i].toLowerCase()) {
        i++;
        if (i === keys.length) { setInverted(v => !v); i = 0; }
      } else { i = (e.key === keys[0]) ? 1 : 0; }
    };
    window.addEventListener("keydown", onKey);
    return () => window.removeEventListener("keydown", onKey);
  }, []);

  /* lock body scroll while menu is open */
  React.useEffect(() => {
    document.body.style.overflow = menuOpen ? "hidden" : "";
    return () => { document.body.style.overflow = ""; };
  }, [menuOpen]);

  /* track active section for sidenav */
  React.useEffect(() => {
    if (!loaded) return;
    const ids = ["works", "more", "aosp", "stack", "about", "github", "research", "contact"];
    const io = new IntersectionObserver((entries) => {
      entries.forEach(e => { if (e.isIntersecting) setActiveSec(e.target.id); });
    }, { rootMargin: "-30% 0px -60% 0px" });
    ids.forEach(id => { const el = document.getElementById(id); if (el) io.observe(el); });
    return () => io.disconnect();
  }, [loaded]);

  const jump = (id) => {
    const el = document.getElementById(id);
    if (el) window.scrollTo({ top: el.getBoundingClientRect().top + window.scrollY - 40, behavior: "smooth" });
  };

  return (
    <div className={"app " + (touch ? "is-touch" : "")}>
      <ScrollProgress />
      <div className="grain" />
      {!loaded && <Loader onDone={() => setLoaded(true)} />}
      {!touch && <Cursor showNative={!tweaks.showCursor} />}
      <Topbar time={time} spinning={tweaks.spinningMark}
              onMenuToggle={() => setMenuOpen(v => !v)} menuOpen={menuOpen}
              inverted={inverted} onThemeToggle={() => setInverted(v => !v)} />
      <MenuOverlay open={menuOpen} onClose={() => setMenuOpen(false)} onJump={jump} />
      <SideNav active={activeSec} onJump={jump} />
      <Hero titleVariant={tweaks.titleVariant} />
      <Marquee />
      <section className="section">
        <Works variant={touch ? "tiles" : tweaks.worksLayout} onOpen={(code) => setOpenProject(code)} />
      </section>
      <section className="section">
        <MoreProjects />
      </section>
      <section className="section">
        <AOSPSection />
      </section>
      <section className="section">
        <Stack />
      </section>
      <section className="section">
        <About />
      </section>
      <section className="section">
        <GitHubStats />
      </section>
      <section className="section">
        <Research />
      </section>
      <Foot />
      {tweaks.showStatus && !touch && <StatusPill time={time} />}

      <ProjectModal code={openProject} onClose={() => setOpenProject(null)} />

      <TweaksPanel title="Tweaks">
        <TweakSection label="Hero">
          <TweakRadio label="Headline" value={tweaks.titleVariant}
            onChange={(v) => setTweak("titleVariant", v)}
            options={[
              { value: "classic", label: "Intro" },
              { value: "bold",    label: "Bold" },
              { value: "studio",  label: "Tech" },
            ]} />
        </TweakSection>
        <TweakSection label="Work">
          <TweakRadio label="Layout" value={tweaks.worksLayout}
            onChange={(v) => setTweak("worksLayout", v)}
            options={[
              { value: "list",  label: "List" },
              { value: "tiles", label: "Tiles" },
            ]} />
        </TweakSection>
        <TweakSection label="Atmosphere">
          <TweakSlider label="Grain" value={tweaks.grain} min={0} max={0.2} step={0.005}
            onChange={(v) => setTweak("grain", v)} />
          <TweakSlider label="Marquee speed" value={tweaks.marqueeSpeed} min={12} max={80} step={1} unit="s"
            onChange={(v) => setTweak("marqueeSpeed", v)} />
          <TweakToggle label="Custom cursor" value={tweaks.showCursor}
            onChange={(v) => setTweak("showCursor", v)} />
          <TweakToggle label="Status pill" value={tweaks.showStatus}
            onChange={(v) => setTweak("showStatus", v)} />
          <TweakToggle label="Spinning mark" value={tweaks.spinningMark}
            onChange={(v) => setTweak("spinningMark", v)} />
          <TweakToggle label="Invert (B&W swap)" value={inverted}
            onChange={(v) => setInverted(v)} />
        </TweakSection>
      </TweaksPanel>
    </div>
  );
}

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