/* ==========================================================================
 * ADMIN NEXT — page-autopeer.jsx  (พอร์ตจากแอดมินเดิม: รายงาน Autopeer + การ์ด Wallet/สำรองถอน)
 *   - AutopeerPage            หน้ารายงาน Autopeer (สิทธิ์ tool_autopeer) — tools.js / deposits.js เดิม
 *   - AutopeerDepositsPanel   ตารางรายการ + ตัวกรอง ใช้ร่วมกับแท็บ "รายการ Autopeer" ในหน้า Payment
 *   - AutopeerProviderCard    การ์ดยอด Wallet + ปุ่มสร้างรายการสำรองถอน (หน้า Payment) — payments.js เดิม
 * API: GET /autopeer-deposits, POST /autopeer-deposits/:id/sync, /autopeer-deposits/ref/:ref/{extend,retrigger,logs},
 *      GET /autopeer-withdrawals, POST /autopeer-withdrawals/approve, GET /autopeer/summary,
 *      GET /payment-provider-accounts, POST /autopeer/reserve-withdraw
 * ========================================================================== */

const AP_STATUS = {
  success:{t:"สำเร็จ",c:"success"}, rejected:{t:"ปฏิเสธ",c:"danger"},
  timeout:{t:"หมดเวลา",c:"warn"}, pending:{t:"รอดำเนินการ",c:"info"},
};
const AP_STATUS_TABS = [["","ทั้งหมด"],["success","สำเร็จ"],["pending","รอดำเนินการ"],["rejected","ปฏิเสธ"],["timeout","หมดเวลา"]];
const apStatus = (s)=> AP_STATUS[s] || {t:s||"-",c:"danger"};
const AP_LOGO = "/admin/assets/autopeer-logo.png";

const AP_PAGE_TABS = [["deposit","รายการฝาก"],["withdraw","รายการถอน"]];
function AutopeerPage({ toast }) {
  const [tab,setTab]=useState("deposit");
  return (<div className="space-y-4">
    <AutopeerSummary/>
    <div className="flex w-fit items-center gap-1 rounded-lg border border-line bg-sunken p-1">
      {AP_PAGE_TABS.map(([k,l])=>(<button key={k} onClick={()=>setTab(k)} className={"rounded-md px-3 py-1.5 text-xs font-semibold transition-colors "+(tab===k?"bg-accent text-accent-fg shadow-sm":"text-fg-2 hover:text-fg")}>{l}</button>))}
    </div>
    {tab==="deposit" ? <AutopeerDepositsPanel toast={toast} mode="report"/> : <AutopeerWithdrawalsPanel toast={toast}/>}
  </div>);
}
const apBaht = (n)=>Number(n||0).toLocaleString("th-TH",{minimumFractionDigits:2,maximumFractionDigits:2})+" บาท";
const apRefOf = (r)=>String((r&&(r.ref||r.ref_id))||"").replace(/^AP_/,"");

/* สรุปบนหน้ารายงาน: เครดิตคงเหลือ (บาท จาก Autopeer) + ยอดฝาก / ยอดถอน แยกกัน ตามช่วงวันที่ */
const AP_SUM_RANGES=[["today","วันนี้"],["yesterday","เมื่อวาน"],["7d","7 วัน"],["30d","30 วัน"],["month","เดือนนี้"]];
function AutopeerSummary() {
  const [range,setRange]=useState("today"),[d,setD]=useState(null),[loading,setLoading]=useState(true),[err,setErr]=useState(null);
  const load=useCallback(async(rg)=>{ setLoading(true); setErr(null);
    try{ const {from,to}=rangeToDates(rg); setD(await api("/autopeer/summary?"+new URLSearchParams({from,to}).toString())); }
    catch(e){ setErr(e.message||"โหลดสรุปไม่สำเร็จ"); } finally{ setLoading(false); } },[]);
  useEffect(()=>{ load(range); },[range,load]);
  const bahtText=(n)=>Number(n).toLocaleString("th-TH",{minimumFractionDigits:2,maximumFractionDigits:2})+" บาท";
  const Card=({label,value,sub,color})=>(<div className="rounded-xl border border-line bg-surface p-3 shadow-sm">
    <div className="text-[11px] font-semibold text-muted">{label}</div>
    {loading?<div className="skel mt-1.5 h-6 w-28"/>:<div className="mt-1 text-lg font-semibold tnum" style={{color}}>{value}</div>}
    {!loading&&sub&&<div className="text-[11px] text-faint">{sub}</div>}
  </div>);
  return (<div className="space-y-2">
    <div className="flex flex-wrap items-center gap-2">
      <div className="flex flex-wrap gap-1 rounded-lg bg-sunken p-1">{AP_SUM_RANGES.map(([k,l])=>(<button key={k} onClick={()=>setRange(k)} className={"rounded-md px-3 py-1 text-xs font-semibold transition-colors "+(range===k?"bg-accent text-accent-fg shadow-sm":"text-fg-2 hover:text-fg")}>{l}</button>))}</div>
      <button onClick={()=>load(range)} className="grid h-8 w-8 place-items-center rounded-lg border border-line bg-surface text-fg-2 hover:bg-sunken"><Ic d={I.refresh} size={15} cls={loading?"animate-spin":""}/></button>
      {err&&<span className="text-xs text-danger">{err}</span>}
    </div>
    <div className="grid grid-cols-1 gap-3 sm:grid-cols-3">
      {Card({label:"เครดิตคงเหลือ (Autopeer)",value:d&&d.wallet!=null?bahtText(d.wallet):"-",sub:"ยอดปัจจุบัน",color:d&&N(d.wallet)>0?"var(--success)":"var(--danger)"})}
      {Card({label:d&&d.deposit.source==="local"?"ยอดรวมฝาก (ข้อมูลในระบบ — เรียก Autopeer ไม่ได้)":"ยอดรวมฝาก (Autopeer ยืนยัน)",value:money2(d&&d.deposit.total),sub:d?N(d.deposit.count).toLocaleString("th-TH")+" รายการ":"",color:"var(--success)"})}
      {Card({label:"ยอดรวมถอน (จ่ายแล้ว)",value:money2(d&&d.withdraw.total),sub:d?N(d.withdraw.count).toLocaleString("th-TH")+" รายการ"+(N(d.withdraw.pendingCount)?" · รอถอน "+money2(d.withdraw.pendingTotal)+" ("+d.withdraw.pendingCount+")":""):"",color:"var(--danger)"})}
    </div>
  </div>);
}

/* mode="report"  = หน้ารายงานเดิม: ค้นหา + ปุ่มซิงก์ ไม่จำกัดวันที่
   mode="payment" = แท็บในหน้า Payment: กรองวันที่ + เลือกจำนวน + การ์ดสรุป 4 ใบ */
function AutopeerDepositsPanel({ toast, mode="report" }) {
  const isPay = mode==="payment";
  const today = bkkDate(0);
  const [status,setStatus]=useState("");
  const [q,setQ]=useState("");
  const [from,setFrom]=useState(isPay?today:"");
  const [to,setTo]=useState(isPay?today:"");
  const [limit,setLimit]=useState(isPay?50:300);
  const [rows,setRows]=useState([]);
  const [loading,setLoading]=useState(true);
  const [err,setErr]=useState(null);
  const [syncing,setSyncing]=useState(null);
  const debRef=useRef(null);

  const load=useCallback(async(query)=>{ setLoading(true); setErr(null);
    try{
      const p=new URLSearchParams({limit:String(limit)});
      if(status) p.set("status",status);
      if(query) p.set("q",query);
      if(from&&to&&from===to) p.set("date",from);
      else { if(from) p.set("from",from); if(to) p.set("to",to); }
      const d=await api("/autopeer-deposits?"+p.toString());
      setRows(Array.isArray(d)?d:(d&&d.rows)||[]);
    }catch(e){ if(e.status===401||e.status===403){window.__nxAuthFail?.();} setErr(e.message||"โหลดรายการ Autopeer ไม่สำเร็จ"); }
    finally{ setLoading(false); } },[status,from,to,limit]);
  useEffect(()=>{ load(q.trim()); },[load]);
  const firstQ=useRef(true);
  useEffect(()=>{ if(firstQ.current){ firstQ.current=false; return; }
    if(debRef.current) clearTimeout(debRef.current); debRef.current=setTimeout(()=>load(q.trim()),300); return ()=>clearTimeout(debRef.current); },[q]);

  const sync=async(id)=>{ setSyncing(id);
    try{
      const out=await api("/autopeer-deposits/"+encodeURIComponent(id)+"/sync",{method:"POST",body:{}});
      toast(out&&(out.credited||out.status==="success")?"ซิงก์สำเร็จ":"ยังไม่พบยอดสำเร็จ");
      load(q.trim());
    }catch(e){ toast(e.message||"ซิงก์ Autopeer ไม่สำเร็จ"); }
    finally{ setSyncing(null); } };

  const [act,setAct]=useState(null); // { type:"extend"|"logs", row }
  const [nudging,setNudging]=useState(null);
  const retrigger=async(r)=>{ const ref=apRefOf(r); setNudging(ref);
    try{ await api("/autopeer-deposits/ref/"+encodeURIComponent(ref)+"/retrigger",{method:"POST",body:{}}); toast("ส่งคำสั่งให้ Autopeer ตรวจรายการนี้ใหม่แล้ว"); load(q.trim()); }
    catch(e){ toast(e.message||"กระตุ้นรายการไม่สำเร็จ"); }
    finally{ setNudging(null); } };

  const sum=(arr)=>arr.reduce((a,r)=>a+N(r.amount),0);
  const success=rows.filter(r=>r.status==="success"), pending=rows.filter(r=>r.status==="pending");
  const other=rows.filter(r=>r.status!=="success"&&r.status!=="pending");
  const canSync=can("tool_autopeer");
  const inp="h-9 rounded-lg border border-line bg-surface px-3 text-sm";

  return (<div className="space-y-4">
    <div className="flex flex-wrap items-center gap-2">
      <div className="flex flex-wrap gap-1 rounded-lg bg-sunken p-1">
        {AP_STATUS_TABS.map(([k,l])=>(<button key={k} onClick={()=>setStatus(k)} className={"rounded-md px-3 py-1.5 text-xs font-semibold transition-colors "+(status===k?"bg-accent text-accent-fg shadow-sm":"text-fg-2 hover:text-fg")}>{l}</button>))}
      </div>
      {isPay&&<>
        <input type="date" value={from} onChange={e=>setFrom(e.target.value)} className={inp}/>
        <input type="date" value={to} onChange={e=>setTo(e.target.value)} className={inp}/>
        <button onClick={()=>{setFrom(today);setTo(today);}} className="h-9 rounded-lg border border-line bg-surface px-3 text-xs font-medium text-fg-2 hover:bg-sunken">วันนี้</button>
        <button onClick={()=>{setFrom("");setTo("");}} className="h-9 rounded-lg border border-line bg-surface px-3 text-xs font-medium text-fg-2 hover:bg-sunken">ทั้งหมด</button>
        <select value={limit} onChange={e=>setLimit(Number(e.target.value))} className={inp}>{[50,100,200,500].map(n=><option key={n} value={n}>{n} รายการ</option>)}</select>
      </>}
      <input value={q} onChange={e=>setQ(e.target.value)} placeholder="ค้นหา username / เบอร์ / ref" className={inp+" min-w-0 flex-1 sm:max-w-xs"}/>
      <button onClick={()=>load(q.trim())} 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>
    </div>

    {isPay ? (<div className="grid grid-cols-2 gap-3 lg:grid-cols-4">
      {[["ยอดนำเข้าทั้งหมด",sum(rows),"info"],["ยอดทำรายการสำเร็จ",sum(success),"success"],["ยอดค้าง/รอ",sum(pending),"warn"],["ยอดรายการอื่น ๆ",sum(other),"danger"]].map(([l,v,c])=>(
        <div key={l} className="rounded-xl border border-line bg-surface p-3 shadow-sm">
          <div className="text-[11px] font-semibold text-muted">{l}</div>
          <div className="mt-1 text-base font-semibold tnum" style={{color:`var(--${c})`}}>{money2(v)}</div>
        </div>))}
    </div>) : (!loading&&!err&&<div className="text-xs text-muted tnum">พบ {rows.length.toLocaleString("th-TH")} รายการ · ยอดรวม {money2(sum(rows))}</div>)}

    {err ? <HistErr msg={err} onRetry={()=>load(q.trim())}/> : loading ? (
      <div className="flex items-center justify-center gap-2 py-16 text-sm text-muted"><Ic d={I.refresh} size={16} cls="animate-spin"/> กำลังโหลด…</div>
    ) : (<div className="overflow-x-auto rounded-xl border border-line bg-surface shadow-sm">
      <table className="w-full text-sm">
        <thead><tr className="border-b border-line bg-sunken/60 text-left text-xs font-semibold text-muted">
          <th className="px-4 py-3">เวลา</th><th className="px-4 py-3">สมาชิก</th><th className="px-4 py-3">บัญชีลูกค้า</th>
          <th className="px-4 py-3 text-right">ค่าธรรมเนียม</th><th className="px-4 py-3 text-right">ยอด</th>
          <th className="px-4 py-3">สถานะ</th><th className="px-4 py-3">Ref</th><th className="px-4 py-3 text-right">จัดการ</th>
        </tr></thead>
        <tbody>{rows.length===0?(<tr><td colSpan={8} className="px-4 py-12 text-center text-muted">ไม่มีรายการ</td></tr>):rows.map((r,i)=>{
          const st=apStatus(r.status); const id=r.local_id||r.id;
          const acctNo=r.user_bank_account_no||r.account_no;
          return (<tr key={(id||"")+"-"+i} className="border-b border-line last:border-0 hover:bg-sunken/40">
            <td className="whitespace-nowrap px-4 py-3 text-xs text-muted">{fmtDT(r.created_at)}</td>
            <td className="px-4 py-3">
              <div className="flex items-center gap-2">
                <img src={AP_LOGO} alt="" onError={e=>{e.target.style.display="none";}} className="h-7 w-7 shrink-0 rounded-full object-cover"/>
                <div className="min-w-0"><div className="font-medium">{r.username||r.full_name||"-"}</div>
                  <div className="text-[11px] text-muted">{[r.full_name&&r.full_name!==r.username?r.full_name:"",r.phone].filter(Boolean).join(" · ")}</div></div>
              </div>
            </td>
            <td className="px-4 py-3">
              {acctNo ? (<div className="flex items-center gap-2">
                {r.user_bank_code&&<BankLogo code={r.user_bank_code} size={22}/>}
                <div className="min-w-0"><div className="mono text-xs">{[r.user_bank_code?bankName(r.user_bank_code):r.bank_name,acctNo].filter(Boolean).join(" ")}</div>
                  {r.user_bank_account_name&&<div className="text-[11px] text-muted">{r.user_bank_account_name}</div>}</div>
              </div>) : <span className="text-muted">-</span>}
            </td>
            <td className="px-4 py-3 text-right tnum text-muted">{N(r.fee_amount)?money2(r.fee_amount):"-"}</td>
            <td className="px-4 py-3 text-right font-semibold tnum">{money2(r.amount)}</td>
            <td className="px-4 py-3"><Badge tone={st.c}>{st.t}</Badge></td>
            <td className="px-4 py-3 mono text-[11px] text-muted">{r.ref_id||"-"}</td>
            <td className="px-4 py-3 text-right"><div className="flex items-center justify-end gap-1">
              {r.status==="pending"&&r.can_sync&&canSync&&<button onClick={()=>sync(id)} disabled={syncing===id} className={AP_ACT_BTN}><Ic d={I.refresh} size={14} cls={syncing===id?"animate-spin":""}/> ซิงก์</button>}
              {r.status==="pending"&&canSync&&apRefOf(r)&&<>
                <button onClick={()=>setAct({type:"extend",row:r})} title="ต่อเวลาให้ลูกค้าโอน/อัปสลิป" className={AP_ACT_BTN}><Ic d={I.clock} size={14}/> ต่อเวลา</button>
                <button onClick={()=>retrigger(r)} disabled={nudging===apRefOf(r)} title="ให้ Autopeer ตรวจรายการที่ค้างใหม่" className={AP_ACT_BTN}>กระตุ้น</button>
              </>}
              {apRefOf(r)&&<button onClick={()=>setAct({type:"logs",row:r})} title="ประวัติสถานะใน Autopeer" className="grid h-8 w-8 place-items-center rounded-lg border border-line bg-surface text-fg-2 hover:bg-sunken"><Ic d={I.chart} size={14}/></button>}
            </div></td>
          </tr>); })}</tbody>
      </table>
    </div>)}
    {act&&act.type==="extend"&&<AutopeerExtendModal row={act.row} toast={toast} onClose={()=>setAct(null)} onDone={()=>{ setAct(null); load(q.trim()); }}/>}
    {act&&act.type==="logs"&&<AutopeerLogsModal row={act.row} onClose={()=>setAct(null)}/>}
  </div>);
}

const AP_ACT_BTN = "inline-flex h-8 items-center gap-1.5 rounded-lg border border-line bg-surface px-2.5 text-xs font-medium text-fg-2 transition-colors hover:bg-sunken disabled:opacity-50";
const AP_EXTEND_MINUTES = [5,10,15,30];

/* ต่อเวลารายการฝากที่ยังค้าง (/ext/bo/add-time-out) — ใช้แทนการอนุมัติมือ เมื่อลูกค้าบอกว่ากำลังโอน */
function AutopeerExtendModal({ row, toast, onClose, onDone }) {
  const [minutes,setMinutes]=useState(10), [saving,setSaving]=useState(false);
  const save=async()=>{ setSaving(true);
    try{ await api("/autopeer-deposits/ref/"+encodeURIComponent(apRefOf(row))+"/extend",{method:"POST",body:{minutes}}); toast("ต่อเวลา "+minutes+" นาทีแล้ว"); onDone(); }
    catch(e){ toast(e.message||"ต่อเวลาไม่สำเร็จ"); }
    finally{ setSaving(false); } };
  return (<ModalFrame title="ต่อเวลารายการฝาก Autopeer" onClose={onClose}
    note="ใช้เมื่อลูกค้ากำลังโอนแต่ใกล้หมดเวลา เครดิตจะเข้าเองเมื่อ Autopeer ยืนยัน ไม่ต้องอนุมัติมือ"
    footer={<><button onClick={save} disabled={saving} className="h-10 flex-1 rounded-lg bg-accent text-sm font-semibold text-accent-fg hover:bg-accent-h disabled:opacity-50">{saving?"กำลังต่อเวลา…":"ต่อเวลา "+minutes+" นาที"}</button>
      <button onClick={onClose} className="h-10 flex-1 rounded-lg border border-line bg-surface text-sm font-medium text-fg-2 hover:bg-sunken">ยกเลิก</button></>}>
    <div className="text-sm"><span className="font-semibold">{row.username||"-"}</span> · {money2(row.amount)} · <span className="mono text-xs text-muted">{apRefOf(row)}</span></div>
    <MField label="ต่อเวลาเพิ่ม">
      <div className="flex gap-2">{AP_EXTEND_MINUTES.map(m=>(<button key={m} onClick={()=>setMinutes(m)} className={"h-9 flex-1 rounded-lg border text-sm font-semibold transition-colors "+(minutes===m?"border-accent bg-accent text-accent-fg":"border-line bg-surface text-fg-2 hover:bg-sunken")}>{m} นาที</button>))}</div>
    </MField>
  </ModalFrame>);
}

/* ประวัติการเปลี่ยนสถานะของรายการใน Autopeer (/ext/bo/report-action-logs) */
function AutopeerLogsModal({ row, onClose }) {
  const [logs,setLogs]=useState(null), [err,setErr]=useState(null);
  useEffect(()=>{ let alive=true;
    api("/autopeer-deposits/ref/"+encodeURIComponent(apRefOf(row))+"/logs").then(d=>{ if(alive) setLogs(Array.isArray(d)?d:[]); }).catch(e=>{ if(alive) setErr(e.message||"โหลดประวัติไม่สำเร็จ"); });
    return ()=>{ alive=false; }; },[row]);
  return (<ModalFrame title={"ประวัติรายการ "+apRefOf(row)} onClose={onClose}
    footer={<button onClick={onClose} className="h-10 flex-1 rounded-lg border border-line bg-surface text-sm font-medium text-fg-2 hover:bg-sunken">ปิด</button>}>
    {err ? <div className="text-sm text-danger">{err}</div>
      : !logs ? <div className="skel h-16 w-full"/>
      : logs.length===0 ? <div className="py-6 text-center text-sm text-muted">ยังไม่มีการเปลี่ยนสถานะแบบแมนนวลใน Autopeer</div>
      : <div className="space-y-2">{logs.map((l,i)=>(<div key={i} className="flex items-center justify-between gap-3 rounded-lg border border-line px-3 py-2 text-xs">
          <div><span className="font-semibold">{l.action||"-"}</span> <span className="text-muted">{l.from||"-"} → {l.to||"-"}</span></div>
          <div className="text-right text-muted">{l.by||"-"}<br/>{fmtDT(l.at)}</div>
        </div>))}</div>}
  </ModalFrame>);
}

/* ---------- แท็บ "รายการถอน": รายการถอนฝั่ง Autopeer (report-manage SELLER) ---------- */
const AP_PEER_WD_STATUS = {
  PENDING:{t:"รอดำเนินการ",c:"info"}, EXTEND:{t:"ต่อเวลา",c:"info"}, SUCCESS:{t:"สำเร็จ",c:"success"},
  TIMEOUT:{t:"หมดเวลา",c:"warn"}, CANCEL:{t:"ยกเลิก",c:"danger"}, RETURN:{t:"คืนยอด",c:"warn"},
};
const AP_WD_TABS = [["","ทั้งหมด"],["PENDING","รอดำเนินการ"],["SUCCESS","สำเร็จ"],["TIMEOUT","หมดเวลา"],["CANCEL","ยกเลิก"]];
const AP_WD_APPROVABLE = ["PENDING","EXTEND","TIMEOUT"];
const apPeerWdStatus = (s)=> AP_PEER_WD_STATUS[s] || {t:s||"-",c:"info"};

function AutopeerWithdrawalsPanel({ toast }) {
  const [range,setRange]=useState("7d"), [status,setStatus]=useState("");
  const [rows,setRows]=useState([]), [loading,setLoading]=useState(true), [err,setErr]=useState(null);
  const [approveRow,setApproveRow]=useState(null);
  const load=useCallback(async()=>{ setLoading(true); setErr(null);
    try{ const {from,to}=rangeToDates(range); const p=new URLSearchParams({from,to,limit:"200"}); if(status) p.set("status",status);
      const d=await api("/autopeer-withdrawals?"+p.toString()); setRows((d&&d.rows)||[]); }
    catch(e){ setErr(e.message||"โหลดรายการถอน Autopeer ไม่สำเร็จ"); }
    finally{ setLoading(false); } },[range,status]);
  useEffect(()=>{ load(); },[load]);
  const canApprove=can("wdr");
  const pill=(active)=>"rounded-md px-3 py-1 text-xs font-semibold transition-colors "+(active?"bg-accent text-accent-fg shadow-sm":"text-fg-2 hover:text-fg");

  return (<div className="space-y-3">
    <div className="flex flex-wrap items-center gap-2">
      <div className="flex flex-wrap gap-1 rounded-lg bg-sunken p-1">{AP_WD_TABS.map(([k,l])=>(<button key={k||"all"} onClick={()=>setStatus(k)} className={pill(status===k)}>{l}</button>))}</div>
      <div className="flex flex-wrap gap-1 rounded-lg bg-sunken p-1">{AP_SUM_RANGES.map(([k,l])=>(<button key={k} onClick={()=>setRange(k)} className={pill(range===k)}>{l}</button>))}</div>
      <button onClick={load} className="grid h-8 w-8 place-items-center rounded-lg border border-line bg-surface text-fg-2 hover:bg-sunken"><Ic d={I.refresh} size={15} cls={loading?"animate-spin":""}/></button>
      {!loading&&!err&&<span className="ml-auto text-xs text-muted tnum">{rows.length.toLocaleString("th-TH")} รายการ</span>}
    </div>
    {err ? <HistErr msg={err} onRetry={load}/> : loading ? <div className="skel h-40 w-full"/> : (
    <div className="overflow-x-auto rounded-xl border border-line bg-surface shadow-sm">
      <table className="w-full min-w-[980px] text-sm">
        <thead><tr className="border-b border-line bg-sunken/60 text-left text-xs font-semibold text-muted">
          <th className="px-4 py-3">เวลา</th><th className="px-4 py-3">ผู้ถอน</th><th className="px-4 py-3">บัญชีรับ</th>
          <th className="px-4 py-3 text-right">ยอด</th><th className="px-4 py-3">โอนแล้ว / ต้องโอน</th>
          <th className="px-4 py-3">สถานะ Autopeer</th><th className="px-4 py-3">Ref</th><th className="px-4 py-3 text-right">จัดการ</th>
        </tr></thead>
        <tbody>{rows.length===0 ? (<tr><td colSpan={8} className="px-4 py-12 text-center text-muted">ไม่มีรายการถอนใน Autopeer ช่วงนี้</td></tr>) : rows.map(r=>{
          const st=apPeerWdStatus(r.status); const hasProg=r.paid!=null&&r.total;
          const remaining=hasProg?Math.max(0,r.total-r.paid):null;
          return (<tr key={r.ref} className="border-b border-line last:border-0 hover:bg-sunken/40">
            <td className="whitespace-nowrap px-4 py-3 text-xs text-muted">{fmtDT(r.createdAt)}</td>
            <td className="px-4 py-3"><div className="font-medium">{r.local?r.local.username:(r.username==="RESERVE"?"สำรองถอน":r.username||"-")}</div>
              {r.local&&<div className="text-[11px] text-muted">ในระบบ: {depStatus(r.local.status).t}</div>}</td>
            <td className="px-4 py-3"><div className="mono text-xs">{[r.bankName,r.accountNumber].filter(Boolean).join(" ")||"-"}</div>{r.accountName&&<div className="text-[11px] text-muted">{r.accountName}</div>}</td>
            <td className="px-4 py-3 text-right font-semibold tnum">{apBaht(r.amount)}</td>
            <td className="whitespace-nowrap px-4 py-3 text-xs tnum">{hasProg ? (<>
              <span className={r.paid>=r.total?"font-semibold text-success":"font-semibold text-warn"}>{apBaht(r.paid)} / {apBaht(r.total)}</span>
              {remaining>0&&<div className="text-[11px] text-muted">ค้าง {apBaht(remaining)}</div>}</>) : <span className="text-muted">-</span>}</td>
            <td className="px-4 py-3"><Badge tone={st.c}>{st.t}</Badge>{r.isManual&&<div className="mt-0.5 text-[10px] text-faint">ปิดแบบแมนนวล</div>}</td>
            <td className="px-4 py-3 mono text-[11px] text-muted">{r.ref}</td>
            <td className="px-4 py-3 text-right">{canApprove&&AP_WD_APPROVABLE.includes(r.status)&&r.id
              ? <button onClick={()=>setApproveRow(r)} className={AP_ACT_BTN}><Ic d={I.check} size={14}/> อนุมัติใน Autopeer</button>
              : <span className="text-muted">-</span>}</td>
          </tr>); })}</tbody>
      </table>
    </div>)}
    {approveRow&&<AutopeerApproveWithdrawModal row={approveRow} toast={toast} onClose={()=>setApproveRow(null)} onDone={()=>{ setApproveRow(null); load(); }}/>}
  </div>);
}

/* แอดมินโอนส่วนที่เหลือให้ลูกค้าเองแล้ว -> แจ้ง Autopeer ปิดรายการ (/ext/bo/approve-withdraw) แนบสลิปได้ */
function AutopeerApproveWithdrawModal({ row, toast, onClose, onDone }) {
  const [bankCode,setBankCode]=useState(""), [remark,setRemark]=useState(""), [slip,setSlip]=useState(""), [saving,setSaving]=useState(false);
  const banks=(typeof BANK_CODE_OPTIONS!=="undefined"?BANK_CODE_OPTIONS:[]);
  const remaining=row.paid!=null&&row.total?Math.max(0,row.total-row.paid):null;
  const pickSlip=(e)=>{ const f=e.target.files&&e.target.files[0]; if(!f) return setSlip("");
    if(f.size>6*1024*1024) { e.target.value=""; return toast("ไฟล์สลิปใหญ่เกิน 6MB"); }
    const rd=new FileReader(); rd.onload=()=>setSlip(String(rd.result||"")); rd.readAsDataURL(f); };
  const save=async()=>{ if(!bankCode) return toast("กรุณาเลือกธนาคารที่ใช้โอน");
    setSaving(true);
    try{ await api("/autopeer-withdrawals/approve",{method:"POST",body:{ref:row.ref,id:row.id,bankCode,slip:slip||undefined,remark:remark.trim()||undefined}});
      toast("แจ้ง Autopeer ปิดรายการถอนแล้ว"); onDone(); }
    catch(e){ toast(e.message||"อนุมัติใน Autopeer ไม่สำเร็จ"); }
    finally{ setSaving(false); } };
  const field="w-full rounded-lg border border-line bg-surface px-3 py-2 text-sm";
  return (<ModalFrame title="อนุมัติถอนใน Autopeer" onClose={onClose}
    note="กดเมื่อโอนเงินส่วนที่เหลือให้ลูกค้าเองเรียบร้อยแล้วเท่านั้น — Autopeer จะปิดรายการนี้ว่าสำเร็จ"
    footer={<><button onClick={save} disabled={saving} className="h-10 flex-1 rounded-lg bg-accent text-sm font-semibold text-accent-fg hover:bg-accent-h disabled:opacity-50">{saving?"กำลังส่ง…":"ยืนยันอนุมัติ"}</button>
      <button onClick={onClose} className="h-10 flex-1 rounded-lg border border-line bg-surface text-sm font-medium text-fg-2 hover:bg-sunken">ยกเลิก</button></>}>
    <div className="rounded-lg border border-line bg-sunken px-3 py-2 text-sm">
      <div className="font-semibold">{row.local?row.local.username:row.username} · {apBaht(row.amount)}</div>
      <div className="text-xs text-muted">{[row.bankName,row.accountNumber,row.accountName].filter(Boolean).join(" · ")}</div>
      {remaining!=null&&<div className="mt-1 text-xs tnum">Autopeer โอนแล้ว {apBaht(row.paid)} · <b className="text-warn">ต้องโอนเอง {apBaht(remaining)}</b></div>}
    </div>
    <MField label="ธนาคารที่ใช้โอน">
      <select value={bankCode} onChange={e=>setBankCode(e.target.value)} className={field}><option value="">-- เลือกธนาคาร --</option>{banks.map(([c,n])=><option key={c} value={c}>{n}</option>)}</select>
    </MField>
    <MField label="สลิปการโอน" hint="ไม่บังคับ">
      <input type="file" accept="image/png,image/jpeg,image/webp" onChange={pickSlip} className="block w-full text-xs text-fg-2"/>
    </MField>
    <MField label="หมายเหตุ" hint="ไม่บังคับ">
      <input value={remark} onChange={e=>setRemark(e.target.value)} maxLength={200} placeholder="เช่น โอนส่วนที่เหลือจาก KBANK" className={field}/>
    </MField>
  </ModalFrame>);
}

/* การ์ด Autopeer ในหน้า Payment > ผู้ให้บริการ */
function AutopeerProviderCard({ toast, onShowList }) {
  const [p,setP]=useState(null);
  const [loading,setLoading]=useState(true);
  const [err,setErr]=useState(null);
  const [form,setForm]=useState(null);
  const [saving,setSaving]=useState(false);

  const load=useCallback(async()=>{ setLoading(true); setErr(null);
    try{ const d=await api("/payment-provider-accounts"); setP(((d&&d.providers)||[]).find(x=>(x.provider||x.key)==="autopeer")||null); }
    catch(e){ setErr(e.message||"โหลดไม่สำเร็จ"); }
    finally{ setLoading(false); } },[]);
  useEffect(()=>{ load(); },[load]);

  // สวิตช์ระบบถอน Autopeer (setting autopeer_withdraw_enabled — ไม่ได้ตั้ง = เปิด) — null = ไม่มีสิทธิ์/โหลดไม่ได้ ซ่อนสวิตช์
  const [wdOn,setWdOn]=useState(null);
  const [wdSaving,setWdSaving]=useState(false);
  useEffect(()=>{ api("/settings").then(s=>setWdOn((s||{}).autopeer_withdraw_enabled!=="0")).catch(()=>setWdOn(null)); },[]);
  const toggleWithdraw=async()=>{
    if(wdSaving||wdOn==null) return;
    const next=!wdOn; setWdSaving(true);
    try{ await api("/settings",{method:"POST",body:{autopeer_withdraw_enabled:next?"1":"0"}}); setWdOn(next); toast(next?"เปิดระบบถอน Autopeer แล้ว":"ปิดระบบถอน Autopeer แล้ว"); }
    catch(e){ toast(e.message||"บันทึกไม่สำเร็จ"); }
    finally{ setWdSaving(false); } };

  const submit=async()=>{
    const amount=Number(form.amount);
    if(!amount||amount<=0) return toast("กรุณากรอกจำนวนเงิน");
    if(!form.bankCode) return toast("กรุณาเลือกธนาคาร");
    if(!form.accountNumber.trim()) return toast("กรุณากรอกเลขที่บัญชี");
    if(!form.accountName.trim()) return toast("กรุณากรอกชื่อบัญชี");
    setSaving(true);
    try{
      const r=await api("/autopeer/reserve-withdraw",{method:"POST",body:{amount,bankCode:form.bankCode,accountNumber:form.accountNumber.trim(),accountName:form.accountName.trim()}});
      toast("สร้างรายการสำเร็จ ยอด "+amount.toLocaleString("th-TH")+" บาท · Ref: "+((r&&r.result&&r.result.ref)||"-"));
      setForm(null); load();
    }catch(e){ toast(e.message||"สร้างรายการไม่สำเร็จ"); }
    finally{ setSaving(false); } };

  const wallet=p&&p.balance ? (p.balance.wallet??p.balance.balance??p.balance.amount??null) : null;
  const online=!!(p&&p.enabled&&p.configured&&!(p.errors&&p.errors.length));
  const banks=(typeof BANK_CODE_OPTIONS!=="undefined"?BANK_CODE_OPTIONS:[]);
  const field="w-full rounded-lg border border-line bg-surface px-3 py-2 text-sm";

  return (<div className="overflow-hidden rounded-xl border border-line bg-surface shadow-sm">
    <div className="flex items-center gap-3 border-b border-line px-4 py-3">
      <img src={AP_LOGO} alt="" onError={e=>{e.target.style.display="none";}} className="h-9 w-9 shrink-0 rounded-lg object-contain"/>
      <div className="min-w-0"><div className="text-sm font-semibold">Autopeer</div><div className="text-[11px] text-muted">P2C Gateway</div></div>
      <div className="ml-auto flex items-center gap-2">
        {!loading&&!err&&<Badge tone={online?"success":"danger"}>{online?"Online":"Offline"}</Badge>}
        <button onClick={load} className="grid h-8 w-8 place-items-center rounded-lg border border-line text-fg-2 hover:bg-sunken"><Ic d={I.refresh} size={15} cls={loading?"animate-spin":""}/></button>
      </div>
    </div>
    {p&&p.errors&&p.errors.length>0&&<div className="px-4 py-2 text-xs" style={{background:"var(--danger-soft)",color:"var(--danger)"}}>{p.errors.join(" · ")}</div>}
    <div className="flex flex-wrap items-center justify-between gap-3 border-b border-line px-4 py-3">
      <div className="min-w-0">
        <div className="text-[11px] font-semibold uppercase text-muted">เครดิตคงเหลือ</div>
        {loading ? <div className="skel mt-1 h-7 w-40"/>
          : err ? <div className="mt-1 text-sm text-danger">{err}</div>
          : wallet!=null ? <div className="mt-1 text-2xl font-semibold tnum" style={{color:N(wallet)>0?"var(--success)":"var(--danger)"}}>{Number(wallet).toLocaleString("th-TH",{minimumFractionDigits:2,maximumFractionDigits:2})} บาท</div>
          : <div className="mt-1 text-sm text-muted">ไม่มีข้อมูลยอด กดรีเฟรชเพื่อดูยอด</div>}
      </div>
      {wdOn!=null&&<label className="flex w-full cursor-pointer items-center justify-between gap-4 rounded-lg border border-line bg-sunken/40 px-3 py-2.5 hover:bg-sunken/60 sm:w-72">
        <div><span className="text-sm font-medium text-fg">ระบบถอน Autopeer</span><div className="text-[11px] text-muted">ส่งถอนอัตโนมัติ (ปลายทางธนาคาร)</div></div>
        <button type="button" role="switch" aria-checked={wdOn} disabled={wdSaving} onClick={toggleWithdraw}
          className={"relative inline-flex h-6 w-11 shrink-0 items-center rounded-full transition-colors disabled:opacity-60 "+(wdOn?"bg-accent":"bg-line")}>
          <span className={"inline-block h-5 w-5 rounded-full bg-white shadow transition-transform "+(wdOn?"translate-x-5":"translate-x-0.5")}/>
        </button>
      </label>}
    </div>
    <div className="space-y-3 px-4 py-3">
      <div className="text-xs text-muted">ยอดสะสมจากลูกค้าที่ฝากผ่าน Autopeer หากยอดถอนเกินให้กด <b className="text-fg-2">เพิ่มเงิน</b> เพื่อสร้างรายการให้ Peer โอนเข้าบัญชีเราเป็นยอดสำรอง</div>
      <div className="flex flex-wrap gap-2">
        {can("payment")&&<button onClick={()=>setForm({amount:"",bankCode:"",accountNumber:"",accountName:""})} className="flex h-9 items-center gap-1.5 rounded-lg bg-accent px-4 text-sm font-medium text-accent-fg hover:bg-accent-h"><Ic d={I.plus} size={16}/> เพิ่มเงิน (สำรองถอน)</button>}
        {onShowList&&<button onClick={onShowList} 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">ดูรายการ Autopeer <Ic d={I.chevR} size={14}/></button>}
      </div>
    </div>

    {form&&(<div className="fixed inset-0 z-50 flex items-center justify-center bg-black/40 p-4 fade-in" onClick={()=>!saving&&setForm(null)}>
      <div className="w-full max-w-md rounded-xl bg-surface p-6 shadow-lg pop" onClick={e=>e.stopPropagation()}>
        <h3 className="text-sm font-semibold">สร้างรายการสำรองถอน Autopeer</h3>
        <p className="mb-4 mt-1 text-xs text-muted">สร้างรายการให้ Peer โอนเงินเข้าบัญชีเรา เพื่อเติมยอดสำรองใน Autopeer P2C</p>
        <div className="mb-3"><label className="mb-1 block text-xs font-semibold text-fg-2">จำนวนเงิน (บาท)</label>
          <input type="number" min="1" step="0.01" value={form.amount} onChange={e=>setForm(f=>({...f,amount:e.target.value}))} placeholder="เช่น 100" className={field}/></div>
        <div className="mb-3"><label className="mb-1 block text-xs font-semibold text-fg-2">ธนาคาร</label>
          <select value={form.bankCode} onChange={e=>setForm(f=>({...f,bankCode:e.target.value}))} className={field}>
            <option value="">-- เลือกธนาคาร --</option>{banks.map(([c,n])=><option key={c} value={c}>{n}</option>)}
          </select></div>
        <div className="mb-3"><label className="mb-1 block text-xs font-semibold text-fg-2">เลขที่บัญชี</label>
          <input value={form.accountNumber} onChange={e=>setForm(f=>({...f,accountNumber:e.target.value}))} placeholder="เช่น 0123456789" className={field+" mono"}/></div>
        <div className="mb-3"><label className="mb-1 block text-xs font-semibold text-fg-2">ชื่อบัญชี</label>
          <input value={form.accountName} onChange={e=>setForm(f=>({...f,accountName:e.target.value}))} placeholder="ชื่อ นามสกุล" className={field}/></div>
        <div className="mt-4 flex justify-end gap-2">
          <button onClick={()=>setForm(null)} disabled={saving} className="rounded-lg border border-line px-4 py-2 text-sm text-fg-2 hover:bg-sunken">ยกเลิก</button>
          <button onClick={submit} disabled={saving} className="rounded-lg bg-accent px-4 py-2 text-sm font-medium text-accent-fg hover:bg-accent-h disabled:opacity-50">{saving?"...":"สร้างรายการ"}</button>
        </div>
      </div>
    </div>)}
  </div>);
}
