// ============================================================
// App shell — theme toggle, back-to-top, tweaks
// ============================================================

const { useState: useApp, useEffect: useEffApp } = React;

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "accent": "teal",
  "displayFont": "newsreader",
  "density": "comfortable"
}/*EDITMODE-END*/;

const ACCENT_PRESETS = {
  teal:    { light: "48% 0.085 200", dark: "74% 0.10 200" },
  indigo:  { light: "45% 0.12  275", dark: "75% 0.13 275" },
  rust:    { light: "50% 0.13  40",  dark: "72% 0.13 50"  },
  forest:  { light: "44% 0.10  150", dark: "72% 0.11 150" },
  graphite:{ light: "32% 0.012 250", dark: "85% 0.005 80" },
};

const FONT_PRESETS = {
  newsreader: { family: '"Newsreader", Georgia, serif', label: "Newsreader" },
  fraunces:   { family: '"Fraunces", Georgia, serif',   label: "Fraunces"   },
  source:     { family: '"Source Serif 4", Georgia, serif', label: "Source Serif" },
  inter:      { family: '"Inter Tight", -apple-system, sans-serif', label: "Inter Tight" },
};

function ThemeToggle({ theme, setTheme }) {
  return (
    <button
      className="float-btn theme-toggle"
      onClick={() => setTheme(theme === "dark" ? "light" : "dark")}
      aria-label="Toggle dark mode"
      title="Toggle theme"
    >
      {theme === "dark" ? (
        <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><circle cx="12" cy="12" r="4"/><path d="M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M6.34 17.66l-1.41 1.41M19.07 4.93l-1.41 1.41"/></svg>
      ) : (
        <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"/></svg>
      )}
    </button>
  );
}

function BackToTop() {
  const [vis, setVis] = useApp(false);
  useEffApp(() => {
    const onScroll = () => setVis(window.scrollY > 400);
    window.addEventListener("scroll", onScroll, { passive: true });
    return () => window.removeEventListener("scroll", onScroll);
  }, []);
  return (
    <button
      className={"float-btn back-to-top" + (vis ? " visible" : "")}
      onClick={() => window.scrollTo({ top: 0, behavior: "smooth" })}
      aria-label="Back to top"
    >
      <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round"><polyline points="18 15 12 9 6 15"/></svg>
    </button>
  );
}

function Tweaks({ theme }) {
  const [t, setTweak] = useTweaks(TWEAK_DEFAULTS);

  // Apply accent
  useEffApp(() => {
    const a = ACCENT_PRESETS[t.accent] || ACCENT_PRESETS.teal;
    const isDark = document.documentElement.getAttribute("data-theme") === "dark";
    const v = isDark ? a.dark : a.light;
    document.documentElement.style.setProperty("--accent", `oklch(${v})`);
    document.documentElement.style.setProperty("--accent-2", `oklch(${v.replace(/^(\d+)%/, (m, n) => (isDark ? Math.min(95, +n + 8) : Math.max(20, +n - 8)) + "%")})`);
    document.documentElement.style.setProperty("--accent-soft", `oklch(${v} / ${isDark ? 0.14 : 0.1})`);
  }, [t.accent, theme]);

  // Apply display font
  useEffApp(() => {
    const f = FONT_PRESETS[t.displayFont] || FONT_PRESETS.newsreader;
    document.documentElement.style.setProperty("--serif", f.family);
  }, [t.displayFont]);

  // Density
  useEffApp(() => {
    const map = { compact: 0.85, comfortable: 1, spacious: 1.15 };
    document.documentElement.style.setProperty("--density-scale", String(map[t.density] || 1));
  }, [t.density]);

  return (
    <TweaksPanel title="Tweaks">
      <TweakSection label="Accent">
        <TweakRadio
          value={t.accent}
          onChange={(v) => setTweak("accent", v)}
          options={[
            { value: "teal", label: "Teal" },
            { value: "indigo", label: "Indigo" },
            { value: "rust", label: "Rust" },
            { value: "forest", label: "Forest" },
            { value: "graphite", label: "Mono" },
          ]}
        />
      </TweakSection>
      <TweakSection label="Display font">
        <TweakRadio
          value={t.displayFont}
          onChange={(v) => setTweak("displayFont", v)}
          options={[
            { value: "newsreader", label: "Newsreader" },
            { value: "fraunces", label: "Fraunces" },
            { value: "source", label: "Source Serif" },
            { value: "inter", label: "Inter Tight" },
          ]}
        />
      </TweakSection>
      <TweakSection label="Density">
        <TweakRadio
          value={t.density}
          onChange={(v) => setTweak("density", v)}
          options={[
            { value: "compact", label: "Compact" },
            { value: "comfortable", label: "Comfortable" },
            { value: "spacious", label: "Spacious" },
          ]}
        />
      </TweakSection>
    </TweaksPanel>
  );
}

function App() {
  const [theme, setThemeState] = useApp(() => {
    const saved = localStorage.getItem("theme");
    if (saved) return saved;
    return window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
  });

  useEffApp(() => {
    document.documentElement.setAttribute("data-theme", theme);
    localStorage.setItem("theme", theme);
  }, [theme]);

  return (
    <>
      <a className="skip-link" href="#about">Skip to content</a>
      <ThemeToggle theme={theme} setTheme={setThemeState} />
      <div className="page">
        <Identity />
        <main className="content">
          <About />
          <Education />
          <News />
          <Publications />
          <Awards />
          <OffHours />
          {/* <Services /> */}
          <footer className="site-foot">
            <div className="signature">
              <span>Munich</span>
              <span className="dot">·</span>
              <span>© {new Date().getFullYear()} Tony Danjun Wang</span>
            </div>
          </footer>
        </main>
      </div>
      <BackToTop />
      <Tweaks theme={theme} />
    </>
  );
}

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