// ============================================================
// requests.jsx — ส่งคำขอ (อยู่แทน/แลกเวร) + ขอวันหยุด + OT + แจ้งเตือน
// ============================================================
const { useState:uSR, useMemo:uMR } = React;

// ============================================================
// 1. SendRequestModal — dialog หลัก (เหมือน reference)
// ============================================================
function SendRequestModal({ targetStaff, targetDate, store, currentUserId, sendRequest, onClose }){
  const [step, setStep] = uSR('choose'); // choose → swap_pick
  const tAssign = assignmentsForDate(targetDate, store.overrides, store.leaves)[targetStaff.id];
  const tb = tAssign && tAssign!=='off' ? BRANCHES[tAssign.b] : null;
  const ts = tAssign && tAssign!=='off' ? SHIFTS[tAssign.s] : null;

  const handleStandIn = ()=>{
    sendRequest('standin', currentUserId, targetStaff.id, targetDate, null);
    onClose();
  };

  if(step==='swap_pick') return (
    <Overlay onClose={onClose}>
      <ModalBox title="เลือกเวรที่จะเสนอแลก" onClose={onClose}>
        <SwapDatePicker currentUserId={currentUserId} store={store}
          onPick={(offerDate)=>{ sendRequest('swap',currentUserId,targetStaff.id,targetDate,offerDate); onClose(); }}
          onBack={()=>setStep('choose')}/>
      </ModalBox>
    </Overlay>
  );

  return (
    <Overlay onClose={onClose}>
      <div style={{background:'#fff',borderRadius:20,width:'min(420px,95vw)',boxShadow:'0 32px 72px -20px rgba(0,0,0,.5)'}}>
        {/* header */}
        <div style={{padding:'18px 22px',borderBottom:'1px solid #eef0f4',display:'flex',alignItems:'center',justifyContent:'space-between'}}>
          <div style={{display:'flex',alignItems:'center',gap:8}}>
            <span style={{fontSize:18}}>⇄</span>
            <span style={{fontWeight:700,fontSize:17,fontFamily:'Anuphan'}}>ส่งคำขอ</span>
          </div>
          <button onClick={onClose} style={{border:'none',background:'#f0f1f5',width:32,height:32,borderRadius:'50%',cursor:'pointer',fontSize:16,color:'#6b7282'}}>✕</button>
        </div>
        {/* shift info card */}
        <div style={{margin:'16px 22px 0',background:'#f7f8fb',borderRadius:14,padding:'14px 16px'}}>
          <div style={{fontSize:12,color:'#9aa1b0',fontWeight:600,marginBottom:8}}>เวรของ {targetStaff.nick}</div>
          <div style={{display:'grid',gridTemplateColumns:'1fr 1fr',gap:'8px 0'}}>
            <InfoRow icon="📅" text={`${targetDate.getDate()} ${MONTHS_TH[targetDate.getMonth()]} ${thaiYear(targetDate.getFullYear())}`}/>
            <InfoRow icon={ts?'☀️':'—'} text={ts ? `${ts.label} · ${ts.time}` : '—'}/>
            <InfoRow icon="📍" text={tb ? tb.name : '—'}/>
            <InfoRow icon="👤" text={targetStaff.full}/>
          </div>
        </div>
        {/* choice cards */}
        <div style={{padding:'16px 22px',display:'grid',gridTemplateColumns:'1fr 1fr',gap:12}}>
          <ChoiceCard icon="🧑‍💼" color="#1f9e8f" tint="#e6f5f2"
            title="อยู่แทน" sub="อยู่แทนเพื่อน" onClick={handleStandIn}/>
          <ChoiceCard icon="⇄" color="#6664c4" tint="#ececfb"
            title="แลกเวร" sub="เสนอแลกเวรของคุณ" onClick={()=>setStep('swap_pick')}/>
        </div>
        <div style={{padding:'0 22px 18px'}}>
          <button onClick={onClose} style={{width:'100%',padding:'11px',border:'1px solid #fecaca',borderRadius:12,
            background:'#fff',color:'#e05050',fontSize:13.5,fontWeight:600,cursor:'pointer',fontFamily:'inherit'}}>ยกเลิก</button>
        </div>
      </div>
    </Overlay>
  );
}

function InfoRow({ icon, text }){
  return <div style={{display:'flex',alignItems:'center',gap:6,fontSize:13,color:'#2b2f3a'}}>
    <span style={{fontSize:14}}>{icon}</span>{text}
  </div>;
}
function ChoiceCard({ icon, color, tint, title, sub, onClick }){
  const [hov,setHov]=uSR(false);
  return <button onClick={onClick} onMouseEnter={()=>setHov(true)} onMouseLeave={()=>setHov(false)}
    style={{border:`1.5px solid ${hov?color:tint}`,borderRadius:14,padding:'18px 10px',background:hov?tint+'cc':tint,
    cursor:'pointer',fontFamily:'inherit',textAlign:'center',transition:'all .15s'}}>
    <div style={{fontSize:28,marginBottom:6}}>{icon}</div>
    <div style={{fontWeight:700,fontSize:14,color,fontFamily:'Anuphan'}}>{title}</div>
    <div style={{fontSize:11,color:'#8a91a0',marginTop:3}}>{sub}</div>
  </button>;
}

function SwapDatePicker({ currentUserId, store, onPick, onBack }){
  const year = TODAY.getFullYear(), month = TODAY.getMonth();
  const days  = daysOfMonth(year, month);
  const firstDow = new Date(year, month, 1).getDay();
  const me = STAFF_BY_ID[currentUserId];

  // precompute assignments
  const assigns = {};
  days.forEach(d => {
    assigns[d.getDate()] = assignmentsForDate(d, store.overrides, store.leaves)[currentUserId];
  });

  const [hovered, setHovered] = uSR(null);

  return (
    <div>
      <div style={{fontSize:12.5,color:'#7b8194',marginBottom:12}}>
        เลือกวันเวรของคุณที่จะเสนอแลก · <b style={{color:'#3b3f4e'}}>{MONTHS_TH[month]} {thaiYear(year)}</b>
      </div>

      {/* day-of-week header */}
      <div style={{display:'grid',gridTemplateColumns:'repeat(7,1fr)',gap:3,marginBottom:4}}>
        {WEEKDAYS_SHORT.map((d,i)=>(
          <div key={i} style={{textAlign:'center',fontSize:11,fontWeight:700,color:DOW_COLORS[i],padding:'3px 0'}}>{d}</div>
        ))}
      </div>

      {/* calendar grid */}
      <div style={{display:'grid',gridTemplateColumns:'repeat(7,1fr)',gap:3}}>
        {/* leading empty cells */}
        {Array(firstDow).fill(null).map((_,i)=><div key={`e${i}`}/>)}

        {days.map(d=>{
          const dn   = d.getDate();
          const a    = assigns[dn];
          const isWorking = a && a !== 'off';
          const b    = isWorking ? BRANCHES[a.b] : null;
          const sh   = isWorking ? SHIFTS[a.s]   : null;
          const isToday = isSameDay(d, TODAY);
          const isHov = hovered === dn;

          return (
            <button
              key={dn}
              disabled={!isWorking}
              onClick={()=> isWorking && onPick(d)}
              onMouseEnter={()=> isWorking && setHovered(dn)}
              onMouseLeave={()=> setHovered(null)}
              style={{
                border: isWorking
                  ? `2px solid ${isHov ? b.solid : b.tint}`
                  : '2px solid transparent',
                borderRadius: 10,
                background: isWorking
                  ? (isHov ? b.tint : '#fff')
                  : '#f7f8fb',
                cursor: isWorking ? 'pointer' : 'default',
                fontFamily: 'inherit',
                padding: '5px 3px 6px',
                display: 'flex',
                flexDirection: 'column',
                alignItems: 'center',
                gap: 3,
                transition: 'all .13s',
                outline: isToday ? `2px solid ${isWorking ? b.solid : '#9aa3b2'}` : 'none',
                outlineOffset: 1,
              }}
            >
              {/* date number */}
              <span style={{
                fontWeight: 700,
                fontSize: 13,
                fontFamily: 'Anuphan',
                color: !isWorking ? '#c5c9d4' : DOW_COLORS[d.getDay()],
                lineHeight: 1,
              }}>{dn}</span>

              {/* branch dot + shift char */}
              {isWorking ? (
                <>
                  <span style={{
                    width: 7, height: 7,
                    borderRadius: '50%',
                    background: b.solid,
                    flexShrink: 0,
                  }}/>
                  <span style={{
                    fontSize: 9.5,
                    fontWeight: 700,
                    color: sh.text,
                    background: sh.tint,
                    borderRadius: 4,
                    padding: '1px 4px',
                    lineHeight: 1.4,
                  }}>{sh.char}</span>
                </>
              ) : (
                <span style={{fontSize:9,color:'#d5d8e0',lineHeight:1.2}}>—</span>
              )}
            </button>
          );
        })}
      </div>

      {/* legend */}
      <div style={{display:'flex',gap:12,marginTop:10,flexWrap:'wrap'}}>
        {Object.values(BRANCHES).filter(b=>b.id!=='off').map(b=>(
          <div key={b.id} style={{display:'flex',alignItems:'center',gap:5,fontSize:11,color:'#7b8194'}}>
            <span style={{width:8,height:8,borderRadius:'50%',background:b.solid,display:'inline-block'}}/>
            {b.name}
          </div>
        ))}
        {Object.values(SHIFTS).map(s=>(
          <div key={s.id} style={{display:'flex',alignItems:'center',gap:5,fontSize:11,color:'#7b8194'}}>
            <span style={{background:s.tint,color:s.text,borderRadius:4,padding:'1px 5px',fontWeight:700,fontSize:10}}>{s.char}</span>
            {s.label} {s.time}
          </div>
        ))}
      </div>

      <button onClick={onBack} style={{marginTop:12,width:'100%',padding:'10px',border:'1px solid #e3e6ee',
        borderRadius:12,background:'#fff',color:'#7b8194',fontSize:13,cursor:'pointer',fontFamily:'inherit'}}>← กลับ</button>
    </div>
  );
}

// ============================================================
// 2b. AdvanceLeaveModal — ยื่นขอวันหยุดล่วงหน้า (ก่อนวันที่ 28)
// ============================================================
function AdvanceLeaveModal({ staffId, targetMonth, store, requestAdvanceLeaves, onClose }){
  const [sel, setSel] = uSR(new Set());
  const [note, setNote] = uSR('');
  const year = targetMonth.getFullYear(), month = targetMonth.getMonth();
  const days = daysOfMonth(year, month);
  const deadline = TODAY.getDate() <= 28;
  const deadlineDate = `28 ${MONTHS_TH[TODAY.getMonth()]}`;
  const me = STAFF_BY_ID[staffId];

  const toggle = (d)=>{
    const k = d.getDate();
    setSel(s=>{ const n=new Set(s); n.has(k)?n.delete(k):n.add(k); return n; });
  };
  const submit = ()=>{
    const dates = days.filter(d=>sel.has(d.getDate()));
    requestAdvanceLeaves(dates, staffId, note.trim());
    onClose();
  };

  // days already requested
  const reqKeys = new Set(days.filter(d=>{
    const k=`${year}-${String(month+1).padStart(2,'0')}-${String(d.getDate()).padStart(2,'0')}_${staffId}`;
    return !!store.leaves[k];
  }).map(d=>d.getDate()));

  return (
    <Overlay onClose={onClose}>
      <ModalBox title={`ยื่นขอวันหยุดล่วงหน้า · ${MONTHS_TH[month]} ${thaiYear(year)}`} onClose={onClose} wide>
        {!deadline
          ? <div style={{textAlign:'center',padding:'20px 0',color:'#b94040',fontWeight:600}}>หมดเขตยื่นล่วงหน้าเดือนนี้แล้ว (หลังวันที่ 28)</div>
          : <>
            <div style={{background:'#fef5e0',border:'1px solid #e8c45a',borderRadius:10,padding:'10px 14px',marginBottom:14,fontSize:12.5,color:'#9a6a12'}}>
              📌 ยื่นได้ถึง <b>วันที่ {deadlineDate} {thaiYear(TODAY.getFullYear())}</b> · เลือกวันหยุดที่ต้องการในเดือน {MONTHS_TH[month]}
            </div>
            <div style={{display:'grid',gridTemplateColumns:'repeat(7,1fr)',gap:5,marginBottom:14}}>
              {WEEKDAYS_SHORT.map((d,i)=>(
                <div key={i} style={{textAlign:'center',fontSize:11,fontWeight:700,color:DOW_COLORS[i],padding:'4px 0'}}>{d}</div>
              ))}
              {Array(new Date(year,month,1).getDay()).fill(null).map((_,i)=><div key={`e${i}`}/>)}
              {days.map(d=>{
                const k=d.getDate(); const isSel=sel.has(k); const isReq=reqKeys.has(k);
                const isOff=STAFF_BY_ID[staffId].offDays.includes(d.getDay());
                return <button key={k} onClick={()=>!isReq&&!isOff&&toggle(d)}
                  disabled={isReq||isOff}
                  style={{width:'100%',aspectRatio:'1',borderRadius:10,border:`2px solid ${isSel?'#b8901f':'#ebedf2'}`,
                    background:isSel?'#fef5e0':isReq?'#f0f1f5':isOff?'#f7f8fb':'#fff',
                    color:isSel?'#9a6a12':isReq?'#aeb4c2':isOff?'#d0d4db':DOW_COLORS[d.getDay()],
                    fontWeight:700,fontSize:13,cursor:isReq||isOff?'default':'pointer',fontFamily:'Anuphan',
                    position:'relative'}}>
                  {k}
                  {isReq && <span style={{position:'absolute',top:1,right:2,fontSize:8,color:'#9aa1b0'}}>✓</span>}
                </button>;
              })}
            </div>
            {sel.size>0 && (
              <div style={{background:'#f5f6fa',borderRadius:10,padding:'8px 12px',marginBottom:12,fontSize:13,color:'#6b7282'}}>
                เลือกแล้ว <b style={{color:'#9a6a12'}}>{sel.size} วัน</b>: {[...sel].sort((a,b)=>a-b).join(', ')} {MONTHS_TH[month]}
              </div>
            )}
            <label style={{display:'block',fontSize:12.5,fontWeight:600,color:'#6b7282',marginBottom:6}}>หมายเหตุ (ถ้ามี)
              <textarea value={note} onChange={e=>setNote(e.target.value)} placeholder="ระบุเหตุผล..." rows={2}
                style={{width:'100%',border:'1.5px solid #e3e6ee',borderRadius:10,padding:'9px 12px',fontSize:13.5,fontFamily:'inherit',resize:'none',boxSizing:'border-box',marginTop:6}}/>
            </label>
            <div style={{display:'flex',gap:10,marginTop:4}}>
              <button onClick={onClose} style={{flex:1,padding:'11px',border:'1px solid #e3e6ee',borderRadius:12,background:'#fff',color:'#7b8194',fontSize:13,cursor:'pointer',fontFamily:'inherit'}}>ยกเลิก</button>
              <button onClick={submit} disabled={sel.size===0} style={{flex:2,padding:'11px',border:'none',borderRadius:12,background:sel.size>0?'linear-gradient(100deg,#9a7616,#c19a2a)':'#e9ebf0',color:sel.size>0?'#fff':'#aeb4c2',fontSize:14,fontWeight:700,cursor:sel.size>0?'pointer':'default',fontFamily:'inherit'}}>
                ส่งคำขอ {sel.size>0?`(${sel.size} วัน)`:''}
              </button>
            </div>
          </>}
      </ModalBox>
    </Overlay>
  );
}

// ============================================================
// 2c. EmergencyLeaveModal — ขอลาฉุกเฉิน
// ============================================================
function EmergencyLeaveModal({ date, staffId, store, requestLeave, cancelLeave, onClose }){
  const [note,setNote]=uSR('');
  const existing = store.leaves[dayKey(date,staffId)];
  const s = STAFF_BY_ID[staffId];
  const submit=()=>{ requestLeave(date,staffId,note.trim(),'emergency'); onClose(); };
  const cancel=()=>{ cancelLeave(date,staffId); onClose(); };
  return (
    <Overlay onClose={onClose}>
      <ModalBox title="ขอลาฉุกเฉิน" onClose={onClose}>
        <div style={{background:'#fff4e0',border:'1px solid #f0c04a',borderRadius:10,padding:'9px 13px',marginBottom:14,fontSize:12.5,color:'#9a6a12'}}>
          🚨 ใช้เฉพาะกรณีเร่งด่วน / ป่วยกะทันหัน
        </div>
        <div style={{fontSize:14,color:'#6b7282',marginBottom:16}}>
          📅 {date.getDate()} {MONTHS_TH[date.getMonth()]} {thaiYear(date.getFullYear())} — {s.nick}
        </div>
        {existing ? (
          <div>
            <StatusBanner status={existing.status}/>
            {existing.note && <div style={{fontSize:13,color:'#7b8194',marginTop:10}}>หมายเหตุ: "{existing.note}"</div>}
            {existing.status==='pending' && <button onClick={cancel} style={{...btnStyle2,background:'#fde8e8',color:'#b94040',marginTop:14,width:'100%'}}>ยกเลิกคำขอ</button>}
          </div>
        ):(
          <div>
            <label style={{display:'block',fontSize:12.5,fontWeight:600,color:'#6b7282',marginBottom:6}}>เหตุผล *
              <textarea value={note} onChange={e=>setNote(e.target.value)} placeholder="เช่น ป่วยกะทันหัน, ธุระด่วน..." rows={3}
                style={{width:'100%',border:'1.5px solid #e3e6ee',borderRadius:11,padding:'10px 12px',fontSize:14,fontFamily:'inherit',resize:'vertical',boxSizing:'border-box',marginTop:6}}/>
            </label>
            <button onClick={submit} style={{...btnStyle2,background:'linear-gradient(100deg,#9a7616,#c19a2a)',color:'#fff',marginTop:12,width:'100%'}}>ส่งคำขอลาฉุกเฉิน</button>
          </div>
        )}
      </ModalBox>
    </Overlay>
  );
}

// ============================================================
// 3. OTRequestModal — แจ้ง OT
// ============================================================
function OTRequestModal({ date, staffId, store, requestOT, cancelOT, onClose }){
  const [note,setNote]=uSR('');
  const [hours,setHours]=uSR(1);
  const existing = store.ots[dayKey(date,staffId)];
  const s = STAFF_BY_ID[staffId];
  const submit=()=>{ requestOT(date,staffId,note.trim(),hours); onClose(); };
  const cancel=()=>{ cancelOT(date,staffId); onClose(); };
  return (
    <Overlay onClose={onClose}>
      <ModalBox title="แจ้ง OT" onClose={onClose}>
        <div style={{fontSize:14,color:'#6b7282',marginBottom:16}}>
          ⏰ {date.getDate()} {MONTHS_TH[date.getMonth()]} {thaiYear(date.getFullYear())} — {s.nick}
        </div>
        {existing ? (
          <div>
            <StatusBanner status={existing.status}/>
            <div style={{fontSize:13,color:'#7b8194',marginTop:8}}>{existing.hours} ชั่วโมง {existing.note && `· "${existing.note}"`}</div>
            {existing.status==='pending' && <button onClick={cancel} style={{...btnStyle2,background:'#fde8e8',color:'#b94040',marginTop:14,width:'100%'}}>ยกเลิกคำขอ OT</button>}
          </div>
        ):(
          <div style={{display:'flex',flexDirection:'column',gap:12}}>
            <label style={{display:'block',fontSize:12.5,fontWeight:600,color:'#6b7282'}}>จำนวนชั่วโมง OT
              <div style={{display:'flex',alignItems:'center',gap:10,marginTop:6}}>
                <button onClick={()=>setHours(h=>Math.max(0.5,h-0.5))} style={numBtn}>−</button>
                <span style={{fontWeight:700,fontSize:18,fontFamily:'Anuphan',minWidth:36,textAlign:'center'}}>{hours}</span>
                <button onClick={()=>setHours(h=>Math.min(12,h+0.5))} style={numBtn}>+</button>
                <span style={{fontSize:12.5,color:'#9aa1b0'}}>ชั่วโมง</span>
              </div>
            </label>
            <label style={{display:'block',fontSize:12.5,fontWeight:600,color:'#6b7282'}}>หมายเหตุ
              <textarea value={note} onChange={e=>setNote(e.target.value)} placeholder="งานที่ทำ OT..." rows={2}
                style={{width:'100%',border:'1.5px solid #e3e6ee',borderRadius:11,padding:'9px 12px',fontSize:13.5,fontFamily:'inherit',resize:'none',boxSizing:'border-box',marginTop:6}}/>
            </label>
            <button onClick={submit} style={{...btnStyle2,background:'linear-gradient(100deg,#9a7616,#c19a2a)',color:'#fff'}}>ส่งคำขอ OT</button>
          </div>
        )}
      </ModalBox>
    </Overlay>
  );
}
const numBtn={width:32,height:32,borderRadius:8,border:'1px solid #e3e6ee',background:'#f5f6fa',fontSize:18,cursor:'pointer',fontFamily:'inherit'};

// ============================================================
// 4. NotificationPanel — การแจ้งเตือน (สำหรับทุกคน)
// ============================================================
function NotificationPanel({ currentUserId, isAdmin, store, updateRequest, cancelRequest, pendingRequestsFor, pendingLeavesAdmin, pendingOTsAdmin, updateLeave, updateOT, updateTransfer, pendingTransfersAdmin, onClose }){
  const incoming  = uMR(()=>pendingRequestsFor(currentUserId).map(r=>({...r,fromDate:new Date(r.targetDs+'T00:00:00'),offerDate:r.offerDs?new Date(r.offerDs+'T00:00:00'):null})),[store.requests]);
  const leaves    = uMR(()=>isAdmin?pendingLeavesAdmin():[],[store.leaves]);
  const ots       = uMR(()=>isAdmin?pendingOTsAdmin():[],[store.ots]);
  const transfers = uMR(()=>isAdmin&&pendingTransfersAdmin?pendingTransfersAdmin():[],[store.transfers]);
  const mySent    = uMR(()=>Object.entries(store.requests).map(([id,r])=>({...r,id})).filter(r=>r.fromSid===currentUserId).sort((a,b)=>b.at-a.at),[store.requests]);
  const total     = incoming.length + (isAdmin?(leaves.length+ots.length+transfers.length):0);

  return (
    <Overlay onClose={onClose}>
      <ModalBox title={`การแจ้งเตือน${total>0?` (${total})`:''}` } onClose={onClose}>
        {incoming.length>0 && <>
          <SectionLabel>คำขอที่รอการรับทราบจากคุณ</SectionLabel>
          {incoming.map(r=>{
            const from=STAFF_BY_ID[r.fromSid]; const tDate=new Date(r.targetDs+'T00:00:00');
            const tA=assignmentsForDate(tDate,store.overrides,store.leaves)[r.targetSid];
            return <div key={r.id} style={{background:'#fffaf0',border:'1px solid #f0d080',borderRadius:14,padding:'12px 14px',marginBottom:10}}>
              <div style={{fontWeight:600,fontSize:13.5,marginBottom:6}}>
                <span style={{color:'#9a7616'}}>{r.type==='standin'?'อยู่แทน':'แลกเวร'}</span> จาก {from.nick}
              </div>
              <div style={{fontSize:12.5,color:'#7b8194',marginBottom:10}}>
                เวรวันที่ {tDate.getDate()} {MONTHS_TH[tDate.getMonth()]}
                {tA&&tA!=='off'&&` · ${BRANCHES[tA.b].name} · ${SHIFTS[tA.s].label}`}
                {r.offerDs && ` ⇄ เสนอเวรวันที่ ${new Date(r.offerDs+'T00:00:00').getDate()} ${MONTHS_TH[new Date(r.offerDs+'T00:00:00').getMonth()]}`}
              </div>
              <div style={{display:'flex',gap:8}}>
                <button onClick={()=>updateRequest(r.id,'accepted')} style={{...btnStyle2,flex:1,background:'#e6f5f2',color:'#0e6b60'}}>รับทราบ / ยืนยัน</button>
                <button onClick={()=>updateRequest(r.id,'rejected')} style={{...btnStyle2,flex:1,background:'#fde8e8',color:'#b94040'}}>ปฏิเสธ</button>
              </div>
            </div>;
          })}
        </>}
        {isAdmin && leaves.length>0 && <>
          <SectionLabel>คำขอลา ({leaves.length})</SectionLabel>
          {leaves.map(l=>{
            const s=STAFF_BY_ID[l.staffId]; const d=new Date(l.ds+'T00:00:00');
            return <div key={l.staffId+'_'+l.ds} style={{background:'#f0f5ff',border:'1px solid #bfcff0',borderRadius:12,padding:'11px 14px',marginBottom:8}}>
              <div style={{fontWeight:600,fontSize:13,marginBottom:4}}>{s?.nick||l.staffId} · {d.getDate()} {MONTHS_TH[d.getMonth()]} <span style={{fontSize:11,color:'#8a91a0'}}>({l.ltype==='advance'?'ล่วงหน้า':'ฉุกเฉิน'})</span></div>
              {l.note && <div style={{fontSize:12,color:'#7b8194',marginBottom:8}}>"{l.note}"</div>}
              <div style={{display:'flex',gap:8}}>
                <button onClick={()=>updateLeave(d,l.staffId,'approved')} style={{...btnStyle2,flex:1,background:'#e6f5f2',color:'#0e6b60'}}>อนุมัติ</button>
                <button onClick={()=>updateLeave(d,l.staffId,'rejected')} style={{...btnStyle2,flex:1,background:'#fde8e8',color:'#b94040'}}>ปฏิเสธ</button>
              </div>
            </div>;
          })}
        </>}
        {isAdmin && ots.length>0 && <>
          <SectionLabel>คำขอ OT ({ots.length})</SectionLabel>
          {ots.map(o=>{
            const s=STAFF_BY_ID[o.staffId]; const d=new Date(o.ds+'T00:00:00');
            return <div key={o.staffId+'_'+o.ds} style={{background:'#f5f0ff',border:'1px solid #c8b8f0',borderRadius:12,padding:'11px 14px',marginBottom:8}}>
              <div style={{fontWeight:600,fontSize:13,marginBottom:4}}>{s?.nick||o.staffId} · {d.getDate()} {MONTHS_TH[d.getMonth()]} · {o.hours} ชม.</div>
              {o.note && <div style={{fontSize:12,color:'#7b8194',marginBottom:8}}>"{o.note}"</div>}
              <div style={{display:'flex',gap:8}}>
                <button onClick={()=>updateOT(d,o.staffId,'approved')} style={{...btnStyle2,flex:1,background:'#e6f5f2',color:'#0e6b60'}}>อนุมัติ</button>
                <button onClick={()=>updateOT(d,o.staffId,'rejected')} style={{...btnStyle2,flex:1,background:'#fde8e8',color:'#b94040'}}>ปฏิเสธ</button>
              </div>
            </div>;
          })}
        </>}
        {isAdmin && transfers.length>0 && <>
          <SectionLabel>คำขอสลับสาขา ({transfers.length})</SectionLabel>
          {transfers.map(t=>{
            const s=STAFF_BY_ID[t.staffId]; const d=new Date(t.ds+'T00:00:00');
            return <div key={t.staffId+'_'+t.ds} style={{background:'#f0f8ee',border:'1px solid #b8d8b0',borderRadius:12,padding:'11px 14px',marginBottom:8}}>
              <div style={{fontWeight:600,fontSize:13,marginBottom:4}}>🚗 {s?.nick||t.staffId} · {d.getDate()} {MONTHS_TH[d.getMonth()]}</div>
              <div style={{fontSize:12,color:'#7b8194',marginBottom:8}}>→ {BRANCHES[t.toBranch]?.name||t.toBranch} · {t.time} · ⛽ {t.fuel} บาท</div>
              <div style={{display:'flex',gap:8}}>
                <button onClick={()=>updateTransfer(d,t.staffId,'approved')} style={{...btnStyle2,flex:1,background:'#e6f5f2',color:'#0e6b60'}}>อนุมัติ</button>
                <button onClick={()=>updateTransfer(d,t.staffId,'rejected')} style={{...btnStyle2,flex:1,background:'#fde8e8',color:'#b94040'}}>ปฏิเสธ</button>
              </div>
            </div>;
          })}
        </>}
        {mySent.length>0 && <>
          <SectionLabel>คำขอที่ส่งออกไป</SectionLabel>
          {mySent.map(r=>{
            const target=STAFF_BY_ID[r.targetSid];
            const tDate=new Date(r.targetDs+'T00:00:00');
            const st=STATUS_STYLE[r.status]||STATUS_STYLE.pending;
            const typeLabel=r.type==='standin'?'อยู่แทน':'แลกเวร';
            const offerDate=r.offerDs?new Date(r.offerDs+'T00:00:00'):null;
            return (
              <div key={r.id} style={{background:'#fafbfc',border:'1px solid #ebedf2',borderRadius:12,padding:'11px 14px',marginBottom:8}}>
                <div style={{display:'flex',alignItems:'center',gap:8,marginBottom:r.status==='pending'?8:0}}>
                  <div style={{flex:1}}>
                    <span style={{fontWeight:600,fontSize:13,color:'#2b2f3a'}}>{typeLabel}</span>
                    <span style={{fontSize:12.5,color:'#7b8194'}}> กับ </span>
                    <span style={{fontWeight:700,fontSize:13}}>{target.nick}</span>
                    <span style={{fontSize:12,color:'#9aa1b0'}}> · วันที่ {tDate.getDate()} {MONTHS_TH[tDate.getMonth()]}</span>
                    {offerDate && <span style={{fontSize:12,color:'#9aa1b0'}}> ⇄ {offerDate.getDate()} {MONTHS_TH[offerDate.getMonth()]}</span>}
                  </div>
                  <span style={{background:st.bg,color:st.col,borderRadius:999,padding:'3px 10px',fontSize:11,fontWeight:700,whiteSpace:'nowrap'}}>{st.label}</span>
                </div>
                {r.status==='pending' && (
                  <button onClick={()=>cancelRequest(r.id)} style={{...btnStyle2,width:'100%',background:'#fde8e8',color:'#b94040',padding:'7px',fontSize:12.5}}>
                    ยกเลิกคำขอ
                  </button>
                )}
              </div>
            );
          })}
        </>}
        {incoming.length===0 && mySent.length===0 && leaves.length===0 && ots.length===0 && transfers.length===0 && <div style={{textAlign:'center',padding:'28px 0',color:'#aeb4c2',fontSize:14}}>ไม่มีการแจ้งเตือน</div>}
      </ModalBox>
    </Overlay>
  );
}

function SectionLabel({children}){ return <div style={{fontSize:11.5,fontWeight:700,color:'#9aa1b0',marginBottom:8,marginTop:4}}>{children}</div>; }
function StatusBanner({ status }){
  const st=STATUS_STYLE[status]||STATUS_STYLE.pending;
  return <div style={{background:st.bg,color:st.col,borderRadius:10,padding:'10px 14px',fontWeight:700,fontSize:14,textAlign:'center'}}>{st.label}</div>;
}
const btnStyle2={border:'none',cursor:'pointer',borderRadius:10,padding:'9px 14px',fontSize:13,fontWeight:600,fontFamily:'inherit'};

// ============================================================
// 5. TransferModal — สลับสาขาระหว่างวัน
// ============================================================
function TransferModal({ date, staffId, store, requestTransfer, cancelTransfer, onClose }){
  const existing = (store.transfers||{})[dayKey(date,staffId)];
  const s = STAFF_BY_ID[staffId];
  const myA = assignmentsForDate(date, store.overrides, store.leaves)[staffId];
  const myBranch = myA && myA!=='off' ? myA.b : null;
  const allBranches = Object.values(BRANCHES).filter(b=>b.id!=='off');
  const destOptions = myBranch ? allBranches.filter(b=>b.id!==myBranch) : allBranches;

  const [toBranch, setToBranch] = uSR(()=>destOptions.length>0 ? destOptions[0].id : 'b1');
  const [time, setTime] = uSR('13:00');
  const [fuel, setFuel] = uSR(60);

  const submit = ()=>{ requestTransfer(date,staffId,toBranch,time,fuel); onClose(); };
  const cancel = ()=>{ cancelTransfer(date,staffId); onClose(); };

  return (
    <Overlay onClose={onClose}>
      <ModalBox title="สลับสาขาระหว่างวัน" onClose={onClose}>
        <div style={{display:'flex',alignItems:'center',gap:8,fontSize:13.5,color:'#6b7282',marginBottom:16}}>
          <span>🚗</span>
          <span>{date.getDate()} {MONTHS_TH[date.getMonth()]} {thaiYear(date.getFullYear())} — {s.nick}</span>
          {myBranch && <span style={{background:BRANCHES[myBranch].tint,color:BRANCHES[myBranch].text,borderRadius:6,padding:'2px 8px',fontSize:12,fontWeight:700}}>{BRANCHES[myBranch].name}</span>}
        </div>
        {existing ? (
          <div>
            <StatusBanner status={existing.status}/>
            <div style={{fontSize:13,color:'#7b8194',marginTop:10,display:'flex',alignItems:'center',gap:6,flexWrap:'wrap'}}>
              <span>→</span>
              <span style={{background:BRANCHES[existing.toBranch]?.tint||'#f3f4f8',color:BRANCHES[existing.toBranch]?.text||'#6b7282',borderRadius:6,padding:'2px 8px',fontWeight:700,fontSize:12}}>{BRANCHES[existing.toBranch]?.name||existing.toBranch}</span>
              <span style={{color:'#9aa1b0'}}>· {existing.time} · ⛽ {existing.fuel} บาท</span>
            </div>
            {existing.status==='pending' && <button onClick={cancel} style={{...btnStyle2,background:'#fde8e8',color:'#b94040',marginTop:14,width:'100%'}}>ยกเลิกคำขอ</button>}
          </div>
        ):(
          <div style={{display:'flex',flexDirection:'column',gap:14}}>
            <label style={{display:'block',fontSize:12.5,fontWeight:600,color:'#6b7282'}}>ไปสาขา
              <select value={toBranch} onChange={e=>setToBranch(e.target.value)}
                style={{display:'block',width:'100%',marginTop:6,border:'1.5px solid #e3e6ee',borderRadius:10,padding:'9px 12px',fontSize:14,fontFamily:'inherit',background:'#fafbfc'}}>
                {destOptions.map(b=><option key={b.id} value={b.id}>{b.name}</option>)}
              </select>
            </label>
            <label style={{display:'block',fontSize:12.5,fontWeight:600,color:'#6b7282'}}>เวลาเริ่ม
              <input type="time" value={time} onChange={e=>setTime(e.target.value)}
                style={{display:'block',width:'100%',marginTop:6,border:'1.5px solid #e3e6ee',borderRadius:10,padding:'9px 12px',fontSize:14,fontFamily:'inherit',background:'#fafbfc',boxSizing:'border-box'}}/>
            </label>
            <label style={{display:'block',fontSize:12.5,fontWeight:600,color:'#6b7282'}}>ค่าน้ำมัน (บาท)
              <div style={{display:'flex',alignItems:'center',gap:10,marginTop:6}}>
                <button type="button" onClick={()=>setFuel(f=>Math.max(0,f-20))} style={numBtn}>−</button>
                <span style={{fontWeight:700,fontSize:18,fontFamily:'Anuphan',minWidth:36,textAlign:'center'}}>{fuel}</span>
                <button type="button" onClick={()=>setFuel(f=>f+20)} style={numBtn}>+</button>
                <span style={{fontSize:12.5,color:'#9aa1b0'}}>บาท</span>
              </div>
            </label>
            <button onClick={submit} style={{...btnStyle2,background:'linear-gradient(100deg,#9a7616,#c19a2a)',color:'#fff',padding:'11px',fontSize:14}}>บันทึกการสลับสาขา</button>
          </div>
        )}
      </ModalBox>
    </Overlay>
  );
}

Object.assign(window,{SendRequestModal,AdvanceLeaveModal,EmergencyLeaveModal,OTRequestModal,NotificationPanel,TransferModal});
