// Split-screen interactive Survivors lesson.
// Left: sticky reading panel (article + photo + tap-to-glossary).
// Right: dynamic workspace panel (the matching Reading Log).
// 6 tabs at top, each tab pairs an article/intro with one of the 6 logs.

const { useState, useEffect, useMemo, useRef, useCallback } = React;
const DATA = window.LESSON_DATA;

// ---------------- Storage hook ----------------
const STORAGE_KEY = "survivors-split-v1";

function useStore() {
  const [state, setState] = useState(() => {
    try {
      const raw = localStorage.getItem(STORAGE_KEY);
      return raw ? JSON.parse(raw) : {};
    } catch { return {}; }
  });
  const stateRef = useRef(state);
  stateRef.current = state;

  // Debounced autosave
  useEffect(() => {
    const t = setTimeout(() => {
      try { localStorage.setItem(STORAGE_KEY, JSON.stringify(state)); } catch {}
    }, 150);
    return () => clearTimeout(t);
  }, [state]);

  const get = useCallback((path) => {
    const parts = path.split(".");
    let cur = stateRef.current;
    for (const p of parts) { if (cur == null) return undefined; cur = cur[p]; }
    return cur;
  }, []);

  const set = useCallback((path, value) => {
    setState((prev) => {
      const parts = path.split(".");
      const next = { ...prev };
      let cur = next;
      for (let i = 0; i < parts.length - 1; i++) {
        cur[parts[i]] = { ...(cur[parts[i]] || {}) };
        cur = cur[parts[i]];
      }
      cur[parts[parts.length - 1]] = value;
      return next;
    });
  }, []);

  const reset = useCallback(() => {
    setState({});
    try { localStorage.removeItem(STORAGE_KEY); } catch {}
  }, []);

  return { get, set, reset, state };
}

// ---------------- Highlight glossary ----------------
function highlightText(text, glossary, onTap) {
  const keys = Object.keys(glossary).sort((a, b) => b.length - a.length);
  const escaped = keys.map((k) => k.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"));
  const re = new RegExp(`\\b(${escaped.join("|")})\\b`, "gi");
  const out = [];
  let last = 0; let m; let idx = 0;
  while ((m = re.exec(text)) !== null) {
    if (m.index > last) out.push(text.slice(last, m.index));
    const matched = m[0];
    const canon = keys.find((k) => k.toLowerCase() === matched.toLowerCase());
    out.push(
      <span
        key={`g${idx++}`}
        className="gloss"
        onClick={(e) => { e.stopPropagation(); onTap(canon, e.currentTarget); }}
        tabIndex={0}
      >
        {matched}
      </span>
    );
    last = m.index + matched.length;
  }
  if (last < text.length) out.push(text.slice(last));
  return out;
}

// ---------------- Glossary popover ----------------
function GlossPopover({ word, def, anchor, onClose }) {
  const ref = useRef(null);
  const [pos, setPos] = useState({ top: 0, left: 0 });
  useEffect(() => {
    if (!anchor) return;
    const rect = anchor.getBoundingClientRect();
    const popW = 280;
    const left = Math.min(
      Math.max(8, rect.left + rect.width / 2 - popW / 2),
      window.innerWidth - popW - 8
    );
    setPos({ top: rect.bottom + window.scrollY + 8, left: left + window.scrollX });
  }, [anchor]);

  useEffect(() => {
    const handle = (e) => {
      if (ref.current && !ref.current.contains(e.target)) onClose();
    };
    document.addEventListener("mousedown", handle);
    document.addEventListener("touchstart", handle);
    return () => {
      document.removeEventListener("mousedown", handle);
      document.removeEventListener("touchstart", handle);
    };
  }, [onClose]);

  if (!word || !def) return null;
  return (
    <div ref={ref} className="gloss-pop" style={{ top: pos.top, left: pos.left }}>
      <div className="gloss-word">{word}</div>
      <div className="gloss-de">
        <span className="gloss-de-flag">DE</span>
        <span>{def.de}</span>
      </div>
      <div className="gloss-en">{def.en}</div>
      <button className="gloss-close" onClick={onClose} aria-label="Close">×</button>
    </div>
  );
}

// ---------------- Left: Reading Panel (full text, always shown) ----------------
function ReadingPanel({ onTapWord, fontSize }) {
  // Tabs do NOT scroll this panel — the full reading stays where the student left it.
  const scrollRef = useRef(null);

  return (
    <div className="rp-scroll" ref={scrollRef}>
      {/* Intro hero */}
      <section id="rp-intro" className="rp-section">
        <div className="rp-hero">
          <img src="assets/photos/intro-rescue.jpg" alt="A man and his dog on a roof after the flood" />
          <div className="rp-hero-overlay">
            <div className="rp-hero-eyebrow">Introduction</div>
            <h1>Survivors</h1>
            <div className="rp-hero-sub">Stories from New Orleans after Hurricane Katrina</div>
          </div>
        </div>
        <div className="rp-body" style={{ fontSize }}>
          <div className="rp-stats">
            <Stat n="125 mph" label="winds" />
            <Stat n="15 ft" label="sea rise" />
            <Stat n="80%" label="flooded" />
            <Stat n="1,800+" label="dead" />
          </div>
          {DATA.intro.paragraphs.map((p, i) => (
            <p key={i}>{highlightText(p, DATA.glossary, onTapWord)}</p>
          ))}
        </div>
      </section>

      {/* All 5 articles in order */}
      {DATA.articles.map((a) => (
        <section
          key={a.id}
          id={`rp-${a.id}`}
          className="rp-section rp-article"
        >
          <header className="rp-article-head">
            <div className="rp-article-num">{a.number}</div>
            <div>
              <div className="rp-article-kicker">Article {a.number} of 5</div>
              <h2 className="rp-article-title">{a.title}</h2>
              <div className="rp-article-date">Written on {a.date}</div>
            </div>
          </header>
          <div className="rp-photo">
            <img src={`assets/photos/${a.id}.jpg`} alt={a.photo.caption} loading="lazy" />
            <div className="rp-photo-cap">{a.photo.caption}</div>
          </div>
          <div className="rp-body" style={{ fontSize }}>
            {a.paragraphs.map((p, i) => (
              <p key={i}>{highlightText(p, DATA.glossary, onTapWord)}</p>
            ))}
          </div>
        </section>
      ))}

      <div className="rp-source">
        <em>Adapted from</em> "1 Dead in Attic — After Katrina" <em>by Chris Rose</em>
      </div>
    </div>
  );
}

function Stat({ n, label }) {
  return (
    <div className="stat">
      <div className="stat-n">{n}</div>
      <div className="stat-l">{label}</div>
    </div>
  );
}

// ---------------- Right: Workspace Panel ----------------
function WorkspacePanel({ tab, store }) {
  const ref = useRef(null);
  useEffect(() => { if (ref.current) ref.current.scrollTop = 0; }, [tab.id]);
  return (
    <div className="ws-scroll" ref={ref}>
      <div className="ws-progress-hint">
        <span className="ws-hint-icon" aria-hidden>💾</span>
        Your answers save automatically on this device.
      </div>
      {tab.log}
    </div>
  );
}

// ---------------- Export View (off-screen, used for PDF generation) ----------------
function ExportView({ store }) {
  const name = store.get("student.name") || "";
  const klass = store.get("student.class") || "";
  const date = new Date().toLocaleDateString("en-GB");

  return (
    <div id="export-root" className="ex-root">
      {/* Cover */}
      <section className="ex-page ex-cover">
        <div className="ex-cover-eyebrow">English Reading · Unit 8</div>
        <h1>Survivors</h1>
        <h2>My Reading Logs</h2>
        <div className="ex-cover-meta">
          <div><label>Name</label><span>{name}</span></div>
          <div><label>Class</label><span>{klass}</span></div>
          <div><label>Date</label><span>{date}</span></div>
        </div>
        <div className="ex-cover-blurb">
          Based on “1 Dead in Attic — After Katrina” by Chris Rose
        </div>
      </section>

      {/* Log 1 */}
      <section className="ex-page">
        <ExHead n={1} title="Notes" />
        <table className="ex-table">
          <thead>
            <tr>
              <th>Written on</th>
              <th>What happened?</th>
              <th>How did the writer feel?</th>
            </tr>
          </thead>
          <tbody>
            {DATA.articles.map((a) => (
              <tr key={a.id}>
                <td className="ex-date-cell">
                  <strong>{a.dateShort}</strong>
                  <div className="ex-date-sub">{a.number}. {a.title}</div>
                </td>
                <td>{store.get(`log1.${a.id}.what`) || ""}</td>
                <td>{store.get(`log1.${a.id}.feel`) || ""}</td>
              </tr>
            ))}
          </tbody>
        </table>
      </section>

      {/* Log 2 */}
      <section className="ex-page">
        <ExHead n={2} title="Imagine — Your diary" />
        <p className="ex-prompt">Imagine you are one of Chris Rose's kids. Write a diary entry about the trip from New Orleans to Baton Rouge.</p>
        <div className="ex-diary-date">{store.get("log2.date") || "_______________________"}</div>
        <div className="ex-textbox">{store.get("log2.diary") || ""}</div>
      </section>

      {/* Log 3 */}
      <section className="ex-page">
        <ExHead n={3} title="Face to face in New Orleans" />
        <p className="ex-prompt">Questions for the looters.</p>
        <ol className="ex-qlist">
          {(store.get("log3.questions") || []).map((q, i) => (
            <li key={i}>{q || ""}</li>
          ))}
        </ol>
      </section>

      {/* Log 4 */}
      <section className="ex-page">
        <ExHead n={4} title="New Orleans after the storm" />
        <p className="ex-prompt">Describe the scene with your senses.</p>
        <div className="ex-sense-grid">
          <ExSense label="I can hear…" v={store.get("log4.hear")} />
          <ExSense label="I can see…" v={store.get("log4.see")} />
          <ExSense label="I can smell…" v={store.get("log4.smell")} />
          <ExSense label="I feel…" v={store.get("log4.feel")} />
        </div>
      </section>

      {/* Log 5 */}
      <section className="ex-page">
        <ExHead n={5} title="The writer" />
        <p className="ex-prompt">a) How do you think the writer felt when he saw the sign ‘1 DEAD IN ATTIC’? Explain.</p>
        <div className="ex-textbox">{store.get("log5.a") || ""}</div>
        <p className="ex-prompt">b) How did he feel when he saw the Mardi Gras costumes? Why?</p>
        <div className="ex-textbox">{store.get("log5.b") || ""}</div>
      </section>

      {/* Log 6 */}
      <section className="ex-page">
        <ExHead n={6} title="You and New Orleans" />
        <p className="ex-prompt">a) Five or more questions you would like to ask people who were in New Orleans in September 2005.</p>
        <ol className="ex-qlist">
          {(store.get("log6.questions") || []).map((q, i) => (
            <li key={i}>{q || ""}</li>
          ))}
        </ol>
        <p className="ex-prompt">b) Which parts of Chris Rose's reports about New Orleans did you find the most moving? Why?</p>
        <div className="ex-textbox">{store.get("log6.b") || ""}</div>
      </section>
    </div>
  );
}

function ExHead({ n, title }) {
  return (
    <header className="ex-head">
      <span className="ex-tag">Reading Log {n}</span>
      <h2>{title}</h2>
    </header>
  );
}
function ExSense({ label, v }) {
  return (
    <div className="ex-sense">
      <div className="ex-sense-label">{label}</div>
      <div className="ex-sense-v">{v || ""}</div>
    </div>
  );
}

// ---------------- App ----------------
function App() {
  const store = useStore();
  const [tabIdx, setTabIdx] = useState(0);
  const [gloss, setGloss] = useState(null);
  const [fontSize, setFontSize] = useState(
    () => Number(localStorage.getItem("survivors-split-font") || "16")
  );
  const [exportOpen, setExportOpen] = useState(false);
  const [exporting, setExporting] = useState(false);

  useEffect(() => {
    localStorage.setItem("survivors-split-font", String(fontSize));
  }, [fontSize]);

  const onTapWord = (key, anchor) => {
    setGloss({ word: key, def: DATA.glossary[key], anchor });
  };

  // Tabs definition: each pairs left-content (intro or article) with a Reading Log.
  const tabs = useMemo(() => [
    {
      id: "t1",
      label: "Notes",
      logNum: 1,
      kind: "intro",
      log: <ReadingLog1 store={store} articles={DATA.articles} key="log1" />,
    },
    {
      id: "t2",
      label: "Diary",
      logNum: 2,
      kind: "article",
      article: DATA.articles[0],
      log: <ReadingLog2 store={store} starters={DATA.starters.log2} key="log2" />,
    },
    {
      id: "t3",
      label: "Looters",
      logNum: 3,
      kind: "article",
      article: DATA.articles[1],
      log: <ReadingLog3 store={store} hideStarters key="log3" />,
    },
    {
      id: "t4",
      label: "Senses",
      logNum: 4,
      kind: "article",
      article: DATA.articles[2],
      log: <ReadingLog4 store={store} key="log4" />,
    },
    {
      id: "t5",
      label: "The writer",
      logNum: 5,
      kind: "article",
      article: DATA.articles[3],
      log: <ReadingLog5 store={store} starters={DATA.starters.log5} key="log5" />,
    },
    {
      id: "t6",
      label: "You & NO",
      logNum: 6,
      kind: "article",
      article: DATA.articles[4],
      log: <ReadingLog6 store={store} starters={DATA.starters} key="log6" />,
    },
  ], [store]);

  // Completion check per log
  const completion = useMemo(() => {
    const s = store.state || {};
    const filled = (v) => {
      if (!v) return false;
      if (typeof v === "string") return v.trim().length > 3;
      if (Array.isArray(v)) return v.some((x) => x && x.trim && x.trim().length > 2);
      return false;
    };
    return [
      DATA.articles.some((a) => filled(s.log1?.[a.id]?.what) || filled(s.log1?.[a.id]?.feel)),
      filled(s.log2?.diary),
      filled(s.log3?.questions),
      ["hear","see","smell","feel"].some((k) => filled(s.log4?.[k])),
      filled(s.log5?.a) || filled(s.log5?.b),
      filled(s.log6?.questions) || filled(s.log6?.b),
    ];
  }, [store.state]);

  // Tabs only swap the Reading Log on the right — they do NOT scroll the left text.
  const tab = tabs[tabIdx];
  const goPrev = () => setTabIdx((i) => Math.max(0, i - 1));
  const goNext = () => setTabIdx((i) => Math.min(tabs.length - 1, i + 1));

  const downloadPDF = async () => {
    if (!store.get("student.name")) { setExportOpen(true); return; }
    setExporting(true);
    // Yield to React so spinner shows, then generate (sync, ~50ms)
    await new Promise((r) => setTimeout(r, 30));
    try {
      window.generateSurvivorsPDF(store);
    } catch (e) {
      console.error(e);
      alert("Something went wrong generating the PDF.");
    } finally {
      setExporting(false);
    }
  };

  return (
    <div className="app">
      {/* TOP BAR */}
      <header className="topbar">
        <div className="brand">
          <div className="brand-mark">
            <svg viewBox="0 0 28 28" aria-hidden>
              <circle cx="14" cy="14" r="13" fill="#2e7d4a" />
              <path d="M5 16 Q9 12 14 16 T 23 16" stroke="#fff" strokeWidth="2" fill="none" strokeLinecap="round" />
              <path d="M5 19 Q9 15 14 19 T 23 19" stroke="#fff" strokeWidth="2" fill="none" strokeLinecap="round" opacity="0.7" />
            </svg>
          </div>
          <div className="brand-text">
            <div className="brand-title">Survivors</div>
            <div className="brand-sub">English Reading · Unit 8</div>
          </div>
        </div>

        {/* Tabs */}
        <nav className="tabs" role="tablist">
          {tabs.map((t, i) => (
            <button
              key={t.id}
              role="tab"
              aria-selected={i === tabIdx}
              className={`tab ${i === tabIdx ? "active" : ""} ${completion[i] ? "done" : ""}`}
              onClick={() => setTabIdx(i)}
            >
              <span className="tab-num">
                {completion[i] && i !== tabIdx ? "✓" : t.logNum}
              </span>
              <span className="tab-label">{t.label}</span>
            </button>
          ))}
        </nav>

        <div className="topbar-actions">
          <div className="font-ctrl" role="group" aria-label="Text size">
            <button onClick={() => setFontSize((f) => Math.max(14, f - 1))} aria-label="Smaller">A−</button>
            <button onClick={() => setFontSize((f) => Math.min(22, f + 1))} aria-label="Larger">A+</button>
          </div>
          <button
            className="btn btn-primary"
            onClick={downloadPDF}
            disabled={exporting}
            title="Download a PDF of your 6 reading logs"
          >
            {exporting ? (
              <><span className="spinner" aria-hidden /> Generating…</>
            ) : (
              <><span aria-hidden>⬇</span> My Reading Log</>
            )}
          </button>
        </div>
      </header>

      {/* SPLIT */}
      <main className="split">
        <section className="pane pane-left">
          <div className="pane-tag">
            <span>📖 Reading</span>
            <span className="pane-tag-dim">Full text — scroll to read all 5 articles</span>
          </div>
          <ReadingPanel onTapWord={onTapWord} fontSize={fontSize} />
        </section>

        <div className="divider" aria-hidden />

        <section className="pane pane-right">
          <div className="pane-tag pane-tag-right">
            <span>✏️ Reading Log {tab.logNum}</span>
            <span className="pane-tag-dim">{tab.label}</span>
          </div>
          <WorkspacePanel tab={tab} store={store} />
        </section>
      </main>

      {/* Bottom navigation */}
      <footer className="botnav">
        <button className="bn-btn" onClick={goPrev} disabled={tabIdx === 0}>
          <span aria-hidden>←</span> Previous
        </button>
        <div className="bn-progress">
          <span className="bn-count">{tabIdx + 1} / {tabs.length}</span>
          <div className="bn-dots">
            {tabs.map((t, i) => (
              <button
                key={t.id}
                className={`bn-dot ${i === tabIdx ? "active" : ""} ${completion[i] ? "done" : ""}`}
                onClick={() => setTabIdx(i)}
                aria-label={`Go to log ${t.logNum}`}
              />
            ))}
          </div>
          <span className="bn-count bn-done">{completion.filter(Boolean).length} / 6 done</span>
        </div>
        <button className="bn-btn bn-next" onClick={goNext} disabled={tabIdx === tabs.length - 1}>
          Next <span aria-hidden>→</span>
        </button>
      </footer>

      {/* Glossary popover */}
      {gloss && (
        <GlossPopover
          word={gloss.word}
          def={gloss.def}
          anchor={gloss.anchor}
          onClose={() => setGloss(null)}
        />
      )}

      {/* Export name modal */}
      {exportOpen && (
        <div className="modal-bg" onClick={() => setExportOpen(false)}>
          <div className="modal" onClick={(e) => e.stopPropagation()}>
            <h3>Before you download</h3>
            <p>Add your name so your teacher knows whose work this is.</p>
            <label className="modal-label">Your name</label>
            <input
              className="rl-input"
              value={store.get("student.name") || ""}
              onChange={(e) => store.set("student.name", e.target.value)}
              placeholder="Anna Schmidt"
              autoFocus
            />
            <label className="modal-label">Class</label>
            <input
              className="rl-input"
              value={store.get("student.class") || ""}
              onChange={(e) => store.set("student.class", e.target.value)}
              placeholder="9b"
            />
            <div className="modal-actions">
              <button className="btn btn-ghost" onClick={() => setExportOpen(false)}>Cancel</button>
              <button
                className="btn btn-primary"
                onClick={() => { setExportOpen(false); setTimeout(downloadPDF, 60); }}
              >
                Download PDF
              </button>
            </div>
          </div>
        </div>
      )}

      {/* Off-screen export view removed — PDF is now generated natively by jsPDF */}
    </div>
  );
}

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