/* ==================================================================
   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.AppUI;

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.AppApi.get("/admin/subjects")); }
    catch (e) { setSubjectsErr(String(e.message || e)); }
  }, []);
  React.useEffect(() => { refreshSubjects(); }, [refreshSubjects]);

  React.useEffect(() => {
    setClassErr(null);
    window.AppApi.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 className="cx-page" style={{ maxWidth: 1100 }}>
      <window.AppUI.PageHeader
        eyebrow="Admin · catalog"
        title="Chapters"
        meta={["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."]}
      />

      <div className="cx-catalog-split narrow" style={{ gap: 20 }}>
        <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 className="ui-alert red" style={{
    margin: "10px 16px", display: "flex", justifyContent: "space-between", alignItems: "center", gap: 10,
  }}>
    <span>{err}</span>
    {onClear && <button className="btn ghost xs icon-only" onClick={onClear} aria-label="Dismiss" title="Dismiss"><ChIcon name="x" size={13}/></button>}
  </div>
) : null;

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

const SubjectsPanel = ({ subjects, err, selectedId, onSelect }) => (
  <div className="cx-card" style={{ padding: 12, alignSelf: "start" }}>
    <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", padding: "6px 8px 10px" }}>
      <span className="ui-section-label" style={{ margin: 0 }}>Subjects</span>
      <span className="ui-tab-count">{subjects.length}</span>
    </div>
    <ErrBanner err={err}/>
    {subjects.length === 0 && !err && (
      <window.AppUI.EmptyState compact icon="book" title="No subjects yet" hint="Add some on Classes & Subjects."/>
    )}
    <div style={{ display: "flex", flexDirection: "column", gap: 2 }} role="listbox" aria-label="Subjects">
      {subjects.map((s) => {
        const on = selectedId === s.id;
        return (
          <button key={s.id} onClick={() => onSelect(s.id)} role="option" aria-selected={on}
            style={{
              display: "flex", alignItems: "center", gap: 10, width: "100%", textAlign: "left",
              minHeight: 36, padding: "0 10px", border: 0, borderRadius: "var(--radius-ctl)",
              background: on ? "var(--surface-active)" : "transparent",
              fontFamily: "inherit", lineHeight: "inherit",
              color: "var(--ink-0)", fontWeight: on ? 600 : 400,
              fontSize: 14, cursor: "pointer",
            }}
            onMouseEnter={(e) => { if (!on) e.currentTarget.style.background = "var(--surface-hover)"; }}
            onMouseLeave={(e) => { if (!on) e.currentTarget.style.background = "transparent"; }}>
            <ChIcon name="book" size={16} style={{ color: on ? "var(--accent)" : "var(--ink-3)", flexShrink: 0 }}/>
            <span style={{ flex: 1, minWidth: 0, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>{s.name}</span>
            {s.short_code && <span className="ui-id">{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.AppApi.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.AppApi.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.AppApi.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.AppApi.del(`/admin/chapters/${row.id}`); await refresh(); }
    catch (e) { setActionErr(String(e.message || e)); }
  };

  if (!subject) {
    return (
      <window.AppUI.Card title="Chapters">
        <window.AppUI.EmptyState compact icon="library" title="No subject selected"
          hint="Pick a subject on the left to manage its chapters."/>
      </window.AppUI.Card>
    );
  }

  // 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="cx-card flush">
      <div className="cx-card-head" style={{ padding: "18px 20px 14px", margin: 0 }}>
        <div style={{ display: "flex", alignItems: "center", gap: 8, minWidth: 0, flexWrap: "wrap" }}>
          <span className="cx-card-title">Chapters · {subject.name}</span>
          {classFilter && classFilter !== "all" && (
            <window.AppUI.StatusBadge tone="blue">Class {classFilter}</window.AppUI.StatusBadge>
          )}
          <span className="ui-tab-count">{items.length}</span>
        </div>
        <button
          className="btn sm primary"
          onClick={() => setAdding(true)}
          disabled={adding || !canAdd}
          title={canAdd ? "" : "Pick a class above first"}>
          <ChIcon name="plus" size={14}/>Add chapter
        </button>
      </div>

      {/* Class filter segmented control. Sits inside the card head area so it
          visually binds to the chapter list it scopes. */}
      <div style={{
        padding: "0 20px 14px", borderBottom: "1px solid var(--line)",
        display: "flex", alignItems: "center", gap: 10, flexWrap: "wrap",
      }}>
        <span className="muted" style={{ fontSize: 12.5 }}>Class</span>
        <window.AppUI.Tabs size="sm" value={classFilter} onChange={onChangeClass} ariaLabel="Class filter"
          items={[{ value: "all", label: "All" }, ...classLevels.map((cl) => ({ value: cl, label: cl }))]}/>
        {classErr && <span style={{ color: "var(--red)", fontSize: 12 }}>{classErr}</span>}
      </div>

      <div>
        <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: "16px 20px", color: "var(--ink-3)", fontSize: 13 }}>Loading…</div>}
        <ErrBanner err={err}/>
        {!loading && items.length === 0 && !adding && (
          <window.AppUI.EmptyState compact icon="library" title="No chapters yet"
            hint={`No chapters yet for ${subject.name}${classFilter !== "all" ? ` · class ${classFilter}` : ""}.`}/>
        )}
        {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 className="ui-row" style={{ padding: "12px 20px", gap: 12 }}>
    <div className="tabular" style={{ color: "var(--accent)", fontSize: 13, fontWeight: 600, minWidth: 28, textAlign: "right" }}>
      {row.chapter_number}.
    </div>
    <div className="ui-row-main">
      <div className="ui-row-title">{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 ? (
      <window.AppUI.StatusBadge tone="grey">{row.class_level || "—"}</window.AppUI.StatusBadge>
    ) : <span/>}
    <window.AppUI.IconButton icon="edit" label="Rename" size={15} className="sm" onClick={onEdit}/>
    <window.AppUI.IconButton icon="trash" label="Delete" size={15} className="sm" onClick={onDelete} style={{ color: "var(--red)" }}/>
  </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: "16px 20px", borderBottom: "1px solid var(--line)", background: "var(--surface-hover)" }}>
      <div style={{ display: "grid", gridTemplateColumns: "80px minmax(0, 1fr) 100px", gap: 10 }}>
        <div className="field" style={{ margin: 0 }}>
          <label className="label">Number *</label>
          <input className="input" type="number" min="1" value={chapterNumber}
            onChange={(e) => setChapterNumber(e.target.value)} style={{ width: "100%" }}/>
        </div>
        <div className="field" style={{ margin: 0 }}>
          <label className="label">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 className="field" style={{ margin: 0 }}>
          <label className="label">Class *</label>
          <select className="select" 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: 12 }}>
        <button className="btn sm" 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;
})();
