/* scope guard: file-scoped IIFE — see index.html */
(function () {
/* Stoic+ — app shell & router.

   Replaces the prototype's phone-frame harness with a real responsive
   web app (CLAUDE.md §0 + Design Law 10): one centered ~440px column,
   no bezel / notch / fake status bar. Owns navigation, the four routed
   tabs, the check-in overlay, the bottom sheets, and the gating states
   (sign-in → first-launch welcome → app · lapsed → renew wall).

   State is seeded from and written through Store (localStorage in a
   hosted build, in-memory otherwise). The dev "Prototype states" menu
   is mounted only when the URL carries ?dev. */

const { useState, useEffect } = React;

const NAV = [
  { key: "home",    label: "Today",   icon: "Home" },
  { key: "journey", label: "Journey", icon: "Trend" },
  { key: "coach",   label: "Coach",   icon: "Message" },
  { key: "settings",label: "Settings",icon: "Settings" },
];
const TAB_KEYS = NAV.map((n) => n.key);

const IS_DEV = (() => { try { return new URLSearchParams(window.location.search).has("dev"); } catch (e) { return false; } })();

/* Hash router for the four tabs → linkable screens, working back button. */
function useTabRoute() {
  const read = () => window.location.hash.replace(/^#\/?/, "").split("/")[0];
  const [raw, setRaw] = useState(read);
  useEffect(() => {
    const on = () => setRaw(read());
    window.addEventListener("hashchange", on);
    return () => window.removeEventListener("hashchange", on);
  }, []);
  const tab = TAB_KEYS.indexOf(raw) >= 0 ? raw : "home";
  const setTab = (t) => {
    const v = document.querySelector(".viewport");
    if (v) v.scrollTop = 0;
    if (read() === t) setRaw(t); else window.location.hash = "/" + t;
  };
  return [tab, setTab];
}

function App() {
  const boot = window.Store.load();
  const Sheet = window.Sheet;
  const I = window.Icons;

  const [tab, setTab] = useTabRoute();
  const [authed, setAuthed] = useState(boot.authed);
  const [welcomeSeen, setWelcomeSeen] = useState(boot.welcomeSeen);
  const [email, setEmail] = useState(boot.email || "");
  const [sheet, setSheet] = useState(null);
  const [overlay, setOverlay] = useState(null);                 // 'checkin' | 'edit'
  const [values, setValues] = useState(boot.values);
  const [logged, setLogged] = useState(boot.logged);
  const [committedAction, setCommittedAction] = useState(boot.committedAction);
  const [sub, setSub] = useState(boot.sub);                     // 'active' | 'offline'(dev) | 'lapsed'
  const [rangeIdx, setRangeIdx] = useState(1);
  const [online, setOnline] = useState(typeof navigator === "undefined" ? true : navigator.onLine);
  const [scenario, setScenario] = useState("normal");          // DEV-only QA control; always 'normal' in prod
  const [hydrated, setHydrated] = useState(false);             // pulled real server state yet?

  // Real connectivity → fail-open offline indicator (never lock a member out).
  useEffect(() => {
    const up = () => setOnline(true), down = () => setOnline(false);
    window.addEventListener("online", up);
    window.addEventListener("offline", down);
    return () => { window.removeEventListener("online", up); window.removeEventListener("offline", down); };
  }, []);

  // Persist the durable slices through the store on change.
  useEffect(() => { window.Store.save({ authed, welcomeSeen, email, values, logged, committedAction, sub }); },
    [authed, welcomeSeen, email, values, logged, committedAction, sub]);

  // Hydrate real server state once signed in (sets window.__HIST / __BOOT for
  // the charts). Fail-open: on error we keep the cached/seed view.
  useEffect(() => {
    if (!authed || !welcomeSeen || hydrated) return;
    window.Store.hydrate().then((b) => {
      setHydrated(true);
      if (b.today) { setValues(b.today.values); setLogged(!!b.today.logged); }
      if (b.coach) setCommittedAction(b.coach.committedAction || null);
      if (b.subscription && b.subscription.sub) setSub(b.subscription.sub);
      if (b.user && b.user.email) setEmail(b.user.email);
    }).catch(() => setHydrated(true));
  }, [authed, welcomeSeen, hydrated]);

  const go = setTab;

  // ---- flows (each routes through a Store.api seam) ----
  const signIn = (addr) => {
    window.Store.api.signIn(addr)
      .then((r) => { if (addr) setEmail(addr); if (r && r.sub) setSub(r.sub); setAuthed(true); })
      .catch(() => setAuthed(true)); // fail-open (auth verification lands at the end)
  };
  const beginFromWelcome = () => { setWelcomeSeen(true); setOverlay("checkin"); };
  const startCheckin = () => setOverlay("checkin");
  const editCheckin = () => setOverlay("edit");
  const submitCheckin = (vals) => {
    window.Store.api.submitCheckin(vals).then(() => { setValues(vals); setLogged(true); setOverlay(null); setHydrated(false); go("home"); });
  };
  const commit = (action) => { window.Store.api.commitAction(action).then(() => setCommittedAction(action)); };
  const signOut = () => { window.Store.api.signOut().then(() => { setAuthed(false); setSheet(null); go("home"); }); };
  const restore = () => { window.Store.api.restorePurchases().then((r) => setSub(r.sub)); };
  const renew = () => { window.Store.api.renew().then((r) => setSub(r.sub)); };

  const offline = sub === "offline" || !online;

  /* The dev "Prototype states" trigger + sheet — only when ?dev is set. */
  const DevTrigger = IS_DEV ? (
    <button className="dev-beaker press" title="Prototype states" onClick={() => setSheet("demo")}>
      <I.Beaker size={16} />
    </button>
  ) : null;
  const DemoSheet = IS_DEV ? (
    <Sheet open={sheet === "demo"} onClose={() => setSheet(null)} title="Prototype states">
      <window.DemoMenu {...{ scenario, setScenario, sub, setSub, logged, setLogged, welcome: !welcomeSeen, setWelcome: (w) => setWelcomeSeen(!w), authed, setAuthed }} onClose={() => setSheet(null)} />
    </Sheet>
  ) : null;

  // ---- Gating states ----
  if (!authed) {
    return (
      <div className="app stoic-root">
        <div className="ambient"></div>
        <div className="viewport flush"><window.SignInScreen onEnter={signIn} /></div>
        {DevTrigger}{DemoSheet}
      </div>
    );
  }

  if (!welcomeSeen) {
    return (
      <div className="app stoic-root">
        <div className="ambient"></div>
        <div className="viewport flush"><window.WelcomeScreen onBegin={beginFromWelcome} /></div>
        {DevTrigger}{DemoSheet}
      </div>
    );
  }

  if (sub === "lapsed") {
    return (
      <div className="app stoic-root">
        <window.RenewWall onRenew={renew} onRestore={restore} />
        {DevTrigger}{DemoSheet}
      </div>
    );
  }

  // ---- Main app ----
  let Body;
  if (overlay) {
    Body = <window.Checkin initial={overlay === "edit" ? values : null} onSubmit={submitCheckin} onCancel={() => setOverlay(null)} />;
  } else if (tab === "home") {
    Body = <window.TodayScreen {...{ values, logged, scenario, offline, committedAction, rangeIdx, setRangeIdx }} onStartCheckin={startCheckin} onEditCheckin={editCheckin} openSheet={setSheet} />;
  } else if (tab === "journey") {
    Body = <window.JourneyScreen scenario={scenario} openSheet={setSheet} />;
  } else if (tab === "coach") {
    Body = <window.CoachScreen scenario={scenario} committedAction={committedAction} onCommit={commit} onAsk={() => setSheet("ask")} />;
  } else {
    Body = <window.SettingsScreen sub={sub} email={email} onSignOut={signOut} onManageSub={() => { if (sub === "lapsed") renew(); }} onRestore={restore} onExport={() => window.Store.api.exportData()} />;
  }

  const hideNav = !!overlay;

  return (
    <div className="app stoic-root">
      <div className="ambient"></div>
      <div className="viewport" key={tab + (overlay || "") + scenario + logged}>{Body}</div>

      {!hideNav && (
        <nav className="nav glass glass-lit glass-strong" aria-label="Primary">
          <svg width="0" height="0" style={{ position: "absolute" }} aria-hidden="true">
            <defs>
              <linearGradient id="navGold" x1="0" y1="0" x2="0" y2="1">
                <stop offset="0%" stopColor="#D8CC8A" />
                <stop offset="55%" stopColor="#BBB065" />
                <stop offset="100%" stopColor="#9A8F4E" />
              </linearGradient>
            </defs>
          </svg>
          {NAV.map((n) => {
            const Ico = I[n.icon];
            const active = tab === n.key;
            return (
              <button key={n.key} className={active ? "active" : ""} aria-current={active ? "page" : undefined} onClick={() => go(n.key)}>
                <Ico size={22} sw={active ? 2.3 : 2} />
                <span className="nav-lbl">{n.label}</span>
              </button>
            );
          })}
        </nav>
      )}

      <Sheet open={sheet === "monitor"} onClose={() => setSheet(null)} title="Live Monitor">
        <window.MonitorBreakdownBody values={values} />
      </Sheet>

      <Sheet open={sheet === "day"} onClose={() => setSheet(null)} title="Day detail">
        <window.DayDetailBody onEdit={() => { setSheet(null); go("home"); editCheckin(); }} />
      </Sheet>

      <Sheet open={sheet === "ask"} onClose={() => setSheet(null)} title="Ask the Coach">
        <p style={{ fontSize: 15, color: "var(--color-text-muted)", margin: "0 0 16px", lineHeight: 1.5 }}>One question. A straight answer, grounded in your history.</p>
        <div className="glass glass-lit" style={{ borderRadius: 16, padding: "14px 16px", marginBottom: 16, color: "var(--color-text-faint)", fontSize: 15 }}>Why does my focus drop midweek?</div>
        <window.PrimaryButton onClick={() => { window.Store.api.askCoach("Why does my focus drop midweek?"); setSheet(null); }}>Send</window.PrimaryButton>
      </Sheet>

      {DevTrigger}{DemoSheet}
    </div>
  );
}

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