/* ===== Admin wizard — สร้างกิจกรรม + ออกเกียรติบัตร (เชื่อม API) ===== */

const STEPS = [
  { id: 1, label: "ข้อมูลกิจกรรม", icon: Icon.cal },
  { id: 2, label: "เลือกเทมเพลต", icon: Icon.cert },
  { id: 3, label: "วางตำแหน่งชื่อ", icon: Icon.move },
  { id: 4, label: "อัปโหลดรายชื่อ", icon: Icon.table },
  { id: 5, label: "Generate", icon: Icon.sparkle },
];

/* Stepper rail */
function Stepper({ step }) {
  return (
    <div style={{ display: "flex", alignItems: "center", gap: 0, flexWrap: "wrap" }}>
      {STEPS.map((s, i) => {
        const done = step > s.id, cur = step === s.id;
        return (
          <React.Fragment key={s.id}>
            <div style={{ display: "flex", alignItems: "center", gap: 9 }}>
              <div style={{ width: 32, height: 32, borderRadius: 99, display: "grid", placeItems: "center", flex: "none",
                fontWeight: 700, fontSize: 13.5, transition: "all .2s",
                background: done ? "var(--c-ok)" : cur ? "var(--c-primary)" : "var(--c-bg-deep)",
                color: done || cur ? "#fff" : "var(--c-muted)" }}>
                {done ? <Icon.check size={17} /> : s.id}
              </div>
              <div className="step-label" style={{ fontSize: 13.5, fontWeight: cur ? 700 : 600,
                color: cur ? "var(--c-ink)" : "var(--c-muted)" }}>{s.label}</div>
            </div>
            {i < STEPS.length - 1 && <div style={{ width: 26, height: 2, margin: "0 10px", background: done ? "var(--c-ok)" : "var(--c-line)", flex: "none" }} />}
          </React.Fragment>
        );
      })}
    </div>
  );
}

/* Step 1 — event info */
function StepInfo({ draft, set }) {
  return (
    <div style={{ maxWidth: 560, display: "grid", gap: 16 }}>
      <div className="field">
        <label>ชื่อกิจกรรม</label>
        <input className="input" value={draft.title} onChange={e => set({ title: e.target.value })}
          placeholder="เช่น การแข่งขันทักษะทางวิชาการ ระดับกลุ่มโรงเรียน" autoFocus />
      </div>
      <div style={{ display: "grid", gap: 16, gridTemplateColumns: "1fr 1fr" }}>
        <div className="field">
          <label>วันที่จัดกิจกรรม</label>
          <input className="input" value={draft.date} onChange={e => set({ date: e.target.value })} placeholder="12 กุมภาพันธ์ 2568" />
        </div>
        <div className="field">
          <label>กลุ่ม / ผู้รับผิดชอบ</label>
          <input className="input" value={draft.group} onChange={e => set({ group: e.target.value })} placeholder="งานวิชาการ" />
        </div>
      </div>
      <div className="field">
        <label>คำอธิบายเพิ่มเติม (ไม่บังคับ)</label>
        <input className="input" value={draft.subtitle} onChange={e => set({ subtitle: e.target.value })} placeholder="ปีการศึกษา 2568" />
      </div>
    </div>
  );
}

/* Step 2 — template picker */
function StepTemplate({ draft, set }) {
  const fileRef = React.useRef(null);
  const opts = [
    { id: "classic-gold", name: "คลาสสิก ทอง", desc: "กรอบทองคู่ เป็นทางการ" },
    { id: "modern-blue", name: "โมเดิร์น น้ำเงิน", desc: "เรียบ ทันสมัย แถบข้าง" },
    { id: "ornate-cream", name: "วิจิตร ครีม", desc: "ลวดลายอ่อนหวาน" },
  ];
  const [library, setLibrary] = React.useState([]);
  React.useEffect(() => { api.listTemplates().then(d => setLibrary(d.templates || [])).catch(() => setLibrary([])); }, []);

  function handleFile(file) {
    if (!file) return;
    set({ templateFile: file, uploadedName: file.name, templateId: null, libraryImageUrl: null });
  }
  function pickBuiltin(id) { set({ template: id, templateId: null, libraryImageUrl: null, templateFile: null, uploadedName: null }); }
  function pickLibrary(t) {
    set({ templateId: t.id, template: t.base, namePos: t.namePos, noPos: t.noPos,
      nameFont: t.nameFont, nameSize: t.nameSize, accent: t.accent, bg: t.bg, border: t.border,
      libraryImageUrl: t.imageUrl, templateFile: null, uploadedName: null });
  }

  const hasUpload = !!draft.templateFile;
  const [thumb, setThumb] = React.useState(null);
  React.useEffect(() => {
    if (draft.templateFile) { const u = URL.createObjectURL(draft.templateFile); setThumb(u); return () => URL.revokeObjectURL(u); }
    setThumb(null);
  }, [draft.templateFile]);

  return (
    <div>
      <div style={{ display: "flex", gap: 10, alignItems: "center", marginBottom: 16, padding: "12px 15px",
        background: "var(--c-primary-soft)", borderRadius: 12, fontSize: 13.5, color: "var(--c-primary-700)" }}>
        <Icon.upload size={18} />
        <span>เลือกจากคลังเทมเพลตของคุณ อัปโหลดไฟล์ใหม่ หรือใช้แบบสำเร็จรูป — ฟอนต์ไทยฝังให้อัตโนมัติ</span>
      </div>
      <input ref={fileRef} type="file" accept="image/png,image/jpeg" style={{ display: "none" }}
        onChange={e => handleFile(e.target.files[0])} />

      {/* คลังเทมเพลตของผู้ใช้ */}
      {library.length > 0 && (
        <div style={{ marginBottom: 20 }}>
          <div style={{ fontSize: 13.5, fontWeight: 700, margin: "0 2px 10px" }}>เทมเพลตของคุณ</div>
          <div style={{ display: "grid", gap: 16, gridTemplateColumns: "repeat(auto-fill,minmax(230px,1fr))" }}>
            {library.map(t => {
              const active = draft.templateId === t.id;
              return (
                <button key={t.id} onClick={() => pickLibrary(t)}
                  style={{ border: active ? "2px solid var(--c-primary)" : "2px solid var(--c-line-soft)", borderRadius: 14,
                    overflow: "hidden", background: "#fff", textAlign: "left", position: "relative",
                    boxShadow: active ? "var(--sh-md)" : "var(--sh-sm)" }}>
                  <div style={{ height: 124, overflow: "hidden", background: "var(--c-bg-deep)", display: "grid", placeItems: "center" }}>
                    <Certificate event={{ title: "ชื่อกิจกรรม", date: "—" }} rec={{ name: "ชื่อ–นามสกุล", role: "เข้าร่วมกิจกรรม", no: "1/2569" }}
                      template={t.base} imageUrl={t.imageUrl} namePos={t.namePos} noPos={t.noPos}
                      nameFont={t.nameFont} nameSize={t.nameSize} accent={t.accent} bg={t.bg} border={t.border} scale={0.226} />
                  </div>
                  <div style={{ padding: "11px 14px" }}>
                    <div style={{ fontWeight: 700, fontSize: 14 }}>{t.name}</div>
                    <div className="muted" style={{ fontSize: 12.5 }}>{t.description || "เทมเพลตของคุณ"}</div>
                  </div>
                  {active && <div style={{ position: "absolute", top: 9, right: 9, width: 24, height: 24, borderRadius: 99,
                    background: "var(--c-primary)", color: "#fff", display: "grid", placeItems: "center" }}><Icon.check size={15} /></div>}
                </button>
              );
            })}
          </div>
        </div>
      )}

      <div style={{ fontSize: 13.5, fontWeight: 700, margin: "0 2px 10px" }}>อัปโหลดใหม่ / แบบสำเร็จรูป</div>
      <div style={{ display: "grid", gap: 16, gridTemplateColumns: "repeat(auto-fill,minmax(230px,1fr))" }}>
        {/* upload tile */}
        <button onClick={() => fileRef.current && fileRef.current.click()}
          style={{ border: hasUpload ? "2px solid var(--c-primary)" : "2px dashed var(--c-line)", borderRadius: 14, overflow: "hidden",
            background: hasUpload ? "#fff" : "var(--c-surface-2)", position: "relative",
            display: "flex", flexDirection: "column", alignItems: "center", gap: 9, minHeight: 168, justifyContent: "center", color: "var(--c-muted)", padding: hasUpload ? 0 : 20 }}>
          {hasUpload && thumb ? (
            <>
              <img src={thumb} alt={draft.uploadedName} style={{ width: "100%", height: 124, objectFit: "contain", background: "var(--c-bg-deep)" }} />
              <div style={{ padding: "0 12px 12px", textAlign: "center" }}>
                <div style={{ fontWeight: 600, fontSize: 13, color: "var(--c-ink-soft)", wordBreak: "break-all" }}>{draft.uploadedName}</div>
                <div style={{ fontSize: 12 }}>แตะเพื่อเปลี่ยนไฟล์</div>
              </div>
              <div style={{ position: "absolute", top: 9, right: 9, width: 24, height: 24, borderRadius: 99,
                background: "var(--c-primary)", color: "#fff", display: "grid", placeItems: "center" }}><Icon.check size={15} /></div>
            </>
          ) : (
            <>
              <Icon.upload size={28} />
              <div style={{ fontWeight: 600, fontSize: 14, color: "var(--c-ink-soft)" }}>อัปโหลดไฟล์เทมเพลต</div>
              <div style={{ fontSize: 12, fontFamily: "ui-monospace,monospace" }}>PNG / JPG · A4 แนวนอน</div>
            </>
          )}
        </button>
        {opts.map(o => {
          const active = !hasUpload && !draft.templateId && draft.template === o.id;
          return (
            <button key={o.id} onClick={() => pickBuiltin(o.id)}
              style={{ border: active ? "2px solid var(--c-primary)" : "2px solid var(--c-line-soft)", borderRadius: 14,
                overflow: "hidden", background: "#fff", textAlign: "left", position: "relative",
                boxShadow: active ? "var(--sh-md)" : "var(--sh-sm)", transition: "all .15s" }}>
              <div style={{ height: 124, overflow: "hidden", background: "var(--c-bg-deep)", display: "grid", placeItems: "center" }}>
                <Certificate event={{ title: "ชื่อกิจกรรม", date: "—" }} rec={{ name: "ชื่อ–นามสกุล", role: "เข้าร่วมกิจกรรม" }} template={o.id} scale={0.226} />
              </div>
              <div style={{ padding: "11px 14px" }}>
                <div style={{ fontWeight: 700, fontSize: 14 }}>{o.name}</div>
                <div className="muted" style={{ fontSize: 12.5 }}>{o.desc}</div>
              </div>
              {active && <div style={{ position: "absolute", top: 9, right: 9, width: 24, height: 24, borderRadius: 99,
                background: "var(--c-primary)", color: "#fff", display: "grid", placeItems: "center" }}><Icon.check size={15} /></div>}
            </button>
          );
        })}
      </div>
    </div>
  );
}

/* Step 3 — drag to position the name + cert number */
function StepPosition({ draft, set }) {
  const wrapRef = React.useRef(null);
  const [dragT, setDragT] = React.useState(null); // null | 'name' | 'no'
  const namePos = draft.namePos || { x: 50, y: 46 };
  const noPos = draft.noPos || { x: 14, y: 8 };
  const clamp = (v, lo, hi) => Math.max(lo, Math.min(hi, v));

  function moveTo(clientX, clientY) {
    const r = wrapRef.current.getBoundingClientRect();
    let x = ((clientX - r.left) / r.width) * 100;
    let y = ((clientY - r.top) / r.height) * 100;
    if (dragT === "name") set({ namePos: { x: Math.round(clamp(x, 12, 88)), y: Math.round(clamp(y, 18, 82)) } });
    else if (dragT === "no") set({ noPos: { x: Math.round(clamp(x, 4, 96)), y: Math.round(clamp(y, 3, 97)) } });
  }
  React.useEffect(() => {
    if (!dragT) return;
    const mv = e => { const t = e.touches ? e.touches[0] : e; moveTo(t.clientX, t.clientY); };
    const up = () => setDragT(null);
    window.addEventListener("mousemove", mv); window.addEventListener("mouseup", up);
    window.addEventListener("touchmove", mv, { passive: false }); window.addEventListener("touchend", up);
    return () => { window.removeEventListener("mousemove", mv); window.removeEventListener("mouseup", up);
      window.removeEventListener("touchmove", mv); window.removeEventListener("touchend", up); };
  }, [dragT]);

  const [scale, setScale] = React.useState(0.6);
  React.useEffect(() => {
    function fit() { const w = wrapRef.current ? wrapRef.current.parentElement.clientWidth : 700; setScale(Math.min((Math.min(w, 760) - 4) / CERT_W, 0.76)); }
    fit(); window.addEventListener("resize", fit); return () => window.removeEventListener("resize", fit);
  }, []);

  // แสดงรูปเทมเพลต (ไฟล์ที่อัปโหลด หรือจากคลัง) เป็นพื้นหลังขณะวางตำแหน่ง
  const [imgUrl, setImgUrl] = React.useState(null);
  React.useEffect(() => {
    if (draft.templateFile) { const u = URL.createObjectURL(draft.templateFile); setImgUrl(u); return () => URL.revokeObjectURL(u); }
    setImgUrl(draft.libraryImageUrl || null);
  }, [draft.templateFile, draft.libraryImageUrl]);

  const Handle = ({ target, pos, color }) => (
    <div onMouseDown={() => setDragT(target)} onTouchStart={() => setDragT(target)}
      style={{ position: "absolute", left: `${pos.x}%`, top: `${pos.y}%`, transform: "translate(-50%,-50%)", cursor: "grab", padding: 8, zIndex: 5 }}>
      <div style={{ width: 28, height: 28, borderRadius: 99, background: color, color: "#fff",
        display: "grid", placeItems: "center", boxShadow: "var(--sh-md)", border: "2px solid #fff" }}>
        <Icon.move size={15} />
      </div>
    </div>
  );

  const Sliders = ({ label, posKey, pos, color, bounds }) => (
    <div style={{ display: "grid", gap: 8 }}>
      <div style={{ fontSize: 13, fontWeight: 700, color }}>{label}</div>
      {[["แนวนอน (X)", "x"], ["แนวตั้ง (Y)", "y"]].map(([lbl, k]) => (
        <div key={k} style={{ display: "flex", alignItems: "center", gap: 10 }}>
          <span className="muted" style={{ fontSize: 12.5, fontWeight: 600, width: 78 }}>{lbl}</span>
          <input type="range" min={bounds[k][0]} max={bounds[k][1]} value={pos[k]}
            onChange={e => set({ [posKey]: { ...pos, [k]: +e.target.value } })} style={{ accentColor: color, width: 140 }} />
          <span style={{ fontSize: 12.5, fontFamily: "ui-monospace,monospace", width: 34, color: "var(--c-ink-soft)" }}>{pos[k]}%</span>
        </div>
      ))}
    </div>
  );

  return (
    <div>
      <div style={{ display: "flex", gap: 10, alignItems: "center", marginBottom: 14, padding: "11px 15px",
        background: "var(--c-gold-soft)", borderRadius: 12, fontSize: 13.5, color: "var(--c-gold-deep)" }}>
        <Icon.move size={18} /> <span>ลาก <b>จุดสีน้ำเงิน</b> เพื่อวางตำแหน่งชื่อ และ <b>จุดสีทอง</b> เพื่อวางตำแหน่งเลขที่ — ระบบจะพิมพ์ลงตำแหน่งนี้ให้ทุกคน</span>
      </div>
      <div style={{ display: "grid", placeItems: "center" }}>
        <div ref={wrapRef} style={{ position: "relative", boxShadow: "var(--sh-lg)", borderRadius: 2, overflow: "hidden",
          cursor: dragT ? "grabbing" : "default", touchAction: "none", width: CERT_W * scale, height: CERT_H * scale }}>
          <Certificate event={{ ...draft, title: draft.title || "ชื่อกิจกรรม", date: draft.date || "—" }}
            rec={{ name: "ชื่อ–นามสกุล ตัวอย่าง", role: "เข้าร่วมกิจกรรม", no: "1/2569" }}
            template={draft.template} scale={scale} namePos={namePos} noPos={noPos} imageUrl={imgUrl}
            nameFont={draft.nameFont} nameSize={draft.nameSize} accent={draft.accent} bg={draft.bg} border={draft.border} highlightName highlightNo />
          <Handle target="name" pos={namePos} color="var(--c-primary)" />
          <Handle target="no" pos={noPos} color="var(--c-gold-deep)" />
        </div>
      </div>
      <div style={{ display: "flex", gap: 34, justifyContent: "center", marginTop: 18, flexWrap: "wrap" }}>
        <Sliders label="ตำแหน่งชื่อ" posKey="namePos" pos={namePos} color="var(--c-primary)" bounds={{ x: [12, 88], y: [18, 82] }} />
        <Sliders label="ตำแหน่งเลขที่" posKey="noPos" pos={noPos} color="var(--c-gold-deep)" bounds={{ x: [4, 96], y: [3, 97] }} />
      </div>
    </div>
  );
}

/* Step 4 — recipients upload (CSV จริง) */
function StepRecipients({ draft, set }) {
  const [busy, setBusy] = React.useState(false);
  const [error, setError] = React.useState("");
  const [over, setOver] = React.useState(false);
  const fileRef = React.useRef(null);
  const rows = draft.recipients || [];

  async function handleFile(file) {
    if (!file) return;
    setBusy(true); setError("");
    try {
      const text = await file.text();
      const parsed = parseRecipientsCsv(text);
      if (!parsed.length) setError("ไม่พบรายชื่อในไฟล์ — ตรวจรูปแบบคอลัมน์: ชื่อ-นามสกุล, โรงเรียน, ประเภทรางวัล, กิจกรรม/รายการ, เลขที่");
      else set({ recipients: parsed, fileName: file.name });
    } catch (e) {
      setError("อ่านไฟล์ไม่สำเร็จ");
    } finally {
      setBusy(false);
    }
  }

  if (rows.length === 0) {
    return (
      <div style={{ maxWidth: 620, margin: "0 auto" }}>
        <input ref={fileRef} type="file" accept=".csv,text/csv,text/plain" style={{ display: "none" }}
          onChange={e => handleFile(e.target.files[0])} />
        <button onClick={() => fileRef.current && fileRef.current.click()} disabled={busy}
          onDragOver={e => { e.preventDefault(); setOver(true); }}
          onDragLeave={() => setOver(false)}
          onDrop={e => { e.preventDefault(); setOver(false); handleFile(e.dataTransfer.files[0]); }}
          style={{ width: "100%", border: `2px dashed ${over ? "var(--c-primary)" : "var(--c-line)"}`, borderRadius: 16, padding: "44px 20px",
            background: over ? "var(--c-primary-soft)" : "var(--c-surface-2)", display: "flex", flexDirection: "column", alignItems: "center", gap: 12, color: "var(--c-muted)" }}>
          {busy ? <Spinner size={32} color="var(--c-primary)" /> : <div style={{ width: 60, height: 60, borderRadius: 16, background: "var(--c-primary-soft)", color: "var(--c-primary)", display: "grid", placeItems: "center" }}><Icon.table size={30} /></div>}
          <div style={{ fontWeight: 700, fontSize: 16, color: "var(--c-ink)" }}>{busy ? "กำลังอ่านไฟล์…" : "ลากไฟล์ CSV มาวาง หรือคลิกเพื่อเลือก"}</div>
          {!busy && <div style={{ fontSize: 12.5, fontFamily: "ui-monospace,monospace", textAlign: "center" }}>คอลัมน์: ชื่อ-นามสกุล · โรงเรียน · ประเภทรางวัล · กิจกรรม/รายการ · เลขที่</div>}
        </button>
        {error && <div style={{ color: "var(--c-danger)", fontSize: 13.5, fontWeight: 600, marginTop: 12, textAlign: "center" }}>{error}</div>}
        <div style={{ marginTop: 14, display: "flex", gap: 10, alignItems: "center", justifyContent: "center" }}>
          <button className="btn btn-soft btn-sm" onClick={downloadSampleCsv}><Icon.download size={15} /> ดาวน์โหลดไฟล์ตัวอย่าง</button>
        </div>
      </div>
    );
  }

  return (
    <div>
      <div style={{ display: "flex", alignItems: "center", gap: 12, marginBottom: 14, flexWrap: "wrap" }}>
        <span className="chip chip-ok"><Icon.check size={14} /> อ่านไฟล์สำเร็จ</span>
        <span style={{ fontWeight: 600, fontSize: 14 }}>{draft.fileName}</span>
        <span className="muted" style={{ fontSize: 13.5 }}>พบ {rows.length} รายชื่อ</span>
        <div style={{ flex: 1 }} />
        <button className="btn btn-ghost btn-sm" onClick={() => set({ recipients: [], fileName: null })}>
          <Icon.x size={15} /> ลบ แล้วอัปโหลดใหม่
        </button>
      </div>
      <div className="card" style={{ overflow: "hidden", maxHeight: 320, overflowY: "auto" }}>
        <table style={{ width: "100%", borderCollapse: "collapse", fontSize: 13.5 }}>
          <thead style={{ position: "sticky", top: 0 }}>
            <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>
            </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" }}><span className="muted">{r.role}</span></td>
              </tr>
            ))}
          </tbody>
        </table>
      </div>
    </div>
  );
}

/* Step 5 — generate (เรียก API จริง) */
function StepGenerate({ gen, onPublish, onRetry }) {
  const { phase, done, total, error } = gen;
  const working = phase === "creating" || phase === "uploading" || phase === "generating";
  const statusText = {
    creating: "กำลังบันทึกกิจกรรม…",
    uploading: "กำลังอัปโหลดไฟล์เทมเพลต…",
    generating: `กำลังสร้างเกียรติบัตรและไฟล์ PDF… ${total} ใบ`,
  }[phase];

  return (
    <div style={{ maxWidth: 540, margin: "12px auto", textAlign: "center" }}>
      <div style={{ position: "relative", width: 132, height: 132, margin: "0 auto 22px" }}>
        {phase === "done" ? (
          <div style={{ display: "grid", placeItems: "center", height: "100%" }}>
            <Icon.checkCircle size={70} style={{ color: "var(--c-ok)" }} />
          </div>
        ) : phase === "error" ? (
          <div style={{ display: "grid", placeItems: "center", height: "100%", color: "var(--c-danger)" }}>
            <Icon.info size={66} />
          </div>
        ) : (
          <div style={{ display: "grid", placeItems: "center", height: "100%" }}>
            <Spinner size={62} color="var(--c-primary)" />
          </div>
        )}
      </div>
      {working && (
        <>
          <h3 style={{ fontSize: 19, fontWeight: 700 }}>กำลังดำเนินการ…</h3>
          <p className="muted" style={{ fontSize: 14.5, marginTop: 5 }}>{statusText}</p>
        </>
      )}
      {phase === "error" && (
        <div className="anim-in">
          <h3 style={{ fontSize: 19, fontWeight: 700 }}>เกิดข้อผิดพลาด</h3>
          <p style={{ color: "var(--c-danger)", fontSize: 14.5, marginTop: 5, marginBottom: 20 }}>{error}</p>
          <button className="btn btn-primary" onClick={onRetry}><Icon.arrowR size={18} /> ลองอีกครั้ง</button>
        </div>
      )}
      {phase === "done" && (
        <div className="anim-in">
          <h3 style={{ fontSize: 20, fontWeight: 700 }}>สร้างเกียรติบัตรสำเร็จ 🎉</h3>
          <p className="muted" style={{ fontSize: 14.5, marginTop: 5, marginBottom: 22 }}>
            สร้าง {done} ใบ และเก็บลง R2 เรียบร้อย เผยแพร่ให้ผู้ใช้ค้นหา–ดาวน์โหลดได้ทันที
          </p>
          <button className="btn btn-gold btn-lg" onClick={onPublish}><Icon.checkCircle size={19} /> เสร็จสิ้น — ไปหน้ารายการ</button>
        </div>
      )}
    </div>
  );
}

/* ---------- Wizard container ---------- */
function CreateWizard({ onClose, onDone }) {
  const [step, setStep] = React.useState(1);
  const [draft, setDraft] = React.useState({
    title: "", date: "", group: "", subtitle: "",
    template: "classic-gold", templateId: null, libraryImageUrl: null, templateFile: null, uploadedName: null,
    namePos: { x: 50, y: 46 }, noPos: { x: 14, y: 8 }, nameFont: "pridi", nameSize: 52,
    accent: null, bg: null, border: null, recipients: [], fileName: null,
  });
  const [gen, setGen] = React.useState({ phase: "idle", done: 0, total: 0, error: "", event: null });
  const set = (patch) => setDraft(d => ({ ...d, ...patch }));

  async function runGenerate() {
    const recips = draft.recipients || [];
    setGen({ phase: "creating", done: 0, total: recips.length, error: "", event: null });
    try {
      const { event } = await api.createEvent({
        title: draft.title, subtitle: draft.subtitle, date: draft.date, group: draft.group,
        template: draft.template, templateId: draft.templateId, namePos: draft.namePos, noPos: draft.noPos,
        nameFont: draft.nameFont, nameSize: draft.nameSize,
        accent: draft.accent, bg: draft.bg, border: draft.border, recipients: recips,
      });
      if (draft.templateFile) {
        setGen(g => ({ ...g, phase: "uploading" }));
        await api.uploadTemplate(event.id, draft.templateFile);
      }
      setGen(g => ({ ...g, phase: "generating" }));
      const r = await api.generate(event.id);
      setGen({ phase: "done", done: r.generated, total: recips.length, error: "", event: r.event });
    } catch (e) {
      setGen(g => ({ ...g, phase: "error", error: e.message || "ดำเนินการไม่สำเร็จ" }));
    }
  }

  React.useEffect(() => {
    if (step === 5 && gen.phase === "idle") runGenerate();
  }, [step]);

  const canNext = {
    1: draft.title.trim() && draft.date.trim(),
    2: !!draft.template || !!draft.templateFile,
    3: true,
    4: (draft.recipients || []).length > 0,
    5: true,
  }[step];

  return (
    <div style={{ minHeight: "100vh", display: "flex", flexDirection: "column", background: "var(--c-bg)" }}>
      <div style={{ padding: "16px 28px", borderBottom: "1px solid var(--c-line-soft)", display: "flex", alignItems: "center", gap: 16,
        background: "var(--c-surface)", position: "sticky", top: 0, zIndex: 20 }}>
        <button className="btn btn-ghost btn-sm" onClick={onClose} style={{ padding: 9 }}><Icon.x size={18} /></button>
        <div style={{ fontWeight: 700, fontSize: 16 }}>สร้างกิจกรรมใหม่</div>
        <div style={{ flex: 1 }} />
        <div className="stepper-wrap"><Stepper step={step} /></div>
      </div>

      <div style={{ flex: 1, overflow: "auto", padding: "30px 28px" }}>
        <div style={{ maxWidth: 880, margin: "0 auto" }}>
          <div style={{ marginBottom: 22 }}>
            <div className="chip" style={{ marginBottom: 9 }}>ขั้นตอนที่ {step} / 5</div>
            <h2 style={{ fontSize: 22, fontWeight: 700 }}>{STEPS[step - 1].label}</h2>
          </div>
          <div className="anim-in" key={step}>
            {step === 1 && <StepInfo draft={draft} set={set} />}
            {step === 2 && <StepTemplate draft={draft} set={set} />}
            {step === 3 && <StepPosition draft={draft} set={set} />}
            {step === 4 && <StepRecipients draft={draft} set={set} />}
            {step === 5 && <StepGenerate gen={gen} onRetry={runGenerate} onPublish={() => onDone(gen.event)} />}
          </div>
        </div>
      </div>

      {step < 5 && (
        <div style={{ padding: "15px 28px", borderTop: "1px solid var(--c-line-soft)", background: "var(--c-surface)",
          display: "flex", gap: 12, alignItems: "center" }}>
          <button className="btn btn-ghost" onClick={() => step === 1 ? onClose() : setStep(s => s - 1)}>
            <Icon.arrowL size={17} /> {step === 1 ? "ยกเลิก" : "ย้อนกลับ"}
          </button>
          <div style={{ flex: 1 }} />
          <button className="btn btn-primary" disabled={!canNext} onClick={() => setStep(s => s + 1)}>
            {step === 4 ? "เริ่ม Generate" : "ถัดไป"} <Icon.arrowR size={17} />
          </button>
        </div>
      )}

      <style>{`
        @media (max-width: 880px){ .step-label{ display:none; } }
      `}</style>
    </div>
  );
}

Object.assign(window, { CreateWizard });
