/* ===== หลังบ้าน (Admin) — login → dashboard → wizard ===== */

/* ---------- Login ---------- */
function AdminLogin({ onLogin, onBack }) {
  const [u, setU] = React.useState("admin");
  const [p, setP] = React.useState("");
  const [show, setShow] = React.useState(false);
  const [loading, setLoading] = React.useState(false);
  const [err, setErr] = React.useState("");

  async function submit(e) {
    e.preventDefault();
    setErr(""); setLoading(true);
    try {
      await api.login(u.trim(), p);
      onLogin();
    } catch (e2) {
      setErr(e2.message || "ชื่อผู้ใช้หรือรหัสผ่านไม่ถูกต้อง");
    } finally {
      setLoading(false);
    }
  }

  return (
    <div style={{ minHeight: "100vh", display: "grid", placeItems: "center", padding: 20,
      background: "radial-gradient(120% 80% at 50% -10%, var(--c-primary-soft) 0%, var(--c-bg) 55%)" }}>
      <div style={{ width: "100%", maxWidth: 400 }}>
        <button className="btn btn-ghost btn-sm" onClick={onBack} style={{ marginBottom: 18 }}>
          <Icon.arrowL size={16} /> กลับหน้าค้นหา
        </button>
        <div className="card" style={{ padding: 30, boxShadow: "var(--sh-lg)" }}>
          <div style={{ display: "flex", alignItems: "center", gap: 12, marginBottom: 22 }}>
            <Logo size={44} />
            <div style={{ whiteSpace: "nowrap" }}>
              <div style={{ fontWeight: 700, fontSize: 17 }}>เข้าสู่ระบบผู้ดูแล</div>
              <div className="muted" style={{ fontSize: 13 }}>กลุ่มโรงเรียนบ้านด่าน 2</div>
            </div>
          </div>
          <form onSubmit={submit} style={{ display: "grid", gap: 14 }}>
            <div className="field">
              <label>ชื่อผู้ใช้</label>
              <input className="input" value={u} onChange={(e) => setU(e.target.value)} autoFocus />
            </div>
            <div className="field">
              <label>รหัสผ่าน</label>
              <div style={{ position: "relative" }}>
                <input className="input" type={show ? "text" : "password"} value={p}
                  onChange={(e) => setP(e.target.value)} placeholder="••••" style={{ paddingRight: 44 }} />
                <button type="button" onClick={() => setShow(s => !s)}
                  style={{ position: "absolute", right: 10, top: "50%", transform: "translateY(-50%)", color: "var(--c-muted)", padding: 4 }}>
                  {show ? <Icon.eyeOff size={18} /> : <Icon.eye size={18} />}
                </button>
              </div>
            </div>
            {err && <div style={{ color: "var(--c-danger)", fontSize: 13.5, fontWeight: 600 }}>{err}</div>}
            <button className="btn btn-primary btn-block" disabled={loading} style={{ marginTop: 4 }}>
              {loading ? <Spinner size={18} color="#fff" /> : <><Icon.lock size={17} /> เข้าสู่ระบบ</>}
            </button>
          </form>
        </div>
      </div>
    </div>
  );
}

/* ---------- Dashboard shell ---------- */
function AdminShell({ children, onLogout, active = "events", onNav, onNew }) {
  const nav = [
    { id: "events", label: "กิจกรรม", icon: Icon.grid },
    { id: "recipients", label: "รายชื่อทั้งหมด", icon: Icon.users },
    { id: "templates", label: "เทมเพลต", icon: Icon.cert },
    { id: "reports", label: "รายงาน / Export", icon: Icon.doc },
    { id: "settings", label: "ตั้งค่า", icon: Icon.settings },
  ];
  return (
    <div style={{ minHeight: "100vh", display: "flex", background: "var(--c-bg)" }}>
      {/* sidebar */}
      <aside className="adm-side" style={{ width: 232, flex: "none", borderRight: "1px solid var(--c-line-soft)",
        background: "var(--c-surface)", display: "flex", flexDirection: "column", position: "sticky", top: 0, height: "100vh" }}>
        <div style={{ padding: "18px 18px 14px", display: "flex", alignItems: "center", gap: 11, borderBottom: "1px solid var(--c-line-soft)" }}>
          <Logo size={36} />
          <div style={{ lineHeight: 1.25, whiteSpace: "nowrap" }}>
            <div style={{ fontWeight: 700, fontSize: 14 }}>ผู้ดูแลระบบ</div>
            <div className="muted" style={{ fontSize: 11.5 }}>บ้านด่าน 2</div>
          </div>
        </div>
        <nav style={{ padding: 12, display: "grid", gap: 3, flex: 1 }}>
          {nav.map(n => (
            <button key={n.id} onClick={() => onNav && onNav(n.id)}
              style={{ display: "flex", alignItems: "center", gap: 11, padding: "10px 12px", borderRadius: 10,
                fontSize: 14.5, fontWeight: 600, textAlign: "left", width: "100%",
                color: active === n.id ? "var(--c-primary-700)" : "var(--c-ink-soft)",
                background: active === n.id ? "var(--c-primary-soft)" : "transparent" }}>
              <n.icon size={19} /> {n.label}
            </button>
          ))}
        </nav>
        <div style={{ padding: 12, borderTop: "1px solid var(--c-line-soft)" }}>
          <button onClick={onLogout} style={{ display: "flex", alignItems: "center", gap: 11, padding: "10px 12px",
            borderRadius: 10, fontSize: 14, fontWeight: 600, color: "var(--c-muted)", width: "100%" }}>
            <Icon.logout size={18} /> ออกจากระบบ
          </button>
        </div>
      </aside>
      <main style={{ flex: 1, minWidth: 0, display: "flex", flexDirection: "column" }}>{children}</main>
    </div>
  );
}

/* ---------- Status badge ---------- */
function StatusBadge({ status }) {
  if (status === "published") return <span className="chip chip-ok"><Icon.check size={13} /> เผยแพร่แล้ว</span>;
  if (status === "draft") return <span className="chip chip-warn">ฉบับร่าง</span>;
  return <span className="chip chip-muted">{status}</span>;
}

/* ---------- Events list ---------- */
function EventsView({ events, onNew, onOpen, onEdit, onDelete }) {
  return (
    <>
      <div style={{ padding: "20px 28px", borderBottom: "1px solid var(--c-line-soft)", display: "flex", alignItems: "center", gap: 14,
        position: "sticky", top: 0, background: "oklch(1 0 0 / .85)", backdropFilter: "blur(8px)", zIndex: 20 }}>
        <div>
          <h1 style={{ fontSize: 21, fontWeight: 700 }}>กิจกรรม</h1>
          <div className="muted" style={{ fontSize: 13.5 }}>จัดการกิจกรรมและออกเกียรติบัตร</div>
        </div>
        <div style={{ flex: 1 }} />
        <button className="btn btn-primary" onClick={onNew}><Icon.plus size={18} /> สร้างกิจกรรมใหม่</button>
      </div>

      <div style={{ padding: 28 }}>
        {/* stat row */}
        <div style={{ display: "grid", gap: 14, gridTemplateColumns: "repeat(auto-fit,minmax(180px,1fr))", marginBottom: 24 }}>
          {[
            { label: "กิจกรรมทั้งหมด", val: events.length, icon: Icon.grid, tone: "primary" },
            { label: "เผยแพร่แล้ว", val: events.filter(e => e.status === "published").length, icon: Icon.checkCircle, tone: "ok" },
            { label: "เกียรติบัตรที่ออก", val: events.reduce((a, e) => a + (e.status === "published" ? e.count : 0), 0).toLocaleString(), icon: Icon.cert, tone: "gold" },
          ].map((s, i) => (
            <div key={i} className="card" style={{ padding: "16px 18px", display: "flex", alignItems: "center", gap: 14 }}>
              <div style={{ width: 44, height: 44, borderRadius: 12, display: "grid", placeItems: "center",
                background: s.tone === "ok" ? "var(--c-ok-soft)" : s.tone === "gold" ? "var(--c-gold-soft)" : "var(--c-primary-soft)",
                color: s.tone === "ok" ? "var(--c-ok)" : s.tone === "gold" ? "var(--c-gold-deep)" : "var(--c-primary)" }}>
                <s.icon size={23} />
              </div>
              <div>
                <div style={{ fontSize: 25, fontWeight: 700, fontFamily: "var(--font-display)", lineHeight: 1 }}>{s.val}</div>
                <div className="muted" style={{ fontSize: 13 }}>{s.label}</div>
              </div>
            </div>
          ))}
        </div>

        {/* table */}
        <div className="card" style={{ overflow: "hidden" }}>
          <table style={{ width: "100%", borderCollapse: "collapse", fontSize: 14 }}>
            <thead>
              <tr style={{ textAlign: "left", color: "var(--c-muted)", fontSize: 12.5, background: "var(--c-surface-2)" }}>
                <th style={{ padding: "12px 18px", fontWeight: 600 }}>กิจกรรม</th>
                <th style={{ padding: "12px 14px", fontWeight: 600 }}>วันที่</th>
                <th style={{ padding: "12px 14px", fontWeight: 600 }}>รายชื่อ</th>
                <th style={{ padding: "12px 14px", fontWeight: 600 }}>สถานะ</th>
                <th style={{ padding: "12px 18px", fontWeight: 600, textAlign: "right" }}>จัดการ</th>
              </tr>
            </thead>
            <tbody>
              {events.map((e, i) => (
                <tr key={e.id} style={{ borderTop: "1px solid var(--c-line-soft)", cursor: "pointer" }}
                  onClick={() => onOpen(e)}
                  onMouseEnter={ev => ev.currentTarget.style.background = "var(--c-surface-2)"}
                  onMouseLeave={ev => ev.currentTarget.style.background = "transparent"}>
                  <td style={{ padding: "14px 18px" }}>
                    <div style={{ display: "flex", alignItems: "center", gap: 12 }}>
                      <div style={{ width: 38, height: 38, borderRadius: 9, flex: "none", display: "grid", placeItems: "center",
                        background: "var(--c-primary-soft)", color: "var(--c-primary)" }}><Icon.cert size={20} /></div>
                      <div style={{ minWidth: 0 }}>
                        <div style={{ fontWeight: 600, lineHeight: 1.3 }}>{e.title}</div>
                        <div className="muted" style={{ fontSize: 12.5 }}>{e.group}</div>
                      </div>
                    </div>
                  </td>
                  <td style={{ padding: "14px 14px", color: "var(--c-ink-soft)", whiteSpace: "nowrap" }}>{e.date}</td>
                  <td style={{ padding: "14px 14px", color: "var(--c-ink-soft)" }}>{e.count} คน</td>
                  <td style={{ padding: "14px 14px" }}><StatusBadge status={e.status} /></td>
                  <td style={{ padding: "14px 18px", textAlign: "right", whiteSpace: "nowrap" }}>
                    <div style={{ display: "inline-flex", gap: 7, alignItems: "center" }}>
                      <button className="btn btn-soft btn-sm" title="แก้ไข"
                        onClick={ev => { ev.stopPropagation(); onEdit(e); }}><Icon.settings size={15} /></button>
                      <button className="btn btn-ghost btn-sm" title="ลบ" style={{ color: "var(--c-danger)" }}
                        onClick={ev => { ev.stopPropagation(); onDelete(e); }}><Icon.x size={15} /></button>
                      <Icon.chevR size={18} style={{ color: "var(--c-faint)" }} />
                    </div>
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      </div>
    </>
  );
}

/* ---------- แก้ไขข้อมูลกิจกรรม ---------- */
function EventEditModal({ event, onClose, onSaved }) {
  const [title, setTitle] = React.useState(event.title || "");
  const [date, setDate] = React.useState(event.date || "");
  const [group, setGroup] = React.useState(event.group || "");
  const [subtitle, setSubtitle] = React.useState(event.subtitle || "");
  const [busy, setBusy] = React.useState(false);
  const [err, setErr] = React.useState("");

  async function save() {
    if (!title.trim()) { setErr("กรุณาระบุชื่อกิจกรรม"); return; }
    setErr(""); setBusy(true);
    try { await api.updateEvent(event.id, { title, date, group, subtitle }); onSaved(); }
    catch (e) { setErr(e.message || "บันทึกไม่สำเร็จ"); setBusy(false); }
  }

  return (
    <Modal open onClose={onClose} maxW={520}>
      <div style={{ fontWeight: 700, fontSize: 18, marginBottom: 18 }}>แก้ไขกิจกรรม</div>
      <div style={{ display: "grid", gap: 14 }}>
        <div className="field"><label>ชื่อกิจกรรม</label>
          <input className="input" value={title} onChange={e => setTitle(e.target.value)} autoFocus /></div>
        <div style={{ display: "grid", gap: 14, gridTemplateColumns: "1fr 1fr" }}>
          <div className="field"><label>วันที่จัดกิจกรรม</label>
            <input className="input" value={date} onChange={e => setDate(e.target.value)} /></div>
          <div className="field"><label>กลุ่ม / ผู้รับผิดชอบ</label>
            <input className="input" value={group} onChange={e => setGroup(e.target.value)} /></div>
        </div>
        <div className="field"><label>คำอธิบายเพิ่มเติม</label>
          <input className="input" value={subtitle} onChange={e => setSubtitle(e.target.value)} /></div>
        {err && <div style={{ color: "var(--c-danger)", fontSize: 13.5, fontWeight: 600 }}>{err}</div>}
        <div style={{ display: "flex", gap: 10, justifyContent: "flex-end", marginTop: 4 }}>
          <button className="btn btn-ghost" onClick={onClose}>ยกเลิก</button>
          <button className="btn btn-primary" onClick={save} disabled={busy}>
            {busy ? <Spinner size={17} color="#fff" /> : <Icon.check size={17} />} บันทึก
          </button>
        </div>
      </div>
    </Modal>
  );
}

/* ---------- กล่องยืนยันการลบ (ใช้ซ้ำได้) ---------- */
function ConfirmModal({ title, message, confirmLabel = "ลบ", onClose, onConfirm }) {
  const [busy, setBusy] = React.useState(false);
  return (
    <Modal open onClose={onClose} maxW={420}>
      <div style={{ fontWeight: 700, fontSize: 17, marginBottom: 8 }}>{title}</div>
      <div className="muted" style={{ fontSize: 14, marginBottom: 20 }}>{message}</div>
      <div style={{ display: "flex", gap: 10, justifyContent: "flex-end" }}>
        <button className="btn btn-ghost" onClick={onClose}>ยกเลิก</button>
        <button className="btn btn-gold" style={{ background: "var(--c-danger)" }} disabled={busy}
          onClick={async () => { setBusy(true); try { await onConfirm(); } finally { setBusy(false); } }}>
          {busy ? <Spinner size={16} color="#fff" /> : <Icon.x size={16} />} {confirmLabel}
        </button>
      </div>
    </Modal>
  );
}

/* ---------- แก้ไขรายชื่อ ---------- */
function RecipientEditModal({ rec, onClose, onSaved }) {
  const [name, setName] = React.useState(rec.name || "");
  const [school, setSchool] = React.useState(rec.school || "");
  const [role, setRole] = React.useState(rec.role || "");
  const [no, setNo] = React.useState(rec.no || "");
  const [busy, setBusy] = React.useState(false);
  const [err, setErr] = React.useState("");

  async function save() {
    if (!name.trim()) { setErr("กรุณาระบุชื่อ–นามสกุล"); return; }
    setErr(""); setBusy(true);
    try {
      await api.updateRecipient(rec.id, { name, school, role, no, tone: toneForRole(role) });
      onSaved();
    } catch (e) { setErr(e.message || "บันทึกไม่สำเร็จ"); setBusy(false); }
  }

  return (
    <Modal open onClose={onClose} maxW={480}>
      <div style={{ fontWeight: 700, fontSize: 18, marginBottom: 18 }}>แก้ไขรายชื่อ</div>
      <div style={{ display: "grid", gap: 14 }}>
        <div className="field"><label>ชื่อ–นามสกุล</label>
          <input className="input" value={name} onChange={e => setName(e.target.value)} autoFocus /></div>
        <div style={{ display: "grid", gap: 14, gridTemplateColumns: "2fr 1fr" }}>
          <div className="field"><label>โรงเรียน / สังกัด</label>
            <input className="input" value={school} onChange={e => setSchool(e.target.value)} /></div>
          <div className="field"><label>เลขที่</label>
            <input className="input" value={no} onChange={e => setNo(e.target.value)} placeholder="1/2569" /></div>
        </div>
        <div className="field"><label>ประเภท / บทบาท</label>
          <input className="input" value={role} onChange={e => setRole(e.target.value)} placeholder="เช่น ได้รับรางวัลชนะเลิศ" /></div>
        {err && <div style={{ color: "var(--c-danger)", fontSize: 13.5, fontWeight: 600 }}>{err}</div>}
        <div style={{ display: "flex", gap: 10, justifyContent: "flex-end", marginTop: 4 }}>
          <button className="btn btn-ghost" onClick={onClose}>ยกเลิก</button>
          <button className="btn btn-primary" onClick={save} disabled={busy}>
            {busy ? <Spinner size={17} color="#fff" /> : <Icon.check size={17} />} บันทึก
          </button>
        </div>
      </div>
    </Modal>
  );
}

/* ---------- รายชื่อทั้งหมด ---------- */
function AllRecipientsView({ onOpenEvent }) {
  const [q, setQ] = React.useState("");
  const [rows, setRows] = React.useState([]);
  const [loading, setLoading] = React.useState(true);
  const [editRec, setEditRec] = React.useState(null);
  const [delRec, setDelRec] = React.useState(null);

  function load(query) {
    setLoading(true);
    api.listAllRecipients(query ?? q)
      .then(d => setRows(d.recipients || []))
      .catch(() => setRows([]))
      .finally(() => setLoading(false));
  }
  React.useEffect(() => { load(""); }, []);

  return (
    <>
      <div style={{ padding: "20px 28px", borderBottom: "1px solid var(--c-line-soft)", display: "flex", alignItems: "center", gap: 14,
        position: "sticky", top: 0, background: "oklch(1 0 0 / .85)", backdropFilter: "blur(8px)", zIndex: 20 }}>
        <div>
          <h1 style={{ fontSize: 21, fontWeight: 700 }}>รายชื่อทั้งหมด</h1>
          <div className="muted" style={{ fontSize: 13.5 }}>ผู้รับเกียรติบัตรจากทุกกิจกรรม</div>
        </div>
        <div style={{ flex: 1 }} />
        <form onSubmit={e => { e.preventDefault(); load(q); }} style={{ position: "relative", width: "min(320px, 45vw)" }}>
          <Icon.search size={17} style={{ position: "absolute", left: 12, top: "50%", transform: "translateY(-50%)", color: "var(--c-muted)" }} />
          <input className="input" value={q} onChange={e => setQ(e.target.value)} placeholder="ค้นหาชื่อ / โรงเรียน"
            style={{ paddingLeft: 38, height: 42 }} />
        </form>
      </div>

      <div style={{ padding: 28 }}>
        {loading ? (
          <div style={{ display: "grid", placeItems: "center", padding: "60px 0", color: "var(--c-muted)" }}><Spinner size={28} /></div>
        ) : (
          <div className="card" style={{ overflow: "hidden" }}>
            <div style={{ padding: "11px 18px", borderBottom: "1px solid var(--c-line-soft)", display: "flex", alignItems: "center", gap: 10 }}>
              <span style={{ fontWeight: 700, fontSize: 14 }}>พบ {rows.length} รายชื่อ</span>
            </div>
            <div style={{ overflowX: "auto" }}>
              <table style={{ width: "100%", borderCollapse: "collapse", fontSize: 13.5 }}>
                <thead>
                  <tr style={{ textAlign: "left", color: "var(--c-muted)", fontSize: 12, background: "var(--c-surface-2)" }}>
                    <th style={{ padding: "10px 16px", fontWeight: 600 }}>เลขที่</th>
                    <th style={{ padding: "10px 12px", fontWeight: 600 }}>ชื่อ–นามสกุล</th>
                    <th style={{ padding: "10px 12px", fontWeight: 600 }}>โรงเรียน</th>
                    <th style={{ padding: "10px 12px", fontWeight: 600 }}>กิจกรรม</th>
                    <th style={{ padding: "10px 12px", fontWeight: 600 }}>สถานะ</th>
                    <th style={{ padding: "10px 16px", fontWeight: 600, textAlign: "right" }}>จัดการ</th>
                  </tr>
                </thead>
                <tbody>
                  {rows.map(r => (
                    <tr key={r.id} style={{ borderTop: "1px solid var(--c-line-soft)" }}>
                      <td style={{ padding: "9px 16px", color: "var(--c-faint)", fontFamily: "ui-monospace,monospace" }}>{r.no}</td>
                      <td style={{ padding: "9px 12px", fontWeight: 600 }}>{r.name}</td>
                      <td style={{ padding: "9px 12px", color: "var(--c-ink-soft)" }}>{r.school}</td>
                      <td style={{ padding: "9px 12px", color: "var(--c-ink-soft)", maxWidth: 240, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>{r.event.title}</td>
                      <td style={{ padding: "9px 12px" }}><StatusBadge status={r.event.status} /></td>
                      <td style={{ padding: "9px 16px", textAlign: "right", whiteSpace: "nowrap" }}>
                        <div style={{ display: "inline-flex", gap: 6 }}>
                          <button className="btn btn-soft btn-sm" title="ดาวน์โหลด PDF"
                            onClick={() => api.downloadCert(r.id, `เกียรติบัตร_${r.name.replace(/\s+/g, "_")}.pdf`)}>
                            <Icon.download size={15} />
                          </button>
                          <button className="btn btn-ghost btn-sm" title="แก้ไข" onClick={() => setEditRec(r)}>
                            <Icon.settings size={15} />
                          </button>
                          <button className="btn btn-ghost btn-sm" title="ลบ" style={{ color: "var(--c-danger)" }} onClick={() => setDelRec(r)}>
                            <Icon.x size={15} />
                          </button>
                        </div>
                      </td>
                    </tr>
                  ))}
                  {rows.length === 0 && (
                    <tr><td colSpan={6} className="muted" style={{ padding: "26px 16px", textAlign: "center", fontSize: 14 }}>ยังไม่มีรายชื่อ</td></tr>
                  )}
                </tbody>
              </table>
            </div>
          </div>
        )}
      </div>

      {editRec && <RecipientEditModal rec={editRec} onClose={() => setEditRec(null)} onSaved={() => { setEditRec(null); load(); }} />}
      {delRec && (
        <ConfirmModal title="ลบรายชื่อ?" message={`ต้องการลบ “${delRec.name}” (${delRec.event.title}) ใช่ไหม การลบนี้ย้อนกลับไม่ได้`}
          onClose={() => setDelRec(null)}
          onConfirm={async () => { await api.deleteRecipient(delRec.id); setDelRec(null); load(); }} />
      )}
    </>
  );
}

/* TemplatesView ย้ายไปไฟล์ TemplatesAdmin.jsx (จัดการคลังเทมเพลตได้เต็มรูปแบบ) */

/* ---------- ตั้งค่า ---------- */
function adminInfoFromToken() {
  try {
    const p = api.token.split(".")[0].replace(/-/g, "+").replace(/_/g, "/");
    return JSON.parse(atob(p + "=".repeat((4 - p.length % 4) % 4)));
  } catch (_) { return {}; }
}

function SettingsView() {
  const info = adminInfoFromToken();
  const [cur, setCur] = React.useState("");
  const [nw, setNw] = React.useState("");
  const [cf, setCf] = React.useState("");
  const [busy, setBusy] = React.useState(false);
  const [msg, setMsg] = React.useState(null); // {ok, text}

  async function submit(e) {
    e.preventDefault();
    setMsg(null);
    if (nw !== cf) { setMsg({ ok: false, text: "รหัสผ่านใหม่ทั้งสองช่องไม่ตรงกัน" }); return; }
    if (nw.length < 6) { setMsg({ ok: false, text: "รหัสผ่านใหม่ต้องยาวอย่างน้อย 6 ตัวอักษร" }); return; }
    setBusy(true);
    try {
      await api.changePassword(cur, nw);
      setMsg({ ok: true, text: "เปลี่ยนรหัสผ่านเรียบร้อยแล้ว" });
      setCur(""); setNw(""); setCf("");
    } catch (e2) {
      setMsg({ ok: false, text: e2.message || "เปลี่ยนรหัสผ่านไม่สำเร็จ" });
    } finally { setBusy(false); }
  }

  return (
    <>
      <div style={{ padding: "20px 28px", borderBottom: "1px solid var(--c-line-soft)" }}>
        <h1 style={{ fontSize: 21, fontWeight: 700 }}>ตั้งค่า</h1>
        <div className="muted" style={{ fontSize: 13.5 }}>บัญชีผู้ดูแลและความปลอดภัย</div>
      </div>
      <div style={{ padding: 28, display: "grid", gap: 22, gridTemplateColumns: "repeat(auto-fit,minmax(300px,1fr))", maxWidth: 760 }}>
        {/* account info */}
        <div className="card" style={{ padding: 22 }}>
          <div style={{ fontWeight: 700, fontSize: 15, marginBottom: 14, display: "flex", alignItems: "center", gap: 8 }}>
            <Icon.user size={18} /> บัญชีผู้ดูแล
          </div>
          <div style={{ display: "grid", gap: 9, fontSize: 14 }}>
            <div style={{ display: "flex", gap: 10 }}><span className="muted" style={{ width: 90 }}>ชื่อผู้ใช้</span><span style={{ fontWeight: 600 }}>{info.username || "admin"}</span></div>
            <div style={{ display: "flex", gap: 10 }}><span className="muted" style={{ width: 90 }}>สิทธิ์</span><span style={{ fontWeight: 600 }}>{info.role || "admin"}</span></div>
          </div>
        </div>
        {/* change password */}
        <div className="card" style={{ padding: 22 }}>
          <div style={{ fontWeight: 700, fontSize: 15, marginBottom: 14, display: "flex", alignItems: "center", gap: 8 }}>
            <Icon.lock size={18} /> เปลี่ยนรหัสผ่าน
          </div>
          <form onSubmit={submit} style={{ display: "grid", gap: 13 }}>
            <div className="field"><label>รหัสผ่านเดิม</label>
              <input className="input" type="password" value={cur} onChange={e => setCur(e.target.value)} autoComplete="current-password" /></div>
            <div className="field"><label>รหัสผ่านใหม่</label>
              <input className="input" type="password" value={nw} onChange={e => setNw(e.target.value)} autoComplete="new-password" /></div>
            <div className="field"><label>ยืนยันรหัสผ่านใหม่</label>
              <input className="input" type="password" value={cf} onChange={e => setCf(e.target.value)} autoComplete="new-password" /></div>
            {msg && <div style={{ fontSize: 13.5, fontWeight: 600, color: msg.ok ? "var(--c-ok)" : "var(--c-danger)" }}>{msg.text}</div>}
            <button className="btn btn-primary" disabled={busy} style={{ justifySelf: "start" }}>
              {busy ? <Spinner size={17} color="#fff" /> : <Icon.check size={17} />} บันทึกรหัสผ่านใหม่
            </button>
          </form>
        </div>
      </div>
    </>
  );
}

/* ---------- รายงาน / Export ---------- */
function statusTh(s) { return s === "published" ? "เผยแพร่แล้ว" : s === "draft" ? "ฉบับร่าง" : (s || ""); }
function csvCell(v) { return `"${String(v == null ? "" : v).replace(/"/g, '""')}"`; }
function escHtml(v) { return String(v == null ? "" : v).replace(/[&<>"]/g, c => ({ "&": "&amp;", "<": "&lt;", ">": "&gt;", '"': "&quot;" }[c])); }

function ReportsView() {
  const [events, setEvents] = React.useState([]);
  const [scope, setScope] = React.useState("all"); // "all" | event id
  const [rows, setRows] = React.useState([]);
  const [loading, setLoading] = React.useState(true);

  React.useEffect(() => { api.listEvents(true).then(d => setEvents(d.events || [])).catch(() => {}); }, []);

  React.useEffect(() => {
    setLoading(true);
    const done = (rs) => { setRows(rs); setLoading(false); };
    if (scope === "all") {
      api.listAllRecipients("").then(d => done((d.recipients || []).map(r => ({
        no: r.no, name: r.name, school: r.school, role: r.role,
        eventTitle: r.event.title, eventDate: r.event.date, status: r.event.status,
      })))).catch(() => done([]));
    } else {
      const ev = events.find(e => e.id === scope);
      api.getEvent(scope, true).then(d => done((d.recipients || []).map(r => ({
        no: r.no, name: r.name, school: r.school, role: r.role,
        eventTitle: ev?.title || "", eventDate: ev?.date || "", status: ev?.status || "",
      })))).catch(() => done([]));
    }
  }, [scope, events]);

  const scopeLabel = scope === "all" ? "ทุกกิจกรรม" : (events.find(e => e.id === scope)?.title || "");

  function exportCsv() {
    const head = ["เลขที่", "ชื่อ-นามสกุล", "โรงเรียน", "ประเภท", "กิจกรรม", "วันที่", "สถานะ"];
    const lines = rows.map(r => [r.no, r.name, r.school, r.role, r.eventTitle, r.eventDate, statusTh(r.status)].map(csvCell).join(","));
    const blob = new Blob(["﻿" + head.map(csvCell).join(",") + "\n" + lines.join("\n")], { type: "text/csv;charset=utf-8" });
    const url = URL.createObjectURL(blob);
    const a = document.createElement("a");
    a.href = url; a.download = `รายงานเกียรติบัตร_${scopeLabel}.csv`;
    document.body.appendChild(a); a.click(); a.remove();
    setTimeout(() => URL.revokeObjectURL(url), 4000);
  }

  function exportPdf() {
    const w = window.open("", "_blank");
    if (!w) { alert("เบราว์เซอร์บล็อกการเปิดหน้าต่างใหม่ — กรุณาอนุญาต popup"); return; }
    const body = rows.map((r, i) => `<tr><td>${escHtml(r.no)}</td><td>${escHtml(r.name)}</td><td>${escHtml(r.school)}</td><td>${escHtml(r.role)}</td><td>${escHtml(r.eventTitle)}</td><td>${escHtml(statusTh(r.status))}</td></tr>`).join("");
    w.document.write(`<!doctype html><html lang="th"><head><meta charset="utf-8">
      <title>รายงานเกียรติบัตร ${escHtml(scopeLabel)}</title>
      <link href="https://fonts.googleapis.com/css2?family=Sarabun:wght@400;600;700&display=swap" rel="stylesheet">
      <style>
        *{box-sizing:border-box} body{font-family:'Sarabun',sans-serif;color:#1f2433;margin:0;padding:28px}
        h1{font-size:20px;margin:0 0 2px} .meta{color:#5a6072;font-size:13px;margin:2px 0}
        table{width:100%;border-collapse:collapse;font-size:12.5px;margin-top:14px}
        th,td{border:1px solid #d7dae3;padding:6px 9px;text-align:left;vertical-align:top}
        th{background:#eef1f7;font-weight:700} tr:nth-child(even) td{background:#fafbfd}
        .noprint{margin-top:18px;padding:9px 18px;border:none;border-radius:8px;background:#3b4fb0;color:#fff;font-family:inherit;font-size:14px;cursor:pointer}
        @media print{ .noprint{display:none} body{padding:10px} }
      </style></head><body>
      <h1>รายงานเกียรติบัตร — ${escHtml(scopeLabel)}</h1>
      <div class="meta">กลุ่มโรงเรียนบ้านด่าน 2 · สพป.บุรีรัมย์ เขต 1</div>
      <div class="meta">รวม ${rows.length} รายชื่อ · พิมพ์เมื่อ ${new Date().toLocaleString("th-TH")}</div>
      <table><thead><tr><th>เลขที่</th><th>ชื่อ–นามสกุล</th><th>โรงเรียน</th><th>ประเภท</th><th>กิจกรรม</th><th>สถานะ</th></tr></thead><tbody>${body}</tbody></table>
      <button class="noprint" onclick="window.print()">พิมพ์ / บันทึก PDF</button>
      <script>setTimeout(function(){window.print()},700)<\/script>
      </body></html>`);
    w.document.close();
  }

  return (
    <>
      <div style={{ padding: "20px 28px", borderBottom: "1px solid var(--c-line-soft)" }}>
        <h1 style={{ fontSize: 21, fontWeight: 700 }}>รายงาน / Export</h1>
        <div className="muted" style={{ fontSize: 13.5 }}>ออกรายงานรายชื่อผู้รับเกียรติบัตรเป็นไฟล์ Excel หรือ PDF</div>
      </div>
      <div style={{ padding: 28 }}>
        <div className="card" style={{ padding: 20, marginBottom: 20, display: "flex", gap: 16, alignItems: "flex-end", flexWrap: "wrap" }}>
          <div className="field" style={{ flex: "1 1 320px" }}>
            <label>ขอบเขตรายงาน</label>
            <select className="input" value={scope} onChange={e => setScope(e.target.value)}>
              <option value="all">ทุกกิจกรรม (รวมทั้งหมด)</option>
              {events.map(e => <option key={e.id} value={e.id}>{e.title}</option>)}
            </select>
          </div>
          <button className="btn btn-soft" onClick={exportCsv} disabled={loading || rows.length === 0}>
            <Icon.table size={17} /> ดาวน์โหลด Excel (CSV)
          </button>
          <button className="btn btn-primary" onClick={exportPdf} disabled={loading || rows.length === 0}>
            <Icon.print size={17} /> พิมพ์ / บันทึก PDF
          </button>
        </div>

        <div className="card" style={{ overflow: "hidden" }}>
          <div style={{ padding: "12px 18px", borderBottom: "1px solid var(--c-line-soft)", display: "flex", alignItems: "center", gap: 10 }}>
            <Icon.users size={17} style={{ color: "var(--c-muted)" }} />
            <span style={{ fontWeight: 700, fontSize: 14 }}>ตัวอย่างรายงาน</span>
            {!loading && <span className="chip chip-muted">{rows.length} รายชื่อ</span>}
          </div>
          {loading ? (
            <div style={{ display: "grid", placeItems: "center", padding: "50px 0", color: "var(--c-muted)" }}><Spinner size={26} /></div>
          ) : rows.length === 0 ? (
            <div className="muted" style={{ padding: "40px 0", textAlign: "center", fontSize: 14 }}>ยังไม่มีรายชื่อ</div>
          ) : (
            <div style={{ maxHeight: 460, overflow: "auto" }}>
              <table style={{ width: "100%", borderCollapse: "collapse", fontSize: 13.5 }}>
                <thead><tr style={{ textAlign: "left", color: "var(--c-muted)", fontSize: 12, background: "var(--c-surface-2)", position: "sticky", top: 0 }}>
                  <th style={{ padding: "10px 16px", fontWeight: 600 }}>เลขที่</th>
                  <th style={{ padding: "10px 12px", fontWeight: 600 }}>ชื่อ–นามสกุล</th>
                  <th style={{ padding: "10px 12px", fontWeight: 600 }}>โรงเรียน</th>
                  <th style={{ padding: "10px 12px", fontWeight: 600 }}>ประเภท</th>
                  <th style={{ padding: "10px 12px", fontWeight: 600 }}>กิจกรรม</th>
                  <th style={{ padding: "10px 16px", fontWeight: 600 }}>สถานะ</th>
                </tr></thead>
                <tbody>
                  {rows.map((r, i) => (
                    <tr key={i} style={{ borderTop: "1px solid var(--c-line-soft)" }}>
                      <td style={{ padding: "9px 16px", color: "var(--c-faint)", fontFamily: "ui-monospace,monospace" }}>{r.no}</td>
                      <td style={{ padding: "9px 12px", fontWeight: 600 }}>{r.name}</td>
                      <td style={{ padding: "9px 12px", color: "var(--c-ink-soft)" }}>{r.school}</td>
                      <td style={{ padding: "9px 12px", color: "var(--c-ink-soft)" }}>{r.role}</td>
                      <td style={{ padding: "9px 12px", color: "var(--c-ink-soft)", maxWidth: 220, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>{r.eventTitle}</td>
                      <td style={{ padding: "9px 16px" }}><StatusBadge status={r.status} /></td>
                    </tr>
                  ))}
                </tbody>
              </table>
            </div>
          )}
        </div>
      </div>
    </>
  );
}

Object.assign(window, { AdminLogin, AdminShell, EventsView, StatusBadge, AllRecipientsView, SettingsView, ReportsView, EventEditModal, ConfirmModal });
