/* ==================================================================
   Admin → Chapters
   ------------------------------------------------------------------
   Curate the chapter catalog teachers pick from when authoring a
   test or logging daily progress. Chapters are scoped per (school,
   class_level, subject) — pick a subject on the left, narrow by
   class chip-row, then edit chapters on the right.

   IIFE wrap: babel-standalone transpiles every <script type="babel">
   into the global scope and turns `const` into `var`, so a bare
   top-level `const SubjectsPanel` here clobbered the same-named
   helper in screen-admin-taxonomy.jsx (Babel browser-side has no
   module isolation). Wrapping each screen's locals in an IIFE keeps
   the file-local helpers truly local; the only thing that escapes is
   the `window.ChaptersScreen` export at the bottom.
   ================================================================== */

(() => {
const { Icon: ChIcon } = window.KXUI;

const ChaptersScreen = () => {
  const [subjects, setSubjects] = React.useState([]);
  const [subjectsErr, setSubjectsErr] = React.useState(null);
  const [selectedSubjectId, setSelectedSubjectId] = React.useState(null);

  // Class levels derived from class_sections — same source the rest of the
  // app uses. We just need the distinct class_level strings ("IX", "X", …).
  // Selected class scopes the chapter list and is REQUIRED when adding a new
  // chapter. The special "all" value (default) lists every chapter across
  // classes, useful for re-tagging legacy NULL-class rows.
  const [classLevels, setClassLevels] = React.useState([]);
  const [classFilter, setClassFilter] = React.useState("all");
  const [classErr, setClassErr] = React.useState(null);

  const refreshSubjects = React.useCallback(async () => {
    setSubjectsErr(null);
    try { setSubjects(await window.KXApi.get("/admin/subjects")); }
    catch (e) { setSubjectsErr(String(e.message || e)); }
  }, []);
  React.useEffect(() => { refreshSubjects(); }, [refreshSubjects]);

  React.useEffect(() => {
    setClassErr(null);
    window.KXApi.get("/admin/class-sections")
      .then((sections) => {
        const uniq = Array.from(new Set((sections || []).map((s) => s.class_level).filter(Boolean))).sort();
        setClassLevels(uniq);
      })
      .catch((e) => setClassErr(String(e.message || e)));
  }, []);

  // Auto-select the first subject so the right panel isn't empty on mount.
  React.useEffect(() => {
    if (selectedSubjectId == null && subjects.length > 0) setSelectedSubjectId(subjects[0].id);
  }, [subjects, selectedSubjectId]);

  const selectedSubject = subjects.find((s) => s.id === selectedSubjectId) || null;

  return (
    <div style={{ padding: "24px 28px", maxWidth: 1100, margin: "0 auto" }}>
      <div style={{ display: "flex", alignItems: "center", gap: 12, marginBottom: 4 }}>
        <span style={{ color: "var(--accent)" }}><ChIcon name="library" size={18}/></span>
        <div className="muted" style={{ fontSize: 11, letterSpacing: ".08em", textTransform: "uppercase" }}>Admin · Catalog</div>
      </div>
      <h1 style={{ margin: "4px 0 6px", color: "var(--ink-0)", fontFamily: "'Instrument Serif', serif", fontWeight: 400, fontSize: 32, letterSpacing: "-0.01em" }}>
        Chapters
      </h1>
      <p className="muted" style={{ margin: 0, fontSize: 13.5, maxWidth: 720 }}>
        Curate the chapter list teachers pick from when generating tests + logging daily progress. Chapters are scoped per (class × subject) — pick a class above and a subject on the left, then add chapters on the right. Delete is blocked once a chapter has been used in a teacher's log.
      </p>

      <div className="cx-catalog-split narrow" style={{ marginTop: 22 }}>
        <SubjectsPanel
          subjects={subjects}
          err={subjectsErr}
          selectedId={selectedSubjectId}
          onSelect={setSelectedSubjectId}/>
        <ChaptersPanel
          subject={selectedSubject}
          classLevels={classLevels}
          classFilter={classFilter}
          onChangeClass={setClassFilter}
          classErr={classErr}/>
      </div>
    </div>
  );
};

/* --------------------- shared bits --------------------- */

const ErrBanner = ({ err, onClear }) => err ? (
  <div style={{
    margin: "8px 0", padding: "8px 10px",
    background: "rgba(255,107,107,0.08)", border: "1px solid var(--red)",
    borderRadius: 6, color: "var(--red)", fontSize: 12,
    display: "flex", justifyContent: "space-between", gap: 10,
  }}>
    <span>{err}</span>
    {onClear && <button className="btn ghost sm" onClick={onClear} style={{ padding: 2 }}><ChIcon name="x" size={11}/></button>}
  </div>
) : null;

/* --------------------- subjects panel (left) --------------------- */

const SubjectsPanel = ({ subjects, err, selectedId, onSelect }) => (
  <div className="card">
    <div className="card-head" style={{ gap: 10 }}>
      <span className="card-title">Subjects</span>
      <span className="muted" style={{ fontSize: 11 }}>{subjects.length}</span>
    </div>
    <div className="card-body" style={{ padding: 0 }}>
      <ErrBanner err={err}/>
      {subjects.length === 0 && !err && (
        <div style={{ padding: 28, textAlign: "center", color: "var(--ink-3)", fontSize: 12 }}>
          No subjects yet. Add some on Classes &amp; Subjects.
        </div>
      )}
      {subjects.map((s) => (
        <button key={s.id} onClick={() => onSelect(s.id)}
          style={{
            display: "block", width: "100%", textAlign: "left",
            padding: "10px 14px", border: 0, borderBottom: "1px solid var(--line-soft)",
            background: selectedId === s.id ? "var(--bg-2)" : "transparent",
            color: selectedId === s.id ? "var(--accent)" : "var(--ink-0)",
            fontSize: 13, cursor: "pointer",
          }}>
          {s.name}
          {s.short_code && <span className="mono muted" style={{ fontSize: 11, marginLeft: 8 }}>{s.short_code}</span>}
        </button>
      ))}
    </div>
  </div>
);

/* --------------------- chapters panel (right) --------------------- */

const ChaptersPanel = ({ subject, classLevels, classFilter, onChangeClass, classErr }) => {
  const [items, setItems] = React.useState([]);
  const [loading, setLoading] = React.useState(false);
  const [err, setErr] = React.useState(null);
  const [actionErr, setActionErr] = React.useState(null);
  const [adding, setAdding] = React.useState(false);
  const [editingId, setEditingId] = React.useState(null);

  // Build the chapter list URL based on the class filter. "all" → no
  // class_level query (returns everything across classes); an empty selection
  // could not happen here. We always include subject_id since the backend
  // requires it.
  const refresh = React.useCallback(async () => {
    if (!subject) { setItems([]); return; }
    setLoading(true); setErr(null);
    try {
      const q = new URLSearchParams({ subject_id: subject.id });
      if (classFilter && classFilter !== "all") q.set("class_level", classFilter);
      setItems(await window.KXApi.get(`/admin/chapters?${q.toString()}`));
    }
    catch (e) { setErr(String(e.message || e)); }
    finally { setLoading(false); }
  }, [subject, classFilter]);

  React.useEffect(() => { refresh(); }, [refresh]);

  const create = async (draft) => {
    setActionErr(null);
    try {
      await window.KXApi.post("/admin/chapters", { subject_id: subject.id, ...draft });
      setAdding(false); await refresh();
    } catch (e) { setActionErr(String(e.message || e)); }
  };
  const update = async (id, draft) => {
    setActionErr(null);
    try {
      await window.KXApi.patch(`/admin/chapters/${id}`, draft);
      setEditingId(null); await refresh();
    } catch (e) { setActionErr(String(e.message || e)); }
  };
  const remove = async (row) => {
    if (!window.confirm(`Delete chapter "${row.chapter_number}. ${row.chapter_name}"?`)) return;
    setActionErr(null);
    try { await window.KXApi.del(`/admin/chapters/${row.id}`); await refresh(); }
    catch (e) { setActionErr(String(e.message || e)); }
  };

  if (!subject) {
    return (
      <div className="card">
        <div className="card-head"><span className="card-title">Chapters</span></div>
        <div className="card-body">
          <div style={{ padding: 28, textAlign: "center", color: "var(--ink-3)", fontSize: 12 }}>
            Pick a subject on the left to manage its chapters.
          </div>
        </div>
      </div>
    );
  }

  // The "add chapter" form needs a concrete class — block it (with a hint)
  // when the filter is "all" so the admin first narrows down.
  const canAdd = classFilter && classFilter !== "all";

  return (
    <div className="card">
      <div className="card-head" style={{ gap: 10, flexWrap: "wrap" }}>
        <span className="card-title">
          Chapters · {subject.name}
          {classFilter && classFilter !== "all" && (
            <span className="mono muted" style={{ fontSize: 11, marginLeft: 8 }}>· Class {classFilter}</span>
          )}
        </span>
        <span className="muted" style={{ fontSize: 11 }}>{items.length}</span>
        <button
          className="btn sm primary"
          style={{ marginLeft: "auto" }}
          onClick={() => setAdding(true)}
          disabled={adding || !canAdd}
          title={canAdd ? "" : "Pick a class above first"}>
          <ChIcon name="plus" size={11}/> Add chapter
        </button>
      </div>

      {/* Class filter chip row. Sits inside the card head area so it visually
          binds to the chapter list it scopes. */}
      <div style={{
        padding: "8px 14px", borderBottom: "1px solid var(--line-soft)",
        display: "flex", alignItems: "center", gap: 6, flexWrap: "wrap",
      }}>
        <span className="muted" style={{ fontSize: 11, marginRight: 4 }}>Class</span>
        <ClassChip active={classFilter === "all"} onClick={() => onChangeClass("all")}>All</ClassChip>
        {classLevels.map((cl) => (
          <ClassChip key={cl} active={classFilter === cl} onClick={() => onChangeClass(cl)}>
            {cl}
          </ClassChip>
        ))}
        {classErr && <span style={{ color: "var(--red)", fontSize: 11 }}>{classErr}</span>}
      </div>

      <div className="card-body" style={{ padding: 0 }}>
        <ErrBanner err={actionErr} onClear={() => setActionErr(null)}/>
        {adding && (
          <ChapterEditor onCancel={() => setAdding(false)} onSave={create}
            classLevel={classFilter}
            classLevels={classLevels}
            suggestedNumber={(items.filter(i => i.class_level === classFilter).slice(-1)[0]?.chapter_number ?? 0) + 1}/>
        )}
        {loading && <div style={{ padding: 16, color: "var(--ink-3)", fontSize: 12 }}>Loading…</div>}
        <ErrBanner err={err}/>
        {!loading && items.length === 0 && !adding && (
          <div style={{ padding: 28, textAlign: "center", color: "var(--ink-3)", fontSize: 12 }}>
            No chapters yet for {subject.name}{classFilter !== "all" ? ` · class ${classFilter}` : ""}.
          </div>
        )}
        {items.map((row) =>
          editingId === row.id
            ? <ChapterEditor key={row.id} initial={row} classLevels={classLevels}
                onCancel={() => setEditingId(null)}
                onSave={(d) => update(row.id, d)}/>
            : <ChapterRow key={row.id} row={row}
                showClassPill={classFilter === "all"}
                onEdit={() => setEditingId(row.id)}
                onDelete={() => remove(row)}/>
        )}
      </div>
    </div>
  );
};

const ClassChip = ({ active, onClick, children }) => (
  <button
    className={`btn sm ${active ? "primary" : "ghost"}`}
    style={{ padding: "3px 10px", fontSize: 11 }}
    onClick={onClick}>
    {children}
  </button>
);

const ChapterRow = ({ row, showClassPill, onEdit, onDelete }) => (
  <div style={{
    padding: "10px 14px", borderBottom: "1px solid var(--line-soft)",
    display: "grid", gridTemplateColumns: "auto 1fr auto auto auto", gap: 12, alignItems: "center",
  }}>
    <div className="mono" style={{ color: "var(--accent)", fontSize: 12, minWidth: 26, textAlign: "right" }}>
      {row.chapter_number}.
    </div>
    <div>
      <div style={{ color: "var(--ink-0)", fontSize: 13, fontWeight: 500 }}>{row.chapter_name}</div>
    </div>
    {/* Class pill only visible in the "All classes" view — hides the
        redundant per-row label when the filter is already narrowed. */}
    {showClassPill ? (
      <span className="mono muted" style={{
        fontSize: 10, padding: "2px 6px", border: "1px solid var(--line-soft)", borderRadius: 4,
      }}>
        {row.class_level || "—"}
      </span>
    ) : <span/>}
    <button className="btn ghost sm" title="Rename" onClick={onEdit}><ChIcon name="edit" size={11}/></button>
    <button className="btn ghost sm" title="Delete" onClick={onDelete} style={{ color: "var(--red)" }}>
      <ChIcon name="trash" size={11}/>
    </button>
  </div>
);

const ChapterEditor = ({ initial, suggestedNumber, onCancel, onSave, classLevel, classLevels }) => {
  const [chapterNumber, setChapterNumber] = React.useState(
    String(initial?.chapter_number ?? suggestedNumber ?? 1),
  );
  const [chapterName, setChapterName] = React.useState(initial?.chapter_name || "");
  // Default to the current screen-level filter when adding fresh; when
  // editing, pre-fill from the row so the admin can re-tag legacy NULL rows.
  const [pickClassLevel, setPickClassLevel] = React.useState(
    initial?.class_level ?? (classLevel && classLevel !== "all" ? classLevel : "")
  );
  const [busy, setBusy] = React.useState(false);

  const submit = async () => {
    const n = parseInt(chapterNumber, 10);
    if (!Number.isFinite(n) || n < 1) return;
    if (!chapterName.trim()) return;
    if (!pickClassLevel) return;
    setBusy(true);
    try {
      await onSave({
        chapter_number: n,
        chapter_name: chapterName.trim(),
        class_level: pickClassLevel,
      });
    } finally { setBusy(false); }
  };

  return (
    <div style={{ padding: "10px 14px", borderBottom: "1px solid var(--line-soft)", background: "var(--bg-2)" }}>
      <div style={{ display: "grid", gridTemplateColumns: "80px 1fr 90px", gap: 8 }}>
        <div>
          <label className="muted" style={{ fontSize: 10 }}>Number *</label>
          <input className="input" type="number" min="1" value={chapterNumber}
            onChange={(e) => setChapterNumber(e.target.value)} style={{ width: "100%" }}/>
        </div>
        <div>
          <label className="muted" style={{ fontSize: 10 }}>Chapter name *</label>
          <input className="input" autoFocus value={chapterName}
            onChange={(e) => setChapterName(e.target.value)}
            placeholder="e.g. Coordinate Geometry" style={{ width: "100%" }}/>
        </div>
        <div>
          <label className="muted" style={{ fontSize: 10 }}>Class *</label>
          <select className="input" value={pickClassLevel}
            onChange={(e) => setPickClassLevel(e.target.value)} style={{ width: "100%" }}>
            <option value="">—</option>
            {(classLevels || []).map((cl) => <option key={cl} value={cl}>{cl}</option>)}
          </select>
        </div>
      </div>
      <div style={{ display: "flex", justifyContent: "flex-end", gap: 6, marginTop: 8 }}>
        <button className="btn sm ghost" onClick={onCancel} disabled={busy}>Cancel</button>
        <button className="btn sm primary" onClick={submit}
          disabled={busy || !chapterName.trim() || !chapterNumber.trim() || !pickClassLevel}>
          {busy ? "Saving…" : initial ? "Save" : "Add chapter"}
        </button>
      </div>
    </div>
  );
};

window.ChaptersScreen = ChaptersScreen;
})();
