/* ============================================================
   MTOPS Academy — module detail view + root App
   ============================================================ */
const { useState, useEffect, useRef, useMemo, useCallback } = React;
const { TopBar, SearchOverlay, MapView, topicId, moduleTopicIds, ALL_TOPIC_IDS, MODULES, DATA, moduleAccent } = window.AcademyParts;

/* ============ Topic card ============ */
function TopicCard({ id, topic, done, onToggle }) {
  const [open, setOpen] = useState(false);
  return (
    <div id={`t-${id}`} className="panel" style={{ background: done ? "var(--accent-soft)" : "var(--bg-1)", borderColor: done ? "var(--accent-line)" : "var(--line)", overflow: "hidden", transition: "background .2s, border-color .2s" }}>
      <div style={{ display: "flex", alignItems: "center", gap: 13, padding: "13px 16px", cursor: "pointer" }} onClick={() => setOpen((v) => !v)}>
        <button onClick={(e) => { e.stopPropagation(); onToggle(id); }} title={done ? "Mark incomplete" : "Mark complete"}
          style={{ width: 22, height: 22, flex: "none", borderRadius: "50%", cursor: "pointer", display: "grid", placeItems: "center",
            border: `1.5px solid ${done ? "var(--accent)" : "var(--line-2)"}`, background: done ? "var(--accent)" : "transparent", color: "var(--bg)", transition: "all .15s" }}>
          {done && <svg width="11" height="11" viewBox="0 0 12 12" fill="none"><path d="M2.5 6.2l2.2 2.3L9.5 3.5" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"/></svg>}
        </button>
        <span style={{ flex: 1, fontSize: 15.5, fontWeight: 500, color: done ? "var(--tx-2)" : "var(--tx)", lineHeight: 1.35 }}>{topic.title}</span>
        <span style={{ color: "var(--tx-4)", flex: "none", transform: open ? "rotate(90deg)" : "none", transition: "transform .2s", fontFamily: "var(--mono)", fontSize: 12 }}>›</span>
      </div>
      {open && (
        <p className="fade-in" style={{ margin: 0, padding: "0 16px 16px 51px", fontSize: 14.5, color: "var(--tx-2)", lineHeight: 1.62, textWrap: "pretty" }}>{topic.body}</p>
      )}
    </div>
  );
}

/* ============ Group ============ */
function Group({ mod, group, gi, progress, onToggle }) {
  const [open, setOpen] = useState(true);
  const ids = group.topics.map((_, ti) => topicId(mod.id, gi, ti));
  const done = ids.filter((id) => progress[id]).length;
  const all = done === ids.length;
  const Diagram = group.diagram ? window.DIAGRAMS[group.diagram] : null;
  const markAll = () => { const target = !all; ids.forEach((id) => onToggle(id, target)); };

  return (
    <section style={{ marginBottom: 30 }}>
      <header style={{ display: "flex", alignItems: "center", gap: 13, marginBottom: 16 }}>
        <span style={{ color: "var(--accent)", display: "flex" }}><Marker kind={group.kind} size={17} /></span>
        <button onClick={() => setOpen((v) => !v)} style={{ display: "flex", alignItems: "center", gap: 10, background: "none", border: "none", cursor: "pointer", padding: 0, flex: 1, minWidth: 0 }}>
          <h2 className="disp" style={{ margin: 0, fontSize: 20, fontWeight: 600, color: "var(--tx)", textAlign: "left" }}>{group.title}</h2>
          <span style={{ color: "var(--tx-4)", transform: open ? "none" : "rotate(-90deg)", transition: "transform .2s", fontFamily: "var(--mono)", fontSize: 13 }}>▾</span>
        </button>
        <span className="mono" style={{ fontSize: 11, color: all ? "var(--accent)" : "var(--tx-4)", flex: "none" }}>{done}/{ids.length}</span>
        <button onClick={markAll} className="mono btn ghost" style={{ fontSize: 10, padding: "4px 9px", flex: "none" }}>{all ? "RESET" : "MARK ALL"}</button>
      </header>
      {open && (
        <div className="fade-in" style={{ display: "flex", flexDirection: "column", gap: 9 }}>
          {Diagram && <Diagram />}
          {group.topics.map((t, ti) => {
            const id = topicId(mod.id, gi, ti);
            return <TopicCard key={id} id={id} topic={t} done={!!progress[id]} onToggle={(x) => onToggle(x)} />;
          })}
        </div>
      )}
    </section>
  );
}

/* ============ Module view ============ */
function ModuleView({ mod, progress, onToggle, onHome, onNav, pendingTopic, clearPending }) {
  const ids = moduleTopicIds(mod);
  const done = ids.filter((id) => progress[id]).length;
  const pct = done / ids.length;
  const idx = MODULES.findIndex((m) => m.id === mod.id);
  const prev = MODULES[idx - 1], next = MODULES[idx + 1];

  useEffect(() => { window.scrollTo(0, 0); }, [mod.id]);
  useEffect(() => {
    if (!pendingTopic) return;
    const el = document.getElementById(`t-${pendingTopic}`);
    if (el) {
      const y = el.getBoundingClientRect().top + window.scrollY - 90;
      window.scrollTo({ top: y, behavior: "smooth" });
      el.style.transition = "box-shadow .3s"; el.style.boxShadow = "0 0 0 2px var(--accent)";
      setTimeout(() => { el.style.boxShadow = "none"; }, 1600);
    }
    clearPending();
  }, [pendingTopic, mod.id]);

  return (
    <main data-accent={moduleAccent(mod)} className="fade-in" style={{ maxWidth: 860, margin: "0 auto", padding: "0 24px 110px" }}>
      <nav style={{ display: "flex", alignItems: "center", gap: 8, padding: "26px 0 0", fontFamily: "var(--mono)", fontSize: 12 }}>
        <button onClick={onHome} className="btn ghost" style={{ fontSize: 12, padding: "5px 9px" }}>← Curriculum</button>
        <span style={{ color: "var(--tx-4)" }}>/</span>
        <span style={{ color: "var(--accent)" }}>{mod.n} {mod.title}</span>
      </nav>

      {/* header */}
      <header style={{ padding: "30px 0 34px", borderBottom: "1px solid var(--line)", marginBottom: 38 }}>
        <div style={{ display: "flex", alignItems: "flex-start", gap: 22, flexWrap: "wrap" }}>
          <span className="disp" style={{ fontSize: 58, fontWeight: 600, color: "var(--accent)", lineHeight: .9, flex: "none" }}>{mod.n}</span>
          <div style={{ flex: 1, minWidth: 240 }}>
            <span className="pill" style={{ marginBottom: 12 }}>{mod.tag}</span>
            <h1 className="disp" style={{ margin: "0 0 10px", fontSize: "clamp(28px, 4vw, 40px)", fontWeight: 600, letterSpacing: "-0.02em", lineHeight: 1.05 }}>{mod.title}</h1>
            <p style={{ margin: 0, fontSize: 16, color: "var(--tx-2)", lineHeight: 1.55, maxWidth: 560 }}>{mod.blurb}</p>
          </div>
          <ProgressRing pct={pct} size={58} stroke={4}>{done === ids.length ? "✓" : `${done}/${ids.length}`}</ProgressRing>
        </div>
        {mod.quote && (
          <blockquote className="disp" style={{ margin: "28px 0 0", padding: "2px 0 2px 20px", borderLeft: "3px solid var(--accent)", fontSize: 20, fontWeight: 500, color: "var(--tx)", fontStyle: "italic", lineHeight: 1.4, maxWidth: 640, textWrap: "balance" }}>
            “{mod.quote}”
          </blockquote>
        )}
      </header>

      {mod.groups.map((g, gi) => <Group key={gi} mod={mod} group={g} gi={gi} progress={progress} onToggle={onToggle} />)}

      {mod.reflection && <ReflectionExercise reflection={mod.reflection} moduleId={mod.id} />}
      {mod.quiz && <KnowledgeCheck quiz={mod.quiz} moduleId={mod.id} />}

      {/* prev / next */}
      <nav style={{ display: "flex", gap: 14, marginTop: 44 }}>
        {prev ? (
          <button onClick={() => onNav(prev.id)} className="panel" data-accent={moduleAccent(prev)} style={{ flex: 1, textAlign: "left", cursor: "pointer", padding: "16px 18px", background: "var(--bg-2)" }}>
            <div className="mono" style={{ fontSize: 11, color: "var(--tx-4)", marginBottom: 4 }}>← PREVIOUS · {prev.n}</div>
            <div className="disp" style={{ fontSize: 15, fontWeight: 600, color: "var(--accent)" }}>{prev.title}</div>
          </button>
        ) : <div style={{ flex: 1 }} />}
        {next ? (
          <button onClick={() => onNav(next.id)} className="panel" data-accent={moduleAccent(next)} style={{ flex: 1, textAlign: "right", cursor: "pointer", padding: "16px 18px", background: "var(--bg-2)" }}>
            <div className="mono" style={{ fontSize: 11, color: "var(--tx-4)", marginBottom: 4 }}>NEXT · {next.n} →</div>
            <div className="disp" style={{ fontSize: 15, fontWeight: 600, color: "var(--accent)" }}>{next.title}</div>
          </button>
        ) : <div style={{ flex: 1 }} />}
      </nav>
    </main>
  );
}

/* ============ Root ============ */
function App() {
  const [progress, setProgress] = useStore("progress", {});
  const [layout, setLayout] = useStore("layout2", "path"); // key bumped to reset everyone to Path once (progress/light preserved)
  const [light, setLight] = useStore("light", false);
  const [view, setView] = useState("map");      // 'map' | 'module'
  const [activeId, setActiveId] = useStore("lastModule", null);
  const [searchOpen, setSearchOpen] = useState(false);
  const [pendingTopic, setPendingTopic] = useState(null);

  const activeMod = MODULES.find((m) => m.id === activeId);

  const toggle = useCallback((id, force) => {
    setProgress((p) => {
      const next = { ...p };
      const target = typeof force === "boolean" ? force : !next[id];
      if (target) next[id] = true; else delete next[id];
      return next;
    });
  }, [setProgress]);

  const openModule = (id) => { setActiveId(id); setView("module"); };
  const goHome = () => setView("map");

  useEffect(() => {
    document.documentElement.classList.toggle("dir-daylight", light);
    document.body.classList.toggle("dir-daylight", light);
  }, [light]);

  useEffect(() => {
    const onKey = (e) => {
      if (e.key === "/" && !searchOpen && !/input|textarea/i.test(document.activeElement.tagName)) { e.preventDefault(); setSearchOpen(true); }
      if (e.key === "Escape") setSearchOpen(false);
    };
    window.addEventListener("keydown", onKey);
    return () => window.removeEventListener("keydown", onKey);
  }, [searchOpen]);

  const pickSearch = (modId, tId) => { setSearchOpen(false); setActiveId(modId); setView("module"); setPendingTopic(tId); };

  return (
    <React.Fragment>
      <div className="app-bg" />
      <div style={{ position: "relative", zIndex: 1 }}>
        <TopBar progress={progress} onHome={goHome} onSearch={() => setSearchOpen(true)}
          layout={layout} setLayout={setLayout} light={light} setLight={setLight} view={view} />
        {view === "map" || !activeMod
          ? <MapView progress={progress} layout={layout} onOpen={openModule} />
          : <ModuleView mod={activeMod} progress={progress} onToggle={toggle} onHome={goHome} onNav={openModule}
              pendingTopic={pendingTopic} clearPending={() => setPendingTopic(null)} />}
      </div>
      {searchOpen && <SearchOverlay onClose={() => setSearchOpen(false)} onPick={pickSearch} />}
    </React.Fragment>
  );
}

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