/* ===== App orchestrator: public ↔ admin + event detail (เชื่อม API) ===== */

/* ---------- Event detail (admin) ---------- */
function EventDetail({ event, onBack, onTogglePublish, onRegenerate, onPatched }) {
  const [recipients, setRecipients] = React.useState([]);
  const [loading, setLoading] = React.useState(true);
  const [preview, setPreview] = React.useState(null);
  const [regen, setRegen] = React.useState(false);
  const [scale, setScale] = React.useState(0.42);
  const boxRef = React.useRef(null);
  const [editPos, setEditPos] = React.useState(false);
  const [nPos, setNPos] = React.useState(event.namePos || { x: 50, y: 46 });
  const [noP, setNoP] = React.useState(event.noPos || { x: 14, y: 8 });
  const [savingPos, setSavingPos] = React.useState(false);

  React.useEffect(() => {
    setNPos(event.namePos || { x: 50, y: 46 });
    setNoP(event.noPos || { x: 14, y: 8 });
  }, [event.id, event.namePos, event.noPos]);

  async function savePositions() {
    setSavingPos(true);
    try {
      await api.updateEvent(event.id, { namePos: nPos, noPos: noP });
      await api.generate(event.id); // ล้าง cache PDF → สร้างใหม่ตามตำแหน่งใหม่ตอนดาวน์โหลด
      onPatched && onPatched({ namePos: nPos, noPos: noP });
      setEditPos(false);
    } catch (e) { alert(e.message); }
    finally { setSavingPos(false); }
  }

  React.useEffect(() => {
    setLoading(true);
    api.getEvent(event.id, true)
      .then(d => { setRecipients(d.recipients || []); setPreview((d.recipients || [])[0] || null); })
      .catch(() => setRecipients([]))
      .finally(() => setLoading(false));
  }, [event.id]);

  React.useEffect(() => {
    function fit() { const w = boxRef.current ? boxRef.current.clientWidth : 500; setScale(Math.min((w - 4) / CERT_W, 0.5)); }
    fit(); window.addEventListener("resize", fit); return () => window.removeEventListener("resize", fit);
  }, []);

  async function regenerate() {
    setRegen(true);
    try { await onRegenerate(); } finally { setRegen(false); }
  }

  return (
    <>
      <div style={{ padding: "16px 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 }}>
        <button className="btn btn-ghost btn-sm" onClick={onBack}><Icon.arrowL size={16} /> กลับ</button>
        <div style={{ minWidth: 0 }}>
          <h1 style={{ fontSize: 18, fontWeight: 700, whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>{event.title}</h1>
          <div className="muted" style={{ fontSize: 13 }}>{event.date} · {event.count} รายชื่อ</div>
        </div>
        <div style={{ flex: 1 }} />
        <StatusBadge status={event.status} />
        <button className={"btn btn-sm " + (event.status === "published" ? "btn-ghost" : "btn-gold")} onClick={onTogglePublish}>
          {event.status === "published" ? <><Icon.eyeOff size={15} /> ซ่อนหน้าบ้าน</> : <><Icon.checkCircle size={15} /> เผยแพร่</>}
        </button>
      </div>

      <div style={{ padding: 28, display: "grid", gap: 22, gridTemplateColumns: "minmax(0,1fr) 340px", alignItems: "start" }} className="detail-grid">
        {/* recipients */}
        <div className="card" style={{ overflow: "hidden" }}>
          <div style={{ padding: "13px 18px", borderBottom: "1px solid var(--c-line-soft)", display: "flex", alignItems: "center", gap: 10 }}>
            <Icon.users size={18} style={{ color: "var(--c-muted)" }} />
            <span style={{ fontWeight: 700, fontSize: 14.5 }}>รายชื่อผู้รับ</span>
            <span className="chip chip-muted">{recipients.length}</span>
          </div>
          {loading ? (
            <div style={{ display: "grid", placeItems: "center", padding: "50px 0", color: "var(--c-muted)" }}><Spinner size={26} /></div>
          ) : (
            <div style={{ maxHeight: 460, overflowY: "auto" }}>
              <table style={{ width: "100%", borderCollapse: "collapse", fontSize: 13.5 }}>
                <tbody>
                  {recipients.map((r, i) => (
                    <tr key={r.id} onClick={() => setPreview(r)}
                      style={{ borderTop: i ? "1px solid var(--c-line-soft)" : "none", cursor: "pointer",
                        background: preview?.id === r.id ? "var(--c-primary-soft)" : "transparent" }}>
                      <td style={{ padding: "10px 16px", color: "var(--c-faint)", fontFamily: "ui-monospace,monospace", width: 50 }}>{r.no}</td>
                      <td style={{ padding: "10px 12px", fontWeight: 600 }}>{r.name}</td>
                      <td style={{ padding: "10px 12px", color: "var(--c-ink-soft)" }}>{r.school}</td>
                      <td style={{ padding: "10px 16px", textAlign: "right" }}>
                        {r.tone === "gold" ? <span className="chip chip-gold"><Icon.trophy size={12} />{r.role}</span>
                          : <span className="muted" style={{ fontSize: 12.5 }}>{r.role}</span>}
                      </td>
                    </tr>
                  ))}
                  {recipients.length === 0 && (
                    <tr><td className="muted" style={{ padding: "20px 16px", fontSize: 14 }}>ยังไม่มีรายชื่อ</td></tr>
                  )}
                </tbody>
              </table>
            </div>
          )}
        </div>

        {/* preview panel */}
        <div className="card" style={{ padding: 16, position: "sticky", top: 92 }}>
          <div style={{ fontWeight: 700, fontSize: 14, marginBottom: 11, display: "flex", alignItems: "center", gap: 7 }}>
            <Icon.eye size={16} /> ตัวอย่างเกียรติบัตร
          </div>
          <div ref={boxRef} style={{ background: "var(--c-bg-deep)", borderRadius: 10, padding: 12, display: "grid", placeItems: "center", overflow: "hidden", minHeight: 120 }}>
            {preview ? (
              <div style={{ boxShadow: "var(--sh-md)", borderRadius: 2, overflow: "hidden" }}>
                <Certificate event={event} rec={preview} scale={scale} />
              </div>
            ) : <span className="muted" style={{ fontSize: 13 }}>เลือกรายชื่อเพื่อดูตัวอย่าง</span>}
          </div>
          {preview && <div className="muted" style={{ fontSize: 12.5, marginTop: 10, textAlign: "center" }}>{preview.name} · เลขที่ {preview.no}</div>}
          {preview && (
            <button className="btn btn-soft btn-block btn-sm" style={{ marginTop: 12 }}
              onClick={() => api.downloadCert(preview.id, `เกียรติบัตร_${preview.name.replace(/\s+/g, "_")}.pdf`)}>
              <Icon.download size={15} /> ดาวน์โหลด PDF รายคน
            </button>
          )}
          <button className="btn btn-ghost btn-block btn-sm" style={{ marginTop: 8 }} onClick={() => setEditPos(true)}>
            <Icon.move size={15} /> แก้ไขตำแหน่งเกียรติบัตร
          </button>
        </div>
      </div>

      {editPos && (
        <Modal open onClose={() => !savingPos && setEditPos(false)} maxW={820}>
          <div style={{ display: "flex", alignItems: "center", gap: 12, marginBottom: 6 }}>
            <div style={{ fontWeight: 700, fontSize: 18 }}>แก้ไขตำแหน่งเกียรติบัตร</div>
            <div style={{ flex: 1 }} />
            <button className="btn btn-ghost btn-sm" onClick={() => !savingPos && setEditPos(false)} style={{ padding: 8 }}><Icon.x size={18} /></button>
          </div>
          <div className="muted" style={{ fontSize: 13, textAlign: "center", marginBottom: 12 }}>
            ลากจุด <b style={{ color: "var(--c-primary)" }}>น้ำเงิน</b> = ตำแหน่งเนื้อหา (ชื่อ+รายละเอียด) · จุด <b style={{ color: "var(--c-gold-deep)" }}>ทอง</b> = ตำแหน่งเลขที่
          </div>
          <PositionEditor base={event.template} imageUrl={event.templateUrl}
            namePos={nPos} noPos={noP} setNamePos={setNPos} setNoPos={setNoP}
            nameFont={event.nameFont} nameSize={event.nameSize}
            accent={event.accent} bg={event.bg} border={event.border} sampleRec={preview} />
          <div style={{ display: "flex", gap: 10, justifyContent: "flex-end", marginTop: 16 }}>
            <button className="btn btn-ghost" onClick={() => setEditPos(false)} disabled={savingPos}>ยกเลิก</button>
            <button className="btn btn-primary" onClick={savePositions} disabled={savingPos}>
              {savingPos ? <Spinner size={17} color="#fff" /> : <Icon.check size={17} />} บันทึกตำแหน่ง
            </button>
          </div>
        </Modal>
      )}

      <style>{`@media (max-width: 860px){ .detail-grid{ grid-template-columns: 1fr !important; } }`}</style>
    </>
  );
}

/* ---------- Admin root ---------- */
function AdminRoot({ onExit }) {
  const [authed, setAuthed] = React.useState(api.isAuthed());
  const [screen, setScreen] = React.useState("events"); // events | recipients | templates | settings | wizard | detail
  const [events, setEvents] = React.useState([]);
  const [loading, setLoading] = React.useState(true);
  const [current, setCurrent] = React.useState(null);
  const [editEvent, setEditEvent] = React.useState(null);
  const [delEvent, setDelEvent] = React.useState(null);

  async function refresh() {
    setLoading(true);
    try {
      const d = await api.listEvents(true);
      setEvents(d.events || []);
    } catch (e) {
      if (e.status === 401) { api.logout(); setAuthed(false); }
    } finally {
      setLoading(false);
    }
  }

  React.useEffect(() => { if (authed) refresh(); }, [authed]);

  function logout() { api.logout(); setAuthed(false); onExit(); }

  if (!authed) return <AdminLogin onLogin={() => setAuthed(true)} onBack={onExit} />;

  if (screen === "wizard") {
    return <CreateWizard onClose={() => setScreen("events")}
      onDone={() => { setScreen("events"); refresh(); }} />;
  }

  async function togglePublish() {
    const next = current.status === "published" ? "draft" : "published";
    try {
      await api.updateEvent(current.id, { status: next });
      setCurrent(c => ({ ...c, status: next }));
      setEvents(es => es.map(e => e.id === current.id ? { ...e, status: next } : e));
    } catch (e) { alert(e.message); }
  }

  async function regenerate() {
    try {
      const r = await api.generate(current.id);
      if (r.event) { setCurrent(c => ({ ...c, ...r.event })); setEvents(es => es.map(e => e.id === current.id ? { ...e, ...r.event } : e)); }
    } catch (e) { alert(e.message); }
  }

  const activeNav = screen === "detail" ? "events" : screen;

  function renderScreen() {
    if (screen === "detail" && current)
      return <EventDetail event={current} onBack={() => { setScreen("events"); refresh(); }}
        onTogglePublish={togglePublish} onRegenerate={regenerate}
        onPatched={(patch) => { setCurrent(c => ({ ...c, ...patch })); setEvents(es => es.map(e => e.id === current.id ? { ...e, ...patch } : e)); }} />;
    if (screen === "recipients") return <AllRecipientsView />;
    if (screen === "templates") return <TemplatesView />;
    if (screen === "reports") return <ReportsView />;
    if (screen === "settings") return <SettingsView />;
    // default: events list
    if (loading) return <div style={{ display: "grid", placeItems: "center", padding: "80px 0", color: "var(--c-muted)" }}><Spinner size={30} /></div>;
    return <EventsView events={events} onNew={() => setScreen("wizard")}
      onOpen={(e) => { setCurrent(e); setScreen("detail"); }}
      onEdit={(e) => setEditEvent(e)} onDelete={(e) => setDelEvent(e)} />;
  }

  return (
    <AdminShell onLogout={logout} active={activeNav} onNew={() => setScreen("wizard")}
      onNav={(id) => { setCurrent(null); setScreen(id); }}>
      {renderScreen()}
      {editEvent && <EventEditModal event={editEvent} onClose={() => setEditEvent(null)}
        onSaved={() => { setEditEvent(null); refresh(); }} />}
      {delEvent && <ConfirmModal title="ลบกิจกรรม?"
        message={`ต้องการลบ “${delEvent.title}” พร้อมรายชื่อทั้งหมดในกิจกรรมนี้ใช่ไหม การลบนี้ย้อนกลับไม่ได้`}
        onClose={() => setDelEvent(null)}
        onConfirm={async () => { await api.deleteEvent(delEvent.id); setDelEvent(null); refresh(); }} />}
    </AdminShell>
  );
}

/* ---------- Top-level App ---------- */
function getVerifyId() {
  const m = location.pathname.match(/^\/verify\/([^/?#]+)/);
  return m ? decodeURIComponent(m[1]) : null;
}

function App() {
  const [mode, setMode] = React.useState("public"); // public | admin
  const [verifyId, setVerifyId] = React.useState(getVerifyId());

  function goHome() {
    if (location.pathname !== "/") history.pushState({}, "", "/");
    setVerifyId(null); setMode("public");
  }

  React.useEffect(() => {
    const onPop = () => setVerifyId(getVerifyId());
    window.addEventListener("popstate", onPop);
    return () => window.removeEventListener("popstate", onPop);
  }, []);

  if (verifyId) return <VerifyPage id={verifyId} onHome={goHome} />;

  return (
    mode === "public"
      ? <PublicApp onAdmin={() => setMode("admin")} />
      : <AdminRoot onExit={() => setMode("public")} />
  );
}

ReactDOM.createRoot(document.getElementById("root")).render(<App />);
