/* ==========================================================================
 * ADMIN NEXT — page-gamemanager.jsx  (จัดการค่ายเกม + เกม)
 * โครง: หมวด (ซ้าย) -> แหล่ง (พับได้) -> ค่าย -> เกม  พร้อม toggle + อัพโหลดปก/โลโก้
 * ========================================================================== */
const GM_SRC_LABEL={amb:"Agent",pghard:"PG Hard",ufa:"UFA",oneallsport:"ONESPORT",rb7:"RB7"};
const GM_SRC_ORDER=["amb","pghard","ufa","oneallsport","rb7"];
const GM_TOGGLEABLE=["amb","pghard"];
const gmSrc=(s)=>GM_SRC_LABEL[s]||s||"-";
const GM_CAT_LABEL={slot:"สล็อต",casino:"คาสิโน",card:"ไพ่",fish:"ยิงปลา",sport:"กีฬา",esport:"อีสปอร์ต",lotto:"หวย",keno:"คีโน",cock:"ไก่ชน",trade:"เทรด",table:"โต๊ะ",wheel:"วงล้อ"};
const gmCat=(c)=>GM_CAT_LABEL[c]||c||"อื่นๆ";
function gmPickImage(){ return new Promise(resolve=>{ const inp=document.createElement("input"); inp.type="file"; inp.accept="image/png,image/jpeg,image/webp,image/gif,image/svg+xml";
  inp.onchange=()=>{ const f=inp.files&&inp.files[0]; if(!f)return resolve(null); if(f.size>10*1024*1024)return resolve(null); const r=new FileReader(); r.onload=e=>resolve(e.target.result); r.onerror=()=>resolve(null); r.readAsDataURL(f); }; inp.click(); }); }

function GmSwitch({ on, onClick, disabled, title, small }){
  return (<button type="button" disabled={disabled} title={title} onClick={onClick}
    className={"inline-flex items-center gap-1.5 rounded-full border px-2.5 font-medium transition-colors disabled:opacity-50 "+(small?"h-6 text-[11px]":"h-7 text-xs")+" "+(on?"border-transparent text-white":"border-line text-fg-2 hover:bg-sunken")}
    style={on?{background:"var(--success)"}:{}}>{on?"เปิด":"ปิด"}</button>);
}

function GameManagerPage({ toast }) {
  const [st,setSt]=useState(null),[loading,setLoading]=useState(true),[err,setErr]=useState(null);
  const [cat,setCat]=useState("");
  const [prov,setProv]=useState(null); // {provider,source}
  const [games,setGames]=useState(null),[gLoading,setGLoading]=useState(false);
  const [q,setQ]=useState(""),[srcFilter,setSrcFilter]=useState(""),[status,setStatus]=useState("");
  const [closed,setClosed]=useState(()=>new Set());
  const [busy,setBusy]=useState(false);
  const load=useCallback(async()=>{ setLoading(true); setErr(null);
    try{ const d=await api("/games/stats"); setSt(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 providers=useMemo(()=>((st&&st.providers)||[]).filter(r=>Number(r.total||0)>0),[st]);
  const summary=(st&&st.summary)||[];
  const cats=useMemo(()=>{ const c={}; providers.forEach(r=>(r.categories||[]).forEach(x=>{ if(x)c[x]=(c[x]||0)+Number(r.total||0); })); return Object.entries(c).sort((a,b)=>b[1]-a[1]).map(([k])=>k); },[providers]);
  const provsFor=(category,source)=>providers.filter(r=>(!category||(r.categories||[]).includes(category))&&(!source||r.source===source));

  const loadGames=useCallback(async(p,category)=>{ setGLoading(true); setGames(null);
    try{ const qs=new URLSearchParams({provider:p.provider,source:p.source}); if(category)qs.set("category",category);
      setGames(await api("/games/by-provider?"+qs.toString())); }
    catch(e){ toast(e.message||"โหลดเกมไม่สำเร็จ"); setGames([]); }finally{ setGLoading(false); } },[toast]);
  useEffect(()=>{ if(prov) loadGames(prov,cat); },[prov,cat,loadGames]);

  const toggleGame=async(g)=>{ const en=!g.is_enabled;
    try{ await api("/games/"+g.id+"/toggle",{method:"POST",body:{enabled:en}}); setGames(gs=>gs.map(x=>x.id===g.id?{...x,is_enabled:en}:x)); }catch(e){ toast(e.message||"ไม่สำเร็จ"); } };
  const toggleProvider=async(r)=>{ const en=!(Number(r.enabled||0)>0);
    if(!window.confirm((en?"เปิด":"ปิด")+"ทั้งค่าย "+r.provider+" ("+gmSrc(r.source)+") ?"))return; setBusy(true);
    try{ const res=await api("/games/bulk-toggle",{method:"POST",body:{source:r.source,provider:r.provider,enabled:en}}); toast((en?"เปิด":"ปิด")+" "+r.provider+" แล้ว "+((res&&res.updated)||0)+" เกม"); load(); if(prov&&prov.provider===r.provider&&prov.source===r.source)loadGames(prov,cat); }catch(e){ toast(e.message||"ไม่สำเร็จ"); }finally{ setBusy(false); } };
  const toggleSourceAll=async(x)=>{ const en=!(Number(x.enabled||0)>0);
    if(!window.confirm((en?"เปิด":"ปิด")+"ทุกเกมของ "+gmSrc(x.source)+" ("+Number(x.total||0)+" เกม) ?"))return; setBusy(true);
    try{ const res=await api("/games/bulk-toggle",{method:"POST",body:{source:x.source,enabled:en}}); toast((en?"เปิด":"ปิด")+" "+gmSrc(x.source)+" แล้ว "+((res&&res.updated)||0)+" เกม"); load(); }catch(e){ toast(e.message||"ไม่สำเร็จ"); }finally{ setBusy(false); } };
  const refreshCatalog=async()=>{ if(!window.confirm("ดึงรายการเกมจาก API ทุกค่าย?"))return; setBusy(true);
    try{ const r=await api("/games/refresh",{method:"POST"}); toast("ดึงเกมสำเร็จ · PG Hard "+((r&&r.pghard)||0)+" · Agent "+((r&&r.amb)||0)); load(); }catch(e){ toast(e.message||"ดึงไม่สำเร็จ"); }finally{ setBusy(false); } };
  const uploadCover=async(g)=>{ const f=await gmPickImage(); if(!f)return;
    try{ await api("/games/"+g.id+"/cover-upload",{method:"POST",body:{dataUrl:f}}); toast("เปลี่ยนปกเกมแล้ว"); loadGames(prov,cat); }catch(e){ toast(e.message||"อัพโหลดไม่สำเร็จ"); } };
  const uploadProviderLogo=async(p)=>{ const f=await gmPickImage(); if(!f)return;
    try{ await api("/providers/"+encodeURIComponent(p.provider)+"/logo-upload",{method:"POST",body:{dataUrl:f}}); toast("อัพโหลดโลโก้ค่ายแล้ว"); load(); }catch(e){ toast(e.message||"อัพโหลดไม่สำเร็จ"); } };

  if(err) return <HistErr msg={err} onRetry={load}/>;
  if(loading) return (<div className="space-y-3"><div className="skel h-24 w-full"/><div className="skel h-72 w-full"/></div>);

  const rail=(<nav className="flex shrink-0 flex-col gap-1 lg:w-44">
    <button onClick={()=>{setCat("");setProv(null);}} className={"flex items-center gap-2 rounded-lg px-3 py-2 text-sm font-medium transition-colors "+(cat?"text-fg-2 hover:bg-sunken":"bg-accent-soft text-accent")}><Ic d={I.grid} size={15}/> ทั้งหมด <span className="ml-auto text-xs text-faint">{providers.length}</span></button>
    {cats.map(c=>(<button key={c} onClick={()=>{setCat(c);setProv(null);}} className={"flex items-center gap-2 rounded-lg px-3 py-2 text-sm font-medium transition-colors "+(cat===c?"bg-accent-soft text-accent":"text-fg-2 hover:bg-sunken")}><Ic d={I.game} size={15}/> {gmCat(c)} <span className="ml-auto text-xs text-faint">{provsFor(c).length}</span></button>))}
  </nav>);

  // ── game view ──
  if(prov){
    const meta=providers.find(r=>r.provider===prov.provider&&r.source===prov.source)||{};
    const on=Number(meta.enabled||0)>0, canTog=GM_TOGGLEABLE.includes(prov.source);
    const gq=q.trim().toLowerCase();
    const list=(games||[]).filter(g=>{ if(status==="on"&&!g.is_enabled)return false; if(status==="off"&&g.is_enabled)return false; if(gq&&!String(g.name||"").toLowerCase().includes(gq))return false; return true; });
    return (<div className="space-y-3">
      <div className="flex flex-wrap items-center gap-2 text-sm">
        <button onClick={()=>setProv(null)} className="flex h-8 items-center gap-1.5 rounded-lg border border-line px-2.5 text-xs font-medium text-fg-2 hover:bg-sunken"><Ic d={I.back} size={14}/> ย้อนกลับ</button>
        <span className="text-muted">{gmSrc(prov.source)}{cat?" · "+gmCat(cat):""}</span><Ic d={I.chevR} size={13} cls="text-faint"/><span className="font-semibold">{meta.provider_name||prov.provider}</span>
      </div>
      <div className="flex flex-col gap-3 lg:flex-row">
        <aside className="rounded-xl border border-line bg-surface p-4 shadow-sm lg:w-56">
          <div className="mx-auto grid h-20 w-20 place-items-center overflow-hidden rounded-xl bg-sunken">{meta.logo_url?<img src={meta.logo_url} className="h-full w-full object-contain" onError={(e)=>e.target.style.display='none'}/>:<Ic d={I.game} size={28} cls="text-faint"/>}</div>
          <div className="mt-2 text-center text-sm font-semibold">{meta.provider_name||prov.provider}</div>
          <div className="text-center text-[11px] text-muted">{gmSrc(prov.source)}</div>
          <div className="mt-3 text-center text-xs text-muted">เปิดอยู่ <b style={{color:on?"var(--success)":"var(--danger)"}}>{meta.enabled||0}</b> / {meta.total||0} เกม</div>
          {canTog ? <button disabled={busy} onClick={()=>toggleProvider(meta)} className="mt-3 w-full rounded-lg px-3 py-2 text-xs font-semibold text-white disabled:opacity-50" style={{background:on?"var(--danger)":"var(--success)"}}>{on?"ปิดทั้งค่าย":"เปิดทั้งค่าย"}</button> : <div className="mt-3 rounded-lg bg-sunken px-3 py-2 text-center text-[11px] text-muted">เปิด/ปิดที่หน้าจัดการ API</div>}
          <button onClick={()=>uploadProviderLogo(meta)} className="mt-2 w-full rounded-lg border border-line px-3 py-2 text-xs font-medium text-fg-2 hover:bg-sunken"><Ic d={I.down} size={13} cls="inline"/> อัพโหลดโลโก้ค่าย</button>
        </aside>
        <section className="min-w-0 flex-1">
          <div className="mb-2 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={15}/></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 focus:border-accent focus:outline-none"/></div>
            <select value={status} onChange={(e)=>setStatus(e.target.value)} className="h-9 rounded-lg border border-line bg-surface px-2 text-sm text-fg-2"><option value="">สถานะ: ทั้งหมด</option><option value="on">เปิดอยู่</option><option value="off">ปิดอยู่</option></select>
          </div>
          {gLoading ? <div className="grid grid-cols-2 gap-3 sm:grid-cols-4 lg:grid-cols-5 xl:grid-cols-6">{Array.from({length:8}).map((_,i)=><div key={i} className="skel h-32 w-full"/>)}</div>
            : list.length===0 ? <div className="rounded-xl border border-dashed border-line py-16 text-center text-sm text-muted">{(games||[]).length===0?"ค่ายนี้ยังไม่มีเกม":"ไม่พบเกมตามเงื่อนไข"}</div>
            : <div className="grid grid-cols-2 gap-3 sm:grid-cols-4 lg:grid-cols-5 xl:grid-cols-6">{list.map(g=>(
              <article key={g.id} className={"rounded-xl border bg-surface p-2 shadow-sm "+(g.is_enabled?"border-line":"border-line opacity-60")}>
                <button onClick={()=>uploadCover(g)} title="เปลี่ยนปกเกม" className="group relative grid aspect-[2/3] w-full place-items-center overflow-hidden rounded-lg bg-sunken">
                  {g.image_url?<img src={g.image_url} loading="lazy" className="h-full w-full object-contain" onError={(e)=>e.target.style.display='none'}/>:<Ic d={I.game} size={28} cls="text-faint"/>}
                  <span className="absolute bottom-1 right-1 rounded bg-black/60 px-1.5 py-0.5 text-[10px] text-white opacity-0 group-hover:opacity-100"><Ic d={I.down} size={10} cls="inline"/> ปก</span>
                </button>
                <div className="mt-1.5 truncate text-xs font-medium" title={g.name}>{g.name||"-"}</div>
                <div className="text-[10px] text-faint">{Number(g.plays||0)>0?"เล่น "+Number(g.plays).toLocaleString("th-TH")+" ครั้ง":"ยังไม่มีสถิติ"}</div>
                <div className="mt-1.5"><GmSwitch small on={!!g.is_enabled} onClick={()=>toggleGame(g)}/></div>
              </article>))}</div>}
        </section>
      </div>
    </div>);
  }

  // ── provider list view ──
  const gq2=q.trim().toLowerCase();
  const match=(r)=>{ if(status==="on"&&!(Number(r.enabled||0)>0))return false; if(status==="off"&&Number(r.enabled||0)>0)return false; if(gq2&&!String(r.provider).toLowerCase().includes(gq2))return false; return true; };
  const groups=GM_SRC_ORDER.filter(s=>!srcFilter||s===srcFilter).map(s=>({source:s,rows:provsFor(cat,s).filter(match)})).filter(g=>g.rows.length);
  return (<div className="space-y-4">
    {summary.length>0 && <div className="grid grid-cols-2 gap-3 sm:grid-cols-3 lg:grid-cols-5">
      {summary.map((x,i)=>(<div key={i} className="rounded-xl border border-line bg-surface p-3 shadow-sm">
        <div className="text-[11px] text-muted">{gmSrc(x.source)} · เกมในระบบ</div>
        <div className="mt-0.5 text-lg font-semibold tnum" style={{color:Number(x.enabled||0)>0?"var(--fg)":"var(--muted)"}}>{Number(x.enabled||0).toLocaleString()} / {Number(x.total||0).toLocaleString()}</div>
        <div className="mt-1.5">{GM_TOGGLEABLE.includes(x.source)?<GmSwitch small on={Number(x.enabled||0)>0} disabled={busy} onClick={()=>toggleSourceAll(x)} title="เปิด/ปิดทั้งแหล่ง"/>:<span className="text-[10px] text-faint">ตั้งที่หน้าจัดการ API</span>}</div>
      </div>))}
    </div>}
    <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 focus:border-accent focus:outline-none"/></div>
      <select value={srcFilter} onChange={(e)=>setSrcFilter(e.target.value)} className="h-9 rounded-lg border border-line bg-surface px-2 text-sm text-fg-2"><option value="">แหล่ง: ทุกค่าย</option>{GM_SRC_ORDER.map(s=><option key={s} value={s}>{gmSrc(s)}</option>)}</select>
      <select value={status} onChange={(e)=>setStatus(e.target.value)} className="h-9 rounded-lg border border-line bg-surface px-2 text-sm text-fg-2"><option value="">สถานะ: ทั้งหมด</option><option value="on">เปิดอยู่</option><option value="off">ปิดอยู่</option></select>
      <button disabled={busy} onClick={refreshCatalog} 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 disabled:opacity-50"><Ic d={I.refresh} size={16} cls={busy?"animate-spin":""}/> ดึงจาก API</button>
    </div>
    <div className="flex flex-col gap-4 lg:flex-row">
      {rail}
      <div className="min-w-0 flex-1 space-y-3">
        {groups.length===0 ? <div className="rounded-xl border border-dashed border-line py-16 text-center text-sm text-muted">ไม่พบค่ายตามเงื่อนไข</div>
          : groups.map(g=>{ const open=!!q||!!srcFilter||!closed.has(g.source); const onN=g.rows.reduce((a,r)=>a+Number(r.enabled||0),0); const totN=g.rows.reduce((a,r)=>a+Number(r.total||0),0);
            return (<div key={g.source} className="overflow-hidden rounded-xl border border-line bg-surface shadow-sm">
              <button onClick={()=>setClosed(s=>{const n=new Set(s); n.has(g.source)?n.delete(g.source):n.add(g.source); return n;})} className="flex w-full items-center gap-2 border-b border-line px-4 py-3 text-left">
                <Ic d={open?I.chevD:I.chevR} size={15} cls="text-muted"/><b className="text-sm">{gmSrc(g.source)}</b>
                <span className="ml-auto text-xs text-muted tnum">{g.rows.length} ค่าย · เปิด {onN.toLocaleString()}/{totN.toLocaleString()} เกม</span>
              </button>
              {open && <div className="grid grid-cols-2 gap-3 p-4 sm:grid-cols-3 lg:grid-cols-4">{g.rows.map(r=>{ const on=Number(r.enabled||0)>0; const canTog=GM_TOGGLEABLE.includes(r.source);
                return (<div key={r.provider+r.source} className={"rounded-xl border bg-surface p-3 shadow-sm "+(on?"border-line":"border-line opacity-70")}>
                  <button onClick={()=>setProv({provider:r.provider,source:r.source})} className="block w-full text-left">
                    <div className="mx-auto grid h-16 w-12 place-items-center overflow-hidden rounded-lg bg-sunken">{r.logo_url?<img src={r.logo_url} loading="lazy" className="h-full w-full object-contain" onError={(e)=>e.target.style.display='none'}/>:<Ic d={I.game} size={22} cls="text-faint"/>}</div>
                    <div className="mt-1.5 truncate text-sm font-medium">{r.provider_name||r.provider}</div>
                  </button>
                  <div className="mt-1 flex items-center gap-2"><span className="text-[11px] text-muted">{gmSrc(r.source)} · <b style={{color:on?"var(--success)":"var(--danger)"}}>{r.enabled}/{r.total}</b></span>
                    <span className="ml-auto">{canTog?<GmSwitch small on={on} disabled={busy} onClick={()=>toggleProvider(r)}/>:<span className="text-[10px] text-faint">API</span>}</span></div>
                </div>);})}</div>}
            </div>); })}
      </div>
    </div>
  </div>);
}
