/* ============================================================
   ENERGY FLUENCY — React reader
   A series of lectures sourced from primer/session_*.md files.
   Each lecture has three parts: notes, a case study, and an
   exercise — surfaced as tabs within the reader.
   Reuses the markdown helpers (epFetchMd / epRenderMarkdown)
   and the .ep-* styling defined alongside the Energy Primer.
   ============================================================ */
const { useState: efUse, useEffect: efEffect, useRef: efRef } = React;

/* ---------- lecture metadata ----------
   `base` is the shared filename stem; the three parts are derived
   by appending _notes / _case_study / _exercise. */
const EF_LECTURES = [
  {
    id: "01", base: "primer/session_01_energy_foundations",
    title: "Energy Foundations & Systems Thinking",
    subtitle: "Units, stocks vs. flows, and the categories that prevent costly analytical errors.",
    blindSpot: "Confusing stocks with flows, primary with final energy, installed MW with delivered MWh.",
    deliverable: "Country energy snapshot",
  },
  {
    id: "02", base: "primer/session_02_global_energy_system",
    title: "The Global Energy System: Map, Flows, Trajectory",
    subtitle: "Where energy comes from, where it goes, and how the map has actually changed.",
    blindSpot: "Treating the system as smaller, more substitutable, or faster-moving than it is.",
    deliverable: "Regional energy snapshot",
  },
  {
    id: "03", base: "primer/session_03_oil",
    title: "Oil & Liquid Fuels Beyond the Futures Curve",
    subtitle: "The physical and corporate machinery underneath the price curve.",
    blindSpot: "Knowing the curve but not the machinery and demand that ultimately move it.",
    deliverable: "Oil demand model with GDP elasticity",
  },
  {
    id: "04", base: "primer/session_04_natural_gas_and_lng",
    title: "Natural Gas, LNG & the Most Geopolitical Molecule",
    subtitle: "Why gas is bound to its infrastructure — and what LNG does and doesn't change.",
    blindSpot: "Pricing gas like oil and ignoring the infrastructure it is physically bound to.",
    deliverable: "LNG project economics model",
  },
  {
    id: "05", base: "primer/session_05_power_markets",
    title: "Power Markets: Where Most Traders Get Surprised",
    subtitle: "No inventory; supply equals demand every second — the course's biggest intellectual shift.",
    blindSpot: "Pattern-matching power to inventory commodities like oil and gas.",
    deliverable: "Merit-order dispatch model",
  },
  {
    id: "06a", base: "primer/session_06a_renewables_economics",
    title: "Renewables Economics Beyond the Headline LCOE",
    subtitle: "Why LCOE is necessary but not sufficient to judge a renewable investment.",
    blindSpot: "Reading a low LCOE number as a complete investment case.",
    deliverable: "LCOE model with sensitivity",
  },
  {
    id: "06b", base: "primer/session_06b_storage_and_flexibility",
    title: "Storage, Grids & the Flexibility Constraint",
    subtitle: "From 'how much energy' to 'when and where' — the cost of integrating intermittency.",
    blindSpot: "Assuming storage alone solves intermittency.",
    deliverable: "Battery dispatch optimizer",
  },
  {
    id: "07", base: "primer/session_07_nuclear_and_firm_power",
    title: "Nuclear & Other Firm Power",
    subtitle: "The firm, dispatchable, low-carbon ingredient missing from most transition narratives.",
    blindSpot: "Leaving firm, dispatchable power out of the decarbonization story.",
    deliverable: "New-nuclear vs. alternatives LCOE comparison",
  },
  {
    id: "08", base: "primer/session_08_decarbonization_pathways",
    title: "Decarbonization Pathways: Sectors Are Not Interchangeable",
    subtitle: "Eight or ten sectoral transitions, each with its own physics and economics.",
    blindSpot: "Treating 'the energy transition' as a single object.",
    deliverable: "Corporate MACC",
  },
  {
    id: "09", base: "primer/session_09_geopolitics_and_critical_minerals",
    title: "Geopolitics, Critical Minerals & the New Energy Map",
    subtitle: "When the chokepoints moved from oil straits to mineral processing.",
    blindSpot: "Still mapping energy power only through oil.",
    deliverable: "Critical-minerals risk scorecard",
  },
];

/* ---------- the three parts of every lecture ---------- */
const EF_PARTS = [
  { key: "notes",    label: "Lecture notes", suffix: "_notes.md",      glyph: "❡" },
  { key: "case",     label: "Case study",    suffix: "_case_study.md", glyph: "◆" },
  { key: "exercise", label: "Exercise",      suffix: "_exercise.md",   glyph: "✎" },
];
function efPartFile(lecture, partKey) {
  const part = EF_PARTS.find((p) => p.key === partKey) || EF_PARTS[0];
  return lecture.base + part.suffix;
}

/* ---------- progress tracking ---------- */
const EF_PROG_KEY = "energy-fluency-progress-v1";
function efLoadProgress() {
  try { return JSON.parse(localStorage.getItem(EF_PROG_KEY) || "{}"); }
  catch { return {}; }
}
function efSaveProgress(p) {
  try { localStorage.setItem(EF_PROG_KEY, JSON.stringify(p)); } catch {}
}

/* ============================================================
   HOME VIEW
   ============================================================ */
function EfHome({ go, progress }) {
  const completed = Object.values(progress).filter(Boolean).length;
  const pct = (completed / EF_LECTURES.length) * 100;
  const next = EF_LECTURES.find((l) => !progress[l.id]) || EF_LECTURES[0];

  return (
    <div className="ep">
      <div className="ep-bar">
        <div className="ep-bar-left">
          <span className="ep-bar-brand"><span className="ep-bar-dot" />Energy Fluency</span>
          <span className="ep-bar-crumb"><span className="ep-bar-sep">·</span><span>Lecture series</span></span>
        </div>
        <div className="ep-bar-right">
          <span className="ep-bar-prog">
            <span>{completed}/{EF_LECTURES.length} lectures</span>
            <span className="ep-bar-prog-track"><span className="ep-bar-prog-fill" style={{width: pct + "%"}} /></span>
          </span>
        </div>
      </div>

      <header className="ep-home-hero">
        <div>
          <div className="ep-home-eyebrow">A lecture series in energy fluency</div>
          <h1 className="ep-home-title">
            Read the system <em>fluently</em> — fuel by fuel, sector by sector.
          </h1>
          <p className="ep-home-lede">
            Ten lectures that build structural intuition across the whole energy
            system: foundations, oil, gas, power, renewables, storage, nuclear,
            decarbonization, and the new geopolitics of minerals. Each lecture
            pairs the theory with a real-world case study and a hands-on exercise.
          </p>
          <button className="ep-home-cta" onClick={() => go("/energy-fluency/" + next.id)}>
            <span>{completed === 0 ? "Start lecture 01" : "Continue · lecture " + next.id}</span>
            <span>→</span>
          </button>
        </div>
        <div className="ep-home-meta">
          <div className="ep-home-meta-row">
            <span className="ep-home-meta-lbl">Format</span>
            <span className="ep-home-meta-val">{EF_LECTURES.length} lectures<small>notes · case · exercise</small></span>
          </div>
          <div className="ep-home-meta-row">
            <span className="ep-home-meta-lbl">Per lecture</span>
            <span className="ep-home-meta-val">3 parts<small>read · study · build</small></span>
          </div>
          <div className="ep-home-meta-row">
            <span className="ep-home-meta-lbl">Output</span>
            <span className="ep-home-meta-val">{EF_LECTURES.length} exercises<small>reusable analytical artifacts</small></span>
          </div>
        </div>
      </header>

      <section>
        <div className="ep-howto">
          <div className="ep-howto-item">
            <div className="ep-howto-num">01</div>
            <div className="ep-howto-title">Read the lecture notes</div>
            <div className="ep-howto-text">
              The conceptual frame: numbered theory sections, key tables, and
              worked examples for the fuel or system in focus.
            </div>
          </div>
          <div className="ep-howto-item">
            <div className="ep-howto-num">02</div>
            <div className="ep-howto-title">Work the case study</div>
            <div className="ep-howto-text">
              A real episode — Uri, the European gas crisis, rare-earth
              weaponization — walked through for what to generalize.
            </div>
          </div>
          <div className="ep-howto-item">
            <div className="ep-howto-num">03</div>
            <div className="ep-howto-title">Build the exercise</div>
            <div className="ep-howto-text">
              A model, scorecard, or snapshot you produce yourself and can reuse
              directly in real analytical work.
            </div>
          </div>
        </div>
      </section>

      <section>
        <div className="ep-home-secthead">
          <h2>The lectures</h2>
          <span className="ep-home-secthead-meta">{EF_LECTURES.length} lectures · notes, case study & exercise each</span>
        </div>
        <div className="ep-cards">
          {EF_LECTURES.map((l) => (
            <a key={l.id}
               className={"ep-card " + (progress[l.id] ? "is-done" : "")}
               href={"#/energy-fluency/" + l.id}
               onClick={(e) => { e.preventDefault(); go("/energy-fluency/" + l.id); }}>
              <div className="ep-card-top">
                <span className="ep-card-num">Lecture · {l.id}</span>
                <span className={"ep-card-pill " + (progress[l.id] ? "is-done" : "")}>
                  {progress[l.id] ? "✓ Completed" : "3 parts"}
                </span>
              </div>
              <div className="ep-card-title">{l.title}</div>
              <div className="ep-card-sub">{l.subtitle}</div>
              <div className="ep-card-bs">
                <b>Blind spot targeted</b>
                {l.blindSpot}
              </div>
              <div className="ep-card-foot">
                <span>Exercise · <b>{l.deliverable}</b></span>
                <span>Open →</span>
              </div>
            </a>
          ))}
        </div>
      </section>

      <div className="ep-home-footnote">
        Lecture material is generated and adapted for self-study. Where the notes
        reference institutional sources — IEA, EIA, IRENA, Lazard, BNEF — always
        validate live figures against the primary publications.
      </div>
    </div>
  );
}

/* ============================================================
   READER VIEW (single lecture, three tabbed parts)
   ============================================================ */
function EfReader({ lecture, part, go, progress, toggleDone }) {
  const [state, setState] = efUse({ html: "", toc: [], loading: true, err: null });
  const [activeHeading, setActiveHeading] = efUse(null);
  const articleRef = efRef(null);

  const file = efPartFile(lecture, part);

  // load markdown for the active part
  efEffect(() => {
    let cancelled = false;
    setState({ html: "", toc: [], loading: true, err: null });
    (async () => {
      try {
        for (let i = 0; i < 30 && !window.marked; i++) {
          await new Promise((r) => setTimeout(r, 100));
        }
        const md = await epFetchMd(file);
        const { html, toc } = epRenderMarkdown(md);
        if (!cancelled) setState({ html, toc, loading: false, err: null });
      } catch (e) {
        if (!cancelled) setState({ html: "", toc: [], loading: false, err: e.message });
      }
    })();
    return () => { cancelled = true; };
  }, [file]);

  // scroll spy for "on this page"
  efEffect(() => {
    if (!state.toc.length) return;
    const handler = () => {
      const headings = state.toc.map((h) => document.getElementById(h.slug)).filter(Boolean);
      let active = null;
      for (const h of headings) {
        if (h.getBoundingClientRect().top < 100) active = h.id;
      }
      setActiveHeading(active);
    };
    handler();
    window.addEventListener("scroll", handler, { passive: true });
    return () => window.removeEventListener("scroll", handler);
  }, [state.toc]);

  // scroll to top when the part changes
  efEffect(() => { window.scrollTo({ top: 0, behavior: "auto" }); }, [file]);

  const idx = EF_LECTURES.findIndex((l) => l.id === lecture.id);
  const prev = idx > 0 ? EF_LECTURES[idx - 1] : null;
  const next = idx >= 0 && idx < EF_LECTURES.length - 1 ? EF_LECTURES[idx + 1] : null;
  const isDone = !!progress[lecture.id];

  return (
    <div className="ep">
      <div className="ep-bar">
        <div className="ep-bar-left">
          <a className="ep-bar-brand" href="#/energy-fluency"
             onClick={(e) => { e.preventDefault(); go("/energy-fluency"); }}>
            <span className="ep-bar-dot" />Energy Fluency
          </a>
          <span className="ep-bar-crumb">
            <span className="ep-bar-sep">/</span>
            <a href="#/energy-fluency" onClick={(e) => { e.preventDefault(); go("/energy-fluency"); }}>Lectures</a>
            <span className="ep-bar-sep">/</span>
            <span>Lecture {lecture.id}</span>
          </span>
        </div>
        <div className="ep-bar-right">
          <span className="ep-bar-prog">
            <span>{idx + 1} of {EF_LECTURES.length}</span>
            <span className="ep-bar-prog-track">
              <span className="ep-bar-prog-fill" style={{width: (((idx + 1) / EF_LECTURES.length) * 100) + "%"}} />
            </span>
          </span>
        </div>
      </div>

      <div className="ep-reader">
        {/* left: lecture list */}
        <aside className="ep-side">
          <div className="ep-side-title">The lectures</div>
          <ul className="ep-side-list">
            {EF_LECTURES.map((l) => (
              <li key={l.id}>
                <a className={"ep-side-link " + (l.id === lecture.id ? "is-current" : "")}
                   href={"#/energy-fluency/" + l.id}
                   onClick={(e) => { e.preventDefault(); go("/energy-fluency/" + l.id); }}>
                  <span className="ep-side-num">{l.id}</span>
                  <span className="ep-side-name">{l.title}</span>
                  <span className="ep-side-tick">{progress[l.id] ? "✓" : ""}</span>
                </a>
              </li>
            ))}
          </ul>
        </aside>

        {/* center: main reader */}
        <article className="ep-main" ref={articleRef}>
          <div className="ep-eyebrow">Lecture {lecture.id}</div>
          <h1 className="ep-h1">{lecture.title}</h1>
          <p className="ep-main-sub">{lecture.subtitle}</p>
          <div className="ep-spec">
            <div className="ep-spec-row">
              <b>Blind spot targeted</b>
              <span>{lecture.blindSpot}</span>
            </div>
            <div className="ep-spec-row">
              <b>Exercise</b>
              <span>{lecture.deliverable}</span>
            </div>
          </div>

          {/* tab switcher: notes / case study / exercise */}
          <div className="ef-tabs" role="tablist" aria-label="Lecture parts">
            {EF_PARTS.map((p) => (
              <button
                key={p.key}
                role="tab"
                aria-selected={p.key === part}
                className={"ef-tab " + (p.key === part ? "is-active" : "")}
                onClick={() => go("/energy-fluency/" + lecture.id + "/" + p.key)}>
                <span className="ef-tab-glyph">{p.glyph}</span>
                <span>{p.label}</span>
              </button>
            ))}
          </div>

          {state.loading && (
            <div className="ep-loading">
              Loading {(EF_PARTS.find((p) => p.key === part) || {}).label || "content"}
              <div className="ep-loading-bar" />
            </div>
          )}
          {state.err && (
            <div className="ep-loading">Could not load this part — {state.err}</div>
          )}
          {!state.loading && !state.err && (
            <div className="ep-prose" key={part} dangerouslySetInnerHTML={{ __html: state.html }} />
          )}

          {/* prev / next pager across lectures */}
          <div className="ep-pager">
            {prev ? (
              <a className="ep-pager-card is-prev"
                 href={"#/energy-fluency/" + prev.id}
                 onClick={(e) => { e.preventDefault(); go("/energy-fluency/" + prev.id); }}>
                <span className="ep-pager-lbl">← Previous · {prev.id}</span>
                <span className="ep-pager-title">{prev.title}</span>
              </a>
            ) : (
              <a className="ep-pager-card ep-pager-empty" href="#/energy-fluency"
                 onClick={(e) => { e.preventDefault(); go("/energy-fluency"); }}>
                <span className="ep-pager-lbl">↩ Back</span>
                <span className="ep-pager-title">Lecture series</span>
              </a>
            )}
            {next ? (
              <a className="ep-pager-card is-next"
                 href={"#/energy-fluency/" + next.id}
                 onClick={(e) => { e.preventDefault(); go("/energy-fluency/" + next.id); }}>
                <span className="ep-pager-lbl">Next · {next.id} →</span>
                <span className="ep-pager-title">{next.title}</span>
              </a>
            ) : (
              <a className="ep-pager-card is-next ep-pager-empty" href="#/energy-fluency"
                 onClick={(e) => { e.preventDefault(); go("/energy-fluency"); }}>
                <span className="ep-pager-lbl">Done →</span>
                <span className="ep-pager-title">Back to all lectures</span>
              </a>
            )}
          </div>
        </article>

        {/* right: on-this-page */}
        <aside className="ep-onpage">
          <div className="ep-onpage-title">On this page</div>
          <ul className="ep-onpage-list">
            {state.toc.map((h) => (
              <li key={h.slug}>
                <a className={activeHeading === h.slug ? "is-active" : ""}
                   href={"#" + h.slug}
                   onClick={(e) => {
                     e.preventDefault();
                     const el = document.getElementById(h.slug);
                     if (el) window.scrollTo({ top: el.getBoundingClientRect().top + window.scrollY - 16, behavior: "smooth" });
                   }}>
                  {h.text}
                </a>
              </li>
            ))}
          </ul>
          <div className="ep-onpage-meta">
            <div>Lecture · <b>{lecture.id}</b></div>
            <div>Viewing · <b>{(EF_PARTS.find((p) => p.key === part) || {}).label}</b></div>
            <div className="ep-onpage-actions">
              <button className={"ep-onpage-btn " + (isDone ? "is-done" : "")} onClick={() => toggleDone(lecture.id)}>
                {isDone ? "✓ Completed" : "Mark complete"}
              </button>
            </div>
          </div>
        </aside>
      </div>
    </div>
  );
}

/* ============================================================
   ROUTER
   ============================================================ */
function EnergyFluencyView() {
  // sub-route after #/energy-fluency/...
  const parse = () => {
    const hash = (window.location.hash || "").replace(/^#\/?/, "");
    const rest = hash.replace(/^energy-fluency\/?/, "").replace(/^\/+/, "");
    if (!rest) return { view: "home" };
    const [id, partRaw] = rest.split("/");
    const lecture = EF_LECTURES.find((l) => l.id === id);
    if (!lecture) return { view: "home" };
    const part = EF_PARTS.find((p) => p.key === partRaw) ? partRaw : "notes";
    return { view: "lecture", lecture, part };
  };

  const [route, setRoute] = efUse(parse);
  const [progress, setProgress] = efUse(efLoadProgress);

  efEffect(() => {
    const onHash = () => setRoute(parse());
    window.addEventListener("hashchange", onHash);
    return () => window.removeEventListener("hashchange", onHash);
  }, []);

  const go = (path) => { window.location.hash = path.replace(/^\/?/, "/"); };
  const toggleDone = (id) => {
    const next = { ...progress, [id]: !progress[id] };
    setProgress(next);
    efSaveProgress(next);
  };

  if (route.view === "home") {
    return <EfHome go={go} progress={progress} />;
  }
  return <EfReader lecture={route.lecture} part={route.part} go={go} progress={progress} toggleDone={toggleDone} />;
}

window.EnergyFluencyView = EnergyFluencyView;
