/* ==========================================================================
 * ADMIN NEXT — page-staffkpi.jsx
 * KPI พนักงานจาก admin_activity_logs (กิจกรรมที่ระบบบันทึกจริง)
 * ========================================================================== */
const STAFF_KPI_RANGES = [["today","วันนี้"],["yesterday","เมื่อวาน"],["7d","7 วัน"],["month","เดือนนี้"],["custom","กำหนดเอง"]];
const staffKpiDate = (offset=0) => new Intl.DateTimeFormat("en-CA",{timeZone:"Asia/Bangkok"}).format(new Date(Date.now()-offset*86400000));
const staffKpiFmt = (n) => Number(n||0).toLocaleString("th-TH");
const staffKpiDuration = (minutes) => { const value=Math.max(0,Math.round(Number(minutes||0))); const h=Math.floor(value/60),m=value%60; return h?`${h} ชม. ${m} นาที`:`${m} นาที`; };
const staffKpiWhen = (v) => {
  if(!v) return "ไม่มีข้อมูล";
  try { return new Intl.DateTimeFormat("th-TH",{timeZone:"Asia/Bangkok",day:"2-digit",month:"short",year:"2-digit",hour:"2-digit",minute:"2-digit"}).format(new Date(v)); }
  catch { return "—"; }
};
function StaffKpiPage({ toast }) {
  const [range,setRange]=useState("7d");
  const [custom,setCustom]=useState({from:staffKpiDate(6),to:staffKpiDate(0)});
  const [from,setFrom]=useState(staffKpiDate(6));
  const [to,setTo]=useState(staffKpiDate(0));
  const [tab,setTab]=useState("overview");
  const [q,setQ]=useState("");
  const [roleFilter,setRoleFilter]=useState("all");
  const [data,setData]=useState(null);
  const [sessionData,setSessionData]=useState(null);
  const [sessionErr,setSessionErr]=useState(null);
  const [loading,setLoading]=useState(true);
  const [err,setErr]=useState(null);
  const [selected,setSelected]=useState(null);

  const resolveDates=useCallback(()=>{
    const today=staffKpiDate(0);
    if(range==="today")return {from:today,to:today};
    if(range==="yesterday"){const y=staffKpiDate(1);return {from:y,to:y};}
    if(range==="month")return {from:today.slice(0,8)+"01",to:today};
    if(range==="custom")return {from:custom.from||today,to:custom.to||today};
    return {from:staffKpiDate(6),to:today};
  },[range,custom]);

  const load=useCallback(async()=>{
    setLoading(true);setErr(null);setSessionErr(null);setSessionData(null);
    try{
      const dates=resolveDates();
      const params=new URLSearchParams({from:dates.from,to:dates.to});
      const result=await api("/staff-kpi?"+params.toString());
      setData(result||null);setFrom(dates.from);setTo(dates.to);setSelected(null);
      try{
        const sessionResult=await api("/staff-kpi-sessions?"+params.toString());
        setSessionData(sessionResult||null);
      }catch(sessionError){
        setSessionData(null);
        setSessionErr(sessionError.message||"โหลดเวลาเซสชันไม่สำเร็จ");
      }
    }catch(e){
      if(e.status===401||e.status===403)window.__nxAuthFail?.();
      setErr(e.status===403?"บัญชีนี้ไม่มีสิทธิ์ดู KPI พนักงาน":(e.message||"โหลด KPI ไม่สำเร็จ"));
    }finally{setLoading(false);}
  },[resolveDates]);
  useEffect(()=>{load();},[load]);

  const rows=data?.rows||[];
  const hours=data?.hourly||[];
  const rawSummary=data?.summary||{};
  const sessionRowsById={};
  (sessionData?.rows||[]).forEach(r=>{sessionRowsById[String(r.id)]=r;});
  const sessionRoleRows=(sessionData?.rows||[]).filter(r=>roleFilter==="all"||r.role===roleFilter);
  const sessionSum=(key)=>sessionRoleRows.reduce((total,row)=>total+Number(row[key]||0),0);
  const filteredSessionCount=sessionSum("sessions_count");
  const sessionSummary={
    sessions_total:filteredSessionCount,
    active_sessions:sessionSum("active_sessions"),
    total_minutes:sessionSum("total_minutes"),
    average_session_minutes:filteredSessionCount?Math.round(sessionSum("total_minutes")/filteredSessionCount):0,
    staff_with_sessions:sessionRoleRows.filter(r=>Number(r.sessions_count||0)>0).length,
  };
  const roleRows=rows.filter(r=>roleFilter==="all"||r.role===roleFilter);
  const activeRows=roleRows.filter(r=>Number(r.actions_total||0)>0);
  const filtered=roleRows.filter(r=>{
    const term=q.trim().toLowerCase();
    return !term||String(r.username||"").toLowerCase().includes(term)||String(r.full_name||"").toLowerCase().includes(term)||String(r.role||"").toLowerCase().includes(term);
  });
  const maxActions=Math.max(1,...roleRows.map(r=>Number(r.actions_total||0)));
  const roleSum=(key)=>roleRows.reduce((total,row)=>total+Number(row[key]||0),0);
  const summary=roleFilter==="all"?rawSummary:{staff_total:roleRows.length,active_staff:activeRows.length,total_actions:roleSum("actions_total"),member_actions:roleSum("member_actions"),deposit_actions:roleSum("deposit_actions"),withdrawal_actions:roleSum("withdrawal_actions"),credit_actions:roleSum("credit_actions"),withdrawal_managed:roleSum("withdrawal_managed"),finance_actions:roleSum("deposit_actions")+roleSum("withdrawal_actions")+roleSum("credit_actions"),settings_actions:roleSum("settings_actions")};
  const activeCount=Number(summary.active_staff||0);
  const totalActions=Number(summary.total_actions||0);
  const average=activeCount?totalActions/activeCount:0;
  const activeRate=Number(summary.staff_total||0)?Math.round(activeCount/Number(summary.staff_total)*1000)/10:0;
  const hourlyMap={};
  hours.forEach(h=>{hourlyMap[String(h.staff_id)+":"+Number(h.hour)]=Number(h.count||0);});
  const H=({children,extra=""})=><th className={"whitespace-nowrap px-3 py-2.5 text-left text-[12px] font-bold text-fg-2 "+extra}>{children}</th>;

  const chooseRange=(key)=>{
    setRange(key);
    if(key==="today"){setCustom({from:staffKpiDate(0),to:staffKpiDate(0)});}
    if(key==="yesterday"){setCustom({from:staffKpiDate(1),to:staffKpiDate(1)});}
    if(key==="7d"){setCustom({from:staffKpiDate(6),to:staffKpiDate(0)});}
    if(key==="month"){const today=staffKpiDate(0);setCustom({from:today.slice(0,8)+"01",to:today});}
  };
  const exportCsv=()=>{
    const exportRows=[["อันดับ","ชื่อพนักงาน","ยูสเซอร์","บทบาท","กิจกรรมทั้งหมด","สมาชิก","ฝาก","ถอน","คืน/เติม/ตัดเครดิต","ถอนที่จัดการ","ตั้งค่า/ระบบ","กิจกรรมล่าสุด","Login ล่าสุด","Logout ล่าสุด","เวลาเซสชันรวม (นาที)","จำนวนเซสชัน"]];
    filtered.forEach((r,i)=>{const session=sessionRowsById[String(r.id)]||{};exportRows.push([i+1,r.full_name||r.username,r.username,r.role,Number(r.actions_total||0),Number(r.member_actions||0),Number(r.deposit_actions||0),Number(r.withdrawal_actions||0),Number(r.credit_actions||0),Number(r.withdrawal_managed||0),Number(r.settings_actions||0),staffKpiWhen(r.last_activity),staffKpiWhen(session.last_login),staffKpiWhen(session.last_logout),Number(session.total_minutes||0),Number(session.sessions_count||0)]);});
    csvDownload("staff-kpi-"+from+"-"+to+".csv",exportRows);
    toast("ส่งออก KPI "+filtered.length+" รายการแล้ว");
  };

  const tablePanel = (
    <section className="overflow-hidden rounded-xl border border-line bg-surface shadow-sm">
      <div className="flex flex-wrap items-center gap-2 border-b border-line px-4 py-3">
        <div><h2 className="text-sm font-semibold">ผลงานรายพนักงาน</h2><p className="mt-0.5 text-xs text-muted">นับจาก Activity Log ที่ระบบบันทึกจริง · {staffKpiFmt(filtered.length)} จาก {staffKpiFmt(roleRows.length)} คน</p></div>
        <span className="ml-auto rounded-full border border-line bg-sunken px-2.5 py-1 text-[11px] text-muted">ไม่รวม sync อัตโนมัติ</span>
      </div>
      <div className="overflow-x-auto"><table className="w-full min-w-[1450px] border-collapse text-xs">
        <thead className="border-b border-line bg-sunken"><tr>
          <th className="w-12 px-3 py-3 text-left font-bold text-fg-2">#</th>
          <th className="min-w-[190px] px-3 py-3 text-left font-bold text-fg-2">พนักงาน</th>
          <th className="px-3 py-3 text-left font-bold text-fg-2">บทบาท / สถานะ</th>
          <th className="min-w-[145px] px-3 py-3 text-left font-bold text-fg-2">Login ล่าสุด</th>
          <th className="min-w-[145px] px-3 py-3 text-left font-bold text-fg-2">Logout ล่าสุด</th>
          <th className="min-w-[120px] px-3 py-3 text-right font-bold text-fg-2">เวลาเซสชันรวม</th>
          <th className="px-3 py-3 text-right font-bold text-fg-2">Action รวม</th>
          <th className="px-3 py-3 text-right font-bold text-fg-2">สมาชิก</th>
          <th className="px-3 py-3 text-right font-bold text-fg-2">ฝาก</th>
          <th className="px-3 py-3 text-right font-bold text-fg-2">ถอน</th>
          <th className="px-3 py-3 text-right font-bold text-fg-2">เครดิต</th>
          <th className="px-3 py-3 text-right font-bold text-fg-2">ถอนที่จัดการ</th>
          <th className="px-3 py-3 text-right font-bold text-fg-2">ตั้งค่า / ระบบ</th>
          <th className="min-w-[155px] px-3 py-3 text-left font-bold text-fg-2">กิจกรรมล่าสุด</th>
          <th className="min-w-[140px] px-3 py-3 text-left font-bold text-fg-2">เทียบกับคนที่สูงสุด</th>
        </tr></thead>
        <tbody>
          {loading?Array.from({length:6}).map((_,i)=><tr key={i} className="border-b border-line-soft"><td className="px-3 py-3" colSpan="15"><div className="skel h-5 w-full"/></td></tr>)
          :filtered.map((r)=>{const originalIndex=roleRows.findIndex(x=>x.id===r.id);const session=sessionRowsById[String(r.id)]||{};const ratio=Math.round(Number(r.actions_total||0)/maxActions*100);return <tr key={r.id} onClick={()=>setSelected(r.id)} className={"cursor-pointer border-b border-line-soft last:border-0 transition-colors hover:bg-sunken "+(selected===r.id?"bg-accent-soft":"")}>
            <td className="px-3 py-3 text-muted">{originalIndex+1}</td>
            <td className="px-3 py-3"><div className="font-semibold text-fg">{r.full_name||r.username}</div><div className="mt-1 text-[11px] text-muted">@{r.username}</div></td>
            <td className="px-3 py-3"><div className="font-medium text-fg-2">{r.role==="staff"?"พนักงาน":"แอดมิน"}</div><div className={"mt-1 inline-flex rounded-full px-2 py-0.5 text-[10px] "+(r.status==="active"?"bg-emerald-50 text-emerald-700":"bg-slate-100 text-slate-500")}>{r.status==="active"?"ใช้งาน":(r.status||"ไม่ทราบ")}</div></td>
            <td className="whitespace-nowrap px-3 py-3 text-[11px] text-fg-2">{session.last_login?staffKpiWhen(session.last_login):"—"}</td>
            <td className="whitespace-nowrap px-3 py-3 text-[11px] text-fg-2">{session.last_logout?staffKpiWhen(session.last_logout):(Number(session.active_sessions||0)>0?"ยังเปิดอยู่":(Number(session.sessions_count||0)>0?"ไม่มี Logout":"—"))}</td>
            <td className="px-3 py-3 text-right"><div className="font-semibold tabular-nums text-fg">{Number(session.sessions_count||0)>0||Number(session.total_minutes||0)>0?staffKpiDuration(session.total_minutes):"—"}</div><div className="mt-1 text-[10px] text-muted">{staffKpiFmt(session.sessions_count||0)} เซสชัน</div></td>
            <td className="px-3 py-3 text-right"><span className="font-bold tabular-nums text-fg">{staffKpiFmt(r.actions_total)}</span><div className="ml-auto mt-1 h-1.5 w-20 overflow-hidden rounded-full bg-sunken"><div className="h-full rounded-full bg-accent" style={{width:ratio+"%"}}/></div></td>
            <td className="px-3 py-3 text-right tabular-nums text-[#4c78bd]">{staffKpiFmt(r.member_actions)}</td>
            <td className="px-3 py-3 text-right tabular-nums text-emerald-700">{staffKpiFmt(r.deposit_actions)}</td>
            <td className="px-3 py-3 text-right tabular-nums text-rose-700">{staffKpiFmt(r.withdrawal_actions)}</td>
            <td className="px-3 py-3 text-right tabular-nums text-amber-700">{staffKpiFmt(r.credit_actions)}</td>
            <td className="px-3 py-3 text-right tabular-nums text-orange-700">{staffKpiFmt(r.withdrawal_managed)}</td>
            <td className="px-3 py-3 text-right tabular-nums text-[#7665c4]">{staffKpiFmt(r.settings_actions)}</td>
            <td className="whitespace-nowrap px-3 py-3 text-[11px] text-fg-2">{staffKpiWhen(r.last_activity)}</td>
            <td className="px-3 py-3"><div className="flex min-w-[105px] items-center gap-2"><div className="h-2 flex-1 overflow-hidden rounded-full bg-sunken"><div className="h-full rounded-full bg-accent" style={{width:ratio+"%"}}/></div><span className="w-8 text-right tabular-nums text-muted">{ratio}%</span></div></td>
          </tr>})}
          {!loading&&!filtered.length&&<tr><td colSpan="15" className="px-4 py-12 text-center text-sm text-muted">{rows.length?"ไม่พบพนักงานที่ตรงกับคำค้นหา":"ไม่มีพนักงานในช่วงที่เลือก"}</td></tr>}
        </tbody>
      </table></div>
      {selected&&roleRows.some(r=>r.id===selected)&&<div className="border-t border-line bg-sunken p-4">
        {(()=>{const r=roleRows.find(x=>x.id===selected);return <div className="flex flex-wrap items-center gap-3"><span className="grid h-10 w-10 place-items-center rounded-xl bg-[#efedff] text-[#7168c8]"><Ic d={I.users} size={20}/></span><div className="min-w-0 flex-1"><div className="font-semibold">{r.full_name||r.username}</div><div className="text-xs text-muted">Action {staffKpiFmt(r.actions_total)} · ฝาก {staffKpiFmt(r.deposit_actions)} · ถอน {staffKpiFmt(r.withdrawal_actions)} · เครดิต {staffKpiFmt(r.credit_actions)} · สมาชิก {staffKpiFmt(r.member_actions)}</div></div><div className="text-right text-xs text-muted">กิจกรรมล่าสุด<br/><span className="font-semibold text-fg">{staffKpiWhen(r.last_activity)}</span></div><button onClick={(e)=>{e.stopPropagation();setSelected(null);}} className="rounded-lg border border-line px-2.5 py-1.5 text-xs hover:bg-surface">ปิด</button></div>;})()}
      </div>}
      <div className="border-t border-line bg-sunken px-4 py-2 text-[11px] leading-5 text-muted">ข้อมูลเซสชันเริ่มนับหลังติดตั้งและเข้าสู่ระบบใหม่เท่านั้น เวลาเซสชันคำนวณจาก Login และ heartbeat ทุก 60 วินาทีขณะหน้าแอดมินเปิดอยู่ หากไม่มี Logout จริงจะประเมินจาก heartbeat ล่าสุด + 2 นาที ไม่ใช่หลักฐานเวลาทำงาน</div>
    </section>
  );

  const heatmapPanel = (
    <section className="overflow-hidden rounded-xl border border-line bg-surface shadow-sm">
      <div className="flex flex-wrap items-start justify-between gap-3 border-b border-line px-4 py-3">
        <div><h2 className="text-sm font-semibold">ช่วงเวลาที่มีการบันทึกกิจกรรม</h2><p className="mt-0.5 text-xs text-muted">จำนวน Activity Log แยกตามชั่วโมงตามเวลาไทย (UTC+7) รวมตลอดช่วงที่เลือก</p></div>
        <div className="flex items-center gap-1.5 text-[10px] text-muted"><span>น้อย</span>{[0,1,2,3,4].map(v=><span key={v} className="h-3 w-3 rounded-sm border border-line" style={{background:v===0?"#f7f7fb":"rgba(116,108,218,"+(0.15+v*0.18)+")"}}/>)}<span>มาก</span></div>
      </div>
      <div className="overflow-x-auto"><table className="w-full min-w-[1120px] border-collapse text-[11px]">
        <thead><tr className="border-b border-line bg-sunken"><th className="sticky left-0 z-10 min-w-[170px] bg-sunken px-3 py-2 text-left font-semibold text-fg-2">พนักงาน / ชั่วโมง</th>{Array.from({length:24},(_,i)=><th key={i} className="min-w-[34px] px-1 py-2 text-center font-semibold text-fg-2">{String(i).padStart(2,"0")}</th>)}</tr></thead>
        <tbody>
          {loading?Array.from({length:5}).map((_,i)=><tr key={i}><td colSpan="25" className="px-3 py-2"><div className="skel h-5 w-full"/></td></tr>)
          :filtered.slice(0,30).map(r=><tr key={r.id} className="border-b border-line-soft"><td className="sticky left-0 z-10 bg-surface px-3 py-2"><div className="max-w-[165px] truncate font-medium text-fg">{r.full_name||r.username}</div><div className="text-[10px] text-muted">@{r.username}</div></td>{Array.from({length:24},(_,hour)=>{const count=hourlyMap[String(r.id)+":"+hour]||0;const opacity=count?Math.min(.88,.16+Math.log2(count+1)*.15):0;return <td key={hour} className="p-0.5 text-center"><div title={hour+" น. · "+staffKpiFmt(count)+" รายการ"} className="grid h-7 min-w-[27px] place-items-center rounded-sm" style={{background:count?"rgba(116,108,218,"+opacity+")":"#f7f7fb",color:count?"#292446":"#b0aec3"}}>{count||""}</div></td>})}</tr>)}
          {!loading&&!filtered.length&&<tr><td colSpan="25" className="px-4 py-12 text-center text-sm text-muted">ไม่มีข้อมูลในช่วงที่เลือก</td></tr>}
        </tbody>
      </table></div>
      <div className="border-t border-line px-4 py-2 text-[11px] text-muted">แสดงสูงสุด 30 คนแรกตามตัวกรอง ข้อมูลเป็นจำนวนเหตุการณ์ ไม่ใช่เวลาทำงานหรือสถานะออนไลน์</div>
    </section>
  );

  const comparisonPanel = (
    <div className="grid grid-cols-1 gap-3 xl:grid-cols-2">
      <section className="overflow-hidden rounded-xl border border-line bg-surface shadow-sm">
        <div className="border-b border-line px-4 py-3"><h2 className="text-sm font-semibold">อันดับพนักงานตามกิจกรรม</h2><p className="mt-0.5 text-xs text-muted">เรียงจาก Activity Log ที่บันทึกจริง</p></div>
        <div className="divide-y divide-line-soft">
          {loading?Array.from({length:5}).map((_,i)=><div key={i} className="px-4 py-3"><div className="skel h-5 w-full"/></div>)
          :activeRows.slice().sort((a,b)=>Number(b.actions_total||0)-Number(a.actions_total||0)).slice(0,10).map((r,i)=><button key={r.id} onClick={()=>{setSelected(r.id);setTab("staff");}} className="flex w-full items-center gap-3 px-4 py-3 text-left hover:bg-sunken">
            <span className={"grid h-7 w-7 shrink-0 place-items-center rounded-lg text-xs font-bold "+(i===0?"bg-accent text-accent-fg":"bg-accent-soft text-accent")}>{i+1}</span>
            <span className="min-w-0 flex-1"><span className="block truncate text-sm font-medium text-fg">{r.full_name||r.username}</span><span className="block truncate text-[11px] text-muted">@{r.username} · {r.role==="staff"?"พนักงาน":"แอดมิน"}</span></span>
            <span className="w-24 shrink-0"><span className="block text-right text-sm font-bold tabular-nums">{staffKpiFmt(r.actions_total)}</span><span className="mt-1 block h-1.5 overflow-hidden rounded-full bg-sunken"><span className="block h-full rounded-full bg-accent" style={{width:(Number(r.actions_total||0)/maxActions*100)+"%"}}/></span></span>
          </button>)}
          {!loading&&!activeRows.length&&<div className="px-4 py-10 text-center text-sm text-muted">ไม่มีข้อมูลกิจกรรม</div>}
        </div>
      </section>
      <section className="overflow-hidden rounded-xl border border-line bg-surface shadow-sm">
        <div className="border-b border-line px-4 py-3"><h2 className="text-sm font-semibold">สัดส่วนประเภทกิจกรรม</h2><p className="mt-0.5 text-xs text-muted">จำแนกจาก path / action · หมวดอาจนับซ้อนกัน</p></div>
        <div className="space-y-4 p-4">
          {[
            ["สมาชิก",Number(summary.member_actions||0),"#7197d6"],
            ["การเงิน / เครดิต",Number(summary.finance_actions||0),"#55aa88"],
            ["การตั้งค่า / จัดการระบบ",Number(summary.settings_actions||0),"#8c83dc"]
          ].map(([label,value,color])=><div key={label}>
            <div className="mb-1.5 flex items-center justify-between gap-3 text-xs"><span className="text-fg-2">{label}</span><span className="font-semibold tabular-nums">{staffKpiFmt(value)}</span></div>
            <div className="h-2 overflow-hidden rounded-full bg-sunken"><div className="h-full rounded-full" style={{width:(totalActions?Math.min(100,value/totalActions*100):0)+"%",background:color}}/></div>
          </div>)}
          <div className="border-t border-line pt-3 text-[11px] leading-5 text-muted">ยอดรวมเป็นจำนวน log ทั้งหมด หมวดกิจกรรมอาจซ้อนทับกันและไม่ใช่คะแนนคุณภาพงาน</div>
        </div>
      </section>
    </div>
  );

  const kpiColors = ["#6366F1","#0EA5E9","#10B981","#EF4444","#F59E0B","#F97316","#8B5CF6","#64748B","#14B8A6","#EC4899","#06B6D4","#D946EF","#22C55E"];
  return (<div className="space-y-3">
    <div className="rounded-xl border border-line bg-surface p-3 shadow-sm">
      <div className="flex flex-wrap items-center gap-2">
        <div className="flex flex-wrap gap-1 rounded-lg border border-line bg-sunken p-1">
          {[["overview","ภาพรวม"],["staff","รายบุคคล"],["hours","กิจกรรมรายชั่วโมง"],["compare","เปรียบเทียบ"]].map(([k,label])=><button key={k} onClick={()=>setTab(k)} className={"rounded-md px-3 py-1.5 text-xs font-semibold transition-colors "+(tab===k?"bg-white text-[#5c56a6] shadow-sm":"text-fg-2 hover:text-fg")}>{label}</button>)}
        </div>
        <div className="flex flex-wrap gap-1 rounded-lg border border-line bg-sunken p-1">
          {STAFF_KPI_RANGES.map(([k,label])=><button key={k} onClick={()=>chooseRange(k)} className={"rounded-md px-2.5 py-1.5 text-[11px] font-semibold transition-colors "+(range===k?"bg-accent text-accent-fg shadow-sm":"text-fg-2 hover:bg-surface")}>{label}</button>)}
        </div>
        <div className="flex flex-wrap items-center gap-1.5">
          <label className="text-[11px] text-muted">จาก</label><input aria-label="วันที่เริ่มต้น" type="date" value={custom.from} onChange={e=>{setCustom(c=>({...c,from:e.target.value}));setRange("custom");}} className="h-8 rounded-lg border border-line bg-surface px-2 text-[11px]"/>
          <label className="text-[11px] text-muted">ถึง</label><input aria-label="วันที่สิ้นสุด" type="date" value={custom.to} onChange={e=>{setCustom(c=>({...c,to:e.target.value}));setRange("custom");}} className="h-8 rounded-lg border border-line bg-surface px-2 text-[11px]"/>
        </div>
        <select aria-label="ตัวกรองบทบาท" value={roleFilter} onChange={e=>setRoleFilter(e.target.value)} className="h-8 rounded-lg border border-line bg-surface px-2 text-xs">
          <option value="all">ทุกบทบาท</option><option value="staff">พนักงาน</option><option value="admin">แอดมิน</option>
        </select>
        <div className="relative min-w-[150px] flex-1 sm:max-w-[220px]"><span className="pointer-events-none absolute left-2.5 top-1/2 -translate-y-1/2 text-muted"><Ic d={I.search} size={14}/></span><input value={q} onChange={e=>setQ(e.target.value)} placeholder="ค้นหาพนักงาน..." className="h-8 w-full rounded-lg border border-line bg-sunken pl-8 pr-2 text-xs focus:border-accent focus:outline-none"/></div>
        <button onClick={load} className="h-8 rounded-lg bg-accent px-3 text-xs font-semibold text-accent-fg hover:bg-accent-h">ดูข้อมูล</button>
        <button onClick={load} title="รีเฟรชข้อมูล" aria-label="รีเฟรชข้อมูล" 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={14} cls={loading?"animate-spin":""}/></button>
        <button onClick={exportCsv} disabled={loading||!filtered.length} className="h-8 rounded-lg border border-line bg-surface px-3 text-xs font-semibold text-fg-2 hover:bg-sunken disabled:opacity-40"><Ic d={I.down} size={14}/> CSV</button>
      </div>
      <div className="mt-2 flex flex-wrap items-center justify-between gap-2 text-[11px] text-muted">
        <span>ช่วงข้อมูล: <strong className="font-semibold text-fg-2">{from} ถึง {to}</strong></span>
        <span>ตัวกรองบทบาทมีผลกับการ์ด ตาราง และ Heatmap · เวลา Asia/Bangkok</span>
      </div>
    </div>

    <div className="grid grid-cols-2 gap-2.5 lg:grid-cols-4">
      {[
        ["พนักงานที่ทำงาน",staffKpiFmt(summary.active_staff),"มี Activity Log อย่างน้อย 1 รายการ",I.users],
        ["Action ทั้งหมด",staffKpiFmt(summary.total_actions),"รายการที่ระบบบันทึกจริง",I.check],
        ["งานฝาก",staffKpiFmt(summary.deposit_actions),"รายการฝากที่พนักงานจัดการ",I.dep],
        ["งานถอน",staffKpiFmt(summary.withdrawal_actions),"รายการถอนที่พนักงานจัดการ",I.wdr],
        ["คืน / เติม / ตัดเครดิต",staffKpiFmt(summary.credit_actions),"การปรับเครดิตสมาชิก",I.coins],
        ["ถอนที่จัดการ",staffKpiFmt(summary.withdrawal_managed),"อนุมัติ / ยกเลิก / จ่ายถอน",I.check],
        ["สมาชิก",staffKpiFmt(summary.member_actions),"กิจกรรมเกี่ยวกับสมาชิก",I.users],
        ["ตั้งค่า / ระบบ",staffKpiFmt(summary.settings_actions),"กิจกรรมด้านดูแลระบบ",I.grid],
        ["อัตราทีมที่มีกิจกรรม",activeRate.toLocaleString("th-TH",{maximumFractionDigits:1})+"%","สัดส่วนบัญชีที่มี log",I.check],
        ["เฉลี่ย Action / คน",average.toLocaleString("th-TH",{maximumFractionDigits:1}),"เฉลี่ยในกลุ่มที่มีกิจกรรม",I.grid],
        ["จำนวนเซสชัน",sessionData?staffKpiFmt(sessionSummary.sessions_total):"—","นับ Login จริงหลังเปิดใช้ระบบ",I.check],
        ["เวลาเซสชันสะสม",sessionData?staffKpiDuration(sessionSummary.total_minutes):"—","เวลาประมาณจาก heartbeat / Logout",I.grid],
        ["กำลังใช้งาน",sessionData?staffKpiFmt(sessionSummary.active_sessions):"—","มี heartbeat ภายใน 5 นาที",I.users]
      ].map(([label,value,caption,icon],index)=>{const color=kpiColors[index%kpiColors.length];const gradient=`linear-gradient(135deg, ${color} 0%, ${darkenHex(color,0.24)} 100%)`;return <div key={label} className="relative min-h-[106px] overflow-hidden rounded-2xl border border-transparent p-3 text-white shadow-md" style={{background:gradient}}>
        <div className="pointer-events-none absolute -bottom-5 -right-3 opacity-[0.16]"><Ic d={icon} size={92} sw={1.5}/></div>
        <div className="relative flex items-start gap-2"><span className="min-h-[2.5rem] flex-1 text-sm font-semibold leading-5 text-white/90">{label}</span><span className="grid h-7 w-7 shrink-0 place-items-center rounded-lg bg-white/20 text-white"><Ic d={icon} size={15}/></span></div>
        <div className="relative mt-1.5 text-xl font-bold tracking-tight tabular-nums">{loading?"—":value}</div>
        <div className="relative mt-1 text-[10px] leading-4 text-white/75">{caption}</div>
      </div>})}
    </div>

    {sessionErr&&<div className="rounded-lg border border-amber-200 bg-amber-50 px-3 py-2 text-xs text-amber-800">โหลดข้อมูลเวลาเซสชันไม่ได้: {sessionErr} · ตรวจ migration และ API session tracking</div>}
    {err?<div className="rounded-xl border border-red-200 bg-red-50 px-4 py-10 text-center"><div className="text-sm font-semibold text-red-800">{err}</div><button onClick={load} className="mt-3 rounded-lg border border-red-200 bg-white px-3 py-1.5 text-xs hover:bg-red-50">ลองอีกครั้ง</button></div>:<>
      {tab==="overview"&&<>{tablePanel}{heatmapPanel}</>}
      {tab==="staff"&&tablePanel}
      {tab==="hours"&&heatmapPanel}
      {tab==="compare"&&comparisonPanel}
    </>}
  </div>);
}
