/* ==================================================================
   Admin → Parents
   ------------------------------------------------------------------
   Approval queue + lifecycle controls for Adarshabani Parent, the
   parent portal.

   Parents self-register and land here with status='pending'. The admin
   reviews each parent's claimed child(ren) against the school register
   and clicks Approve — that flips status to 'active' and stamps
   `verified_at` on every link row.

   Tabs:
     • Pending   — review queue, [Approve] / [Reject]
     • Active    — approved parents, [Suspend], last-login info
     • Suspended — paused or rejected, [Restore]

   All endpoints live under /api/admin/parents/* and require admin.
   ================================================================== */

const { Icon: PAIcon } = window.KXUI;

const AdminParentsScreen = () => {
  const [tab, setTab]             = React.useState("pending");
  const [rows, setRows]           = React.useState([]);
  const [loading, setLoading]     = React.useState(true);
  const [err, setErr]             = React.useState(null);
  const [openId, setOpenId]       = React.useState(null);    // parent currently expanded
  const [openDetail, setOpenDetail] = React.useState(null);  // { ...parent, links: [] }
  const [busy, setBusy]           = React.useState({});      // { [parentId]: true }

  const load = React.useCallback(async () => {
    setLoading(true); setErr(null);
    try {
      setRows(await window.KXApi.get(`/admin/parents?status=${tab}`));
    } catch (e) {
      setErr(String(e.message || e));
    } finally {
      setLoading(false);
    }
  }, [tab]);

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

  const openDetails = async (parentId) => {
    if (openId === parentId) { setOpenId(null); setOpenDetail(null); return; }
    setOpenId(parentId); setOpenDetail(null);
    try {
      setOpenDetail(await window.KXApi.get(`/admin/parents/${parentId}`));
    } catch (e) {
      window.alert("Could not load parent: " + (e.message || e));
      setOpenId(null);
    }
  };

  const act = async (parentId, action, prompt) => {
    if (prompt && !window.confirm(prompt)) return;
    setBusy(b => ({ ...b, [parentId]: true }));
    try {
      await window.KXApi.post(`/admin/parents/${parentId}/${action}`, {});
      if (openId === parentId) setOpenId(null);
      await load();
    } catch (e) {
      window.alert(`Could not ${action}: ` + (e.message || e));
    } finally {
      setBusy(b => { const n = { ...b }; delete n[parentId]; return n; });
    }
  };

  // The phone is the parent's login identity — it's what they type on the sign-in
  // screen and where the code lands — so this is the repair path when a family
  // changes number. Reloads the list too, since the row shows the phone.
  const savePhone = async (parentId, phone) => {
    await window.KXApi.patch(`/admin/parents/${parentId}`, { phone });
    setOpenDetail(await window.KXApi.get(`/admin/parents/${parentId}`));
    await load();
  };

  const removeLink = async (parentId, linkId, studentName) => {
    if (!window.confirm(`Remove ${studentName} from this parent's claimed children?`)) return;
    try {
      await window.KXApi.del(`/admin/parents/${parentId}/links/${linkId}`);
      // refresh the expanded detail
      setOpenDetail(await window.KXApi.get(`/admin/parents/${parentId}`));
    } catch (e) {
      window.alert("Could not remove link: " + (e.message || e));
    }
  };

  const tabs = [
    { id: "pending",   label: "Pending",   icon: "inbox" },
    { id: "active",    label: "Active",    icon: "check" },
    { id: "suspended", label: "Suspended", icon: "x" },
  ];

  const fmt = (iso) => iso ? new Date(iso).toLocaleString(undefined, {
    month: "short", day: "numeric", hour: "2-digit", minute: "2-digit",
  }) : "—";

  return (
    <div style={{ overflow: "auto", padding: "24px 28px", height: "100%" }}>
      <div style={{ display: "flex", alignItems: "center", gap: 12, marginBottom: 4 }}>
        <span style={{ color: "var(--accent)" }}><PAIcon name="cohort" size={18}/></span>
        <div className="muted" style={{ fontSize: 11, letterSpacing: ".08em", textTransform: "uppercase" }}>Admin · Parents</div>
      </div>
      <h1 style={{ margin: "4px 0 6px", color: "var(--ink-0)", fontFamily: "'Instrument Serif', serif", fontWeight: 400, fontSize: 32, letterSpacing: "-0.01em" }}>
        Adarshabani Parent
      </h1>
      <p className="muted" style={{ margin: 0, fontSize: 13.5, maxWidth: 720 }}>
        Parents self-register and wait here. Verify the claimed child(ren) against the school
        register, then approve. Approved parents can log in and see their child's daily briefing.
      </p>

      {/* Tabs */}
      <div style={{ display: "flex", gap: 4, marginTop: 18, borderBottom: "1px solid var(--line-soft)" }}>
        {tabs.map(t => (
          <button key={t.id}
            onClick={() => setTab(t.id)}
            className="btn ghost"
            style={{
              padding: "8px 14px", borderRadius: 0,
              borderBottom: tab === t.id ? "2px solid var(--accent)" : "2px solid transparent",
              color: tab === t.id ? "var(--ink-0)" : "var(--ink-3)",
              fontSize: 13, fontWeight: tab === t.id ? 600 : 400,
            }}>
            <PAIcon name={t.icon} size={11}/> {t.label}
          </button>
        ))}
        <button className="btn ghost sm" onClick={load} disabled={loading} style={{ marginLeft: "auto" }}>
          Refresh
        </button>
      </div>

      {err && (
        <div style={{ marginTop: 16, padding: "10px 14px", background: "rgba(225, 80, 80, 0.08)",
                     border: "1px solid var(--red)", borderRadius: 8, color: "var(--ink-0)", fontSize: 13 }}>
          {err}
        </div>
      )}

      <div className="card" style={{ marginTop: 16 }}>
        <div className="card-body" style={{ padding: 0 }}>
          {loading && <div style={{ padding: 20, color: "var(--ink-3)", fontSize: 12 }}>Loading…</div>}
          {!loading && rows.length === 0 && (
            <div style={{ padding: 28, textAlign: "center", color: "var(--ink-3)", fontSize: 13 }}>
              No {tab} parents.
            </div>
          )}
          {rows.map(p => (
            <div key={p.id} style={{ borderBottom: "1px solid var(--line-soft)" }}>
              <div
                onClick={() => openDetails(p.id)}
                style={{
                  padding: "12px 16px", cursor: "pointer",
                  display: "grid", gridTemplateColumns: "1fr 160px 140px auto", gap: 12, alignItems: "center",
                }}>
                <div>
                  <div style={{ color: "var(--ink-0)", fontSize: 13.5, fontWeight: 500 }}>{p.name}</div>
                  <div className="muted" style={{ fontSize: 11.5, marginTop: 2 }}>
                    <span className="mono">{p.phone}</span>
                    {p.email && <> · {p.email}</>}
                  </div>
                </div>
                <div style={{ fontSize: 11.5, color: "var(--ink-2)" }}>
                  {p.verified_count}/{p.link_count} child{p.link_count === 1 ? "" : "ren"} verified
                </div>
                <div className="muted" style={{ fontSize: 11.5 }}>
                  {tab === "pending"   && <>requested {fmt(p.requested_at)}</>}
                  {tab === "active"    && <>last login {fmt(p.last_login_at)}</>}
                  {tab === "suspended" && <>since {fmt(p.requested_at)}</>}
                </div>
                <div style={{ display: "flex", gap: 6 }}>
                  {tab === "pending" && (
                    <>
                      <button className="btn sm primary" disabled={!!busy[p.id]}
                        onClick={(e) => { e.stopPropagation(); act(p.id, "approve",
                          `Approve ${p.name}? They'll be able to log in and see their child's briefing.`); }}>
                        <PAIcon name="check" size={11}/> Approve
                      </button>
                      <button className="btn sm" disabled={!!busy[p.id]}
                        onClick={(e) => { e.stopPropagation(); act(p.id, "reject",
                          `Reject ${p.name}? They will not be able to log in. (You can restore later.)`); }}>
                        <PAIcon name="x" size={11}/> Reject
                      </button>
                    </>
                  )}
                  {tab === "active" && (
                    <button className="btn sm" disabled={!!busy[p.id]}
                      onClick={(e) => { e.stopPropagation(); act(p.id, "suspend",
                        `Suspend ${p.name}? Their session will be killed.`); }}>
                      <PAIcon name="x" size={11}/> Suspend
                    </button>
                  )}
                  {tab === "suspended" && (
                    <button className="btn sm primary" disabled={!!busy[p.id]}
                      onClick={(e) => { e.stopPropagation(); act(p.id, "unsuspend",
                        `Restore ${p.name}?`); }}>
                      <PAIcon name="check" size={11}/> Restore
                    </button>
                  )}
                </div>
              </div>

              {openId === p.id && (
                <div style={{ padding: "0 16px 16px", background: "var(--bg)" }}>
                  {!openDetail && <div className="muted" style={{ fontSize: 12, padding: 8 }}>Loading children…</div>}
                  {openDetail && (
                    <div style={{ marginTop: 4 }}>
                      <div className="muted" style={{ fontSize: 11, textTransform: "uppercase", letterSpacing: ".08em", margin: "8px 0 6px" }}>
                        Sign-in number
                      </div>
                      <PhoneEditor
                        value={openDetail.phone || p.phone}
                        onSave={(v) => savePhone(p.id, v)}/>

                      <div className="muted" style={{ fontSize: 11, textTransform: "uppercase", letterSpacing: ".08em", margin: "14px 0 6px" }}>
                        Claimed children — verify against the school register
                      </div>
                      {openDetail.links.length === 0 && (
                        <div className="muted" style={{ fontSize: 12, padding: 8 }}>No claimed children.</div>
                      )}
                      {openDetail.links.map(l => (
                        <div key={l.id} style={{
                          padding: "8px 12px", background: "var(--panel)",
                          border: "1px solid var(--line-soft)", borderRadius: 6, marginBottom: 6,
                          display: "grid", gridTemplateColumns: "70px 1fr 90px 90px auto", gap: 10, alignItems: "center",
                        }}>
                          <span className="mono muted" style={{ fontSize: 11 }}>{l.roll_no}</span>
                          <div style={{ color: "var(--ink-0)", fontSize: 12.5 }}>{l.student_name}</div>
                          <div className="muted" style={{ fontSize: 11 }}>{l.class_label || "—"}</div>
                          <div className="muted" style={{ fontSize: 11 }}>{l.relation}</div>
                          <div style={{ display: "flex", gap: 6, alignItems: "center" }}>
                            {l.verified_at ? (
                              <span style={{
                                fontSize: 10, color: "var(--green)", border: "1px solid var(--green)",
                                borderRadius: 4, padding: "1px 6px", textTransform: "uppercase", letterSpacing: ".06em",
                              }}>verified</span>
                            ) : (
                              <span style={{
                                fontSize: 10, color: "var(--ink-3)", border: "1px solid var(--line)",
                                borderRadius: 4, padding: "1px 6px", textTransform: "uppercase", letterSpacing: ".06em",
                              }}>pending</span>
                            )}
                            <button className="btn ghost sm"
                              onClick={() => removeLink(p.id, l.id, l.student_name)}
                              title="Remove this claimed child (e.g. parent over-claimed)">
                              <PAIcon name="trash" size={11}/>
                            </button>
                          </div>
                        </div>
                      ))}
                    </div>
                  )}
                </div>
              )}
            </div>
          ))}
        </div>
      </div>
    </div>
  );
};

// Inline editor for the parent's sign-in number. Kept as its own component so
// each expanded row owns its draft state — the parent list renders these inside
// a .map, and shared state would leak one row's edit into another.
//
// The server does the real validation (E.164 normalisation + duplicate check);
// this only blocks the obviously-empty case and surfaces whatever the server
// says. It deliberately does NOT pre-normalise the draft, so the admin sees
// exactly what they typed if the server rejects it.
const PhoneEditor = ({ value, onSave }) => {
  const [editing, setEditing] = React.useState(false);
  const [draft, setDraft]     = React.useState(value || "");
  const [busy, setBusy]       = React.useState(false);
  const [err, setErr]         = React.useState(null);

  React.useEffect(() => { setDraft(value || ""); setErr(null); }, [value]);

  const commit = async () => {
    setBusy(true); setErr(null);
    try {
      await onSave(draft.trim());
      setEditing(false);
    } catch (e) {
      setErr(e.message || String(e));
    } finally {
      setBusy(false);
    }
  };

  if (!editing) {
    return (
      <div style={{ display: "flex", alignItems: "center", gap: 8 }}>
        <span className="mono" style={{ fontSize: 12.5, color: "var(--ink-0)" }}>{value || "—"}</span>
        <button className="btn ghost sm" onClick={() => setEditing(true)}>
          <PAIcon name="edit" size={11}/> Change
        </button>
      </div>
    );
  }

  return (
    <div>
      <div style={{ display: "flex", gap: 6, alignItems: "center" }}>
        <input className="input" value={draft} placeholder="10-digit mobile"
          disabled={busy} onChange={(e) => setDraft(e.target.value)}
          style={{ flex: "0 0 200px" }}/>
        <button className="btn sm primary"
          disabled={busy || !draft.trim() || draft.trim() === (value || "")}
          onClick={commit}>Save</button>
        <button className="btn sm ghost" disabled={busy}
          onClick={() => { setDraft(value || ""); setErr(null); setEditing(false); }}>Cancel</button>
      </div>
      <div className="muted" style={{ fontSize: 11, marginTop: 4 }}>
        Receives the sign-in code. Saved as +91…; any code already sent to the old number stops working.
      </div>
      {err && <div style={{ fontSize: 11.5, marginTop: 4, color: "var(--red)" }}>{err}</div>}
    </div>
  );
};

window.AdminParentsScreen = AdminParentsScreen;
