// Main app: orchestrates everything.
const { useState: useAppState, useEffect: useAppEffect, useMemo: useAppMemo } = React;

const ANNIVERSARY = "2025-11-10";

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "aesthetic": "sakura",
  "layout": "scrap",
  "showSlideshowOnLogin": true,
  "showMap": true
}/*EDITMODE-END*/;

function diff(fromIso) {
  const [y, m, d] = fromIso.split("-").map(Number);
  const from = new Date(y, m - 1, d);
  const now = new Date();
  const to = new Date(now.getFullYear(), now.getMonth(), now.getDate());
  const days = Math.max(0, Math.round((to - from) / 86400000));
  const weeks = Math.floor(days / 7);
  let months = (to.getFullYear() - from.getFullYear()) * 12 + (to.getMonth() - from.getMonth());
  if (to.getDate() < from.getDate()) months--;
  return { days, weeks, months: Math.max(0, months) };
}

function App() {
  const [t, setTweak] = useTweaks(TWEAK_DEFAULTS);
  const [loggedIn, setLoggedIn] = useAppState(() => sessionStorage.getItem("kk_login") === "1");
  const [remoteDates, setRemoteDates] = useAppState(null);
  const dates = useAppMemo(() => {
    const src = remoteDates !== null ? remoteDates : (window.DATES || []);
    return [...src].sort((a, b) => a.date.localeCompare(b.date));
  }, [remoteDates]);
  const [view, setView] = useAppState("timeline"); // timeline | map
  const [picked, setPicked] = useAppState(null);
  const [adminOpen, setAdminOpen] = useAppState(false);
  const [showMOTD, setShowMOTD] = useAppState(false);

  useAppEffect(() => {
    // Clear pre-bot local stores.
    localStorage.removeItem("kk_dates");
    localStorage.removeItem("kk_user_dates");
    document.documentElement.setAttribute("data-aesthetic", t.aesthetic);
  }, [t.aesthetic]);

  useAppEffect(() => {
    let cancelled = false;
    fetch("/api/dates")
      .then((r) => r.ok ? r.json() : Promise.reject(r.status))
      .then((data) => { if (!cancelled) setRemoteDates(data); })
      .catch((e) => console.warn("could not load /api/dates, using local seed:", e));
    return () => { cancelled = true; };
  }, []);

  useAppEffect(() => {
    if (loggedIn && t.showSlideshowOnLogin && dates.length) {
      const seen = sessionStorage.getItem("kk_motd_seen");
      if (!seen) {
        setShowMOTD(true);
        sessionStorage.setItem("kk_motd_seen", "1");
      }
    }
  }, [loggedIn, t.showSlideshowOnLogin, dates.length]);

  // Re-tick every minute so the counter stays fresh.
  const [tick, setTick] = useAppState(0);
  useAppEffect(() => {
    const id = setInterval(() => setTick((t) => t + 1), 60000);
    return () => clearInterval(id);
  }, []);

  const counts = useAppMemo(() => diff(ANNIVERSARY), [tick]);

  // Random memory of the day
  const motd = useAppMemo(() => {
    if (!dates.length) return null;
    return dates[Math.floor(Math.random() * dates.length)];
  }, [showMOTD]);

  function handleLogin() {
    sessionStorage.setItem("kk_login", "1");
    setLoggedIn(true);
  }

  if (!loggedIn) {
    return <Login onPass={handleLogin} />;
  }

  const sorted = dates;

  return (
    <div className="app" data-screen-label="02 Home">
      <header className="topbar">
        <div className="brand">
          <div className="brand-mark">♥</div>
          <div>
            <div className="brand-name">Karen &amp; Ming Yuan</div>
            <div className="brand-sub">a little museum of us</div>
          </div>
        </div>
        <div className="counter">
          <div className="counter-cell">
            <div className="counter-num">{counts.days}</div>
            <div className="counter-lbl">days</div>
          </div>
          <div className="counter-cell">
            <div className="counter-num">{counts.weeks}</div>
            <div className="counter-lbl">weeks</div>
          </div>
          <div className="counter-cell">
            <div className="counter-num">{counts.months}</div>
            <div className="counter-lbl">months</div>
          </div>
          <div className="counter-cell">
            <div className="counter-num">{dates.length}</div>
            <div className="counter-lbl">dates</div>
          </div>
        </div>
      </header>

      <h1 className="hero-title">our timeline.</h1>
      <p className="hero-sub">every wandering, in order. tap a card to remember.</p>

      <div className="row-between" style={{ marginBottom: 24 }}>
        <div className="viewer-tabs">
          <button className={"viewer-tab" + (view === "timeline" ? " on" : "")} onClick={() => setView("timeline")}>timeline</button>
          {t.showMap && (
            <button className={"viewer-tab" + (view === "map" ? " on" : "")} onClick={() => setView("map")}>map</button>
          )}
        </div>
        {view === "timeline" && (
          <div className="viewer-tabs">
            <button className={"viewer-tab" + (t.layout === "vertical" ? " on" : "")} onClick={() => setTweak("layout", "vertical")}>vertical</button>
            <button className={"viewer-tab" + (t.layout === "strip" ? " on" : "")} onClick={() => setTweak("layout", "strip")}>film strip</button>
            <button className={"viewer-tab" + (t.layout === "scrap" ? " on" : "")} onClick={() => setTweak("layout", "scrap")}>scrapbook</button>
            <button className={"viewer-tab" + (t.layout === "calendar" ? " on" : "")} onClick={() => setTweak("layout", "calendar")}>calendar</button>
          </div>
        )}
      </div>

      {view === "timeline" && t.layout === "vertical" && <VerticalTimeline dates={sorted} onPick={setPicked} />}
      {view === "timeline" && t.layout === "strip" && <FilmStrip dates={sorted} onPick={setPicked} />}
      {view === "timeline" && t.layout === "scrap" && <Scrapbook dates={sorted} onPick={setPicked} />}
      {view === "timeline" && t.layout === "calendar" && <CalendarView dates={sorted} onPick={setPicked} />}
      {view === "map" && <DateMap dates={sorted} onPick={setPicked} />}

      <DetailOverlay date={picked} onClose={() => setPicked(null)} />
      <AdminPanel open={adminOpen} onClose={() => setAdminOpen(false)} />

      {showMOTD && motd && (
        <div className="slideshow" onClick={() => setShowMOTD(false)} data-screen-label="03 Memory of the day">
          <div className="slide-card" onClick={(e) => e.stopPropagation()}>
            <div className="slide-img" style={{ background: motd.color }}>
              <Photo fileId={motd.photos?.[0]} alt={motd.area} caption={motd.area} />
            </div>
            <div className="slide-body">
              <div className="slide-eyebrow">memory of the day · {formatDate(motd.date)}</div>
              <h2 className="slide-h">{motd.title}</h2>
              <p className="slide-memory">{motd.memory}</p>
              <button className="slide-dismiss" onClick={() => setShowMOTD(false)}>more memories</button>
            </div>
          </div>
        </div>
      )}

      <button className="admin-fab" onClick={() => setAdminOpen(true)} title="add a memory">+</button>

      <TweaksPanel title="Tweaks">
        <TweakSection label="Aesthetic" />
        <TweakSelect
          label="Palette"
          value={t.aesthetic}
          options={["blush", "sakura", "twilight", "cream"]}
          onChange={(v) => setTweak("aesthetic", v)}
        />
        <div style={{display:"grid", gridTemplateColumns:"repeat(4, 1fr)", gap:8}}>
          {[
            { name: "blush",    sw: ["#fbf4ef","#e8b4b8","#9d4c5b"] },
            { name: "sakura",   sw: ["#fef6f6","#f4b6c2","#c75a78"] },
            { name: "twilight", sw: ["#f3eef7","#c9b6e0","#6d4a8f"] },
            { name: "cream",    sw: ["#f7f0e3","#d9a89a","#a05a3f"] },
          ].map((p) => (
            <button
              key={p.name}
              type="button"
              onClick={() => setTweak("aesthetic", p.name)}
              style={{
                appearance:"none", border: t.aesthetic === p.name ? "2px solid #29261b" : "1px solid rgba(0,0,0,.1)",
                borderRadius: 10, padding: 4, background: "white", cursor: "pointer",
                display:"flex", flexDirection:"column", gap:3, alignItems:"stretch"
              }}
              title={p.name}
            >
              <div style={{display:"flex", height:18, borderRadius:6, overflow:"hidden"}}>
                {p.sw.map((c, i) => <div key={i} style={{flex:1, background:c}} />)}
              </div>
              <div style={{fontSize:9, textTransform:"uppercase", letterSpacing:".08em", color:"#29261b"}}>{p.name}</div>
            </button>
          ))}
        </div>
        <TweakSection label="Layout" />
        <TweakRadio
          label="Timeline"
          value={t.layout}
          options={["vertical", "strip", "scrap", "calendar"]}
          onChange={(v) => setTweak("layout", v)}
        />
        <TweakToggle
          label="Show map tab"
          value={t.showMap}
          onChange={(v) => setTweak("showMap", v)}
        />
        <TweakSection label="On open" />
        <TweakToggle
          label="Memory-of-the-day"
          value={t.showSlideshowOnLogin}
          onChange={(v) => setTweak("showSlideshowOnLogin", v)}
        />
        <TweakButton label="Replay memory now" onClick={() => setShowMOTD(true)} />
        <TweakSection label="Session" />
        <TweakButton label="Lock again (log out)" onClick={() => {
          sessionStorage.removeItem("kk_login");
          sessionStorage.removeItem("kk_motd_seen");
          setLoggedIn(false);
        }} />
        <TweakButton label="Reset user-added dates" onClick={() => {
          localStorage.removeItem("kk_user_dates");
          localStorage.removeItem("kk_dates"); /* clear legacy too */
          setUserAdded([]);
        }} />
      </TweaksPanel>
    </div>
  );
}

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