/* global React */
const { useState: useStateA, useEffect: useEffectA, useMemo: useMemoA } = React;

// Parse YouTube URL → Video ID
// Supports: youtu.be/ID, youtube.com/watch?v=ID, youtube.com/embed/ID, youtube.com/shorts/ID, raw ID
function parseYouTube(input) {
  if (!input) return "";
  const s = input.trim();
  // Raw 11-char ID
  if (/^[A-Za-z0-9_-]{11}$/.test(s)) return s;
  // Try URL patterns
  const patterns = [
    /youtu\.be\/([A-Za-z0-9_-]{11})/,
    /[?&]v=([A-Za-z0-9_-]{11})/,
    /youtube\.com\/embed\/([A-Za-z0-9_-]{11})/,
    /youtube\.com\/shorts\/([A-Za-z0-9_-]{11})/,
    /youtube\.com\/live\/([A-Za-z0-9_-]{11})/,
  ];
  for (const p of patterns) {
    const m = s.match(p);
    if (m) return m[1];
  }
  return "";
}

const ADMIN_PASSWORD = "admin1234";
const LS_KEY = "crubank_episodes_v1";
const SESSION_KEY = "crubank_admin_session";

// Load from localStorage, fall back to defaults
function loadEpisodes(defaults) {
  try {
    const raw = localStorage.getItem(LS_KEY);
    if (!raw) return defaults;
    const data = JSON.parse(raw);
    if (!Array.isArray(data)) return defaults;
    return data;
  } catch { return defaults; }
}

function saveEpisodes(eps) {
  try { localStorage.setItem(LS_KEY, JSON.stringify(eps)); } catch {}
}

// ──────────────── Admin Gate (secret gesture + password) ────────────────
function AdminGate({ onUnlock }) {
  const [stage, setStage] = useStateA("idle"); // idle | prompt
  const [pw, setPw] = useStateA("");
  const [err, setErr] = useStateA("");

  useEffectA(() => {
    let taps = [];
    const onLogoTap = (e) => {
      const target = e.target.closest(".brand");
      if (!target) return;
      const now = Date.now();
      taps = taps.filter(t => now - t < 2000);
      taps.push(now);
      if (taps.length >= 5) {
        taps = [];
        setStage("prompt");
      }
    };
    document.addEventListener("click", onLogoTap);

    // Also allow ?admin=1 query
    if (new URLSearchParams(location.search).get("admin") === "1") {
      setStage("prompt");
    }
    return () => document.removeEventListener("click", onLogoTap);
  }, []);

  const submit = (e) => {
    e.preventDefault();
    if (pw === ADMIN_PASSWORD) {
      setStage("idle");
      setPw("");
      setErr("");
      sessionStorage.setItem(SESSION_KEY, "1");
      onUnlock();
    } else {
      setErr("รหัสผ่านไม่ถูกต้อง");
    }
  };

  if (stage !== "prompt") return null;

  return (
    <div className="pv-overlay" onClick={() => setStage("idle")}>
      <div className="admin-gate" onClick={e=>e.stopPropagation()}>
        <div className="admin-gate-icon">🔐</div>
        <h3>เข้าสู่โหมดแอดมิน</h3>
        <p>ใส่รหัสผ่านเพื่อจัดการบทเรียน</p>
        <form onSubmit={submit}>
          <input
            type="password"
            className="input"
            autoFocus
            placeholder="รหัสผ่าน"
            value={pw}
            onChange={e => { setPw(e.target.value); setErr(""); }}
          />
          {err && <div className="admin-err">{err}</div>}
          <div className="admin-gate-actions">
            <button type="button" className="btn btn-secondary" onClick={() => setStage("idle")}>ยกเลิก</button>
            <button type="submit" className="btn btn-primary">เข้าสู่ระบบ</button>
          </div>
          <div className="admin-hint">💡 Hint: รหัสเริ่มต้นคือ <code>admin1234</code></div>
        </form>
      </div>
    </div>
  );
}

// ──────────────── Admin Panel ────────────────
function AdminPanel({ open, onClose, episodes, setEpisodes, onResetDefaults, defaultPrice, setDefaultPrice, showToast }) {
  const [editingN, setEditingN] = useStateA(null);
  const [tab, setTab] = useStateA("lessons"); // lessons | members

  if (!open) return null;

  const editingEp = episodes.find(e => e.n === editingN);

  const update = (n, patch) => {
    const next = episodes.map(e => e.n === n ? { ...e, ...patch } : e);
    setEpisodes(next);
  };

  const addEpisode = () => {
    const nextN = episodes.length ? Math.max(...episodes.map(e=>e.n)) + 1 : 1;
    const blank = {
      n: nextN, yt: "", emoji: "🎬",
      title: "บทเรียนใหม่", duration: "20:00",
      desc: "คำอธิบายสั้นๆ", manual: `${String(nextN).padStart(2,'0')}-new.doc`,
      size: "1.0 MB", manualUrl: "",
    };
    setEpisodes([...episodes, blank]);
    setEditingN(nextN);
  };

  const removeEp = (n) => {
    if (!confirm(`ลบบทที่ ${n}?`)) return;
    setEpisodes(episodes.filter(e => e.n !== n));
    if (editingN === n) setEditingN(null);
  };

  const moveUp = (n) => {
    const i = episodes.findIndex(e=>e.n===n);
    if (i <= 0) return;
    const next = [...episodes];
    [next[i-1], next[i]] = [next[i], next[i-1]];
    setEpisodes(next);
  };
  const moveDown = (n) => {
    const i = episodes.findIndex(e=>e.n===n);
    if (i < 0 || i >= episodes.length-1) return;
    const next = [...episodes];
    [next[i], next[i+1]] = [next[i+1], next[i]];
    setEpisodes(next);
  };

  const ytChange = (n, val) => {
    const id = parseYouTube(val);
    update(n, { yt: id, ytRaw: val });
  };

  return (
    <div className="adm-overlay">
      <div className="adm-panel">
        <div className="adm-head">
          <div>
            <div className="adm-head-badge">🔐 ADMIN MODE</div>
            <h2>จัดการบทเรียน</h2>
            <p>ใส่ลิงก์ YouTube, แก้ชื่อบท, อัปโหลดไฟล์คู่มือ ทุกอย่างเซฟในเบราว์เซอร์อัตโนมัติ</p>
          </div>
          <button className="adm-close" onClick={onClose}>×</button>
        </div>

        <div className="adm-toolbar">
          <div className="adm-stat">
            <span className="adm-stat-num">{episodes.length}</span>
            <span className="adm-stat-lbl">บทเรียนทั้งหมด</span>
          </div>
          <div className="adm-stat">
            <span className="adm-stat-num">{episodes.filter(e => e.yt).length}</span>
            <span className="adm-stat-lbl">มีคลิปแล้ว</span>
          </div>
          <div className="adm-stat">
            <span className="adm-stat-num">{episodes.filter(e => !e.yt).length}</span>
            <span className="adm-stat-lbl">ยังไม่ใส่คลิป</span>
          </div>
          <div style={{flex:1}}/>
          <div className="adm-price-box">
            <label>ราคา/บท:</label>
            <div className="adm-price-input">
              <span>฿</span>
              <input type="number" value={defaultPrice} onChange={e=>setDefaultPrice(+e.target.value||0)} min="0"/>
            </div>
          </div>
          <button className="btn btn-secondary btn-sm" onClick={() => {
            if (confirm("รีเซ็ตข้อมูลทั้งหมดกลับเป็นค่าเริ่มต้น?")) {
              onResetDefaults();
              showToast("รีเซ็ตข้อมูลแล้ว");
            }
          }}>รีเซ็ต</button>
          <button className="btn btn-primary btn-sm" onClick={addEpisode}>+ เพิ่มบท</button>
        </div>

        <div className="adm-tabs">
          <button className={"adm-tab" + (tab==="lessons"?" active":"")} onClick={()=>setTab("lessons")}>📖 บทเรียน</button>
          <button className={"adm-tab" + (tab==="payments"?" active":"")} onClick={()=>setTab("payments")}>💳 ชำระเงิน</button>
          <button className={"adm-tab" + (tab==="members"?" active":"")} onClick={()=>setTab("members")}>👥 สมาชิก</button>
        </div>

        {tab === "members" ? (
          <AdminMembers showToast={showToast} episodes={episodes} />
        ) : tab === "payments" ? (
          <AdminPayments showToast={showToast} episodes={episodes} />
        ) : (
        <div className="adm-body">
          <div className="adm-list">
            <div className="adm-list-head">รายการบทเรียน</div>
            {episodes.map((ep, i) => (
              <div
                key={ep.n}
                className={"adm-row" + (editingN===ep.n?" active":"") + (!ep.yt?" warn":"")}
                onClick={()=>setEditingN(ep.n)}
              >
                <div className="adm-row-n">{String(i+1).padStart(2,'0')}</div>
                <div className="adm-row-emoji">{ep.emoji || "🎬"}</div>
                <div className="adm-row-info">
                  <div className="adm-row-title">{ep.title}</div>
                  <div className="adm-row-sub">
                    {ep.yt
                      ? <span className="adm-chip ok">✓ {ep.yt}</span>
                      : <span className="adm-chip warn">⚠ ยังไม่ใส่คลิป</span>
                    }
                    <span className="adm-chip">{ep.duration}</span>
                  </div>
                </div>
                <div className="adm-row-actions" onClick={e=>e.stopPropagation()}>
                  <button className="adm-iconbtn" onClick={()=>moveUp(ep.n)} title="เลื่อนขึ้น">↑</button>
                  <button className="adm-iconbtn" onClick={()=>moveDown(ep.n)} title="เลื่อนลง">↓</button>
                  <button className="adm-iconbtn danger" onClick={()=>removeEp(ep.n)} title="ลบ">🗑</button>
                </div>
              </div>
            ))}
          </div>

          <div className="adm-editor">
            {!editingEp ? (
              <div className="adm-empty">
                <div style={{fontSize:48, marginBottom:8}}>👈</div>
                <h3>เลือกบทเรียนที่ต้องการแก้ไข</h3>
                <p>หรือกด "+ เพิ่มบท" เพื่อสร้างใหม่</p>
              </div>
            ) : (
              <div className="adm-form">
                <div className="adm-form-head">
                  <div className="adm-form-badge">บทที่ {String(episodes.findIndex(e=>e.n===editingEp.n)+1).padStart(2,'0')}</div>
                  <h3>{editingEp.title}</h3>
                </div>

                <AdminField label="🎥 ลิงก์ YouTube" sublabel="วาง URL เต็ม เช่น https://youtu.be/xxx หรือ https://youtube.com/watch?v=xxx">
                  <input
                    className="input"
                    placeholder="https://youtu.be/..."
                    value={editingEp.ytRaw || (editingEp.yt ? `https://youtu.be/${editingEp.yt}` : "")}
                    onChange={e=>ytChange(editingEp.n, e.target.value)}
                  />
                  {editingEp.yt ? (
                    <div className="adm-preview">
                      <iframe
                        src={`https://www.youtube.com/embed/${editingEp.yt}?controls=1&modestbranding=1`}
                        title="preview"
                        allow="encrypted-media"
                      />
                    </div>
                  ) : (
                    <div className="adm-note warn">⚠ ยังไม่มีลิงก์หรือลิงก์ไม่ถูกต้อง — ลูกค้าจะเห็นบทนี้แต่เปิดดูไม่ได้</div>
                  )}
                </AdminField>

                <div className="adm-row-2">
                  <AdminField label="📝 ชื่อบทเรียน">
                    <input className="input" value={editingEp.title} onChange={e=>update(editingEp.n, {title: e.target.value})}/>
                  </AdminField>
                  <AdminField label="😀 อีโมจิ" sublabel="1 ตัว">
                    <input className="input" value={editingEp.emoji || ""} maxLength={4} onChange={e=>update(editingEp.n, {emoji: e.target.value})}/>
                  </AdminField>
                </div>

                <AdminField label="💬 คำอธิบายสั้น">
                  <textarea className="input" rows={2} value={editingEp.desc} onChange={e=>update(editingEp.n, {desc: e.target.value})}/>
                </AdminField>

                <div className="adm-row-2">
                  <AdminField label="⏱ ความยาว" sublabel="เช่น 20:12">
                    <input className="input" value={editingEp.duration} onChange={e=>update(editingEp.n, {duration: e.target.value})}/>
                  </AdminField>
                  <AdminField label="💰 ราคา" sublabel="เว้นว่าง = ใช้ราคามาตรฐาน">
                    <div className="adm-price-input">
                      <span>฿</span>
                      <input type="number" placeholder={defaultPrice} value={editingEp.price ?? ""} onChange={e=>update(editingEp.n, {price: e.target.value === "" ? null : +e.target.value})}/>
                    </div>
                  </AdminField>
                </div>

                <div className="adm-section-head">📄 ไฟล์คู่มือประกอบบทเรียน</div>
                <div className="adm-row-2">
                  <AdminField label="ชื่อไฟล์ (.doc)">
                    <input className="input" value={editingEp.manual} onChange={e=>update(editingEp.n, {manual: e.target.value})}/>
                  </AdminField>
                  <AdminField label="ขนาดไฟล์">
                    <input className="input" value={editingEp.size} onChange={e=>update(editingEp.n, {size: e.target.value})}/>
                  </AdminField>
                </div>
                <AdminField label="🔗 URL ไฟล์ดาวน์โหลด" sublabel="ลิงก์ Google Drive / Dropbox / S3 ที่ลูกค้าจะกดดาวน์โหลด">
                  <input
                    className="input"
                    placeholder="https://drive.google.com/..."
                    value={editingEp.manualUrl || ""}
                    onChange={e=>update(editingEp.n, {manualUrl: e.target.value})}
                  />
                  {!editingEp.manualUrl && <div className="adm-note">💡 ถ้าไม่ใส่ ลูกค้าจะได้แค่ข้อความ "กำลังดาวน์โหลด" (mock)</div>}
                </AdminField>

                <div className="adm-save-hint">
                  ✓ การแก้ไขทั้งหมดถูกบันทึกในเบราว์เซอร์โดยอัตโนมัติ
                </div>
              </div>
            )}
          </div>
        </div>
        )}
      </div>
    </div>
  );
}

// ──────────── Members tab ────────────
function AdminMembers({ showToast, episodes }) {
  const Auth = window.AuthModule;
  const [users, setUsers] = useStateA(() => Auth.loadUsers());
  const [q, setQ] = useStateA("");
  const refresh = () => setUsers(Auth.loadUsers());

  const filtered = users.filter(u => {
    if (!q.trim()) return true;
    const s = q.toLowerCase();
    return u.name.toLowerCase().includes(s) || u.email.toLowerCase().includes(s);
  });

  const del = (u) => {
    if (!confirm(`ลบสมาชิก ${u.email}? ข้อมูลการซื้อจะหายด้วย`)) return;
    Auth.deleteUser(u.id);
    refresh();
    showToast("ลบสมาชิกแล้ว");
  };

  const resetPw = (u) => {
    const np = prompt(`ตั้งรหัสผ่านใหม่สำหรับ ${u.email}`, "123456");
    if (!np || np.length < 6) return;
    const all = Auth.loadUsers().map(x => x.id === u.id ? { ...x, pwHash: Auth.hashPw(np) } : x);
    Auth.saveUsers(all);
    refresh();
    showToast(`รีเซ็ตรหัสของ ${u.email} แล้ว`);
  };

  const grantAll = (u) => {
    if (!confirm(`ปลดล็อกทุกบทเรียนให้ ${u.email}?`)) return;
    const set = new Set(episodes.map(e => e.n));
    Auth.saveUserUnlocked(u.id, set);
    showToast(`ปลดล็อกครบทุกบทให้ ${u.email} แล้ว`);
  };

  const revokeAll = (u) => {
    if (!confirm(`ยกเลิกบทเรียนทั้งหมดของ ${u.email}?`)) return;
    Auth.saveUserUnlocked(u.id, new Set());
    showToast(`ยกเลิกบทเรียนของ ${u.email} แล้ว`);
  };

  return (
    <div className="adm-members">
      <div className="adm-members-head">
        <div className="adm-members-stats">
          <div><b>{users.length}</b> สมาชิกทั้งหมด</div>
        </div>
        <input className="input" placeholder="ค้นหาชื่อ/อีเมล..." value={q} onChange={e=>setQ(e.target.value)} style={{maxWidth:280}}/>
      </div>

      {filtered.length === 0 ? (
        <div className="adm-empty">
          <div style={{fontSize:48, marginBottom:8}}>👤</div>
          <h3>{users.length === 0 ? "ยังไม่มีสมาชิก" : "ไม่พบสมาชิกที่ตรงกับคำค้นหา"}</h3>
          <p>{users.length === 0 ? "รอให้ผู้เรียนสมัครเข้ามา" : ""}</p>
        </div>
      ) : (
        <div className="adm-members-list">
          <div className="adm-members-row head">
            <div>สมาชิก</div>
            <div>บทที่ซื้อ</div>
            <div>สมัครเมื่อ</div>
            <div>จัดการ</div>
          </div>
          {filtered.map(u => {
            const unlocked = Auth.loadUserUnlocked(u.id);
            return (
              <div key={u.id} className="adm-members-row">
                <div>
                  <div className="adm-mem-avatar">{u.name[0] || "?"}</div>
                  <div className="adm-mem-info">
                    <div className="adm-mem-name">{u.name}</div>
                    <div className="adm-mem-email">{u.email}</div>
                  </div>
                </div>
                <div>
                  <span className={"adm-chip" + (unlocked.size>0?" ok":"")}>{unlocked.size}/{episodes.length} บท</span>
                </div>
                <div className="adm-mem-date">{new Date(u.createdAt).toLocaleDateString("th-TH")}</div>
                <div className="adm-mem-actions">
                  <button className="adm-iconbtn" onClick={()=>grantAll(u)} title="ปลดล็อกทุกบท">🔓</button>
                  <button className="adm-iconbtn" onClick={()=>revokeAll(u)} title="ยกเลิกการซื้อ">🔒</button>
                  <button className="adm-iconbtn" onClick={()=>resetPw(u)} title="รีเซ็ตรหัส">🔑</button>
                  <button className="adm-iconbtn danger" onClick={()=>del(u)} title="ลบบัญชี">🗑</button>
                </div>
              </div>
            );
          })}
        </div>
      )}
    </div>
  );
}

// ──────────── Payments tab ────────────
function AdminPayments({ showToast, episodes }) {
  const Auth = window.AuthModule;
  const [payments, setPayments] = useStateA(() => loadPayments());
  const [q, setQ] = useStateA("");
  const [statusFilter, setStatusFilter] = useStateA("all");
  const [viewing, setViewing] = useStateA(null); // payment record being inspected

  function loadPayments() {
    try { return JSON.parse(localStorage.getItem("payments_v1") || "[]").reverse(); }
    catch { return []; }
  }
  function savePayments(list) {
    // saved in chronological order, but we display reversed
    localStorage.setItem("payments_v1", JSON.stringify([...list].reverse()));
    setPayments(list);
  }

  const filtered = payments.filter(p => {
    if (statusFilter !== "all" && p.status !== statusFilter) return false;
    if (!q.trim()) return true;
    const s = q.toLowerCase();
    return (p.userEmail||"").toLowerCase().includes(s)
      || (p.userName||"").toLowerCase().includes(s)
      || (p.orderId||"").toLowerCase().includes(s)
      || (p.episodeTitle||"").toLowerCase().includes(s);
  });

  // Stats
  const stats = useMemoA(() => {
    const today = new Date(); today.setHours(0,0,0,0);
    const monthStart = new Date(today.getFullYear(), today.getMonth(), 1);
    const approved = payments.filter(p => p.status === "approved");
    const todayRev = approved.filter(p => new Date(p.submittedAt) >= today).reduce((s,p)=>s+p.amount,0);
    const monthRev = approved.filter(p => new Date(p.submittedAt) >= monthStart).reduce((s,p)=>s+p.amount,0);
    const totalRev = approved.reduce((s,p)=>s+p.amount,0);
    return {
      totalCount: payments.length,
      approvedCount: approved.length,
      pendingCount: payments.filter(p=>p.status==="pending").length,
      rejectedCount: payments.filter(p=>p.status==="rejected").length,
      todayRev, monthRev, totalRev,
    };
  }, [payments]);

  const approve = (p) => {
    if (!confirm(`อนุมัติการชำระเงินของ ${p.userEmail} สำหรับบทที่ ${p.episodeNumber}?`)) return;
    // Add ep to user's unlocked
    if (p.userId) {
      const set = Auth.loadUserUnlocked(p.userId);
      set.add(p.episodeNumber);
      Auth.saveUserUnlocked(p.userId, set);
    }
    // Update payment
    const updated = payments.map(x => x.id === p.id ? { ...x, status: "approved", reviewedAt: new Date().toISOString(), reviewedBy: "admin" } : x);
    savePayments(updated);
    setViewing(null);
    showToast(`✓ อนุมัติแล้ว · ปลดล็อกบทที่ ${p.episodeNumber} ให้ ${p.userEmail}`);
  };

  const reject = (p) => {
    if (!confirm(`ปฏิเสธการชำระเงินนี้?`)) return;
    const updated = payments.map(x => x.id === p.id ? { ...x, status: "rejected", reviewedAt: new Date().toISOString(), reviewedBy: "admin" } : x);
    savePayments(updated);
    setViewing(null);
    showToast(`ปฏิเสธรายการแล้ว`);
  };

  const remove = (p) => {
    if (!confirm(`ลบรายการนี้ออกจากประวัติ?`)) return;
    savePayments(payments.filter(x => x.id !== p.id));
    setViewing(null);
  };

  const exportCSV = () => {
    const headers = ["วันที่ส่ง","Order ID","สมาชิก","อีเมล","บทที่","หัวข้อ","ยอด","สถานะ","เลขอ้างอิง AI","ความมั่นใจ AI"];
    const rows = payments.map(p => [
      new Date(p.submittedAt).toLocaleString("th-TH"),
      p.orderId || "",
      p.userName || "",
      p.userEmail || "",
      p.episodeNumber,
      (p.episodeTitle||"").replace(/"/g,'""'),
      p.amount,
      p.status,
      p.ai?.referenceId || "",
      p.ai?.confidence != null ? (p.ai.confidence*100).toFixed(0)+"%" : "",
    ]);
    const csv = [headers, ...rows].map(r => r.map(c => `"${c}"`).join(",")).join("\n");
    const bom = "\uFEFF"; // for Excel Thai
    const blob = new Blob([bom + csv], { type: "text/csv;charset=utf-8" });
    const url = URL.createObjectURL(blob);
    const a = document.createElement("a");
    a.href = url; a.download = `payments_${new Date().toISOString().slice(0,10)}.csv`;
    a.click();
    URL.revokeObjectURL(url);
    showToast("ดาวน์โหลด CSV แล้ว");
  };

  const statusLabel = (s) => ({
    approved: "✓ อนุมัติ",
    pending:  "⏳ รอตรวจ",
    rejected: "✕ ปฏิเสธ",
    error:    "⚠ ผิดพลาด",
  })[s] || s;

  return (
    <div className="adm-payments">
      {/* Analytics row */}
      <div className="adm-pay-stats">
        <div className="adm-pay-stat">
          <div className="apl-num green">฿{stats.todayRev.toLocaleString()}</div>
          <div className="apl-lbl">รายได้วันนี้</div>
        </div>
        <div className="adm-pay-stat">
          <div className="apl-num">฿{stats.monthRev.toLocaleString()}</div>
          <div className="apl-lbl">รายได้เดือนนี้</div>
        </div>
        <div className="adm-pay-stat">
          <div className="apl-num">฿{stats.totalRev.toLocaleString()}</div>
          <div className="apl-lbl">รายได้รวม</div>
        </div>
        <div className="adm-pay-stat">
          <div className="apl-num">{stats.approvedCount}</div>
          <div className="apl-lbl">อนุมัติแล้ว</div>
        </div>
        <div className="adm-pay-stat">
          <div className="apl-num orange">{stats.pendingCount}</div>
          <div className="apl-lbl">รอตรวจ</div>
        </div>
        <div className="adm-pay-stat">
          <div className="apl-num red">{stats.rejectedCount}</div>
          <div className="apl-lbl">ปฏิเสธ</div>
        </div>
      </div>

      {/* Toolbar */}
      <div className="adm-pay-toolbar">
        <div className="adm-pay-filters">
          {[
            ["all","ทั้งหมด"],
            ["pending","รอตรวจ"],
            ["approved","อนุมัติ"],
            ["rejected","ปฏิเสธ"],
          ].map(([k,l]) => (
            <button key={k} className={"adm-fchip" + (statusFilter===k?" active":"")} onClick={()=>setStatusFilter(k)}>{l}</button>
          ))}
        </div>
        <input className="input" placeholder="ค้นหา email / order / บทเรียน..." value={q} onChange={e=>setQ(e.target.value)} style={{maxWidth:260}}/>
        <button className="btn btn-secondary btn-sm" onClick={exportCSV}>📊 Export CSV</button>
      </div>

      {filtered.length === 0 ? (
        <div className="adm-empty">
          <div style={{fontSize:48, marginBottom:8}}>💳</div>
          <h3>{payments.length === 0 ? "ยังไม่มีรายการชำระเงิน" : "ไม่พบรายการ"}</h3>
          <p>{payments.length === 0 ? "รอให้ลูกค้าซื้อบทเรียน" : "ลองค้นหาด้วยคำอื่น"}</p>
        </div>
      ) : (
        <div className="adm-pay-list">
          <div className="adm-pay-row head">
            <div>เวลา</div>
            <div>สมาชิก</div>
            <div>บทเรียน</div>
            <div>ยอด</div>
            <div>สถานะ</div>
            <div></div>
          </div>
          {filtered.map(p => (
            <div key={p.id} className="adm-pay-row" onClick={()=>setViewing(p)}>
              <div className="adm-pay-time">{new Date(p.submittedAt).toLocaleString("th-TH",{day:'2-digit',month:'short',hour:'2-digit',minute:'2-digit'})}</div>
              <div>
                <div className="adm-mem-name">{p.userName || "-"}</div>
                <div className="adm-mem-email">{p.userEmail || "-"}</div>
              </div>
              <div>
                <div className="adm-mem-name">บทที่ {String(p.episodeNumber).padStart(2,'0')}</div>
                <div className="adm-mem-email" style={{
                  display:"-webkit-box", WebkitLineClamp:1, WebkitBoxOrient:"vertical", overflow:"hidden"
                }}>{p.episodeTitle}</div>
              </div>
              <div className="adm-pay-amt">฿{p.amount}</div>
              <div><span className={"adm-pay-status " + p.status}>{statusLabel(p.status)}</span></div>
              <div className="adm-mem-actions">
                <button className="adm-iconbtn" onClick={e=>{e.stopPropagation(); setViewing(p);}}>👁</button>
              </div>
            </div>
          ))}
        </div>
      )}

      {viewing && (
        <PaymentDetailModal
          payment={viewing}
          onClose={()=>setViewing(null)}
          onApprove={approve}
          onReject={reject}
          onDelete={remove}
        />
      )}
    </div>
  );
}

function PaymentDetailModal({ payment: p, onClose, onApprove, onReject, onDelete }) {
  return (
    <div className="adm-pdetail-backdrop" onClick={onClose}>
      <div className="adm-pdetail" onClick={e=>e.stopPropagation()}>
        <div className="adm-pdetail-head">
          <div>
            <div className="adm-pdetail-title">รายละเอียดการชำระเงิน</div>
            <div className="adm-pdetail-sub">Order: <code>{p.orderId}</code></div>
          </div>
          <button className="adm-iconbtn" onClick={onClose}>✕</button>
        </div>

        <div className="adm-pdetail-body">
          <div className="adm-pdetail-image">
            {p.slipImage ? (
              <img src={p.slipImage} alt="สลิป"/>
            ) : (
              <div className="adm-pdetail-noslip">ไม่มีรูปสลิป</div>
            )}
          </div>

          <div className="adm-pdetail-info">
            <div className="adm-pd-section">
              <div className="adm-pd-lbl">สถานะปัจจุบัน</div>
              <span className={"adm-pay-status " + p.status}>
                {p.status === "approved" ? "✓ อนุมัติแล้ว" : p.status === "pending" ? "⏳ รอตรวจสอบ" : p.status === "rejected" ? "✕ ปฏิเสธ" : "⚠ ผิดพลาด"}
              </span>
            </div>

            <div className="adm-pd-section">
              <div className="adm-pd-lbl">สมาชิก</div>
              <div><b>{p.userName}</b></div>
              <div style={{fontSize:13, color:"var(--ink-3)"}}>{p.userEmail}</div>
            </div>

            <div className="adm-pd-section">
              <div className="adm-pd-lbl">บทเรียนที่ซื้อ</div>
              <div><b>บทที่ {String(p.episodeNumber).padStart(2,'0')}</b> · ฿{p.amount}</div>
              <div style={{fontSize:13, color:"var(--ink-3)"}}>{p.episodeTitle}</div>
            </div>

            <div className="adm-pd-section">
              <div className="adm-pd-lbl">เวลา</div>
              <div>ส่งสลิป: {new Date(p.submittedAt).toLocaleString("th-TH")}</div>
              {p.reviewedAt && <div style={{fontSize:13, color:"var(--ink-3)"}}>ตรวจ: {new Date(p.reviewedAt).toLocaleString("th-TH")}</div>}
            </div>

            <div className="adm-pd-section">
              <div className="adm-pd-lbl">🤖 ผลตรวจ AI</div>
              <div className="adm-pd-ai">
                <div className="adm-pd-ai-row"><span>ยอดที่อ่านได้</span><b>{p.ai?.amount != null ? `฿${p.ai.amount}` : "-"}</b></div>
                <div className="adm-pd-ai-row"><span>เวลา</span><b>{p.ai?.datetime || "-"}</b></div>
                <div className="adm-pd-ai-row"><span>เลขอ้างอิง</span><code>{p.ai?.referenceId || "-"}</code></div>
                <div className="adm-pd-ai-row"><span>ผู้รับ</span><b>{p.ai?.receiverName || "-"}</b></div>
                <div className="adm-pd-ai-row"><span>บัญชีปลายทาง</span><b>{p.ai?.receiverAccount || "-"}</b></div>
                <div className="adm-pd-ai-row"><span>ความมั่นใจ</span><b>{p.ai?.confidence != null ? (p.ai.confidence*100).toFixed(0)+"%" : "-"}</b></div>
              </div>
              {p.ai?.rawText && (
                <div className="adm-pd-rawtext">{p.ai.rawText}</div>
              )}
            </div>

            {p.checks?.length > 0 && (
              <div className="adm-pd-section">
                <div className="adm-pd-lbl">การตรวจสอบ</div>
                <div className="pr-checks" style={{margin:0}}>
                  {p.checks.map((c,i) => (
                    <div key={i} className={"pr-check " + (c.ok?"ok":"fail")}>
                      <span className="pr-check-ico">{c.ok?"✓":"✕"}</span>
                      <span>{c.label}</span>
                    </div>
                  ))}
                </div>
              </div>
            )}
          </div>
        </div>

        <div className="adm-pdetail-actions">
          <button className="btn btn-secondary" onClick={()=>onDelete(p)}>🗑 ลบรายการ</button>
          <div style={{flex:1}}/>
          {p.status !== "rejected" && <button className="btn btn-secondary" onClick={()=>onReject(p)}>ปฏิเสธ</button>}
          {p.status !== "approved" && <button className="btn btn-primary" onClick={()=>onApprove(p)}>✓ อนุมัติ + ปลดล็อก</button>}
        </div>
      </div>
    </div>
  );
}

function AdminField({ label, sublabel, children }) {
  return (
    <div className="adm-field">
      <label className="adm-lbl">
        {label}
        {sublabel && <span className="adm-sublbl">{sublabel}</span>}
      </label>
      {children}
    </div>
  );
}

// Floating pen (visible only after admin login in this session)
function AdminPen({ onClick }) {
  const [show, setShow] = useStateA(() => sessionStorage.getItem(SESSION_KEY) === "1");
  useEffectA(() => {
    const onStorage = () => setShow(sessionStorage.getItem(SESSION_KEY) === "1");
    window.addEventListener("admin-session-changed", onStorage);
    const t = setInterval(onStorage, 1000);
    return () => { window.removeEventListener("admin-session-changed", onStorage); clearInterval(t); };
  }, []);
  if (!show) return null;
  return (
    <button className="edit-pen" onClick={onClick} title="แก้ไขบทเรียน">✏️</button>
  );
}

window.AdminModule = { AdminGate, AdminPanel, AdminPen, parseYouTube, loadEpisodes, saveEpisodes, LS_KEY, SESSION_KEY };
