/* ==================================================================
   Admin → Classes & Subjects
   ------------------------------------------------------------------
   Manage the class_sections and subjects rows that drive every test
   creation picker, every roster import, and the teacher-assignment
   matrix. Earlier they only grew (auto-inserted by test creation /
   roster import) and any typo ("hi" as a subject) lingered forever.
   This screen lets the admin rename or delete them, with delete
   blocked when something still references the row.
   ================================================================== */

const { Icon: TxIcon } = window.KXUI;

const TaxonomyScreen = () => {
  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)" }}><TxIcon name="cohort" 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" }}>
        Classes &amp; Subjects
      </h1>
      <p className="muted" style={{ margin: 0, fontSize: 13.5, maxWidth: 720 }}>
        Edit the catalog used by every test-creation picker and the teacher-assignment matrix. Delete is blocked when an entry is still referenced by tests, students, or concepts.
      </p>

      <div className="cx-catalog-split even" style={{ marginTop: 22 }}>
        <ClassesPanel/>
        <SubjectsPanel/>
      </div>
    </div>
  );
};

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

const useList = (path) => {
  const [items, setItems] = React.useState([]);
  const [loading, setLoading] = React.useState(true);
  const [err, setErr] = React.useState(null);
  const refresh = React.useCallback(async () => {
    setLoading(true); setErr(null);
    try { setItems(await window.KXApi.get(path)); }
    catch (e) { setErr(String(e.message || e)); }
    finally { setLoading(false); }
  }, [path]);
  React.useEffect(() => { refresh(); }, [refresh]);
  return { items, loading, err, refresh };
};

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 }}><TxIcon name="x" size={11}/></button>}
  </div>
) : null;

/* --------------------- classes panel --------------------- */

const ClassesPanel = () => {
  const { items, loading, err, refresh } = useList("/admin/class-sections");
  const [actionErr, setActionErr] = React.useState(null);
  const [adding, setAdding] = React.useState(false);
  const [editingId, setEditingId] = React.useState(null);

  const create = async (draft) => {
    setActionErr(null);
    try { await window.KXApi.post("/admin/class-sections", 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/class-sections/${id}`, draft); setEditingId(null); await refresh(); }
    catch (e) { setActionErr(String(e.message || e)); }
  };
  const remove = async (row) => {
    if (!window.confirm(`Delete class "${row.label}" (${row.academic_year})?`)) return;
    setActionErr(null);
    try { await window.KXApi.del(`/admin/class-sections/${row.id}`); await refresh(); }
    catch (e) { setActionErr(String(e.message || e)); }
  };

  return (
    <div className="card">
      <div className="card-head" style={{ gap: 10 }}>
        <span className="card-title">Classes</span>
        <span className="muted" style={{ fontSize: 11 }}>{items.length}</span>
        <button className="btn sm primary" style={{ marginLeft: "auto" }} onClick={() => setAdding(true)} disabled={adding}>
          <TxIcon name="plus" size={11}/> Add class
        </button>
      </div>
      <div className="card-body" style={{ padding: 0 }}>
        <ErrBanner err={actionErr} onClear={() => setActionErr(null)}/>
        {adding && (
          <ClassEditor onCancel={() => setAdding(false)} onSave={create}/>
        )}
        {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 classes yet.</div>
        )}
        {items.map(row =>
          editingId === row.id
            ? <ClassEditor key={row.id} initial={row} onCancel={() => setEditingId(null)} onSave={(d) => update(row.id, d)}/>
            : <ClassRow key={row.id} row={row} onEdit={() => setEditingId(row.id)} onDelete={() => remove(row)}/>
        )}
      </div>
    </div>
  );
};

const ClassRow = ({ row, onEdit, onDelete }) => {
  const safeToDelete = row.test_count === 0 && row.student_count === 0;
  return (
    <div style={{
      padding: "10px 14px", borderBottom: "1px solid var(--line-soft)",
      display: "grid", gridTemplateColumns: "1fr auto auto", gap: 10, alignItems: "center",
    }}>
      <div>
        <div style={{ color: "var(--ink-0)", fontSize: 13, fontWeight: 500 }}>
          {row.label} <span className="muted" style={{ fontSize: 11, marginLeft: 4 }}>{row.academic_year}</span>
        </div>
        <div className="muted" style={{ fontSize: 11, marginTop: 2 }}>
          {row.test_count} test{row.test_count === 1 ? "" : "s"} · {row.student_count} student{row.student_count === 1 ? "" : "s"} · {row.assignment_count} scope{row.assignment_count === 1 ? "" : "s"}
        </div>
      </div>
      <button className="btn ghost sm" title="Rename" onClick={onEdit}><TxIcon name="edit" size={11}/></button>
      <button className="btn ghost sm" title={safeToDelete ? "Delete" : "In use — cannot delete"}
        onClick={onDelete} disabled={!safeToDelete}
        style={{ color: safeToDelete ? "var(--red)" : "var(--ink-3)" }}>
        <TxIcon name="trash" size={11}/>
      </button>
    </div>
  );
};

const ClassEditor = ({ initial, onCancel, onSave }) => {
  const [classLevel, setClassLevel] = React.useState(initial?.class_level || "");
  const [section, setSection] = React.useState(initial?.section || "");
  const [academicYear, setAcademicYear] = React.useState(initial?.academic_year || "");
  const [busy, setBusy] = React.useState(false);
  const submit = async () => {
    if (!classLevel.trim()) return;
    setBusy(true);
    try {
      await onSave({
        class_level: classLevel.trim(),
        section: section.trim() || null,
        ...(academicYear.trim() ? { academic_year: academicYear.trim() } : {}),
      });
    } finally { setBusy(false); }
  };
  return (
    <div style={{ padding: "10px 14px", borderBottom: "1px solid var(--line-soft)", background: "var(--bg-2)" }}>
      <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr 1fr", gap: 8 }}>
        <div>
          <label className="muted" style={{ fontSize: 10 }}>Class level *</label>
          <input className="input" autoFocus value={classLevel} onChange={e => setClassLevel(e.target.value)}
            placeholder="e.g. X" style={{ width: "100%" }}/>
        </div>
        <div>
          <label className="muted" style={{ fontSize: 10 }}>Section</label>
          <input className="input" value={section} onChange={e => setSection(e.target.value)}
            placeholder="e.g. A" style={{ width: "100%" }}/>
        </div>
        <div>
          <label className="muted" style={{ fontSize: 10 }}>Academic year</label>
          <input className="input" value={academicYear} onChange={e => setAcademicYear(e.target.value)}
            placeholder="defaults to school year" style={{ width: "100%" }}/>
        </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 || !classLevel.trim()}>
          {busy ? "Saving…" : initial ? "Save" : "Add class"}
        </button>
      </div>
    </div>
  );
};

/* --------------------- subjects panel --------------------- */

const SubjectsPanel = () => {
  const { items, loading, err, refresh } = useList("/admin/subjects");
  const [actionErr, setActionErr] = React.useState(null);
  const [adding, setAdding] = React.useState(false);
  const [editingId, setEditingId] = React.useState(null);

  const create = async (draft) => {
    setActionErr(null);
    try { await window.KXApi.post("/admin/subjects", 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/subjects/${id}`, draft); setEditingId(null); await refresh(); }
    catch (e) { setActionErr(String(e.message || e)); }
  };
  const remove = async (row) => {
    if (!window.confirm(`Delete subject "${row.name}"?`)) return;
    setActionErr(null);
    try { await window.KXApi.del(`/admin/subjects/${row.id}`); await refresh(); }
    catch (e) { setActionErr(String(e.message || e)); }
  };

  return (
    <div className="card">
      <div className="card-head" style={{ gap: 10 }}>
        <span className="card-title">Subjects</span>
        <span className="muted" style={{ fontSize: 11 }}>{items.length}</span>
        <button className="btn sm primary" style={{ marginLeft: "auto" }} onClick={() => setAdding(true)} disabled={adding}>
          <TxIcon name="plus" size={11}/> Add subject
        </button>
      </div>
      <div className="card-body" style={{ padding: 0 }}>
        <ErrBanner err={actionErr} onClear={() => setActionErr(null)}/>
        {adding && (
          <SubjectEditor onCancel={() => setAdding(false)} onSave={create}/>
        )}
        {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 subjects yet.</div>
        )}
        {items.map(row =>
          editingId === row.id
            ? <SubjectEditor key={row.id} initial={row} onCancel={() => setEditingId(null)} onSave={(d) => update(row.id, d)}/>
            : <SubjectRow key={row.id} row={row} onEdit={() => setEditingId(row.id)} onDelete={() => remove(row)}/>
        )}
      </div>
    </div>
  );
};

const SubjectRow = ({ row, onEdit, onDelete }) => {
  const safeToDelete = row.test_count === 0 && row.concept_count === 0;
  return (
    <div style={{
      padding: "10px 14px", borderBottom: "1px solid var(--line-soft)",
      display: "grid", gridTemplateColumns: "1fr auto auto", gap: 10, alignItems: "center",
    }}>
      <div>
        <div style={{ color: "var(--ink-0)", fontSize: 13, fontWeight: 500 }}>
          {row.name}
          {row.short_code && <span className="mono muted" style={{ fontSize: 11, marginLeft: 8 }}>{row.short_code}</span>}
        </div>
        <div className="muted" style={{ fontSize: 11, marginTop: 2 }}>
          {row.test_count} test{row.test_count === 1 ? "" : "s"} · {row.assignment_count} scope{row.assignment_count === 1 ? "" : "s"} · {row.concept_count} concept{row.concept_count === 1 ? "" : "s"}
        </div>
      </div>
      <button className="btn ghost sm" title="Rename" onClick={onEdit}><TxIcon name="edit" size={11}/></button>
      <button className="btn ghost sm" title={safeToDelete ? "Delete" : "In use — cannot delete"}
        onClick={onDelete} disabled={!safeToDelete}
        style={{ color: safeToDelete ? "var(--red)" : "var(--ink-3)" }}>
        <TxIcon name="trash" size={11}/>
      </button>
    </div>
  );
};

const SubjectEditor = ({ initial, onCancel, onSave }) => {
  const [name, setName] = React.useState(initial?.name || "");
  const [shortCode, setShortCode] = React.useState(initial?.short_code || "");
  const [busy, setBusy] = React.useState(false);
  const submit = async () => {
    if (!name.trim()) return;
    setBusy(true);
    try {
      await onSave({ name: name.trim(), short_code: shortCode.trim() || null });
    } finally { setBusy(false); }
  };
  return (
    <div style={{ padding: "10px 14px", borderBottom: "1px solid var(--line-soft)", background: "var(--bg-2)" }}>
      <div style={{ display: "grid", gridTemplateColumns: "2fr 1fr", gap: 8 }}>
        <div>
          <label className="muted" style={{ fontSize: 10 }}>Name *</label>
          <input className="input" autoFocus value={name} onChange={e => setName(e.target.value)}
            placeholder="e.g. Chemistry" style={{ width: "100%" }}/>
        </div>
        <div>
          <label className="muted" style={{ fontSize: 10 }}>Short code</label>
          <input className="input" value={shortCode} onChange={e => setShortCode(e.target.value)}
            placeholder="e.g. CHEM" style={{ width: "100%" }}/>
        </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 || !name.trim()}>
          {busy ? "Saving…" : initial ? "Save" : "Add subject"}
        </button>
      </div>
    </div>
  );
};

window.TaxonomyScreen = TaxonomyScreen;
