// Manager-facing screens
const { useState: useStateM, useMemo: useMemoM } = React;
const { useEffect: useEffectM, useRef: useRefM } = React;
const fmtDateISO = (d) => `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`;

function QrDisplayModal({ onClose }) {
  const [secondsLeft, setSecondsLeft] = useStateM(30);
  const [token, setToken] = useStateM(null);
  const [err, setErr] = useStateM(null);
  const canvasRef = useRefM(null);

  // Fetch a token (called on mount + every 25s)
  const fetchToken = async () => {
    try {
      const r = await fetch('/api/checkin/qr', { credentials: 'include' });
      if (!r.ok) throw new Error('http_' + r.status);
      const j = await r.json();
      setToken(j.token);
      const ms = j.expiresAt - Date.now();
      setSecondsLeft(Math.max(1, Math.round(ms / 1000)));
      setErr(null);
    } catch (e) {
      setErr('Không lấy được mã, thử lại sau ít giây.');
    }
  };

  useEffectM(() => {
    fetchToken();
    const i = setInterval(fetchToken, 25_000);
    return () => clearInterval(i);
  }, []);

  // Countdown ticker
  useEffectM(() => {
    const t = setInterval(() => {
      setSecondsLeft((s) => (s > 0 ? s - 1 : 0));
    }, 1000);
    return () => clearInterval(t);
  }, []);

  // Render the QR onto the canvas whenever the token changes (qrcode-generator API).
  useEffectM(() => {
    if (!token || !canvasRef.current || typeof qrcode === 'undefined') return;
    try {
      const qr = qrcode(0, 'M'); // typeNumber=auto, errorCorrectionLevel='M'
      qr.addData(token);
      qr.make();
      const count = qr.getModuleCount();
      const cell = 6;
      const margin = 4 * cell;
      const px = count * cell + margin * 2;
      const canvas = canvasRef.current;
      canvas.width = px;
      canvas.height = px;
      canvas.style.width = '320px';
      canvas.style.height = '320px';
      const ctx = canvas.getContext('2d');
      ctx.fillStyle = '#ffffff';
      ctx.fillRect(0, 0, px, px);
      ctx.fillStyle = '#0a0a0a';
      for (let r = 0; r < count; r++) {
        for (let c = 0; c < count; c++) {
          if (qr.isDark(r, c)) {
            ctx.fillRect(margin + c * cell, margin + r * cell, cell, cell);
          }
        }
      }
      setErr(null);
    } catch (e) {
      setErr('Không vẽ được QR.');
    }
  }, [token]);

  return (
    <div className="qr-modal" role="dialog" aria-label="Mã QR chấm công">
      <button className="qr-close" onClick={onClose}>✕ Đóng</button>
      <div className="qr-eyebrow">AiiCafe · Chấm công</div>
      <div className="qr-title">Quét mã để chấm công</div>
      <div className="qr-frame">
        {token ? (
          <canvas ref={canvasRef} />
        ) : (
          <div className="qr-skel">Đang lấy mã…</div>
        )}
      </div>
      <div className="qr-counter">
        Mã đổi sau <span className="mono">{secondsLeft}s</span>
      </div>
      <div className="qr-hint">
        Mở app AiiCafe trên điện thoại, bấm <b>Check-in</b> hoặc <b>Check-out</b>, rồi quét mã này.
      </div>
      {err && <div className="qr-err">{err}</div>}
    </div>
  );
}

function EvidenceBlock({ tsId, empId, date, kind, label, manual }) {
  const [log, setLog] = useStateM(null);
  const [err, setErr] = useStateM(null);

  useEffectM(() => {
    if (!tsId || manual) { setErr('skip'); return; }
    if (!empId || !date) { setErr('no_ctx'); return; }
    const url = `/api/attendance/logs?empId=${encodeURIComponent(empId)}&date=${encodeURIComponent(date)}&kind=${kind}&limit=10`;
    fetch(url, { credentials: 'include' })
      .then((r) => r.ok ? r.json() : Promise.reject(r))
      .then((j) => {
        const items = j.items || [];
        // Both checkin and checkout logs carry ts_id once the timesheet is created
        // (checkout sets its own; checkout handler also backfills the matching checkin row).
        // Fallback for legacy logs from before backfill landed: take the most recent checkin
        // on that emp+date that has no ts_id.
        const found = items.find((l) => l.tsId === tsId)
          || (kind === 'checkin' ? items.find((l) => !l.tsId) : null);
        setLog(found || null);
      })
      .catch(() => setErr('load_failed'));
  }, [tsId, empId, date, kind, manual]);

  if (err === 'skip' || !tsId || manual) return null;
  if (err === 'load_failed') return (
    <div className="ds-evidence"><div className="dim">{label}</div><div>Không tải được bằng chứng.</div></div>
  );
  if (!log) return (
    <div className="ds-evidence">
      <div className="dim">{label}</div>
      <div>Không có dữ liệu (lệnh cũ hoặc thủ công).</div>
    </div>
  );
  const gpsLink = log.gps
    ? `https://www.google.com/maps?q=${log.gps.lat},${log.gps.lng}`
    : null;
  return (
    <div className="ds-evidence">
      <div className="dim">{label}</div>
      <div className="ds-evi-row">
        <a className="ds-evi-thumb" href={`/api/attendance/selfie/${log.id}`} target="_blank" rel="noreferrer">
          <img src={`/api/attendance/selfie/${log.id}`} alt={label} loading="lazy"
               onError={(e) => { e.currentTarget.outerHTML = '<div class="ds-evi-missing">Ảnh đã hết hạn lưu trữ</div>'; }} />
        </a>
        <div className="ds-evi-meta">
          <div className="mono small">
            {String(log.time.h).padStart(2,'0')}:{String(log.time.m).padStart(2,'0')}
          </div>
          {gpsLink ? (
            <a className="link" href={gpsLink} target="_blank" rel="noreferrer">Mở Google Maps</a>
          ) : (
            <span className="dim small">Không có GPS</span>
          )}
        </div>
      </div>
    </div>
  );
}

function ManagerApp({ rows, employees, accounts, mgrTab, setMgrTab, onOpenDetail, onAddManual, onSwitchRole, onOpenExport, onLogout, onCreateEmployee, onUpdateAccount, onUpdateEmployee, onArchiveEmployee, onUnarchiveEmployee, onChangePassword, onOpenQr }) {
  return (
    <div className="screen">
      <header className="hdr">
        <div>
          <div className="hdr-eyebrow">AiiCafe · Quản lý</div>
          <div className="hdr-title">{
            mgrTab === 'home' ? 'Tổng quan' :
            mgrTab === 'approve' ? 'Chấm công' :
            mgrTab === 'team' ? 'Đội ngũ' :
            mgrTab === 'salary' ? 'Bảng lương' :
            mgrTab === 'audit' ? 'Nhật ký' : ''
          }</div>
        </div>
        <button className="role-pill" onClick={onSwitchRole} title="Chuyển vai trò">
          <span className="role-dot mgr" /> QL
        </button>
      </header>

      <main className="content">
        {mgrTab === 'home' && <ManagerHome rows={rows} onOpenDetail={onOpenDetail} onJump={setMgrTab} onLogout={onLogout} onChangePassword={onChangePassword} onOpenQr={onOpenQr} />}
        {mgrTab === 'approve' && <ApprovalQueue rows={rows} onOpenDetail={onOpenDetail} onAddManual={onAddManual} />}
        {mgrTab === 'team' && <TeamOverview rows={rows} employees={employees} accounts={accounts} onOpenDetail={onOpenDetail} onCreateEmployee={onCreateEmployee} onUpdateAccount={onUpdateAccount} onUpdateEmployee={onUpdateEmployee} onArchiveEmployee={onArchiveEmployee} onUnarchiveEmployee={onUnarchiveEmployee} />}
        {mgrTab === 'salary' && <PayrollScreen rows={rows} onOpenExport={onOpenExport} />}
        {mgrTab === 'audit' && <AttendanceAuditLog employees={employees} />}
      </main>

      <TabBar
        tabs={[
          { id: 'home',    label: 'Tổng quan', icon: 'home' },
          { id: 'approve', label: 'Duyệt',    icon: 'check' },
          { id: 'team',    label: 'Đội ngũ',  icon: 'users' },
          { id: 'salary',  label: 'Lương',    icon: 'wallet' },
          { id: 'audit',   label: 'Nhật ký',  icon: 'list' },
        ]}
        active={mgrTab}
        onChange={setMgrTab}
      />
    </div>
  );
}

function ManagerHome({ rows, onOpenDetail, onJump, onLogout, onChangePassword, onOpenQr }) {
  const today = TODAY;
  const todayRows = rows.filter((r) =>
    r.date.getDate() === today.getDate() && r.date.getMonth() === today.getMonth()
  );
  const pendingAll = rows.filter((r) => r.status === 'pending');
  const presentToday = new Set(todayRows.map((r) => r.empId)).size;
  // Count only currently-active employees (exclude archived/đã nghỉ)
  const activeEmpCount = EMPLOYEES.filter((e) => !e.archived).length;
  const absentToday = Math.max(0, activeEmpCount - presentToday);

  // Tuần này
  const weekStart = new Date(today); weekStart.setDate(today.getDate() - 6);
  const weekRows = rows.filter((r) => r.date >= weekStart && r.status === 'approved');
  let weekHours = 0, weekOT = 0;
  weekRows.forEach((r) => { const c = calcRow(r); weekHours += c.total; weekOT += c.ot; });

  // Tháng này (tháng 4)
  const monthRows = rows.filter((r) => r.date.getMonth() === 3 && r.date.getFullYear() === 2026);
  const monthNet = EMPLOYEES.reduce((s, emp) => s + calcPayroll(emp, monthRows.filter((r) => r.empId === emp.id)).net, 0);

  // Daily hours bar chart, last 7 days
  const days = [];
  for (let i = 6; i >= 0; i--) {
    const d = new Date(today); d.setDate(today.getDate() - i);
    const dayRows = rows.filter((r) =>
      r.date.getDate() === d.getDate() && r.date.getMonth() === d.getMonth() && r.status === 'approved'
    );
    let h = 0;
    dayRows.forEach((r) => { h += calcRow(r).total; });
    days.push({ d, h });
  }
  const maxH = Math.max(...days.map((d) => d.h), 1);

  const recentPending = pendingAll.slice(0, 3);

  return (
    <div className="mgr-home">
      <button className="qr-cta" onClick={() => onOpenQr()}>
        <div>
          <div className="qr-cta-eyebrow">Chấm công bằng QR</div>
          <div className="qr-cta-title">Hiển thị mã QR cho nhân viên quét</div>
        </div>
        <span className="qr-cta-arrow">›</span>
      </button>
      <div className="hero-card">
        <div className="hc-eyebrow">Hôm nay · {fmtDate(today)}</div>
        <div className="hc-row">
          <div>
            <div className="hc-num mono">{presentToday}<span className="hc-den">/{activeEmpCount}</span></div>
            <div className="hc-lbl">Có mặt</div>
          </div>
          <div className="hc-divider" />
          <div>
            <div className="hc-num mono">{pendingAll.length}</div>
            <div className="hc-lbl">Chờ duyệt</div>
          </div>
          <div className="hc-divider" />
          <div>
            <div className="hc-num mono">{absentToday}</div>
            <div className="hc-lbl">Vắng</div>
          </div>
        </div>
      </div>

      {pendingAll.length > 0 && (
        <section className="section">
          <div className="section-head">
            <h3>Cần duyệt</h3>
            <button className="link" onClick={() => onJump('approve')}>Tất cả →</button>
          </div>
          <div className="list">
            {recentPending.map((r) => {
              const emp = EMPLOYEES.find((e) => e.id === r.empId);
              return <MgrRow key={r.id} row={r} emp={emp} onClick={() => onOpenDetail(r)} />;
            })}
          </div>
        </section>
      )}

      <section className="section">
        <div className="section-head"><h3>Giờ làm 7 ngày qua</h3></div>
        <div className="chart-card">
          <div className="bars">
            {days.map((day, i) => (
              <div key={i} className="bar-wrap">
                <div className="bar" style={{ height: (day.h / maxH * 100) + '%' }} />
                <div className="bar-lbl mono">{day.d.getDate()}</div>
              </div>
            ))}
          </div>
          <div className="chart-foot">
            <div><div className="dim small">Tổng giờ</div><div className="mono">{weekHours.toFixed(1)}h</div></div>
            <div><div className="dim small">Tăng ca</div><div className="mono">{weekOT.toFixed(1)}h</div></div>
          </div>
        </div>
      </section>

      <section className="section">
        <div className="section-head"><h3>Tháng này</h3></div>
        <button className="month-tile" onClick={() => onJump('salary')}>
          <div>
            <div className="dim small">Tổng quỹ lương · Tháng 4/2026</div>
            <div className="mono mt-amount">{fmtVND(monthNet)}</div>
          </div>
          <span className="mt-arrow">›</span>
        </button>
      </section>

      <button className="change-pw-btn" onClick={onChangePassword}>Đổi mật khẩu</button>
      <button className="logout-btn" onClick={onLogout}>Đăng xuất</button>
    </div>
  );
}

function ApprovalQueue({ rows, onOpenDetail, onAddManual }) {
  const [filter, setFilter] = useStateM('pending');
  const [addOpen, setAddOpen] = useStateM(false);

  const filtered = rows
    .filter((r) => filter === 'all' ? true : r.status === filter)
    .sort((a, b) => b.date - a.date);

  const counts = {
    pending: rows.filter((r) => r.status === 'pending').length,
    approved: rows.filter((r) => r.status === 'approved').length,
    rejected: rows.filter((r) => r.status === 'rejected').length,
  };

  return (
    <div className="approve-queue">
      <h2 className="page-title">
        <span>Chấm công</span>
        <button className="add-btn" onClick={() => setAddOpen(true)}>+ Thêm</button>
      </h2>

      <div className="filter-tabs">
        <button className={'ft ' + (filter === 'pending' ? 'on' : '')} onClick={() => setFilter('pending')}>
          Chờ duyệt <span className="ft-c">{counts.pending}</span>
        </button>
        <button className={'ft ' + (filter === 'approved' ? 'on' : '')} onClick={() => setFilter('approved')}>
          Đã duyệt <span className="ft-c">{counts.approved}</span>
        </button>
        <button className={'ft ' + (filter === 'rejected' ? 'on' : '')} onClick={() => setFilter('rejected')}>
          Từ chối <span className="ft-c">{counts.rejected}</span>
        </button>
      </div>

      {filter === 'pending' && counts.pending > 0 && (
        <div className="callout">
          <div className="callout-title">Có {counts.pending} lệnh chờ bạn</div>
          <div className="callout-sub">Chạm vào từng lệnh để duyệt, từ chối, hoặc chỉnh sửa giờ.</div>
        </div>
      )}

      <div className="list">
        {filtered.length === 0 && (
          <div className="empty">Không có bản ghi nào.</div>
        )}
        {filtered.map((r) => {
          const emp = EMPLOYEES.find((e) => e.id === r.empId);
          return <MgrRow key={r.id} row={r} emp={emp} onClick={() => onOpenDetail(r)} />;
        })}
      </div>

      {addOpen && (
        <ManualAddSheet
          onClose={() => setAddOpen(false)}
          onSubmit={(empId, date, ci, co, note) => {
            onAddManual(empId, date, ci, co, note);
            setAddOpen(false);
          }}
        />
      )}
    </div>
  );
}

function MgrRow({ row, emp, onClick }) {
  if (!emp) return null; // guard: timesheet may reference a deleted/unloaded employee
  const c = calcRow(row);
  return (
    <button className="mgr-row" onClick={onClick}>
      <div className="mr-avatar">{emp.name.split(' ').slice(-1)[0][0]}</div>
      <div className="mr-mid">
        <div className="mr-name">{emp.name} <span className="mr-role">· {emp.role}</span></div>
        <div className="mr-meta mono">
          {String(row.date.getDate()).padStart(2,'0')}/{String(row.date.getMonth()+1).padStart(2,'0')}
          <span className="dot-sep">·</span>
          {String(row.checkIn.h).padStart(2,'0')}:{String(row.checkIn.m).padStart(2,'0')}–{String(row.checkOut.h).padStart(2,'0')}:{String(row.checkOut.m).padStart(2,'0')}
          <span className="dot-sep">·</span>
          {c.total.toFixed(1)}h
        </div>
      </div>
      <div className="mr-right">
        <StatusPill status={row.status} small />
        {row.edited && <span className="mini-tag">đã sửa</span>}
        {row.manual && <span className="mini-tag">thủ công</span>}
      </div>
    </button>
  );
}

function TeamOverview({ rows, employees, accounts, onOpenDetail, onCreateEmployee, onUpdateAccount, onUpdateEmployee, onArchiveEmployee, onUnarchiveEmployee }) {
  const [createOpen, setCreateOpen] = useStateM(false);
  const [editAccount, setEditAccount] = useStateM(null);
  const [showArchived, setShowArchived] = useStateM(false);
  const all = employees || EMPLOYEES;
  const list = showArchived ? all : all.filter((e) => !e.archived);
  const archivedCount = all.filter((e) => e.archived).length;

  return (
    <div className="team">
      <h2 className="page-title">
        <span>Đội ngũ ({list.length})</span>
        <button className="add-btn" onClick={() => setCreateOpen(true)}>+ Thêm NV</button>
      </h2>

      {archivedCount > 0 && (
        <label className="archived-toggle">
          <input
            type="checkbox"
            checked={showArchived}
            onChange={(e) => setShowArchived(e.target.checked)}
          />
          <span>Xem cả nhân viên đã nghỉ ({archivedCount})</span>
        </label>
      )}

      <div className="list">
        {list.map((emp) => {
          const empRows = rows.filter((r) => r.empId === emp.id);
          const monthRows = empRows.filter((r) => r.date.getMonth() === 3);
          const p = calcPayroll(emp, monthRows);
          const pending = empRows.filter((r) => r.status === 'pending').length;
          const acc = (accounts || []).find((a) => a.empId === emp.id);
          return (
            <div key={emp.id} className={'team-card' + (emp.archived ? ' archived' : '')}>
              <div className="tc-head">
                <div className="mr-avatar lg">{emp.name.split(' ').slice(-1)[0][0]}</div>
                <div style={{flex: 1}}>
                  <div className="tc-name">
                    {emp.name}
                    <span className={'emp-type ' + (emp.employmentType === 'parttime' ? 'pt' : 'ft')}>
                      {emp.employmentType === 'parttime' ? 'PT' : 'FT'}
                    </span>
                    {emp.archived && <span className="archived-tag">đã nghỉ</span>}
                  </div>
                  <div className="tc-role">
                    {emp.role}
                    {acc && <span className="mono dim small"> · @{acc.username}</span>}
                    {acc && !acc.active && !emp.archived && <span className="locked-tag">tạm khóa</span>}
                  </div>
                </div>
                {pending > 0 && <span className="badge">{pending} chờ</span>}
                {acc && (
                  <button className="manage-btn" onClick={() => setEditAccount({ acc, emp })}>Quản lý</button>
                )}
              </div>
              <div className="tc-stats">
                <div><div className="dim">Ngày công</div><div className="mono">{p.days}</div></div>
                <div><div className="dim">Tổng giờ</div><div className="mono">{p.totalH.toFixed(1)}h</div></div>
                <div><div className="dim">OT</div><div className="mono">{p.ot.toFixed(1)}h</div></div>
                <div><div className="dim">Thực lãnh</div><div className="mono">{(p.net/1e6).toFixed(2)}tr</div></div>
              </div>
            </div>
          );
        })}
      </div>

      {createOpen && (
        <CreateEmployeeSheet
          existingUsernames={(accounts || []).map((a) => a.username)}
          onClose={() => setCreateOpen(false)}
          onSubmit={(data) => { onCreateEmployee(data); setCreateOpen(false); }}
        />
      )}

      {editAccount && (
        <ManageAccountSheet
          acc={editAccount.acc}
          emp={editAccount.emp}
          onClose={() => setEditAccount(null)}
          onUpdateAccount={onUpdateAccount}
          onUpdateEmployee={onUpdateEmployee}
          onArchiveEmployee={onArchiveEmployee}
          onUnarchiveEmployee={onUnarchiveEmployee}
        />
      )}
    </div>
  );
}

function CreateEmployeeSheet({ onClose, onSubmit, existingUsernames }) {
  const [name, setName] = useStateM('');
  const [empRole, setEmpRole] = useStateM('Pha chế');
  const [employmentType, setEmploymentType] = useStateM('fulltime');
  const [allowance, setAllowance] = useStateM('800000');
  const [hourly, setHourly] = useStateM('35000');
  const [username, setUsername] = useStateM('');
  const [password, setPassword] = useStateM('');
  const [showPass, setShowPass] = useStateM(false);
  const [err, setErr] = useStateM(null);

  const genPassword = () => {
    const s = Math.random().toString(36).slice(2, 8);
    setPassword(s);
    setShowPass(true);
  };
  const suggestUser = () => {
    const slug = name
      .toLowerCase()
      .normalize('NFD').replace(/[\u0300-\u036f]/g, '')
      .replace(/đ/g, 'd')
      .replace(/[^a-z0-9]/g, '');
    setUsername(slug.slice(0, 12));
  };

  const submit = () => {
    if (!name.trim()) return setErr('Nhập họ tên');
    if (!Number(hourly)) return setErr('Nhập lương theo giờ');
    if (!username.trim() || !/^[a-z0-9_.]{3,}$/.test(username.trim())) return setErr('Tên đăng nhập tối thiểu 3 ký tự, chỉ a-z 0-9 _ .');
    if (existingUsernames.includes(username.trim().toLowerCase())) return setErr('Tên đăng nhập đã tồn tại');
    if (password.length < 6) return setErr('Mật khẩu tối thiểu 6 ký tự');
    onSubmit({
      name: name.trim(),
      role: empRole,
      employmentType,
      base: 0,
      allowance: Number(allowance) || 0,
      hourly: Number(hourly) || 0,
      username: username.trim().toLowerCase(),
      password,
    });
  };

  return (
    <div className="sheet-overlay" onClick={onClose}>
      <div className="sheet" onClick={(e) => e.stopPropagation()}>
        <div className="sheet-handle" />
        <div className="sheet-head">
          <h3>Thêm nhân viên mới</h3>
          <button className="x-btn" onClick={onClose}>✕</button>
        </div>
        <div className="sheet-body">
          <div className="dim" style={{fontSize: 11, textTransform: 'uppercase', letterSpacing: '0.06em', fontWeight: 600}}>Thông tin</div>
          <label className="field">
            <span className="field-label">Họ và tên</span>
            <input type="text" value={name} onChange={(e) => { setName(e.target.value); setErr(null); }} onBlur={() => !username && suggestUser()} placeholder="VD: Nguyễn Văn An" />
          </label>
          <div className="field-row">
            <label className="field">
              <span className="field-label">Vị trí</span>
              <select value={empRole} onChange={(e) => setEmpRole(e.target.value)}>
                <option>Pha chế</option><option>Phục vụ</option><option>Thu ngân</option><option>Bếp</option><option>Vệ sinh</option>
              </select>
            </label>
            <label className="field">
              <span className="field-label">Hình thức</span>
              <select value={employmentType} onChange={(e) => setEmploymentType(e.target.value)}>
                <option value="fulltime">Full-time</option>
                <option value="parttime">Part-time</option>
              </select>
            </label>
          </div>
          <div className="field-row">
            <label className="field">
              <span className="field-label">Lương theo giờ (₫)</span>
              <input type="number" value={hourly} onChange={(e) => setHourly(e.target.value)} placeholder="VD: 35000" />
            </label>
            <label className="field">
              <span className="field-label">Phụ cấp tháng (₫)</span>
              <input type="number" value={allowance} onChange={(e) => setAllowance(e.target.value)} placeholder="0 nếu không có" />
            </label>
          </div>
          <div className="info-box">
            Lương = giờ thường × lương/giờ + giờ OT × lương/giờ × 1.5. OT là giờ làm sau {String(SHIFT_END.h).padStart(2,'0')}:{String(SHIFT_END.m).padStart(2,'0')}.
          </div>

          <div className="dim" style={{fontSize: 11, textTransform: 'uppercase', letterSpacing: '0.06em', fontWeight: 600, marginTop: 4}}>Tài khoản đăng nhập</div>
          <label className="field">
            <span className="field-label">Tên đăng nhập</span>
            <input
              type="text"
              autoCapitalize="off"
              value={username}
              onChange={(e) => { setUsername(e.target.value.toLowerCase()); setErr(null); }}
              placeholder="vd: nguyenvanan"
            />
          </label>
          <label className="field">
            <span className="field-label">
              Mật khẩu tạm
              <button type="button" className="link" style={{marginLeft: 8}} onClick={genPassword}>Tạo ngẫu nhiên</button>
            </span>
            <div className="pwd-wrap">
              <input
                type={showPass ? 'text' : 'password'}
                value={password}
                onChange={(e) => { setPassword(e.target.value); setErr(null); }}
                placeholder="Tối thiểu 6 ký tự"
              />
              <button type="button" className="pwd-toggle" onClick={() => setShowPass(!showPass)}>{showPass ? 'Ẩn' : 'Hiện'}</button>
            </div>
          </label>
          <div className="info-box">
            Nhân viên sẽ được yêu cầu đổi mật khẩu trong lần đăng nhập đầu tiên.
          </div>

          {err && <div className="login-error">{err}</div>}
        </div>
        <div className="sheet-foot">
          <button className="big-btn ghost" onClick={onClose}>Huỷ</button>
          <button className="big-btn primary" onClick={submit}>Tạo tài khoản</button>
        </div>
      </div>
    </div>
  );
}

function ManageAccountSheet({ acc, emp, onClose, onUpdateAccount, onUpdateEmployee, onArchiveEmployee, onUnarchiveEmployee }) {
  const [tab, setTab] = useStateM('view'); // view | resetpw | editinfo
  const [newPass, setNewPass] = useStateM('');
  const [showPass, setShowPass] = useStateM(false);
  const [name, setName] = useStateM(emp.name);
  const [empRole, setEmpRole] = useStateM(emp.role);
  const [employmentType, setEmploymentType] = useStateM(emp.employmentType || 'fulltime');
  const [hourly, setHourly] = useStateM(String(emp.hourly));
  const [allowance, setAllowance] = useStateM(String(emp.allowance));
  const [err, setErr] = useStateM(null);

  const resetPw = () => {
    if (newPass.length < 6) return setErr('Mật khẩu tối thiểu 6 ký tự');
    onUpdateAccount(acc.username, { password: newPass });
    onClose();
  };
  const saveInfo = () => {
    if (!name.trim()) return setErr('Nhập họ tên');
    if (!Number(hourly)) return setErr('Lương theo giờ phải > 0');
    onUpdateEmployee(emp.id, {
      name: name.trim(),
      role: empRole,
      employmentType,
      hourly: Number(hourly) || 0,
      allowance: Number(allowance) || 0,
    });
    onClose();
  };
  const toggleActive = () => {
    onUpdateAccount(acc.username, { active: !acc.active });
    onClose();
  };
  const archive = () => {
    if (!window.confirm(`Cho ${emp.name} nghỉ việc? Nhân viên không xuất hiện ở danh sách "Đội ngũ" và không đăng nhập được nữa. Lịch sử chấm công + bảng lương cũ vẫn được giữ.`)) return;
    onArchiveEmployee && onArchiveEmployee(emp.id);
    onClose();
  };
  const unarchive = () => {
    onUnarchiveEmployee && onUnarchiveEmployee(emp.id);
    onClose();
  };

  return (
    <div className="sheet-overlay" onClick={onClose}>
      <div className="sheet" onClick={(e) => e.stopPropagation()}>
        <div className="sheet-handle" />
        <div className="sheet-head">
          <h3>Quản lý tài khoản</h3>
          <button className="x-btn" onClick={onClose}>✕</button>
        </div>

        <div className="sheet-body">
          <div className="ds-emp">
            <div className="mr-avatar lg">{emp.name.split(' ').slice(-1)[0][0]}</div>
            <div style={{flex: 1}}>
              <div className="ds-name">{emp.name}</div>
              <div className="dim mono small">@{acc.username}</div>
            </div>
            <span className={'pill ' + (acc.active ? 'approved' : 'rejected')}>
              {acc.active ? 'Đang hoạt động' : 'Tạm khóa'}
            </span>
          </div>

          <div className="ds-grid">
            <div><div className="dim">Vị trí</div><div>{emp.role}</div></div>
            <div><div className="dim">Hình thức</div><div>{emp.employmentType === 'parttime' ? 'Part-time' : 'Full-time'}</div></div>
            <div><div className="dim">Lương / giờ</div><div className="mono">{fmtVND(emp.hourly)}</div></div>
          </div>

          {tab === 'view' && (
            <div className="action-list">
              {!emp.archived && (
                <>
                  <button className="action-row" onClick={() => setTab('resetpw')}>
                    <div>
                      <div className="ar-title">Đặt lại mật khẩu</div>
                      <div className="ar-sub">Cấp mật khẩu mới cho nhân viên</div>
                    </div>
                    <span>›</span>
                  </button>
                  <button className="action-row" onClick={() => setTab('editinfo')}>
                    <div>
                      <div className="ar-title">Sửa thông tin & lương</div>
                      <div className="ar-sub">Tên, vị trí, hình thức, lương theo giờ, phụ cấp</div>
                    </div>
                    <span>›</span>
                  </button>
                  <button className={'action-row ' + (acc.active ? 'danger' : '')} onClick={toggleActive}>
                    <div>
                      <div className="ar-title">{acc.active ? 'Tạm khóa tài khoản' : 'Mở khóa tài khoản'}</div>
                      <div className="ar-sub">{acc.active ? 'Nhân viên không thể đăng nhập (tạm thời)' : 'Cho phép nhân viên đăng nhập lại'}</div>
                    </div>
                    <span>›</span>
                  </button>
                  <button className="action-row danger" onClick={archive}>
                    <div>
                      <div className="ar-title">Cho nghỉ việc</div>
                      <div className="ar-sub">Ẩn khỏi danh sách Đội ngũ, giữ lại lịch sử chấm công</div>
                    </div>
                    <span>›</span>
                  </button>
                </>
              )}
              {emp.archived && (
                <button className="action-row" onClick={unarchive}>
                  <div>
                    <div className="ar-title">Phục hồi nhân viên</div>
                    <div className="ar-sub">Đưa lại danh sách Đội ngũ và mở khóa đăng nhập</div>
                  </div>
                  <span>›</span>
                </button>
              )}
            </div>
          )}

          {tab === 'resetpw' && (
            <div className="edit-block">
              <div className="edit-title">Mật khẩu mới</div>
              <div className="pwd-wrap">
                <input
                  type={showPass ? 'text' : 'password'}
                  value={newPass}
                  onChange={(e) => { setNewPass(e.target.value); setErr(null); }}
                  placeholder="Tối thiểu 6 ký tự"
                />
                <button type="button" className="pwd-toggle" onClick={() => setShowPass(!showPass)}>{showPass ? 'Ẩn' : 'Hiện'}</button>
              </div>
              <button type="button" className="link" onClick={() => { const s = Math.random().toString(36).slice(2, 8); setNewPass(s); setShowPass(true); }}>Tạo ngẫu nhiên</button>
              <div className="info-box">Nhân viên cần đăng nhập lại bằng mật khẩu mới này.</div>
              {err && <div className="login-error">{err}</div>}
            </div>
          )}

          {tab === 'editinfo' && (
            <div className="edit-block">
              <div className="edit-title">Thông tin & lương</div>
              <label className="field">
                <span className="field-label">Họ và tên</span>
                <input type="text" value={name} onChange={(e) => setName(e.target.value)} />
              </label>
              <div className="field-row">
                <label className="field">
                  <span className="field-label">Vị trí</span>
                  <select value={empRole} onChange={(e) => setEmpRole(e.target.value)}>
                    <option>Pha chế</option><option>Phục vụ</option><option>Thu ngân</option><option>Bếp</option><option>Vệ sinh</option>
                  </select>
                </label>
                <label className="field">
                  <span className="field-label">Hình thức</span>
                  <select value={employmentType} onChange={(e) => setEmploymentType(e.target.value)}>
                    <option value="fulltime">Full-time</option>
                    <option value="parttime">Part-time</option>
                  </select>
                </label>
              </div>
              <div className="field-row">
                <label className="field">
                  <span className="field-label">Lương theo giờ (₫)</span>
                  <input type="number" value={hourly} onChange={(e) => setHourly(e.target.value)} />
                </label>
                <label className="field">
                  <span className="field-label">Phụ cấp tháng (₫)</span>
                  <input type="number" value={allowance} onChange={(e) => setAllowance(e.target.value)} />
                </label>
              </div>
              {err && <div className="login-error">{err}</div>}
            </div>
          )}
        </div>

        <div className="sheet-foot">
          {tab === 'view' && <button className="big-btn ghost" onClick={onClose}>Đóng</button>}
          {tab === 'resetpw' && <>
            <button className="big-btn ghost" onClick={() => setTab('view')}>Huỷ</button>
            <button className="big-btn primary" onClick={resetPw}>Đặt lại</button>
          </>}
          {tab === 'editinfo' && <>
            <button className="big-btn ghost" onClick={() => setTab('view')}>Huỷ</button>
            <button className="big-btn primary" onClick={saveInfo}>Lưu</button>
          </>}
        </div>
      </div>
    </div>
  );
}

function PayrollScreen({ rows, onOpenExport }) {
  const monthRows = rows.filter((r) => r.date.getMonth() === 3 && r.date.getFullYear() === 2026);
  const data = EMPLOYEES.map((emp) => ({
    emp,
    p: calcPayroll(emp, monthRows.filter((r) => r.empId === emp.id)),
  }));
  const totalNet = data.reduce((s, d) => s + d.p.net, 0);
  const totalDays = data.reduce((s, d) => s + d.p.days, 0);
  const totalH = data.reduce((s, d) => s + d.p.totalH, 0);
  const pendingCount = rows.filter((r) => r.status === 'pending').length;

  return (
    <div className="payroll">
      <h2 className="page-title">Bảng lương</h2>
      <div className="month-switcher">
        <button className="ms-btn">‹</button>
        <div className="ms-label">Tháng 4 / 2026</div>
        <button className="ms-btn">›</button>
      </div>

      <div className="summary-card">
        <div>
          <div className="sc-eyebrow">Tổng quỹ lương</div>
          <div className="sc-amount mono">{fmtVND(totalNet)}</div>
        </div>
        <div className="sc-divider" />
        <div className="sc-mini">
          <div><div className="dim">Nhân viên</div><div className="mono">{EMPLOYEES.length}</div></div>
          <div><div className="dim">Ngày công</div><div className="mono">{totalDays}</div></div>
          <div><div className="dim">Tổng giờ</div><div className="mono">{totalH.toFixed(0)}h</div></div>
        </div>
      </div>

      {pendingCount > 0 && (
        <div className="warn-callout">
          ⚠ Còn {pendingCount} lệnh chấm công chưa duyệt. Bảng lương có thể chưa chính xác.
        </div>
      )}

      <div className="payroll-table">
        <div className="pt-head">
          <span>Nhân viên</span>
          <span className="ta-r">Giờ</span>
          <span className="ta-r">Thực lãnh</span>
        </div>
        {data.map(({ emp, p }) => (
          <div key={emp.id} className="pt-row">
            <div className="pt-name">
              <div className="mr-avatar sm">{emp.name.split(' ').slice(-1)[0][0]}</div>
              <div>
                <div>{emp.name}</div>
                <div className="dim small">{emp.role}</div>
              </div>
            </div>
            <div className="ta-r mono">
              {p.totalH.toFixed(1)}
              {p.ot > 0 && <div className="ot-tag mono">+{p.ot.toFixed(1)} OT</div>}
            </div>
            <div className="ta-r mono pt-amount">{fmtVND(p.net)}</div>
          </div>
        ))}
      </div>

      <button className="big-btn primary" onClick={onOpenExport}>
        Xuất bảng lương
      </button>
    </div>
  );
}

// ---------- Manual add sheet ----------
function ManualAddSheet({ onClose, onSubmit }) {
  const [empId, setEmpId] = useStateM(EMPLOYEES[0]?.id || '');
  const [dateStr, setDateStr] = useStateM(`${TODAY.getFullYear()}-${String(TODAY.getMonth()+1).padStart(2,'0')}-${String(TODAY.getDate()).padStart(2,'0')}`);
  const [ci, setCi] = useStateM('08:00');
  const [co, setCo] = useStateM('17:00');
  const [note, setNote] = useStateM('');

  const submit = () => {
    const [y, m, d] = dateStr.split('-').map(Number);
    const [cih, cim] = ci.split(':').map(Number);
    const [coh, com] = co.split(':').map(Number);
    onSubmit(empId, new Date(y, m - 1, d), { h: cih, m: cim }, { h: coh, m: com }, note || 'Chấm công thủ công');
  };

  return (
    <div className="sheet-overlay" onClick={onClose}>
      <div className="sheet" onClick={(e) => e.stopPropagation()}>
        <div className="sheet-handle" />
        <div className="sheet-head">
          <h3>Thêm chấm công thủ công</h3>
          <button className="x-btn" onClick={onClose}>✕</button>
        </div>
        <div className="sheet-body">
          <label className="field">
            <span className="field-label">Nhân viên</span>
            <select value={empId} onChange={(e) => setEmpId(e.target.value)}>
              {EMPLOYEES.filter((e) => !e.archived).map((e) => <option key={e.id} value={e.id}>{e.name} — {e.role}</option>)}
            </select>
          </label>
          <label className="field">
            <span className="field-label">Ngày</span>
            <input type="date" value={dateStr} onChange={(e) => setDateStr(e.target.value)} />
          </label>
          <div className="field-row">
            <label className="field">
              <span className="field-label">Giờ vào</span>
              <input type="time" value={ci} onChange={(e) => setCi(e.target.value)} />
            </label>
            <label className="field">
              <span className="field-label">Giờ ra</span>
              <input type="time" value={co} onChange={(e) => setCo(e.target.value)} />
            </label>
          </div>
          <label className="field">
            <span className="field-label">Ghi chú</span>
            <textarea rows={2} value={note} onChange={(e) => setNote(e.target.value)} placeholder="VD: NV quên check-in, có camera xác nhận"></textarea>
          </label>
        </div>
        <div className="sheet-foot">
          <button className="big-btn ghost" onClick={onClose}>Huỷ</button>
          <button className="big-btn primary" onClick={submit}>Thêm & duyệt</button>
        </div>
      </div>
    </div>
  );
}

// ---------- Detail sheet (approve / reject / edit) ----------
function DetailSheet({ row, emp, onClose, onApprove, onReject, onEditApprove }) {
  const [mode, setMode] = useStateM('view'); // view | reject | edit
  const [reason, setReason] = useStateM('');
  const fmt = (t) => `${String(t.h).padStart(2,'0')}:${String(t.m).padStart(2,'0')}`;
  const [ci, setCi] = useStateM(fmt(row.checkIn));
  const [co, setCo] = useStateM(fmt(row.checkOut));
  const [note, setNote] = useStateM(row.note);

  const c = calcRow(row);

  const submitEdit = () => {
    const [cih, cim] = ci.split(':').map(Number);
    const [coh, com] = co.split(':').map(Number);
    onEditApprove(row.id, { h: cih, m: cim }, { h: coh, m: com }, note);
  };

  return (
    <div className="sheet-overlay" onClick={onClose}>
      <div className="sheet" onClick={(e) => e.stopPropagation()}>
        <div className="sheet-handle" />
        <div className="sheet-head">
          <h3>Chi tiết chấm công</h3>
          <button className="x-btn" onClick={onClose}>✕</button>
        </div>

        <div className="sheet-body">
          <div className="ds-emp">
            <div className="mr-avatar lg">{emp.name.split(' ').slice(-1)[0][0]}</div>
            <div>
              <div className="ds-name">{emp.name}</div>
              <div className="dim">{emp.role}</div>
            </div>
            <StatusPill status={row.status} />
          </div>

          <div className="ds-grid">
            <div><div className="dim">Ngày</div><div className="mono">{fmtDate(row.date)}</div></div>
            <div><div className="dim">Tổng giờ</div><div className="mono">{c.total.toFixed(1)}h</div></div>
            <div><div className="dim">Vào</div><div className="mono">{fmt(row.checkIn)}</div></div>
            <div><div className="dim">Ra</div><div className="mono">{fmt(row.checkOut)}</div></div>
            <div><div className="dim">Tăng ca</div><div className="mono">{c.ot.toFixed(1)}h</div></div>
            <div><div className="dim">Đi muộn</div><div className="mono">{c.lateMin}p</div></div>
          </div>

          <div className="ds-note">
            <div className="dim">Ghi chú của nhân viên</div>
            <div>{row.note}</div>
          </div>

          {row.rejectReason && (
            <div className="ds-reject">
              <div className="dim">Lý do từ chối trước đó</div>
              <div>{row.rejectReason}</div>
            </div>
          )}

          <EvidenceBlock
            tsId={row.id}
            empId={row.empId}
            date={fmtDateISO(row.date)}
            kind="checkin"
            label="Bằng chứng vào ca"
            manual={row.manual}
          />
          <EvidenceBlock
            tsId={row.id}
            empId={row.empId}
            date={fmtDateISO(row.date)}
            kind="checkout"
            label="Bằng chứng kết ca"
            manual={row.manual}
          />

          {mode === 'edit' && (
            <div className="edit-block">
              <div className="edit-title">Chỉnh sửa giờ</div>
              <div className="field-row">
                <label className="field">
                  <span className="field-label">Giờ vào</span>
                  <input type="time" value={ci} onChange={(e) => setCi(e.target.value)} />
                </label>
                <label className="field">
                  <span className="field-label">Giờ ra</span>
                  <input type="time" value={co} onChange={(e) => setCo(e.target.value)} />
                </label>
              </div>
              <label className="field">
                <span className="field-label">Ghi chú điều chỉnh</span>
                <textarea rows={2} value={note} onChange={(e) => setNote(e.target.value)} />
              </label>
            </div>
          )}

          {mode === 'reject' && (
            <div className="edit-block">
              <div className="edit-title">Lý do từ chối</div>
              <textarea
                rows={3}
                value={reason}
                onChange={(e) => setReason(e.target.value)}
                placeholder="VD: Không đúng ca làm, đã trao đổi với NV…"
              />
            </div>
          )}
        </div>

        {row.status === 'pending' && (
          <div className="sheet-foot">
            {mode === 'view' && (
              <>
                <button className="big-btn ghost danger-text" onClick={() => setMode('reject')}>Từ chối</button>
                <button className="big-btn ghost" onClick={() => setMode('edit')}>Chỉnh sửa</button>
                <button className="big-btn primary" onClick={() => onApprove(row.id)}>Duyệt</button>
              </>
            )}
            {mode === 'edit' && (
              <>
                <button className="big-btn ghost" onClick={() => setMode('view')}>Huỷ</button>
                <button className="big-btn primary" onClick={submitEdit}>Lưu & duyệt</button>
              </>
            )}
            {mode === 'reject' && (
              <>
                <button className="big-btn ghost" onClick={() => setMode('view')}>Huỷ</button>
                <button className="big-btn danger" onClick={() => onReject(row.id, reason || 'Không có lý do cụ thể')}>Xác nhận từ chối</button>
              </>
            )}
          </div>
        )}
        {row.status !== 'pending' && (
          <div className="sheet-foot">
            <button className="big-btn ghost" onClick={onClose}>Đóng</button>
          </div>
        )}
      </div>
    </div>
  );
}

// ---------- Export sheet ----------
function ExportSheet({ onClose, onDone }) {
  const [format, setFormat] = useStateM('pdf');
  const [step, setStep] = useStateM(1); // 1 chọn, 2 đang xuất, 3 xong

  const start = () => {
    setStep(2);
    setTimeout(() => setStep(3), 1100);
  };

  return (
    <div className="sheet-overlay" onClick={onClose}>
      <div className="sheet" onClick={(e) => e.stopPropagation()}>
        <div className="sheet-handle" />
        <div className="sheet-head">
          <h3>Xuất bảng lương · Tháng 4/2026</h3>
          <button className="x-btn" onClick={onClose}>✕</button>
        </div>

        {step === 1 && (
          <>
            <div className="sheet-body">
              <div className="dim mb">Chọn định dạng</div>
              <div className="format-choices">
                <FormatChoice id="pdf" label="PDF" sub="Phù hợp in & ký" current={format} onPick={setFormat} />
                <FormatChoice id="excel" label="Excel / CSV" sub="Cho kế toán" current={format} onPick={setFormat} />
                <FormatChoice id="web" label="Xem trên web" sub="Mở dạng bảng" current={format} onPick={setFormat} />
              </div>
              <div className="dim mt mb">Bao gồm</div>
              <div className="incl-list">
                <div className="incl"><span>✓</span> Số ngày công, tổng giờ, OT</div>
                <div className="incl"><span>✓</span> Lương cơ bản + phụ cấp</div>
                <div className="incl"><span>✓</span> Trừ đi muộn / về sớm</div>
                <div className="incl"><span>✓</span> Thực lãnh từng nhân viên</div>
              </div>
            </div>
            <div className="sheet-foot">
              <button className="big-btn ghost" onClick={onClose}>Huỷ</button>
              <button className="big-btn primary" onClick={start}>Xuất {format.toUpperCase()}</button>
            </div>
          </>
        )}

        {step === 2 && (
          <div className="sheet-body export-progress">
            <div className="spinner" />
            <div>Đang chuẩn bị file…</div>
          </div>
        )}

        {step === 3 && (
          <>
            <div className="sheet-body">
              <div className="export-done">
                <div className="ok-mark">✓</div>
                <div className="ed-title">Đã sẵn sàng</div>
                <div className="dim">aiicafe-bangluong-T04-2026.{format === 'excel' ? 'xlsx' : format === 'pdf' ? 'pdf' : 'html'}</div>
              </div>
            </div>
            <div className="sheet-foot">
              <button className="big-btn ghost" onClick={onClose}>Đóng</button>
              <button className="big-btn primary" onClick={onDone}>Tải về</button>
            </div>
          </>
        )}
      </div>
    </div>
  );
}

function FormatChoice({ id, label, sub, current, onPick }) {
  return (
    <button className={'fc ' + (current === id ? 'on' : '')} onClick={() => onPick(id)}>
      <div className="fc-radio">{current === id && <span className="fc-dot" />}</div>
      <div>
        <div className="fc-label">{label}</div>
        <div className="fc-sub dim">{sub}</div>
      </div>
    </button>
  );
}

function AttendanceAuditLog({ employees }) {
  const [items, setItems] = useStateM([]);
  const [empId, setEmpId] = useStateM('');
  const [date, setDate] = useStateM('');
  const [kindFilter, setKindFilter] = useStateM('');
  const [loading, setLoading] = useStateM(false);
  const [openSheet, setOpenSheet] = useStateM(null); // log object

  const load = async () => {
    setLoading(true);
    const params = new URLSearchParams();
    if (empId) params.set('empId', empId);
    if (date) params.set('date', date);
    if (kindFilter) params.set('kind', kindFilter);
    params.set('limit', '50');
    try {
      const r = await fetch(`/api/attendance/logs?${params}`, { credentials: 'include' });
      const j = r.ok ? await r.json() : { items: [] };
      setItems(j.items || []);
    } finally { setLoading(false); }
  };

  useEffectM(() => { load(); }, [empId, date, kindFilter]);

  const empName = (id) => {
    const e = (employees || []).find((x) => x.id === id);
    return e ? e.name : id;
  };

  return (
    <div className="audit-log">
      <h2 className="page-title">Nhật ký chấm công</h2>

      <div className="audit-filters">
        <label className="field">
          <span className="field-label">Nhân viên</span>
          <select value={empId} onChange={(e) => setEmpId(e.target.value)}>
            <option value="">Tất cả</option>
            {(employees || []).map((e) => (
              <option key={e.id} value={e.id}>{e.name}</option>
            ))}
          </select>
        </label>
        <label className="field">
          <span className="field-label">Ngày</span>
          <input type="date" value={date} onChange={(e) => setDate(e.target.value)} />
        </label>
        <label className="field">
          <span className="field-label">Loại</span>
          <select value={kindFilter} onChange={(e) => setKindFilter(e.target.value)}>
            <option value="">Tất cả</option>
            <option value="checkin">Vào ca</option>
            <option value="checkout">Kết ca</option>
          </select>
        </label>
      </div>

      {loading && <div className="dim" style={{padding: 12}}>Đang tải…</div>}

      <div className="list">
        {items.length === 0 && !loading && (
          <div className="empty">Không có bản ghi nào.</div>
        )}
        {items.map((it) => (
          <button key={it.id} className="audit-row" onClick={() => setOpenSheet(it)}>
            <img className="audit-thumb"
                 src={`/api/attendance/selfie/${it.id}`}
                 alt="selfie" loading="lazy"
                 onError={(e) => { e.currentTarget.style.background = '#222'; e.currentTarget.removeAttribute('src'); }}
            />
            <div className="audit-mid">
              <div className="audit-name">{empName(it.empId)}</div>
              <div className="audit-meta mono">
                {it.date}
                <span className="dot-sep">·</span>
                {String(it.time.h).padStart(2,'0')}:{String(it.time.m).padStart(2,'0')}
                <span className="dot-sep">·</span>
                {it.kind === 'checkin' ? 'vào' : 'ra'}
              </div>
            </div>
            <div className="audit-right">
              {it.gps ? <span className="pill approved small">GPS</span> : <span className="pill rejected small">no GPS</span>}
            </div>
          </button>
        ))}
      </div>

      {openSheet && <AuditDetailSheet log={openSheet} empName={empName(openSheet.empId)} onClose={() => setOpenSheet(null)} />}
    </div>
  );
}

function AuditDetailSheet({ log, empName, onClose }) {
  const gpsLink = log.gps ? `https://www.google.com/maps?q=${log.gps.lat},${log.gps.lng}` : null;
  return (
    <div className="sheet-overlay" onClick={onClose}>
      <div className="sheet" onClick={(e) => e.stopPropagation()}>
        <div className="sheet-handle" />
        <div className="sheet-head">
          <h3>Chi tiết bản ghi</h3>
          <button className="x-btn" onClick={onClose}>✕</button>
        </div>
        <div className="sheet-body">
          <div className="audit-img-wrap">
            <img src={`/api/attendance/selfie/${log.id}`} alt="selfie"
                 onError={(e) => { e.currentTarget.outerHTML = '<div class="ds-evi-missing">Ảnh đã hết hạn lưu trữ</div>'; }} />
          </div>
          <div className="ds-grid">
            <div><div className="dim">Nhân viên</div><div>{empName}</div></div>
            <div><div className="dim">Loại</div><div>{log.kind === 'checkin' ? 'Vào ca' : 'Kết ca'}</div></div>
            <div><div className="dim">Ngày</div><div className="mono">{log.date}</div></div>
            <div><div className="dim">Giờ</div><div className="mono">{String(log.time.h).padStart(2,'0')}:{String(log.time.m).padStart(2,'0')}</div></div>
            <div><div className="dim">GPS</div>
              <div>
                {gpsLink ? <a className="link" href={gpsLink} target="_blank" rel="noreferrer">Maps</a> : <span className="dim">—</span>}
                {log.gps && <span className="dim small"> ±{Math.round(log.gps.accuracy || 0)}m</span>}
              </div>
            </div>
            <div><div className="dim">IP</div><div className="mono small">{log.ip || '—'}</div></div>
          </div>
          {log.userAgent && (
            <div className="ds-note">
              <div className="dim">Thiết bị</div>
              <div className="small mono">{log.userAgent}</div>
            </div>
          )}
        </div>
        <div className="sheet-foot">
          <button className="big-btn ghost" onClick={onClose}>Đóng</button>
        </div>
      </div>
    </div>
  );
}

window.ManagerApp = ManagerApp;
window.DetailSheet = DetailSheet;
window.ExportSheet = ExportSheet;
window.QrDisplayModal = QrDisplayModal;
window.AttendanceAuditLog = AttendanceAuditLog;
window.AuditDetailSheet = AuditDetailSheet;
