/* ==========================================================================
 * ADMIN NEXT — page-codes.jsx  (คูปองเติมเครดิต — list / สร้าง / ปิด / ลบ)
 * ========================================================================== */
const CODE_TURN={turnover:"โอเวอร์",deposit:"โอเวอร์",credit:"เครดิต",revolving:"หมุนเวียน",fixed:"ระบุจำนวน"};
const CODE_MEMBER={all:"ทุกคน",new:"สมาชิกใหม่",existing:"สมาชิกเก่า"};
function codeStatus(c){
  if(c.is_active===false) return {t:"ปิด",c:"danger"};
  if(c.expires_at && new Date(c.expires_at)<new Date()) return {t:"หมดอายุ",c:"warn"};
  if(Number(c.max_uses||0)>0 && Number(c.uses||0)>=Number(c.max_uses)) return {t:"ใช้ครบ",c:"info"};
  return {t:"เปิด",c:"success"};
}
function CodeCreateModal({ onClose, onDone, toast }) {
  const [f,setF]=useState({ name:"", amount:"", maxUses:"1", maxUsesPerUser:"1", memberType:"all", batchCount:"1", turnoverType:"deposit", turnoverMultiplier:"0", maxWithdraw:"", canWithdraw:true, expiresAt:"" });
  const [busy,setBusy]=useState(false);
  const set=(k,v)=>setF(o=>({...o,[k]:v}));
  const inp="mt-1 h-10 w-full rounded-lg border border-line bg-sunken px-3 text-sm text-fg placeholder:text-faint focus:border-accent focus:bg-surface focus:outline-none focus:ring-4 focus:ring-[var(--accent-ring)]";
  const submit=async()=>{
    const amount=parseInt(f.amount,10), maxUses=parseInt(f.maxUses,10)||1, batchCount=Math.max(1,Math.min(500,parseInt(f.batchCount,10)||1));
    if(!(amount>0)){ toast("กรอกยอดคูปอง (บาท) ให้ถูกต้อง"); return; }
    const body={ name:f.name.trim()||undefined, amount, maxUses, maxUsesPerUser:parseInt(f.maxUsesPerUser,10)||1, memberType:f.memberType, batchCount, turnoverType:f.turnoverType, turnoverMultiplier:parseInt(f.turnoverMultiplier,10)||0, maxWithdraw:parseInt(f.maxWithdraw,10)||0, canWithdraw:!!f.canWithdraw };
    if(f.expiresAt){ try{ body.expiresAt=new Date(f.expiresAt).toISOString(); }catch{} }
    setBusy(true);
    try{ const r=await api("/deposit-codes",{method:"POST",body}); toast(batchCount>1?("สร้างคูปอง "+batchCount+" ใบแล้ว"):("สร้างคูปอง "+((r&&r.code)||"")+" แล้ว")); onDone&&onDone(); onClose(); }
    catch(e){ toast(e.data&&e.data.error==="validation_error"?"ข้อมูลไม่ถูกต้อง":(e.message||"ไม่สำเร็จ")); }finally{ setBusy(false); }
  };
  return (<div className="fixed inset-0 z-[80] flex items-center justify-center p-4 fade-in" onMouseDown={()=>!busy&&onClose()}>
    <div className="absolute inset-0 bg-black/55"/>
    <div className="pop relative max-h-[92vh] w-full max-w-md overflow-y-auto rounded-2xl border border-line bg-surface2 p-5 shadow-lg" onMouseDown={(e)=>e.stopPropagation()}>
      <div className="text-base font-semibold">สร้างคูปอง</div>
      <div className="mt-3 grid grid-cols-2 gap-3">
        <label className="block"><span className="text-xs font-medium text-fg-2">ชื่อชุด (ไม่บังคับ)</span><input className={inp} value={f.name} onChange={(e)=>set("name",e.target.value)} placeholder="เช่น โปรปีใหม่"/></label>
        <label className="block"><span className="text-xs font-medium text-fg-2">ยอดคูปอง (บาท) *</span><input type="number" inputMode="decimal" className={inp+" tnum"} value={f.amount} onChange={(e)=>set("amount",e.target.value)} placeholder="0"/></label>
        <label className="block"><span className="text-xs font-medium text-fg-2">จำนวนใบ (batch)</span><input type="number" min="1" max="500" className={inp+" tnum"} value={f.batchCount} onChange={(e)=>set("batchCount",e.target.value)}/></label>
        <label className="block"><span className="text-xs font-medium text-fg-2">ใช้ได้กี่ครั้ง/ใบ</span><input type="number" min="1" className={inp+" tnum"} value={f.maxUses} onChange={(e)=>set("maxUses",e.target.value)}/></label>
        <label className="block"><span className="text-xs font-medium text-fg-2">ต่อ 1 คน</span><input type="number" min="0" className={inp+" tnum"} value={f.maxUsesPerUser} onChange={(e)=>set("maxUsesPerUser",e.target.value)}/></label>
        <label className="block"><span className="text-xs font-medium text-fg-2">ประเภทสมาชิก</span>
          <select className={inp} value={f.memberType} onChange={(e)=>set("memberType",e.target.value)}><option value="all">ทุกคน</option><option value="new">สมาชิกใหม่</option><option value="existing">สมาชิกเก่า</option></select></label>
        <label className="block"><span className="text-xs font-medium text-fg-2">ชนิดเทิร์น</span>
          <select className={inp} value={f.turnoverType} onChange={(e)=>set("turnoverType",e.target.value)}><option value="deposit">โอเวอร์ (เดิมพัน)</option><option value="credit">เครดิต</option><option value="revolving">หมุนเวียน</option><option value="fixed">ระบุจำนวน</option></select></label>
        <label className="block"><span className="text-xs font-medium text-fg-2">ตัวคูณเทิร์น (เท่า)</span><input type="number" min="0" className={inp+" tnum"} value={f.turnoverMultiplier} onChange={(e)=>set("turnoverMultiplier",e.target.value)} placeholder="0 = ไม่มีเทิร์น"/></label>
        <label className="block"><span className="text-xs font-medium text-fg-2">ถอนสูงสุด (บาท)</span><input type="number" min="0" className={inp+" tnum"} value={f.maxWithdraw} onChange={(e)=>set("maxWithdraw",e.target.value)} placeholder="0 = ไม่จำกัด"/></label>
        <label className="block"><span className="text-xs font-medium text-fg-2">วันหมดอายุ</span><input type="datetime-local" className={inp} value={f.expiresAt} onChange={(e)=>set("expiresAt",e.target.value)}/></label>
      </div>
      <label className="mt-3 flex items-center gap-2 text-sm"><input type="checkbox" checked={f.canWithdraw} onChange={(e)=>set("canWithdraw",e.target.checked)} className="h-4 w-4 accent-[var(--accent)]"/><span className="text-fg-2">ถอนได้เมื่อครบเทิร์น</span></label>
      <div className="mt-4 flex items-center justify-end gap-2">
        <button onClick={onClose} className="h-9 rounded-lg border border-line bg-surface px-3 text-sm font-medium text-fg-2 hover:bg-sunken">ยกเลิก</button>
        <button disabled={busy} onClick={submit} className="h-9 rounded-lg bg-accent px-4 text-sm font-semibold text-accent-fg hover:bg-accent-h disabled:opacity-50">{busy?"กำลังทำ…":"สร้าง"}</button>
      </div>
    </div>
  </div>);
}
function CodesPage({ toast }) {
  const [rows,setRows]=useState([]),[loading,setLoading]=useState(true),[err,setErr]=useState(null);
  const [q,setQ]=useState(""),[addOpen,setAddOpen]=useState(false),[busyId,setBusyId]=useState(null),[expanded,setExpanded]=useState(()=>new Set());
  const [page,setPage]=useState(1),[size,setSize]=useState(50);
  const load=useCallback(async()=>{ setLoading(true); setErr(null);
    try{ const d=await api("/deposit-codes"); setRows(Array.isArray(d)?d:[]); }
    catch(e){ if(e.status===401||e.status===403){window.__nxAuthFail&&window.__nxAuthFail();} setErr(e.status===403?"ไม่มีสิทธิ์จัดการคูปอง":(e.message||"โหลดไม่สำเร็จ")); }
    finally{ setLoading(false); } },[]);
  useEffect(()=>{ load(); },[load]);
  const groups=useMemo(()=>{
    const grouped=new Map();
    rows.forEach(c=>{
      const key=c.batch_id?"batch:"+c.batch_id:"code:"+c.id;
      if(!grouped.has(key))grouped.set(key,{key,batchId:c.batch_id||null,codes:[]});
      grouped.get(key).codes.push(c);
    });
    const search=q.trim().toLowerCase();
    return [...grouped.values()].filter(g=>!search||g.codes.some(c=>String(c.code||"").toLowerCase().includes(search)||String(c.name||"").toLowerCase().includes(search)))
      .sort((a,b)=>new Date(b.codes[0]?.created_at||0)-new Date(a.codes[0]?.created_at||0));
  },[rows,q]);
  useEffect(()=>{ setPage(1); },[q,rows.length]);
  const paged=groups.slice((page-1)*size,page*size);
  const deact=async(c)=>{ if(!window.confirm("ปิดใช้งานคูปอง "+c.code+"?"))return; setBusyId(String(c.id));
    try{ await api("/deposit-codes/"+c.id+"/deactivate",{method:"PATCH",body:{}}); toast("ปิดคูปองแล้ว"); load(); }catch(e){ toast(e.message||"ไม่สำเร็จ"); }finally{ setBusyId(null); } };
  const del=async(c)=>{ if(!window.confirm("ลบคูปอง "+c.code+" ถาวร?"))return; setBusyId(String(c.id));
    try{ await api("/deposit-codes/"+c.id,{method:"DELETE"}); toast("ลบแล้ว"); load(); }catch(e){ toast(e.message||"ไม่สำเร็จ"); }finally{ setBusyId(null); } };
  const toggleBatch=async(g)=>{ const active=g.codes.some(c=>c.is_active!==false),action=active?"ปิด":"เปิด";
    if(!window.confirm(action+"คูปองทั้งชุด "+(g.codes[0]?.name||g.batchId)+"?"))return;
    setBusyId(String(g.batchId));
    try{await api("/deposit-codes/batch/"+g.batchId+"/toggle",{method:"PATCH",body:{active:!active}});toast(action+"คูปองทั้งชุดแล้ว");load();}
    catch(e){toast(e.message||"ไม่สำเร็จ");}finally{setBusyId(null);}
  };
  const renameBatch=async(g)=>{const current=g.codes[0]?.name||"",name=window.prompt("ตั้งชื่อแคมเปญคูปอง",current);if(name===null)return;
    setBusyId(String(g.batchId));
    try{await api("/deposit-codes/batch/"+g.batchId+"/rename",{method:"PATCH",body:{name}});toast("เปลี่ยนชื่อแคมเปญแล้ว");load();}
    catch(e){toast(e.message||"ไม่สำเร็จ");}finally{setBusyId(null);}
  };
  const addToBatch=async(g)=>{const raw=window.prompt("จำนวนโค้ดที่ต้องการเพิ่ม (1-500)","10");if(raw===null)return;
    const count=Number(raw);if(!Number.isInteger(count)||count<1||count>500){toast("ระบุจำนวนโค้ดเป็นจำนวนเต็ม 1-500");return;}
    setBusyId(String(g.batchId));
    try{const r=await api("/deposit-codes/batch/"+g.batchId+"/add",{method:"POST",body:{count}});toast("เพิ่ม "+Number(r.added||count)+" โค้ดแล้ว");load();}
    catch(e){toast(e.message||"ไม่สำเร็จ");}finally{setBusyId(null);}
  };
  const deleteBatch=async(g)=>{if(!window.confirm("นำแคมเปญนี้ออกจากรายการ? โค้ดที่มีประวัติใช้งานจะถูกปิดและเก็บไว้"))return;
    setBusyId(String(g.batchId));
    try{await api("/deposit-codes/batch/"+g.batchId,{method:"DELETE"});toast("ลบแคมเปญแล้ว");load();}
    catch(e){toast(e.message||"ไม่สำเร็จ");}finally{setBusyId(null);}
  };
  const toggleExpanded=(key)=>setExpanded(s=>{const n=new Set(s);n.has(key)?n.delete(key):n.add(key);return n;});
  const H=({children,extra=""})=>(<th className={"whitespace-nowrap px-3 py-2.5 text-left text-[13px] font-bold text-fg-2 "+extra}>{children}</th>);
  const codeRow=(c)=><tr key={c.id} className="border-b border-line-soft last:border-0 hover:bg-sunken/50">
    <td className="px-3 py-2.5"><div className="truncate mono font-semibold text-fg">{c.code}</div></td>
    <td className="whitespace-nowrap px-3 text-right tnum">{money2(c.amount)}</td>
    <td className="whitespace-nowrap px-3 text-right text-fg-2">{Number(c.turnover_multiplier||0)>0?Number(c.turnover_multiplier)+(c.turnover_type==="fixed"?" บาท":"×")+" "+(CODE_TURN[c.turnover_type]||c.turnover_type||""):"ไม่มี"}</td>
    <td className="whitespace-nowrap px-3 text-right tnum text-muted">{Number(c.uses||0)}/{Number(c.max_uses||0)}</td>
    <td className="px-3 text-xs text-fg-2">{CODE_MEMBER[c.member_type]||c.member_type||"ทุกคน"}</td>
    <td className="px-3 text-xs text-fg-2">{c.expires_at?fmtDT(c.expires_at):"ไม่จำกัด"}</td>
    <td className="px-3"><Badge tone={codeStatus(c).c}>{codeStatus(c).t}</Badge></td>
    <td className="pr-4"><div className="flex items-center justify-end gap-1">
      {c.is_active!==false&&<button disabled={String(busyId)===String(c.id)} title="ปิดใช้งาน" onClick={()=>deact(c)} className="grid h-7 w-7 place-items-center rounded-lg border hover:bg-sunken disabled:opacity-50" style={{borderColor:"var(--warn)",color:"var(--warn)"}}><Ic d={I.ban} size={14}/></button>}
      <button disabled={String(busyId)===String(c.id)} title="ลบ" onClick={()=>del(c)} className="grid h-7 w-7 place-items-center rounded-lg border hover:bg-sunken disabled:opacity-50" style={{borderColor:"var(--danger)",color:"var(--danger)"}}><Ic d={I.trash} size={14}/></button>
    </div></td>
  </tr>;
  return (<div className="space-y-3">
    <div className="flex flex-wrap items-center gap-2">
      <div className="relative flex-1 sm:max-w-xs"><span className="pointer-events-none absolute left-3 top-1/2 -translate-y-1/2 text-muted"><Ic d={I.search} size={16}/></span>
        <input value={q} onChange={(e)=>setQ(e.target.value)} placeholder="ค้นหา โค้ด / ชื่อชุด…" className="h-9 w-full rounded-lg border border-line bg-surface pl-9 pr-3 text-sm text-fg placeholder:text-faint focus:border-accent focus:outline-none focus:ring-4 focus:ring-[var(--accent-ring)]"/></div>
      <button onClick={load} className="flex h-9 items-center gap-1.5 rounded-lg border border-line bg-surface px-3 text-sm font-medium text-fg-2 hover:bg-sunken"><Ic d={I.refresh} size={16} cls={loading?"animate-spin":""}/> รีเฟรช</button>
      <button onClick={()=>setAddOpen(true)} className="flex h-9 items-center gap-1.5 rounded-lg bg-accent px-3.5 text-sm font-semibold text-accent-fg shadow-sm hover:bg-accent-h"><Ic d={I.plus} size={17} sw={2}/> สร้างคูปอง</button>
      <div className="ml-auto hidden text-xs text-muted sm:block tnum">{groups.length} แคมเปญ · {rows.length} ใบ</div>
    </div>
    {err ? <HistErr msg={err} onRetry={load}/>
    : (<div className="overflow-hidden rounded-xl border border-line bg-surface shadow-sm"><div className="overflow-x-auto"><table className="w-full min-w-[1040px] border-collapse text-sm">
      <thead className="border-b-2 border-accent/25 bg-accent-soft"><tr>{H({children:"แคมเปญ / คูปอง"})}{H({children:"จำนวน",extra:"text-right"})}{H({children:"ยอด/ใบ",extra:"text-right"})}{H({children:"เทิร์น"})}{H({children:"ใช้แล้ว/ทั้งหมด",extra:"text-right"})}{H({children:"ประเภทสมาชิก"})}{H({children:"สถานะ"})}{H({children:"จัดการ",extra:"text-right pr-4"})}</tr></thead>
      <tbody>
        {loading ? Array.from({length:8}).map((_,i)=>(<tr key={i} className="border-b border-line-soft"><td className="px-3 py-3" colSpan="8"><div className="skel h-5 w-full"/></td></tr>))
          : groups.length===0 ? (<tr><td colSpan="8" className="px-4 py-16 text-center text-sm font-medium text-fg-2">ยังไม่มีคูปอง</td></tr>)
          : paged.map(g=>{
            const first=g.codes[0],isBatch=!!g.batchId,active=g.codes.some(c=>c.is_active!==false);
            const uses=g.codes.reduce((n,c)=>n+Number(c.uses||0),0),maxUses=g.codes.reduce((n,c)=>n+Number(c.max_uses||0),0);
            const statuses=g.codes.map(codeStatus),sameStatus=statuses.every(s=>s.t===statuses[0].t);
            const status=isBatch?(sameStatus?statuses[0]:{t:"หลายสถานะ",c:"warn"}):statuses[0];
            const isExpanded=expanded.has(g.key),groupBusy=String(busyId)===String(g.batchId);
            return (<React.Fragment key={g.key}>
              <tr className="border-b border-line-soft transition-colors hover:bg-sunken/50">
                <td className="px-3 py-2.5"><div className="min-w-0"><div className="truncate font-semibold text-fg">{isBatch?(first.name||"แคมเปญไม่มีชื่อ"):first.code}</div><div className="truncate text-[11px] text-faint">{isBatch?("ชุด "+String(g.batchId).slice(0,8)+" · "+g.codes.length+" โค้ด"):(first.name||"คูปองเดี่ยว")}</div></div></td>
                <td className="px-3 text-right tnum">{g.codes.length}</td>
                <td className="px-3 text-right tnum">{money2(first.amount)}</td>
                <td className="whitespace-nowrap px-3 text-right text-xs text-fg-2">{Number(first.turnover_multiplier||0)>0?Number(first.turnover_multiplier)+(first.turnover_type==="fixed"?" บาท":"×")+" "+(CODE_TURN[first.turnover_type]||first.turnover_type||""):"ไม่มี"}</td>
                <td className="px-3 text-right tnum text-muted">{uses}/{maxUses}</td>
                <td className="px-3 text-xs text-fg-2">{CODE_MEMBER[first.member_type]||first.member_type||"ทุกคน"}</td>
                <td className="px-3"><Badge tone={status.c}>{status.t}</Badge></td>
                <td className="pr-4"><div className="flex items-center justify-end gap-1">
                  {isBatch&&<>
                    <button disabled={groupBusy} title={active?"ปิดทั้งชุด":"เปิดทั้งชุด"} onClick={()=>toggleBatch(g)} className="grid h-7 w-7 place-items-center rounded-lg border border-line hover:bg-sunken disabled:opacity-50"><Ic d={active?I.ban:I.check} size={14}/></button>
                    <button disabled={groupBusy} title="เปลี่ยนชื่อแคมเปญ" onClick={()=>renameBatch(g)} className="grid h-7 w-7 place-items-center rounded-lg border border-line hover:bg-sunken disabled:opacity-50"><Ic d={I.edit} size={14}/></button>
                    <button disabled={groupBusy} title="เพิ่มโค้ดในชุด" onClick={()=>addToBatch(g)} className="grid h-7 w-7 place-items-center rounded-lg border border-line hover:bg-sunken disabled:opacity-50"><Ic d={I.plus} size={14}/></button>
                    <button disabled={groupBusy} title="ลบทั้งชุด" onClick={()=>deleteBatch(g)} className="grid h-7 w-7 place-items-center rounded-lg border hover:bg-sunken disabled:opacity-50" style={{borderColor:"var(--danger)",color:"var(--danger)"}}><Ic d={I.trash} size={14}/></button>
                  </>}
                  <button title={isExpanded?"ซ่อนโค้ด":"ดูโค้ดในชุด"} onClick={()=>toggleExpanded(g.key)} className="grid h-7 w-7 place-items-center rounded-lg border border-line hover:bg-sunken"><Ic d={I.chevD} size={14} cls={isExpanded?"rotate-180":""}/></button>
                </div></td>
              </tr>
              {isExpanded&&<tr className="border-b border-line"><td colSpan="8" className="bg-sunken/40 p-0"><div className="overflow-x-auto">
                <table className="w-full min-w-[760px] border-collapse text-xs">
                  <thead><tr className="border-b border-line text-muted"><th className="px-4 py-2 text-left">โค้ด</th><th className="px-3 py-2 text-right">ยอด</th><th className="px-3 py-2 text-right">เทิร์น</th><th className="px-3 py-2 text-right">ใช้แล้ว</th><th className="px-3 py-2 text-left">สมาชิก</th><th className="px-3 py-2 text-left">หมดอายุ</th><th className="px-3 py-2 text-left">สถานะ</th><th className="px-4 py-2 text-right">จัดการ</th></tr></thead>
                  <tbody>{g.codes.map(codeRow)}</tbody>
                </table>
              </div></td></tr>}
            </React.Fragment>);
          })}
      </tbody>
    </table></div>{!loading && !err && <Pager page={page} setPage={setPage} total={groups.length} size={size} setSize={setSize}/>}</div>)}
    {addOpen && <CodeCreateModal onClose={()=>setAddOpen(false)} onDone={load} toast={toast}/>}
  </div>);
}
