const { useState, useEffect, useRef, useCallback } = React;

const AESTHETICS = [
  { key: "editorial", label: "Editorial", note: "Warm, magazine-like" },
  { key: "quiet",     label: "Quiet",     note: "Modern & restrained" },
  { key: "homey",     label: "Homey",     note: "Soft & grounded" },
];
const DENSITIES = [
  { key: "airy",     label: "Airy" },
  { key: "balanced", label: "Balanced" },
  { key: "compact",  label: "Compact" },
];

// Palette variations — each is a complete cohesive set, applied as overrides
// across all aesthetics so the underlying typography choice is preserved.
const PALETTES = {
  default: null, // honors the aesthetic's built-in palette

  // Cream + clay + dark teal — the requested palette
  teal:    { "--bg": "#f3ecdd", "--bg-soft": "#e8dcc4", "--ink": "#0f3a3e", "--ink-soft": "#5e6a5e", "--accent": "#b16a4a", "--rule": "#d6c9a8" },

  // Soft sage greens on cream
  sage:    { "--bg": "#f2efe6", "--bg-soft": "#e8e4d4", "--ink": "#23291f", "--ink-soft": "#5e6453", "--accent": "#6b7a5d", "--rule": "#d2cebd" },

  // Warm clay/terracotta-led
  clay:    { "--bg": "#f4e8d8", "--bg-soft": "#ead9bf", "--ink": "#2a221c", "--ink-soft": "#6b5a4a", "--accent": "#a0644a", "--rule": "#dac1a3" },

  // Plum + dusty rose on bone
  plum:    { "--bg": "#f3ece4", "--bg-soft": "#e9dfd2", "--ink": "#2a1f29", "--ink-soft": "#6b5e64", "--accent": "#7a3d4f", "--rule": "#d9c8c2" },

  // Inky navy on cool paper
  navy:    { "--bg": "#eef0ec", "--bg-soft": "#e0e3dd", "--ink": "#161b25", "--ink-soft": "#5d6473", "--accent": "#2f4a6b", "--rule": "#cdd1c8" },

  // Forest greens on parchment
  forest:  { "--bg": "#ece8d8", "--bg-soft": "#ddd8c0", "--ink": "#1f2920", "--ink-soft": "#5d6657", "--accent": "#3e5a3c", "--rule": "#c8c2a4" },

  // Mustard ochre on cream
  ochre:   { "--bg": "#f4ecdb", "--bg-soft": "#ebe0c5", "--ink": "#2b2418", "--ink-soft": "#6a5d44", "--accent": "#9a7325", "--rule": "#d8c89c" },

  // Cool slate on snow
  slate:   { "--bg": "#f1f1ee", "--bg-soft": "#e4e4e0", "--ink": "#1d2024", "--ink-soft": "#5e6266", "--accent": "#4a5563", "--rule": "#cdcec8" },

  // === Cream-based with clay + teal accents ===

  // Cream base, clay headlines, teal accents (inverse of "teal")
  creamClay:   { "--bg": "#f7efde", "--bg-soft": "#ede1c7", "--ink": "#5a3322", "--ink-soft": "#8a6650", "--accent": "#1f5358", "--rule": "#dccaa6" },

  // Cream base, teal ink, clay accents (lighter, warmer than "teal")
  creamTeal:   { "--bg": "#f8f1df", "--bg-soft": "#eee2c5", "--ink": "#13474b", "--ink-soft": "#5a7274", "--accent": "#c47a55", "--rule": "#dfcfa9" },

  // Pale cream, deep teal display, soft clay rule
  harbor:      { "--bg": "#fbf4e3", "--bg-soft": "#f3e8cc", "--ink": "#0c3236", "--ink-soft": "#5b6f6f", "--accent": "#a85a3d", "--rule": "#e3d2ad" },

  // Cream + warm rust + sage-teal (earthier, gentler)
  potter:      { "--bg": "#f4ead4", "--bg-soft": "#ead9b7", "--ink": "#2c2017", "--ink-soft": "#6e5c46", "--accent": "#b66a44", "--rule": "#d8c094" },

  // === Other cream-based combinations ===

  // Cream + olive + warm brown (vintage Italian)
  olive:       { "--bg": "#f4ecd6", "--bg-soft": "#e9deb9", "--ink": "#2a2a18", "--ink-soft": "#6a6543", "--accent": "#7a7536", "--rule": "#d6c898" },

  // Cream + dusty rose + sage (gentle, gendered-neutral nursery)
  bloom:       { "--bg": "#f7ecde", "--bg-soft": "#eddbc6", "--ink": "#3a2630", "--ink-soft": "#7d6168", "--accent": "#c47a7a", "--rule": "#e3cdb6" },

  // Cream + cobalt + butter (Matisse-ish)
  cobalt:      { "--bg": "#f7eed8", "--bg-soft": "#ede1bb", "--ink": "#1f2a4a", "--ink-soft": "#5d6480", "--accent": "#c89a3c", "--rule": "#dccfa1" },

  // Cream + chocolate + butter (warm cafe)
  cocoa:       { "--bg": "#f6ecd5", "--bg-soft": "#ecdfb9", "--ink": "#3a2418", "--ink-soft": "#7a5b46", "--accent": "#b07a3a", "--rule": "#d9c895" },
};
const PALETTE_OPTS = [
  { key: "default", label: "Default", swatch: ["#f5efe6", "#2a2420", "#8a6a4a"] },
  { key: "teal",    label: "Teal & Clay", swatch: ["#f3ecdd", "#0f3a3e", "#b16a4a"] },
  { key: "creamClay", label: "Cream / Clay",  swatch: ["#f7efde", "#5a3322", "#1f5358"] },
  { key: "creamTeal", label: "Cream / Teal",  swatch: ["#f8f1df", "#13474b", "#c47a55"] },
  { key: "harbor",  label: "Harbor",      swatch: ["#fbf4e3", "#0c3236", "#a85a3d"] },
  { key: "potter",  label: "Potter",      swatch: ["#f4ead4", "#2c2017", "#b66a44"] },
  { key: "sage",    label: "Sage",        swatch: ["#f2efe6", "#23291f", "#6b7a5d"] },
  { key: "olive",   label: "Olive",       swatch: ["#f4ecd6", "#2a2a18", "#7a7536"] },
  { key: "clay",    label: "Clay",        swatch: ["#f4e8d8", "#2a221c", "#a0644a"] },
  { key: "cocoa",   label: "Cocoa",       swatch: ["#f6ecd5", "#3a2418", "#b07a3a"] },
  { key: "ochre",   label: "Ochre",       swatch: ["#f4ecdb", "#2b2418", "#9a7325"] },
  { key: "bloom",   label: "Bloom",       swatch: ["#f7ecde", "#3a2630", "#c47a7a"] },
  { key: "plum",    label: "Plum",        swatch: ["#f3ece4", "#2a1f29", "#7a3d4f"] },
  { key: "forest",  label: "Forest",      swatch: ["#ece8d8", "#1f2920", "#3e5a3c"] },
  { key: "navy",    label: "Navy",        swatch: ["#eef0ec", "#161b25", "#2f4a6b"] },
  { key: "cobalt",  label: "Cobalt",      swatch: ["#f7eed8", "#1f2a4a", "#c89a3c"] },
  { key: "slate",   label: "Slate",       swatch: ["#f1f1ee", "#1d2024", "#4a5563"] },
];

function applyPalette(palette) {
  const overrides = PALETTES[palette];
  // Clear previously set inline vars on body
  const body = document.body;
  ["--bg", "--bg-soft", "--ink", "--ink-soft", "--accent", "--rule"].forEach((v) => body.style.removeProperty(v));
  if (overrides) {
    Object.entries(overrides).forEach(([k, v]) => body.style.setProperty(k, v));
  }
}

// =============== LOGIN ===============
function LoginScreen({ onEnter }) {
  const [code, setCode] = useState("");
  const [err, setErr] = useState("");
  const [submitting, setSubmitting] = useState(false);
  const inputRef = useRef(null);

  useEffect(() => { inputRef.current?.focus(); }, []);

  const submit = (e) => {
    e?.preventDefault();
    const key = code.trim().toUpperCase();
    if (!key) { setErr("Please enter your access code."); return; }
    const recipient = window.RECIPIENTS[key];
    if (!recipient) { setErr("That code didn't match. Please check what we sent you."); return; }
    setSubmitting(true);
    setErr("");
    // Fire-and-forget analytics ping (endpoint may not exist yet — that's fine).
    try {
      fetch("/api/log-login", {
        method: "POST",
        headers: { "content-type": "application/json" },
        body: JSON.stringify({ code: key, name: recipient.name }),
        keepalive: true,
      }).catch(() => {});
    } catch {}
    setTimeout(() => onEnter({ ...recipient, code: key }), 450);
  };

  return (
    <div className="login-screen" data-screen-label="Login">
      <div className="login-card">
        <h1>Beth &amp; Zach</h1>
        <p className="welcome-line">
          Welcome. This is a small private book made just for you. Please enter the code we shared to open it.
        </p>
        <form onSubmit={submit}>
          <input
            ref={inputRef}
            className="login-input"
            type="text"
            placeholder="ACCESS CODE"
            value={code}
            onChange={(e) => setCode(e.target.value.toUpperCase())}
            autoComplete="off"
            spellCheck="false"
          />
          <div className="login-err">{err}</div>
          <button className="login-btn" type="submit" disabled={submitting || !code.trim()}>
            {submitting ? "Opening…" : "Open the book"}
          </button>
        </form>
      </div>
      <div className="login-footer">A private profile book · Beth &amp; Zach</div>
    </div>
  );
}

// =============== BOOK (post-login) ===============
function Book({ recipient, tweaks, setTweaks, onLogout }) {
  const bookRef = useRef(null);
  const [activeIdx, setActiveIdx] = useState(0);
  const [showGreet, setShowGreet] = useState(true);

  useEffect(() => {
    const t = setTimeout(() => setShowGreet(false), 2800);
    return () => clearTimeout(t);
  }, []);

  const chapters = window.CHAPTERS;
  // Section id -> component. Multiple sections can roll up to one nav
  // entry; CHAPTERS in data.jsx defines the grouping.
  const SECTION_COMPS = {
    letter:     window.ChapterLetter,
    about:      window.ChapterAbout,
    stronger:   window.ChapterStronger,
    story:      window.ChapterStoryInteractive,
    home:       window.ChapterHome,
    family:     window.ChapterFamily,
    friends:    window.ChapterFriends,
    leisure:    window.ChapterLeisure,
    traditions: window.ChapterTraditions,
    day:        window.ChapterDay,
    values:     window.ChapterValues,
    life:       window.ChapterLife,
    parenthood: window.ChapterParenthood,
    hopes:      window.ChapterHopes,
    close:      window.ChapterClose,
  };
  const flatSections = chapters.flatMap((c) => c.sections);

  // Observe which chapter is on screen — map section id back to its chapter.
  useEffect(() => {
    const book = bookRef.current;
    if (!book) return;
    const sections = book.querySelectorAll(".chapter");
    const io = new IntersectionObserver(
      (entries) => {
        entries.forEach((e) => {
          if (e.isIntersecting && e.intersectionRatio > 0.5) {
            const sid = e.target.id.replace(/^chapter-/, "");
            const cIdx = chapters.findIndex((c) => c.sections.includes(sid));
            if (cIdx >= 0) setActiveIdx(cIdx);
          }
        });
      },
      { root: book, threshold: [0.5] }
    );
    sections.forEach((s) => io.observe(s));
    return () => io.disconnect();
  }, [chapters]);

  const scrollTo = (cIdx) => {
    const book = bookRef.current;
    if (!book) return;
    const firstSid = chapters[cIdx]?.sections[0];
    if (!firstSid) return;
    book.querySelector(`#chapter-${firstSid}`)?.scrollIntoView({ behavior: "smooth", block: "start" });
  };

  const greetName = recipient.agency ? `For ${recipient.agency}` : (recipient.name && recipient.name !== "Friend" ? `For ${recipient.name}` : "Welcome, dear friend");

  return (
    <>
      {showGreet && (
        <div className="greet-overlay">
          <div className="hello">{greetName}</div>
        </div>
      )}

      <div className="topbar">
        <div className="mono">Beth &amp; Zach · A Profile Book</div>
        <div style={{ display: "flex", gap: "2rem", alignItems: "center" }}>
          <span className="mono" style={{ opacity: 0.55 }}>
            {String(activeIdx + 1).padStart(2, "0")} / {String(chapters.length).padStart(2, "0")}
          </span>
          <button onClick={onLogout}>Close book</button>
        </div>
      </div>

      <nav className="chapter-nav">
        {chapters.map((c, i) => (
          <button
            key={c.id}
            className={i === activeIdx ? "is-active" : ""}
            onClick={() => scrollTo(i)}
            aria-label={c.nav}
          >
            <span className="label">{c.nav}</span>
          </button>
        ))}
      </nav>

      <div className="book" ref={bookRef}>
        {flatSections.map((sid) => {
          const C = SECTION_COMPS[sid];
          return C ? <C key={sid} /> : null;
        })}
      </div>
    </>
  );
}

// =============== TWEAKS PANEL ===============
function TweaksPanel({ tweaks, setTweaks, visible }) {
  if (!visible) return null;
  const set = (key, val) => {
    const next = { ...tweaks, [key]: val };
    setTweaks(next);
    try {
      window.parent.postMessage({ type: "__edit_mode_set_keys", edits: { [key]: val } }, "*");
    } catch (e) {}
  };
  return (
    <div className="tweaks-panel">
      <h3>Tweaks</h3>
      <div className="tweak-row">
        <label>Aesthetic</label>
        <div className="tweak-options">
          {AESTHETICS.map((a) => (
            <button key={a.key} className={tweaks.aesthetic === a.key ? "is-active" : ""} onClick={() => set("aesthetic", a.key)}>{a.label}</button>
          ))}
        </div>
      </div>
      <div className="tweak-row">
        <label>Palette</label>
        <div className="tweak-options tweak-swatches">
          {PALETTE_OPTS.map((p) => (
            <button key={p.key}
              className={tweaks.palette === p.key ? "swatch is-active" : "swatch"}
              onClick={() => set("palette", p.key)}
              title={p.label}
              aria-label={p.label}>
              <span className="swatch-chips" aria-hidden="true">
                <span style={{ background: p.swatch[0] }} />
                <span style={{ background: p.swatch[1] }} />
                <span style={{ background: p.swatch[2] }} />
              </span>
              <span className="swatch-label">{p.label}</span>
            </button>
          ))}
        </div>
      </div>
      <div className="tweak-row">
        <label>Density</label>
        <div className="tweak-options">
          {DENSITIES.map((d) => (
            <button key={d.key} className={tweaks.density === d.key ? "is-active" : ""} onClick={() => set("density", d.key)}>{d.label}</button>
          ))}
        </div>
      </div>
    </div>
  );
}

// =============== APP ROOT ===============
function App() {
  const [recipient, setRecipient] = useState(null);
  const [tweaks, setTweaks] = useState(() => ({ ...(window.TWEAK_DEFAULTS || { aesthetic: "editorial", density: "airy", palette: "default" }) }));
  const [tweaksVisible, setTweaksVisible] = useState(false);

  // Apply aesthetic + density to body
  useEffect(() => {
    document.body.setAttribute("data-aesthetic", tweaks.aesthetic || "editorial");
    document.body.setAttribute("data-density", tweaks.density || "airy");
    // Need a tick for CSS vars to update before overlaying palette
    requestAnimationFrame(() => applyPalette(tweaks.palette || "default"));
  }, [tweaks.aesthetic, tweaks.density, tweaks.palette]);

  // Edit-mode integration (Tweaks toolbar)
  useEffect(() => {
    const onMsg = (e) => {
      const data = e.data;
      if (!data || typeof data !== "object") return;
      if (data.type === "__activate_edit_mode") setTweaksVisible(true);
      if (data.type === "__deactivate_edit_mode") setTweaksVisible(false);
    };
    window.addEventListener("message", onMsg);
    // Announce after listener exists
    try { window.parent.postMessage({ type: "__edit_mode_available" }, "*"); } catch (e) {}
    return () => window.removeEventListener("message", onMsg);
  }, []);

  return (
    <>
      {!recipient ? (
        <LoginScreen onEnter={setRecipient} />
      ) : (
        <Book recipient={recipient} tweaks={tweaks} setTweaks={setTweaks} onLogout={() => setRecipient(null)} />
      )}
      <TweaksPanel tweaks={tweaks} setTweaks={setTweaks} visible={tweaksVisible} />
    </>
  );
}

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