/* =========================================================================
   screens-core.jsx — Dashboard, Workers, Sites
   ========================================================================= */

/* ====================== DASHBOARD ====================== */
function Dashboard({ go }){
  const { db } = useDB();
  const period = currentPeriod();
  const todayStr = ymd(TODAY);

  const payrolls = db.workers.map(w => computePayroll(db, w.id, period));
  const totalNet = payrolls.reduce((s,p)=>s+p.net,0);
  const totalOtHours = payrolls.reduce((s,p)=>s+p.otHours,0);
  const totalGross = payrolls.reduce((s,p)=>s+p.gross,0);
  const activeWorkers = db.workers.filter(w=>w.active).length;
  const activeSites = db.sites.filter(s=>s.active).length;

  const todayAtt = db.attendance.filter(a=>a.date===todayStr);
  const presentToday = todayAtt.filter(a=>a.status!=='absent').length;

  const siteRows = siteCostReport(db, period).filter(r=>r.total>0).sort((a,b)=>b.total-a.total);
  const maxSite = Math.max(1, ...siteRows.map(r=>r.total));

  // top earners
  const topEarners = [...payrolls].sort((a,b)=>b.net-a.net).slice(0,5);

  return (
    <div data-screen className="space-y-6">
      <PageHead
        title="ภาพรวมระบบ"
        sub={`งวดปัจจุบัน ${period.label} (${period.range}) · วันนี้ ${thaiDateLong(todayStr)}`}
        actions={<>
          <Button variant="dark" icon="check" onClick={()=>go('attendance')} className="hidden sm:inline-flex">ลงเวลาวันนี้</Button>
          <Button icon="slip" onClick={()=>go('payslip')}>ออกสลิป</Button>
        </>}
      />

      <div className="grid grid-cols-2 lg:grid-cols-4 gap-4">
        <Stat strip label="ยอดจ่ายสุทธิงวดนี้" value={baht(totalNet,0)} sub={`ก่อนหัก ${baht(totalGross,0)}`} icon="money" tone="brand"/>
        <Stat label="ลงเวลาวันนี้" value={`${presentToday}/${activeWorkers}`} sub="คนเข้างาน" icon="check" tone="ok"/>
        <Stat label="ชั่วโมง OT รวม" value={num(totalOtHours)} sub="ชั่วโมงสะสมงวดนี้" icon="bolt" tone="hazard"/>
        <Stat label="ไซต์งานที่เปิด" value={num(activeSites)} sub={`จากทั้งหมด ${db.sites.length} ไซต์`} icon="site" tone="chalk"/>
      </div>

      <div className="grid lg:grid-cols-3 gap-6">
        {/* site cost allocation */}
        <Card className="lg:col-span-2">
          <div className="flex items-center justify-between mb-5">
            <div>
              <h2 className="font-display font-bold text-lg whitespace-nowrap">ต้นทุนค่าแรงแยกตามไซต์งาน</h2>
              <p className="text-haze text-sm">ปันส่วนค่าแรง + OT เข้าแต่ละหน้างาน</p>
            </div>
            <Button variant="ghost" size="sm" iconR="arrow" onClick={()=>go('payroll')}>ดูทั้งหมด</Button>
          </div>
          <div className="space-y-4">
            {siteRows.length===0 && <div className="text-haze text-sm py-6 text-center">ยังไม่มีข้อมูลต้นทุน</div>}
            {siteRows.map(r=>(
              <div key={r.site.id}>
                <div className="flex items-center justify-between mb-1.5 text-sm">
                  <div className="flex items-center gap-2 min-w-0">
                    <span className="num text-xs text-haze">{r.site.code}</span>
                    <span className="font-medium truncate">{r.site.name}</span>
                    <span className="text-xs text-haze shrink-0 whitespace-nowrap">· {r.workerCount} คน</span>
                  </div>
                  <span className="num font-semibold text-brand shrink-0">{baht(r.total,0)}</span>
                </div>
                <div className="h-2.5 rounded-full bg-ink overflow-hidden flex">
                  <div className="h-full bg-brand" style={{width:`${(r.base/maxSite)*100}%`}}></div>
                  <div className="h-full bg-hazard" style={{width:`${(r.ot/maxSite)*100}%`}}></div>
                </div>
              </div>
            ))}
          </div>
          <div className="flex items-center gap-4 mt-5 pt-4 border-t border-line text-xs text-haze">
            <span className="flex items-center gap-1.5"><span className="w-3 h-3 rounded-sm bg-brand"></span>ค่าแรงฐาน</span>
            <span className="flex items-center gap-1.5"><span className="w-3 h-3 rounded-sm bg-hazard"></span>ค่าล่วงเวลา (OT)</span>
          </div>
        </Card>

        {/* top earners */}
        <Card>
          <h2 className="font-display font-bold text-lg mb-1">ยอดจ่ายสูงสุด</h2>
          <p className="text-haze text-sm mb-4">5 อันดับแรกเดือนนี้</p>
          <div className="space-y-3">
            {topEarners.map((p,i)=>(
              <div key={p.worker.id} className="flex items-center gap-3">
                <span className="num text-sm text-haze w-4">{i+1}</span>
                <Avatar name={p.worker.name} photo={p.worker.photo} size={36}/>
                <div className="min-w-0 flex-1">
                  <div className="font-medium text-sm truncate">{p.worker.name}</div>
                  <div className="text-xs text-haze">{p.worker.group}</div>
                </div>
                <span className="num font-semibold text-sm">{baht(p.net,0)}</span>
              </div>
            ))}
          </div>
        </Card>
      </div>

      {/* today attendance strip */}
      <Card>
        <div className="flex items-center justify-between mb-4">
          <h2 className="font-display font-bold text-lg whitespace-nowrap">การลงเวลาวันนี้</h2>
          <Button variant="dark" size="sm" icon="check" onClick={()=>go('attendance')}>จัดการลงเวลา</Button>
        </div>
        {todayAtt.length===0 ? (
          <Empty icon="check" title="ยังไม่มีการลงเวลาวันนี้" sub="เริ่มลงเวลาให้คนงานในหน้าลงเวลาเข้างาน"
            action={<Button icon="plus" onClick={()=>go('attendance')}>ลงเวลาเข้างาน</Button>} />
        ) : (
          <div className="grid sm:grid-cols-2 lg:grid-cols-3 gap-3">
            {todayAtt.map(a=>{
              const w = db.workers.find(x=>x.id===a.workerId);
              const s = db.sites.find(x=>x.id===a.siteId);
              const st = STATUS[a.status];
              if(!w) return null;
              return (
                <div key={a.id} className="flex items-center gap-3 bg-ink border border-line rounded-lg p-3">
                  <Avatar name={w.name} photo={w.photo} size={38}/>
                  <div className="min-w-0 flex-1">
                    <div className="font-medium text-sm truncate">{w.name}</div>
                    <div className="text-xs text-haze flex items-center gap-1 truncate"><Icon name="pin" size={12}/>{s?.name||'—'}</div>
                    {a.note && <div className="text-xs text-haze/80 flex items-center gap-1 truncate mt-0.5" title={a.note}><Icon name="edit" size={11}/>{a.note}</div>}
                  </div>
                  <div className="text-right shrink-0">
                    <Badge tone={st.tone}>{st.th}</Badge>
                    {a.otHours>0 && <div className="text-xs text-hazard num mt-1">OT {a.otHours} ชม.</div>}
                    {a.advance>0 && <div className="text-xs text-brand num mt-0.5">เบิก {baht(a.advance,0)}</div>}
                  </div>
                </div>
              );
            })}
          </div>
        )}
      </Card>
    </div>
  );
}

/* ====================== WORKERS ====================== */
const emptyWorker = () => ({ id:null, code:'', name:'', nickname:'', type:'daily', dailyRate:500, monthlyRate:0, otRate:90, group:'', phone:'', bankName:'', bankAccount:'', photo:'', startDate:'', active:true, nationalId:'', idCard:'' });

function PhotoUpload({ value, name, onChange }){
  const ref = uR(null);
  const pick = (file)=>{ if(!file) return; const r=new FileReader(); r.onload=()=>onChange(r.result); r.readAsDataURL(file); };
  return (
    <div className="flex items-center gap-4">
      <div className="relative">
        <Avatar name={name||'?'} photo={value} size={72}/>
        {value && <button type="button" onClick={()=>onChange('')} className="tap absolute -top-1.5 -right-1.5 w-6 h-6 rounded-full bg-bad text-white flex items-center justify-center border-2 border-panel"><Icon name="close" size={13}/></button>}
      </div>
      <div>
        <input ref={ref} type="file" accept="image/*" className="hidden" onChange={e=>pick(e.target.files[0])}/>
        <Button type="button" variant="dark" size="sm" icon="camera" onClick={()=>ref.current.click()}>{value?'เปลี่ยนรูป':'อัปโหลดรูป'}</Button>
        <div className="text-xs text-haze mt-1.5">รูปถ่ายคนงาน (jpg/png)</div>
      </div>
    </div>
  );
}

function IdCardUpload({ value, onChange }){
  const ref = uR(null);
  const pick = (file)=>{
    if(!file) return;
    if(file.size > 3*1024*1024){ alert('ไฟล์ใหญ่เกินไป กรุณาใช้รูปไม่เกิน 3MB'); return; }
    const r=new FileReader(); r.onload=()=>onChange(r.result); r.readAsDataURL(file);
  };
  const isImg = value && value.startsWith('data:image');
  return (
    <div className="flex items-center gap-4">
      <div className="relative">
        {value ? (
          isImg
            ? <img src={value} alt="สำเนาบัตร" className="w-24 h-16 object-cover rounded-lg border border-line"/>
            : <div className="w-24 h-16 rounded-lg border border-line bg-ink flex items-center justify-center text-haze"><Icon name="slip" size={24}/></div>
        ) : <div className="w-24 h-16 rounded-lg border border-dashed border-line bg-ink flex items-center justify-center text-haze"><Icon name="camera" size={22}/></div>}
        {value && <button type="button" onClick={()=>onChange('')} className="tap absolute -top-1.5 -right-1.5 w-6 h-6 rounded-full bg-bad text-white flex items-center justify-center border-2 border-panel"><Icon name="close" size={13}/></button>}
      </div>
      <div>
        <input ref={ref} type="file" accept="image/*" className="hidden" onChange={e=>pick(e.target.files[0])}/>
        <div className="flex gap-2">
          <Button type="button" variant="dark" size="sm" icon="camera" onClick={()=>ref.current.click()}>{value?'เปลี่ยนไฟล์':'แนบสำเนาบัตร'}</Button>
          {value && isImg && <Button type="button" variant="ghost" size="sm" onClick={()=>{ const w=window.open(); if(w) w.document.write('<img src="'+value+'" style="max-width:100%"/>'); }}>ดู</Button>}
        </div>
        <div className="text-xs text-haze mt-1.5">รูปสำเนาบัตรประชาชน (jpg/png ไม่เกิน 3MB)</div>
      </div>
    </div>
  );
}

function WorkerModal({ open, onClose, initial }){
  const { saveWorker } = useDB();
  const [w, setW] = uS(emptyWorker());
  uE(()=>{ if(open) setW(initial ? {...initial} : emptyWorker()); },[open,initial]);
  const f = (k,v)=> setW(p=>({...p,[k]:v}));
  const isMonthly = w.type!=='daily';
  const save = ()=>{ if(!w.name.trim()) return; saveWorker(w); onClose(); };
  return (
    <Modal open={open} onClose={onClose} title={initial?'แก้ไขข้อมูลคนงาน':'เพิ่มคนงานใหม่'}
      footer={<><Button variant="ghost" onClick={onClose}>ยกเลิก</Button><Button icon="check" onClick={save}>บันทึก</Button></>}>
      <div className="space-y-4">
        <PhotoUpload value={w.photo} name={w.name} onChange={v=>f('photo',v)}/>
        <div className="grid sm:grid-cols-3 gap-4">
          <Field label="ชื่อ-นามสกุล" req className="sm:col-span-2"><Input value={w.name} onChange={e=>f('name',e.target.value)} placeholder="เช่น สมชาย ใจดี"/></Field>
          <Field label="ชื่อเล่น"><Input value={w.nickname} onChange={e=>f('nickname',e.target.value)} placeholder="เช่น ชาย"/></Field>
        </div>
        <Field label="รหัสพนักงาน"><Input value={w.code} onChange={e=>f('code',e.target.value)} placeholder="EMP-011 (เว้นว่างให้ระบบตั้ง)"/></Field>
        <Field label="ประเภทการจ้าง" req>
          <div className="grid grid-cols-3 gap-2">
            {Object.values(TYPE).map(t=>(
              <button key={t.key} onClick={()=>f('type',t.key)}
                className={`tap rounded-lg border px-2 py-3 text-sm font-display font-semibold ${w.type===t.key?'border-brand bg-brand/12 text-brand':'border-line text-haze hover:border-haze/50'}`}>
                {t.th}
              </button>
            ))}
          </div>
        </Field>
        <div className="grid sm:grid-cols-2 gap-4">
          {!isMonthly
            ? <Field label="ค่าแรงต่อวัน (บาท)" req><NumberInput value={w.dailyRate} onChange={v=>f('dailyRate',v)} step={10}/></Field>
            : <Field label="เงินเดือน (บาท)" req><NumberInput value={w.monthlyRate} onChange={v=>f('monthlyRate',v)} step={500}/></Field>}
          <Field label="ค่า OT ต่อชั่วโมง (บาท)"><NumberInput value={w.otRate} onChange={v=>f('otRate',v)} step={5}/></Field>
        </div>
        <div className="grid sm:grid-cols-2 gap-4">
          <Field label="กลุ่มแรงงาน / ทีม"><Input value={w.group} onChange={e=>f('group',e.target.value)} placeholder="เช่น ทีมรับเหมา A"/></Field>
          <Field label="เบอร์โทร"><Input value={w.phone} onChange={e=>f('phone',e.target.value)} placeholder="08x-xxx-xxxx"/></Field>
        </div>
        <Field label="วันที่เริ่มงาน"><Input type="date" value={w.startDate||''} onChange={e=>f('startDate',e.target.value)} className="[color-scheme:dark]"/></Field>
        <div className="rounded-lg border border-line bg-ink p-4">
          <div className="flex items-center gap-2 mb-3 text-sm font-medium text-haze"><Icon name="user" size={16} className="text-brand"/>บัตรประชาชน (สำหรับตามตัว/ทำสัญญา)</div>
          <Field label="เลขบัตรประชาชน (13 หลัก)" className="mb-3">
            <Input value={w.nationalId||''} inputMode="numeric"
              onChange={e=>f('nationalId', e.target.value.replace(/[^0-9]/g,'').slice(0,13))}
              placeholder="x xxxx xxxxx xx x" className="num"/>
          </Field>
          <IdCardUpload value={w.idCard||''} onChange={v=>f('idCard',v)}/>
        </div>
        <div className="rounded-lg border border-line bg-ink p-4">
          <div className="flex items-center gap-2 mb-3 text-sm font-medium text-haze"><Icon name="money" size={16} className="text-brand"/>บัญชีรับเงินโอน (สำหรับจ่ายแบบโอนเงิน)</div>
          <div className="grid sm:grid-cols-2 gap-4">
            <Field label="ธนาคาร"><Input value={w.bankName} onChange={e=>f('bankName',e.target.value)} placeholder="เช่น กสิกรไทย"/></Field>
            <Field label="เลขที่บัญชี"><Input value={w.bankAccount} onChange={e=>f('bankAccount',e.target.value)} placeholder="xxx-x-xxxxx-x" className="num"/></Field>
          </div>
        </div>
      </div>
    </Modal>
  );
}

function Workers({ openProfile }){
  const { db, removeWorker } = useDB();
  const [q,setQ] = uS('');
  const [type,setType] = uS('all');
  const [modal,setModal] = uS(false);
  const [editing,setEditing] = uS(null);

  const list = db.workers.filter(w=>{
    if(type!=='all' && w.type!==type) return false;
    if(q && !(`${w.name} ${w.code} ${w.group}`.toLowerCase().includes(q.toLowerCase()))) return false;
    return true;
  });

  const openNew = ()=>{ setEditing(null); setModal(true); };
  const openEdit = (w)=>{ setEditing(w); setModal(true); };

  return (
    <div data-screen>
      <PageHead title="จัดการคนงาน" sub={`ทั้งหมด ${db.workers.length} คน · แยกตามประเภทการจ้างและกลุ่มแรงงาน`}
        actions={<Button icon="plus" onClick={openNew}>เพิ่มคนงาน</Button>} />

      <Card pad={false}>
        <div className="flex flex-wrap items-center gap-3 p-4 border-b border-line">
          <div className="relative flex-1 min-w-[200px]">
            <div className="absolute left-3 top-1/2 -translate-y-1/2 text-haze"><Icon name="search" size={18}/></div>
            <input value={q} onChange={e=>setQ(e.target.value)} placeholder="ค้นหาชื่อ / รหัส / ทีม"
              className={`${inputCls} pl-10`} />
          </div>
          <div className="flex gap-1.5 bg-ink border border-line rounded-lg p-1">
            {[['all','ทั้งหมด'],['daily','รายวัน'],['monthly','รายเดือน'],['permanent','ประจำ']].map(([k,l])=>(
              <button key={k} onClick={()=>setType(k)}
                className={`tap text-sm font-medium px-3 py-1.5 rounded-md ${type===k?'bg-brand text-ink':'text-haze hover:text-chalk'}`}>{l}</button>
            ))}
          </div>
        </div>

        {list.length===0 ? <Empty title="ไม่พบคนงาน" sub="ลองปรับคำค้นหรือเพิ่มคนงานใหม่" action={<Button icon="plus" onClick={openNew}>เพิ่มคนงาน</Button>}/> : (
          <div className="overflow-x-auto">
            <table className="w-full text-sm min-w-[720px]">
              <thead>
                <tr className="text-left text-haze border-b border-line">
                  <th className="font-medium px-4 py-3">คนงาน</th>
                  <th className="font-medium px-4 py-3">ประเภท</th>
                  <th className="font-medium px-4 py-3">กลุ่มแรงงาน</th>
                  <th className="font-medium px-4 py-3 text-right">อัตราค่าแรง</th>
                  <th className="font-medium px-4 py-3 text-right">OT/ชม.</th>
                  <th className="font-medium px-4 py-3"></th>
                </tr>
              </thead>
              <tbody>
                {list.map(w=>(
                  <tr key={w.id} className="border-b border-line/60 hover:bg-white/[0.02] cursor-pointer" onClick={()=>openProfile && openProfile(w.id)}>
                    <td className="px-4 py-3">
                      <div className="flex items-center gap-3">
                        <Avatar name={w.name} photo={w.photo} size={38}/>
                        <div>
                          <div className="font-medium flex items-center gap-2">{w.name}{w.nickname && <span className="text-haze font-normal">({w.nickname})</span>} {w.bankAccount && <Badge tone="haze"><Icon name="money" size={11}/>โอน</Badge>}</div>
                          <div className="text-xs text-haze num flex items-center gap-2">{w.code}{w.phone && <span className="flex items-center gap-1"><Icon name="phone" size={11}/>{w.phone}</span>}</div>
                        </div>
                      </div>
                    </td>
                    <td className="px-4 py-3"><TypeBadge type={w.type}/></td>
                    <td className="px-4 py-3 text-haze">{w.group||'—'}</td>
                    <td className="px-4 py-3 text-right num font-medium">
                      {w.type==='daily' ? `${baht(w.dailyRate,0)}/วัน` : `${baht(w.monthlyRate,0)}/ด.`}
                    </td>
                    <td className="px-4 py-3 text-right num text-haze">{w.otRate?baht(w.otRate,0):'—'}</td>
                    <td className="px-4 py-3">
                      <div className="flex items-center justify-end gap-1">
                        <button onClick={(e)=>{e.stopPropagation(); openProfile && openProfile(w.id);}} className="tap p-2 text-haze hover:text-brand rounded-md hover:bg-white/5" title="ดูประวัติ"><Icon name="history" size={17}/></button>
                        <button onClick={(e)=>{e.stopPropagation(); openEdit(w);}} className="tap p-2 text-haze hover:text-brand rounded-md hover:bg-white/5"><Icon name="edit" size={17}/></button>
                        <button onClick={(e)=>{e.stopPropagation(); if(confirm(`ลบ ${w.name}?`)) removeWorker(w.id); }} className="tap p-2 text-haze hover:text-bad rounded-md hover:bg-white/5"><Icon name="trash" size={17}/></button>
                      </div>
                    </td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
        )}
      </Card>

      <WorkerModal open={modal} onClose={()=>setModal(false)} initial={editing}/>
    </div>
  );
}

/* ====================== SITES ====================== */
function SiteModal({ open, onClose, initial }){
  const { saveSite } = useDB();
  const blank = { id:null, code:'', name:'', location:'', type:'construction', budget:0, active:true };
  const [s,setS] = uS(blank);
  uE(()=>{ if(open) setS(initial?{...initial}:blank); },[open,initial]);
  const f=(k,v)=>setS(p=>({...p,[k]:v}));
  const save=()=>{ if(!s.name.trim()) return; saveSite(s); onClose(); };
  return (
    <Modal open={open} onClose={onClose} title={initial?'แก้ไขไซต์งาน':'เพิ่มไซต์งานใหม่'}
      footer={<><Button variant="ghost" onClick={onClose}>ยกเลิก</Button><Button icon="check" onClick={save}>บันทึก</Button></>}>
      <div className="space-y-4">
        <Field label="ประเภทไซต์">
          <div className="grid grid-cols-3 gap-2">
            {Object.values(SITE_TYPE).map(t=>(
              <button key={t.key} type="button" onClick={()=>f('type',t.key)}
                className={`tap rounded-lg border px-2 py-3 text-sm font-display font-semibold flex flex-col items-center gap-1.5 ${s.type===t.key?'border-brand bg-brand/12 text-brand':'border-line text-haze hover:border-haze/50'}`}>
                <Icon name={t.icon} size={20}/>{t.th}
              </button>
            ))}
          </div>
        </Field>
        <div className="grid sm:grid-cols-3 gap-4">
          <Field label="รหัสไซต์" className="sm:col-span-1"><Input value={s.code} onChange={e=>f('code',e.target.value)} placeholder="BKK-05"/></Field>
          <Field label="ชื่อหน้างาน / โครงการ" className="sm:col-span-2"><Input value={s.name} onChange={e=>f('name',e.target.value)} placeholder="เช่น คอนโดสุขุมวิท 71"/></Field>
        </div>
        <Field label="ที่ตั้ง"><Input value={s.location} onChange={e=>f('location',e.target.value)} placeholder="เขต/อำเภอ จังหวัด"/></Field>
        <Field label="งบลิมิตค่าแรงต่องวด (บาท)" hint="ตั้งเป้าหมายค่าแรงต่องวด — ระบบจะเตือนเมื่อใกล้/เกิน (0 = ไม่จำกัด)">
          <NumberInput value={s.budget||0} onChange={v=>f('budget',v)} step={10000}/>
        </Field>
        <label className="flex items-center gap-3 bg-ink border border-line rounded-lg px-4 py-3 cursor-pointer">
          <input type="checkbox" checked={s.active} onChange={e=>f('active',e.target.checked)} className="w-4 h-4 accent-brand"/>
          <div className="text-sm font-medium">เปิดใช้งานไซต์นี้</div>
        </label>
      </div>
    </Modal>
  );
}

function Sites({ openSite }){
  const { db, removeSite } = useDB();
  const [modal,setModal]=uS(false);
  const [editing,setEditing]=uS(null);
  const period = currentPeriod();
  const report = siteCostReport(db, period);
  const reportMap = Object.fromEntries(report.map(r=>[r.site.id,r]));

  return (
    <div data-screen>
      <PageHead title="ไซต์งาน / หน้างาน" sub={`${db.sites.length} ไซต์ · ต้นทุนค่าแรง + งบลิมิต ${period.label}`}
        actions={<Button icon="plus" onClick={()=>{setEditing(null);setModal(true);}}>เพิ่มไซต์งาน</Button>} />

      <div className="grid sm:grid-cols-2 lg:grid-cols-3 gap-4">
        {db.sites.map(s=>{
          const r = reportMap[s.id];
          const st = SITE_TYPE[s.type||'construction'];
          const toneText = { brand:'text-brand', hazard:'text-hazard', ok:'text-ok' }[st.tone];
          const used = r?.total||0;
          const budget = s.budget||0;
          const over = budget>0 && used>budget;
          const pctTxt = budget>0 ? Math.round(used/budget*100) : null;
          return (
            <Card key={s.id} className="relative overflow-hidden cursor-pointer hover:border-haze/40 transition" onClick={()=>openSite && openSite(s.id)}>
              <div className={`absolute top-0 left-0 right-0 h-1 ${s.active?'brand-strip':'bg-line'}`}></div>
              <div className="flex items-start justify-between gap-2 mb-3">
                <div className="flex items-center gap-3 min-w-0">
                  <div className={`w-11 h-11 rounded-lg bg-white/5 border border-line flex items-center justify-center shrink-0 ${toneText}`}><Icon name={st.icon}/></div>
                  <div className="min-w-0">
                    <div className="num text-xs text-haze flex items-center gap-1.5">{s.code} <Badge tone={st.tone}>{st.th}</Badge></div>
                    <div className="font-display font-semibold truncate">{s.name}</div>
                  </div>
                </div>
                <Badge tone={s.active?'ok':'haze'}>{s.active?'เปิด':'ปิด'}</Badge>
              </div>
              <div className="text-sm text-haze flex items-center gap-1.5 mb-4"><Icon name="pin" size={14}/>{s.location||'—'}</div>
              <div className="grid grid-cols-2 gap-3 mb-3">
                <div className="bg-ink rounded-lg p-3 border border-line">
                  <div className="text-xs text-haze">{st.key==='construction'?'ค่าแรงงวดนี้':'ค่าจ้างงวดนี้'}</div>
                  <div className="num font-display font-bold text-lg text-brand">{baht(used,0)}</div>
                </div>
                <div className="bg-ink rounded-lg p-3 border border-line">
                  <div className="text-xs text-haze">คนในไซต์</div>
                  <div className="num font-display font-bold text-lg">{r?.workerCount||0} คน</div>
                </div>
              </div>
              {budget>0 ? (
                <div className="mb-4">
                  <div className="flex items-center justify-between text-xs mb-1.5">
                    <span className="text-haze">งบลิมิต {baht(budget,0)}</span>
                    <span className={`num font-semibold ${over?'text-bad':pctTxt>85?'text-warn':'text-ok'}`}>{over?'เกินงบ ':''}{pctTxt}%</span>
                  </div>
                  <Progress value={used} max={budget}/>
                </div>
              ) : <div className="text-xs text-haze mb-4">ไม่ได้ตั้งงบลิมิต</div>}
              <div className="flex gap-2">
                <Button variant="dark" size="sm" icon="chart" onClick={(e)=>{e.stopPropagation(); openSite && openSite(s.id);}} className="flex-1">ดูรายละเอียด</Button>
                <Button variant="ghost" size="sm" onClick={(e)=>{e.stopPropagation(); setEditing(s);setModal(true);}} className="!px-3"><Icon name="edit" size={17}/></Button>
                <Button variant="ghost" size="sm" onClick={(e)=>{e.stopPropagation(); if(confirm(`ลบไซต์ ${s.name}?`)) removeSite(s.id); }} className="!px-3"><Icon name="trash" size={17}/></Button>
              </div>
            </Card>
          );
        })}
      </div>
      <SiteModal open={modal} onClose={()=>setModal(false)} initial={editing}/>
    </div>
  );
}

Object.assign(window, { Dashboard, Workers, Sites, WorkerModal });
