/* global React, window */
const { useState: useDashState, useEffect: useDashEffect } = React;

// FaceCheck palette (mirrors gov.css tokens)
const GP = { green:'#16A34A', greenInk:'#166534', amber:'#F59E0B', coral:'#EF4444', blue:'#0EA5E9', violet:'#8B5CF6', ink:'#1E293B', soft:'#64748B', faint:'#94A3B8' };

function dInitials(emp, fallbackName) {
  if (emp && (emp.first_name || emp.last_name)) return ((emp.first_name || '')[0] || '') + ((emp.last_name || '')[0] || '');
  const n = (fallbackName || '').trim();
  return n ? n.slice(0, 2) : '—';
}
function dName(scan) {
  if (scan.employee && (scan.employee.first_name || scan.employee.last_name)) return `${scan.employee.first_name || ''} ${scan.employee.last_name || ''}`.trim();
  if (scan.first_name || scan.last_name) return `${scan.first_name || ''} ${scan.last_name || ''}`.trim();
  return scan.employee_name || 'ไม่รู้จัก';
}
function scanTime(scan) {
  if (scan.time instanceof Date) { const p = (n) => String(n).padStart(2, '0'); return `${p(scan.time.getHours())}:${p(scan.time.getMinutes())}`; }
  return (scan.scan_time || scan.timestamp || '').slice(11, 16) || '--:--';
}
function scanDir(s) { return s.direction || s.type || 'in'; }
// ครั้งแรกของวัน = เข้า (ตรงเวลา/สาย) · ครั้งสุดท้าย = ออก · ระหว่างนั้น = เดินผ่าน ไม่มีผล
function feedDecor(f) {
  const dir = scanDir(f);
  if (dir === 'out') return { label:'ออก (ล่าสุด)', cls:'c-blue' };
  if (dir === 'mid') return { label:'ระหว่างวัน', cls:'c-gray' };
  const late = (f.daily && f.daily.late_min) || f.late_min || 0;
  if (late > 0) return { label:`เข้า · สาย ${late} นาที`, cls:'c-amber' };
  return { label:'เข้า · ตรงเวลา', cls:'c-green' };
}
function deptName(s) { return (s.department && s.department.name) || s.department_name || '—'; }
function dId(f) { return (f.employee && f.employee.id) || f.employeeId || f.employee_id || null; }
function DashAvatar({ f, size = 46 }) {
  const [err, setErr] = useDashState(false);
  const id = dId(f);
  const photo = f.photo_url || (f.employee && f.employee.photo_path ? `/faces/${f.employee.photo_path}` : (id ? `/faces/${id}.jpg` : null));
  const src = (err || !photo) ? '/img/avatar-person.svg' : photo;
  return <img src={src} alt="" onError={() => setErr(true)}
    onClick={() => id && window.openProfile && window.openProfile(id)} title={id ? 'ดูโปรไฟล์' : ''}
    style={{ width: size, height: size, borderRadius: '50%', objectFit: 'cover', flex: 'none', cursor: id ? 'pointer' : 'default', border: '1px solid var(--line)' }} />;
}
const LEAVE_TH = { sick:'ลาป่วย', personal:'ลากิจ', vacation:'ลาพักผ่อน', other:'ลาอื่นๆ' };
const leaveLabel = (t) => LEAVE_TH[t] || t || 'ลา';
const ANN_ICON = { holiday:'📌', urgent:'📢', hr:'🗓️', general:'✅' };
const ANN_TINT = { holiday:'var(--gv-coral-soft)', urgent:'var(--gv-coral-soft)', hr:'var(--gv-primary-soft)', general:'var(--gv-blue-soft)' };

function StatCard({ icon, tint, num, sub, label }) {
  return (
    <div className="gv-stat">
      <div style={{ display: 'flex', alignItems: 'center', gap: 11, marginBottom: 14 }}>
        <div className={`ic ${tint}`} style={{ margin: 0, flex: 'none' }}><svg viewBox="0 0 24 24">{icon}</svg></div>
        <div style={{ fontSize: 14.5, fontWeight: 600, color: 'var(--ink)', lineHeight: 1.25 }}>{label}</div>
      </div>
      <div className="num tnum">{num}{sub && <small> {sub}</small>}</div>
    </div>
  );
}

function Dashboard() {
  const [summary, setSummary] = useDashState(null);
  const [recent, setRecent] = useDashState(window.RECENT_SCANS || []);
  const [anns, setAnns] = useDashState([]);
  const [pending, setPending] = useDashState([]);
  const [trend, setTrend] = useDashState([]);
  const [view, setView] = useDashState('summary');

  // today summary
  useDashEffect(() => {
    let dead = false;
    fetch('/api/attendance/summary', { credentials:'include' }).then((r) => r.ok ? r.json() : null)
      .then((d) => { if (!dead && d) setSummary(d); }).catch(() => {});
    fetch('/api/announcements', { credentials:'include' }).then((r) => r.ok ? r.json() : [])
      .then((d) => { if (!dead && Array.isArray(d)) setAnns(d.slice(0, 4)); }).catch(() => {});
    fetch('/api/leaves?status=pending', { credentials:'include' }).then((r) => r.ok ? r.json() : null)
      .then((d) => { if (dead) return; const arr = Array.isArray(d) ? d : (d && d.leaves) || []; setPending(arr.slice(0, 6)); }).catch(() => {});
    return () => { dead = true; };
  }, []);

  // 7-day attendance rate (parallel per-day summary)
  useDashEffect(() => {
    let dead = false;
    const days = [];
    for (let i = 6; i >= 0; i--) { const d = new Date(); d.setDate(d.getDate() - i); days.push(d.toISOString().slice(0, 10)); }
    Promise.all(days.map((dt) => fetch(`/api/attendance/summary?date=${dt}`, { credentials:'include' })
      .then((r) => r.ok ? r.json() : null).catch(() => null)))
      .then((res) => {
        if (dead) return;
        setTrend(res.map((s, i) => {
          const total = s ? s.total : 0;
          const bs = (s && s.by_status) || {};
          const working = (bs.present || 0) + (bs.in_only || 0);
          return { date: days[i], rate: total ? Math.round(working / total * 100) : 0 };
        }));
      });
    return () => { dead = true; };
  }, []);

  // live scan stream
  useDashEffect(() => {
    if (!window.scanStream) return undefined;
    return window.scanStream.subscribe((scan) => {
      setRecent((prev) => [scan, ...prev].slice(0, 40));
      setSummary((prev) => {
        if (!prev || !scan.daily) return prev;
        const next = { ...prev.by_status };
        next.absent = Math.max(0, (next.absent || 0) - 1);
        next[scan.daily.status] = (next[scan.daily.status] || 0) + 1;
        return { ...prev, by_status: next };
      });
    });
  }, []);

  const total   = summary?.total ?? (window.EMPLOYEES?.length || 0);
  const present = summary?.by_status?.present ?? 0;
  const inOnly  = summary?.by_status?.in_only ?? 0;
  const late    = summary?.by_status?.late ?? 0;
  const leave   = summary?.by_status?.leave ?? 0;
  const absent  = summary?.by_status?.absent ?? Math.max(0, total - present - inOnly - leave);
  const working = present + inOnly;
  const rate = total ? Math.round(working / total * 100) : 0;

  const deptBars = (summary?.by_department || []).map((d) => {
    const p = (d.present || 0) + (d.in_only || 0);
    return { name: d.name, label: `${p}/${d.total}`, pct: d.total ? Math.round(p / d.total * 100) : 0, late: d.late || 0 };
  });

  const feed = recent.slice(0, 7);
  const maxRate = Math.max(100, ...trend.map((t) => t.rate));
  const dowShort = ['อา','จ','อ','พ','พฤ','ศ','ส'];

  const act = async (id, kind) => {
    try {
      await fetch(`/api/leaves/${id}/${kind}`, { method:'PUT', credentials:'include', headers:{ 'Content-Type':'application/json' }, body:'{}' });
      setPending((p) => p.filter((x) => x.id !== id));
      if (window.refreshData) window.refreshData();
    } catch (_) {}
  };

  return (
    <div data-screen-label="Dashboard">
      {/* view toggle */}
      <div style={{ display:'flex', justifyContent:'space-between', alignItems:'center', marginBottom:16, flexWrap:'wrap', gap:10 }}>
        <div className="gv-seg">
          <button className={view === 'summary' ? 'on' : ''} onClick={() => setView('summary')}>การ์ดสรุป</button>
          <button className={view === 'live' ? 'on' : ''} onClick={() => setView('live')}>ไทม์ไลน์สด</button>
        </div>
        <div style={{ fontSize:12.5, color:'var(--gv-soft)' }}>อัปเดตล่าสุด · เรียลไทม์จากเครื่องสแกน</div>
      </div>

      {/* stat cards */}
      <div className="gv-grid" style={{ marginBottom:16 }}>
        <StatCard tint="i-green" num={working} sub={`/ ${total}`} label={`มาทำงานแล้ว · ${rate}%`}
          icon={<path d="M20 6 9 17l-5-5"/>}/>
        <StatCard tint="i-amber" num={late} sub="คน" label="เข้าสาย"
          icon={<><circle cx="12" cy="12" r="9"/><path d="M12 8v4l3 2"/></>}/>
        <StatCard tint="i-coral" num={`${leave}/${absent}`} label="ลา / ขาด"
          icon={<><path d="M18 6 6 18M6 6l12 12"/></>}/>
        <StatCard tint="i-blue" num={inOnly} sub="รายการ" label="ยังไม่สแกนออก"
          icon={<><path d="M9 11l3 3 8-8"/><path d="M20 12v6a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h9"/></>}/>
      </div>

      {view === 'live' ? (
        <div className="gv-card">
          <div className="gv-card-h"><b>⏱️ ไทม์ไลน์การสแกนสด</b><span className="gv-chip c-green">{recent.length} วันนี้</span></div>
          <div className="gv-card-b">
            {recent.length === 0 ? <div className="gv-empty">— ยังไม่มีการสแกนวันนี้ —</div>
              : recent.slice(0, 30).map((f, i) => {
                const d = feedDecor(f);
                return (
                  <div className="gv-row" key={i}>
                    <DashAvatar f={f}/>
                    <div><div className="who">{dName(f)}</div><div className="meta">{deptName(f)} · {f.device_name || '—'}</div></div>
                    <div className="gv-row-act" style={{ alignItems:'center' }}>
                      <span className="tnum" style={{ fontSize:14, fontWeight:700 }}>{scanTime(f)}</span>
                      <span className={`gv-chip ${d.cls}`}>{d.label}</span>
                    </div>
                  </div>
                );
              })}
          </div>
        </div>
      ) : (
        <>
          {/* announcements + recent */}
          <div className="gv-cols" style={{ marginBottom:16 }}>
            <div className="gv-stack">
              <div className="gv-card">
                <div className="gv-card-h"><b>📢 ประกาศจากหน่วยงาน</b><button className="more" onClick={() => window.navigateTo && window.navigateTo('announce')}>ทั้งหมด</button></div>
                <div className="gv-card-b">
                  {anns.length === 0 ? <div className="gv-empty">ยังไม่มีประกาศ</div>
                    : anns.map((a) => (
                      <div className="gv-ann" key={a.id}>
                        <div className="pin" style={{ background: ANN_TINT[a.category] || 'var(--gv-surface-2)' }}>{ANN_ICON[a.category] || '📎'}</div>
                        <div>
                          <div className="ti">{a.pinned ? '📌 ' : ''}{a.title}</div>
                          {a.body && <div className="tx">{a.body}</div>}
                          <div className="dt">{(a.created_at || '').slice(0, 10)}{a.created_by ? ` · ${a.created_by}` : ''}</div>
                        </div>
                      </div>
                    ))}
                </div>
              </div>

              {/* departments */}
              <div className="gv-card">
                <div className="gv-card-h"><b>🏢 การมาทำงานแยกตาม{window.T.dept}</b><span style={{ fontSize:12, color:'var(--gv-faint)' }}>มา / ทั้งหมด</span></div>
                <div className="gv-card-b">
                  {deptBars.length === 0 ? <div className="gv-empty">ยังไม่มีข้อมูล{window.T.dept}</div>
                    : <div style={{ display:'flex', flexDirection:'column', gap:14 }}>
                        {deptBars.map((d, i) => (
                          <div key={i}>
                            <div style={{ display:'flex', justifyContent:'space-between', alignItems:'baseline', marginBottom:5 }}>
                              <span style={{ fontSize:13.5, fontWeight:500 }}>{d.name}</span>
                              <span className="tnum" style={{ fontSize:12.5, color:'var(--gv-soft)' }}>{d.label}{d.late ? ` · สาย ${d.late}` : ''}</span>
                            </div>
                            <div className="gv-bar"><i style={{ width:`${d.pct}%` }}/></div>
                          </div>
                        ))}
                      </div>}
                </div>
              </div>
            </div>

            <div className="gv-stack">
              {/* recent scans */}
              <div className="gv-card">
                <div className="gv-card-h"><b>⏱️ สแกนล่าสุด</b><span className="gv-chip c-green">สด</span></div>
                <div className="gv-card-b" style={{ paddingTop:6 }}>
                  {feed.length === 0 ? <div className="gv-empty">— ยังไม่มีการสแกน —</div>
                    : feed.map((f, i) => {
                      const d = feedDecor(f);
                      return (
                        <div className="gv-row" key={i}>
                          <DashAvatar f={f}/>
                          <div style={{ minWidth:0 }}><div className="who" style={{ whiteSpace:'nowrap', overflow:'hidden', textOverflow:'ellipsis' }}>{dName(f)}</div><div className="meta">{deptName(f)}</div></div>
                          <div className="gv-row-act" style={{ flexDirection:'column', alignItems:'flex-end', gap:3 }}>
                            <span className="tnum" style={{ fontSize:14, fontWeight:700 }}>{scanTime(f)}</span>
                            <span className={`gv-chip ${d.cls}`} style={{ padding:'1px 8px', fontSize:11 }}>{d.label}</span>
                          </div>
                        </div>
                      );
                    })}
                </div>
              </div>
            </div>
          </div>

          {/* 7-day + pending */}
          <div className="gv-cols">
            <div className="gv-card">
              <div className="gv-card-h"><b>📊 อัตราการมาทำงาน 7 วัน</b></div>
              <div className="gv-card-b">
                {trend.length === 0 ? <div className="gv-empty">กำลังรวบรวมข้อมูล…</div>
                  : <div style={{ display:'flex', alignItems:'flex-end', gap:10, height:150 }}>
                      {trend.map((t, i) => {
                        const dt = new Date(t.date + 'T00:00:00');
                        const isToday = i === trend.length - 1;
                        return (
                          <div key={i} style={{ flex:1, display:'flex', flexDirection:'column', alignItems:'center', gap:6, height:'100%', justifyContent:'flex-end' }}>
                            <span className="tnum" style={{ fontSize:11.5, fontWeight:700, color: isToday ? 'var(--gv-primary)' : 'var(--gv-soft)' }}>{t.rate}%</span>
                            <div style={{ width:'100%', maxWidth:34, height:`${Math.max(4, t.rate / maxRate * 100)}%`, background: isToday ? 'var(--gv-primary)' : 'var(--gv-primary-soft)', borderRadius:'8px 8px 4px 4px', transition:'height .4s' }}/>
                            <span style={{ fontSize:11, color:'var(--gv-faint)' }}>{dowShort[dt.getDay()]}</span>
                          </div>
                        );
                      })}
                    </div>}
              </div>
            </div>

            <div className="gv-card">
              <div className="gv-card-h"><b>📌 รอดำเนินการ</b>{pending.length > 0 && <span className="gv-chip c-amber">{pending.length}</span>}</div>
              <div className="gv-card-b">
                {pending.length === 0 ? <div className="gv-empty">ไม่มีคำขอค้าง 🎉</div>
                  : pending.map((p) => (
                    <div className="gv-row" key={p.id}>
                      <div>
                        <div className="who">{p.employee_name || p.first_name + ' ' + (p.last_name || '')}</div>
                        <div className="meta">{leaveLabel(p.leave_type)} · {(p.start_date || '').slice(5)}{p.end_date && p.end_date !== p.start_date ? `–${(p.end_date || '').slice(5)}` : ''}</div>
                      </div>
                      <div className="gv-row-act">
                        <button className="gv-btn no sm" onClick={() => act(p.id, 'reject')}>ปฏิเสธ</button>
                        <button className="gv-btn ok sm" onClick={() => act(p.id, 'approve')}>อนุมัติ</button>
                      </div>
                    </div>
                  ))}
                {pending.length > 0 && <button className="gv-btn ghost sm" style={{ marginTop:12 }} onClick={() => window.navigateTo && window.navigateTo('leave')}>ดูทั้งหมดในหน้าการลา</button>}
              </div>
            </div>
          </div>
        </>
      )}
    </div>
  );
}

window.Dashboard = Dashboard;
