// EquipmentScreen.jsx — AegisComply (Supabase-powered CRUD)

const PAGE_SIZE = 15;

// ── Sortable column header helper ───────────────────────────────────────────
function SortHeader({ label, field, sort, setSort, style }) {
  const active = sort.field === field;
  const dir = active ? sort.dir : null;
  const click = () => setSort({ field, dir: !active ? 'asc' : sort.dir === 'asc' ? 'desc' : 'asc' });
  return (
    <div onClick={click} style={{ ...style, cursor: 'pointer', display: 'inline-flex', alignItems: 'center', gap: 4, userSelect: 'none' }}>
      <span>{label}</span>
      <span style={{ fontSize: 9, color: active ? '#0D9488' : '#CBD5E1', lineHeight: 1 }}>
        {dir === 'asc' ? '▲' : dir === 'desc' ? '▼' : '↕'}
      </span>
    </div>
  );
}
const CATEGORIES = ['Measurement', 'Safety', 'Tool', 'Process', 'Electrical', 'Other'];
const STATUS_OPTIONS = [
  { value: 'active',              label: 'Active' },
  { value: 'expiring',            label: 'Expiring' },
  { value: 'overdue',             label: 'Overdue' },
  { value: 'expired',             label: 'Expired' },
  { value: 'pending_calibration', label: 'Pending Cal.' },
];

// ── Excel helpers (used by Export / Import) ─────────────────────────────────
const STATUS_TO_EXCEL = {
  active: 'Active', expiring: 'Expiring', overdue: 'Overdue', expired: 'Expired',
  pending_calibration: 'Pending Calibration',
};
const STATUS_FROM_EXCEL = {
  'active': 'active', 'expiring': 'expiring', 'overdue': 'overdue', 'expired': 'expired',
  'pending calibration': 'pending_calibration', 'pending_calibration': 'pending_calibration',
};

function isoToDMY(iso) {
  if (!iso) return '';
  const m = String(iso).match(/^(\d{4})-(\d{2})-(\d{2})/);
  return m ? `${m[3]}/${m[2]}/${m[1]}` : String(iso);
}

function parseExcelDate(value) {
  if (value === null || value === undefined || value === '') return null;
  if (value instanceof Date) {
    const y = value.getFullYear(); const m = String(value.getMonth()+1).padStart(2,'0'); const d = String(value.getDate()).padStart(2,'0');
    return `${y}-${m}-${d}`;
  }
  const s = String(value).trim();
  // DD/MM/YYYY (Malaysian/UK)
  const dmy = s.match(/^(\d{1,2})\/(\d{1,2})\/(\d{4})$/);
  if (dmy) return `${dmy[3]}-${dmy[2].padStart(2,'0')}-${dmy[1].padStart(2,'0')}`;
  // YYYY-MM-DD
  const ymd = s.match(/^(\d{4})-(\d{2})-(\d{2})/);
  if (ymd) return s.slice(0,10);
  return null;
}

function mapStatusFromExcel(s) {
  const v = String(s || '').trim().toLowerCase();
  return STATUS_FROM_EXCEL[v] || 'active';
}

const eqStyles = {
  page: { padding: 24 },
  toolbar: { display: 'flex', alignItems: 'center', gap: 10, marginBottom: 20, flexWrap: 'wrap' },
  searchWrap: { position: 'relative', flex: 1, maxWidth: 320 },
  searchInput: { width: '100%', height: 36, border: '1px solid #CBD5E1', borderRadius: 6, padding: '0 12px 0 36px', fontFamily: "'DM Sans', sans-serif", fontSize: 13, color: '#334155', outline: 'none', background: 'white' },
  searchIcon: { position: 'absolute', left: 10, top: '50%', transform: 'translateY(-50%)', color: '#94A3B8', pointerEvents: 'none' },
  select: { height: 36, padding: '0 28px 0 12px', border: '1px solid #CBD5E1', borderRadius: 6, background: 'white', fontSize: 13, fontWeight: 500, color: '#475569', cursor: 'pointer', fontFamily: "'DM Sans', sans-serif", outline: 'none', appearance: 'none', backgroundImage: 'url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns=\'http://www.w3.org/2000/svg\' width=\'12\' height=\'12\' viewBox=\'0 0 24 24\' fill=\'none\' stroke=\'%2364748B\' stroke-width=\'2\' stroke-linecap=\'round\' stroke-linejoin=\'round\'%3e%3cpolyline points=\'6 9 12 15 18 9\'%3e%3c/polyline%3e%3c/svg%3e")', backgroundRepeat: 'no-repeat', backgroundPosition: 'right 8px center' },
  addBtn: { height: 36, padding: '0 16px', border: 'none', borderRadius: 6, background: '#0D9488', fontSize: 13, fontWeight: 600, color: 'white', cursor: 'pointer', display: 'flex', alignItems: 'center', gap: 6, fontFamily: "'DM Sans', sans-serif", marginLeft: 'auto' },
  addBtnDisabled: { background: '#CBD5E1', cursor: 'not-allowed' },
  tableCard: { background: 'white', border: '1px solid #E2E8F0', borderRadius: 8, overflow: 'hidden', boxShadow: '0 1px 3px rgba(0,0,0,0.06)' },
  tableHead: { display: 'grid', gridTemplateColumns: '2.5fr 1.2fr 1.5fr 1.2fr 1.2fr 1fr 80px', gap: 8, padding: '10px 16px', background: '#F8FAFC', borderBottom: '1px solid #E2E8F0' },
  thCell: { fontSize: 11, fontWeight: 600, letterSpacing: '0.07em', textTransform: 'uppercase', color: '#94A3B8' },
  tableRow: { display: 'grid', gridTemplateColumns: '2.5fr 1.2fr 1.5fr 1.2fr 1.2fr 1fr 80px', gap: 8, padding: '11px 16px', borderBottom: '1px solid #F1F5F9', cursor: 'pointer', transition: 'background 150ms' },
  tdName: { fontSize: 13, fontWeight: 500, color: '#0F172A' },
  tdMono: { fontSize: 12, fontFamily: "'JetBrains Mono', monospace", color: '#64748B' },
  tdCell: { fontSize: 13, color: '#475569', display: 'flex', alignItems: 'center' },
  rowActions: { display: 'flex', gap: 4, alignItems: 'center' },
  iconBtn: { width: 28, height: 28, borderRadius: 5, border: '1px solid #E2E8F0', background: 'white', display: 'flex', alignItems: 'center', justifyContent: 'center', cursor: 'pointer', color: '#64748B', transition: 'all 150ms' },
  badge: { display: 'inline-flex', alignItems: 'center', gap: 4, padding: '2px 8px', borderRadius: 4, fontSize: 11, fontWeight: 600, letterSpacing: '0.05em', textTransform: 'uppercase' },
  pagination: { display: 'flex', alignItems: 'center', justifyContent: 'space-between', padding: '12px 16px', borderTop: '1px solid #F1F5F9' },
  pageInfo: { fontSize: 12, color: '#64748B' },
  pageButtons: { display: 'flex', gap: 4 },
  pageBtn: { minWidth: 30, height: 30, borderRadius: 5, border: '1px solid #E2E8F0', background: 'white', fontSize: 12, color: '#475569', cursor: 'pointer', display: 'flex', alignItems: 'center', justifyContent: 'center', padding: '0 8px', fontFamily: "'DM Sans', sans-serif" },
  pageBtnActive: { background: '#0D9488', color: 'white', border: '1px solid #0D9488' },
  pageBtnDisabled: { color: '#CBD5E1', cursor: 'not-allowed' },
  emptyState: { padding: 40, textAlign: 'center', color: '#64748B' },
  emptyIcon: { width: 48, height: 48, borderRadius: 12, background: '#F1F5F9', display: 'inline-flex', alignItems: 'center', justifyContent: 'center', marginBottom: 12 },
  emptyTitle: { fontSize: 14, fontWeight: 600, color: '#334155', marginBottom: 4 },
  emptySub: { fontSize: 12, color: '#94A3B8' },
  // Modal
  modalOverlay: { position: 'fixed', inset: 0, background: 'rgba(15,23,42,0.55)', display: 'flex', alignItems: 'center', justifyContent: 'center', zIndex: 9000, padding: 20 },
  modal: { background: 'white', borderRadius: 12, width: '100%', maxWidth: 640, maxHeight: '90vh', display: 'flex', flexDirection: 'column', boxShadow: '0 24px 64px rgba(0,0,0,0.25)' },
  modalHeader: { padding: '18px 24px', borderBottom: '1px solid #E2E8F0', display: 'flex', alignItems: 'center', justifyContent: 'space-between' },
  modalTitle: { fontFamily: "'Helvetica',Arial,sans-serif", fontSize: 16, fontWeight: 700, color: '#0F172A' },
  modalClose: { width: 30, height: 30, borderRadius: 6, border: 'none', background: '#F1F5F9', cursor: 'pointer', display: 'flex', alignItems: 'center', justifyContent: 'center', color: '#64748B' },
  modalBody: { padding: '20px 24px', overflowY: 'auto', flex: 1 },
  modalFooter: { padding: '14px 24px', borderTop: '1px solid #E2E8F0', display: 'flex', gap: 10, justifyContent: 'flex-end', background: '#F8FAFC' },
  field: { marginBottom: 14 },
  fieldRow: { display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 12, marginBottom: 0 },
  label: { fontSize: 12, fontWeight: 600, color: '#334155', display: 'block', marginBottom: 5 },
  required: { color: '#DC2626', marginLeft: 2 },
  input: { width: '100%', height: 36, border: '1px solid #CBD5E1', borderRadius: 6, padding: '0 10px', fontFamily: "'DM Sans',sans-serif", fontSize: 13, color: '#0F172A', outline: 'none', background: 'white', boxSizing: 'border-box' },
  textarea: { width: '100%', minHeight: 60, border: '1px solid #CBD5E1', borderRadius: 6, padding: '8px 10px', fontFamily: "'DM Sans',sans-serif", fontSize: 13, color: '#0F172A', outline: 'none', background: 'white', resize: 'vertical', boxSizing: 'border-box' },
  selectInput: { width: '100%', height: 36, border: '1px solid #CBD5E1', borderRadius: 6, padding: '0 28px 0 10px', fontFamily: "'DM Sans',sans-serif", fontSize: 13, color: '#0F172A', outline: 'none', background: 'white', appearance: 'none', backgroundImage: 'url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns=\'http://www.w3.org/2000/svg\' width=\'12\' height=\'12\' viewBox=\'0 0 24 24\' fill=\'none\' stroke=\'%2364748B\' stroke-width=\'2\' stroke-linecap=\'round\' stroke-linejoin=\'round\'%3e%3cpolyline points=\'6 9 12 15 18 9\'%3e%3c/polyline%3e%3c/svg%3e")', backgroundRepeat: 'no-repeat', backgroundPosition: 'right 8px center', boxSizing: 'border-box' },
  fileWrap: { display: 'flex', alignItems: 'center', gap: 10 },
  fileBtn: { height: 36, padding: '0 14px', border: '1px dashed #CBD5E1', borderRadius: 6, background: 'white', fontSize: 13, fontWeight: 500, color: '#0D9488', cursor: 'pointer', fontFamily: "'DM Sans',sans-serif" },
  fileName: { fontSize: 12, color: '#64748B' },
  btnPrimary: { height: 38, padding: '0 18px', border: 'none', borderRadius: 6, background: '#0D9488', fontSize: 13, fontWeight: 700, color: 'white', cursor: 'pointer', fontFamily: "'DM Sans',sans-serif" },
  btnPrimaryDisabled: { background: '#CBD5E1', cursor: 'not-allowed' },
  btnSecondary: { height: 38, padding: '0 18px', border: '1px solid #CBD5E1', borderRadius: 6, background: 'white', fontSize: 13, fontWeight: 600, color: '#64748B', cursor: 'pointer', fontFamily: "'DM Sans',sans-serif" },
  btnDanger: { height: 38, padding: '0 18px', border: 'none', borderRadius: 6, background: '#DC2626', fontSize: 13, fontWeight: 700, color: 'white', cursor: 'pointer', fontFamily: "'DM Sans',sans-serif" },
  errorBox: { background: '#FFF5F5', border: '1px solid #FECACA', borderRadius: 6, padding: '8px 12px', fontSize: 12, color: '#DC2626', marginBottom: 12 },
  infoBox: { background: '#F0FDFA', border: '1px solid #99F6E4', borderRadius: 6, padding: '8px 12px', fontSize: 12, color: '#0F766E', marginBottom: 12 },
  detailRow: { display: 'grid', gridTemplateColumns: '140px 1fr', gap: 12, padding: '8px 0', borderBottom: '1px solid #F1F5F9', fontSize: 13 },
  detailLabel: { color: '#94A3B8', fontWeight: 500 },
  detailValue: { color: '#0F172A' },
  certLink: { color: '#0D9488', fontSize: 13, textDecoration: 'none', fontWeight: 600 },
};

const statusMap = {
  active:               { bg: '#F0FDF4', color: '#16A34A', dot: '#16A34A', label: 'Active' },
  expiring:             { bg: '#FFFBEB', color: '#D97706', dot: '#D97706', label: 'Expiring' },
  overdue:              { bg: '#FFF7ED', color: '#EA580C', dot: '#EA580C', label: 'Overdue' },
  expired:              { bg: '#FFF5F5', color: '#DC2626', dot: '#DC2626', label: 'Expired' },
  pending_calibration:  { bg: '#F1F5F9', color: '#475569', dot: '#475569', label: 'Pending' },
  // legacy fallback
  valid:                { bg: '#F0FDF4', color: '#16A34A', dot: '#16A34A', label: 'Active' },
};

function EqBadge({ status }) {
  const s = statusMap[status] || statusMap.active;
  return (
    <span style={{ ...eqStyles.badge, background: s.bg, color: s.color }}>
      <span style={{ width: 6, height: 6, borderRadius: '50%', background: s.dot, display: 'inline-block' }}/>
      {s.label}
    </span>
  );
}

function fmtDate(d) {
  if (!d) return '—';
  try { return new Date(d).toLocaleDateString('en-GB', { day: '2-digit', month: 'short', year: 'numeric' }); }
  catch { return d; }
}

// ── Equipment Form Modal (used for both Add and Edit) ────────────────────────
function EquipmentFormModal({ initial, onSave, onClose, user }) {
  const isEdit = !!initial?.id;
  const empty = {
    name: '', brand_model: '', serial_number: '', category: '', location: '', department: '',
    last_cal_date: '', calibration_due: '', cert_number: '', status: 'active',
    remark: '', verified_by: '', cert_url: '',
  };
  const [form, setForm] = React.useState(initial ? { ...empty, ...initial } : empty);
  const [file, setFile] = React.useState(null);
  const [error, setError] = React.useState('');
  const [saving, setSaving] = React.useState(false);
  const set = (k, v) => setForm(f => ({ ...f, [k]: v }));
  const valid = form.name.trim() && form.serial_number.trim();

  const handleFile = (e) => {
    const f = e.target.files?.[0];
    if (!f) return;
    if (f.size > 10 * 1024 * 1024) { setError('File too large (max 10 MB).'); return; }
    setFile(f);
    setError('');
  };

  const uploadCert = async (equipmentId) => {
    if (!file) return null;
    const sb = window.supabaseClient;
    const ext = file.name.split('.').pop() || 'pdf';
    const path = `${user.id}/${equipmentId}.${ext}`;
    const { error: upErr } = await sb.storage.from('certificates').upload(path, file, { upsert: true });
    if (upErr) {
      // Bucket might not exist yet — warn but don't block save
      console.warn('[Equipment] Cert upload failed:', upErr.message);
      throw new Error(`Certificate upload failed: ${upErr.message}`);
    }
    return path;
  };

  const handleSubmit = async () => {
    setError('');
    if (!valid) { setError('Name and Serial Number are required.'); return; }
    setSaving(true);
    try {
      const sb = window.supabaseClient;
      const payload = {
        ...form,
        user_id: user.id,
        last_cal_date: form.last_cal_date || null,
        calibration_due: form.calibration_due || null,
      };
      // Strip empty strings to null so optional fields don't fail
      Object.keys(payload).forEach(k => { if (payload[k] === '') payload[k] = null; });

      let savedId;
      if (isEdit) {
        delete payload.id; delete payload.created_at; delete payload.updated_at;
        const { data, error: upErr } = await sb.from('equipment').update(payload).eq('id', initial.id).select().single();
        if (upErr) throw upErr;
        savedId = data.id;
      } else {
        const { data, error: insErr } = await sb.from('equipment').insert(payload).select().single();
        if (insErr) throw insErr;
        savedId = data.id;
      }

      // Upload certificate if a file was selected
      if (file) {
        try {
          const certPath = await uploadCert(savedId);
          await sb.from('equipment').update({ cert_url: certPath }).eq('id', savedId);
        } catch (upErr) {
          // Equipment saved but upload failed — warn user but don't lose the record
          setError(upErr.message + ' (Equipment saved without certificate.)');
          setSaving(false);
          setTimeout(() => onSave(), 1500);
          return;
        }
      }

      setSaving(false);
      onSave();
    } catch (err) {
      console.error('[Equipment] Save error:', err);
      setError(err.message || 'Save failed.');
      setSaving(false);
    }
  };

  return (
    <div style={eqStyles.modalOverlay} onClick={onClose}>
      <div style={eqStyles.modal} onClick={e => e.stopPropagation()}>
        <div style={eqStyles.modalHeader}>
          <div style={eqStyles.modalTitle}>{isEdit ? 'Edit Equipment' : 'Add Equipment'}</div>
          <button style={eqStyles.modalClose} onClick={onClose}>
            <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>
          </button>
        </div>

        <div style={eqStyles.modalBody}>
          {error && <div style={eqStyles.errorBox}>{error}</div>}

          <div style={eqStyles.field}>
            <label style={eqStyles.label}>Equipment Name<span style={eqStyles.required}>*</span></label>
            <input style={eqStyles.input} placeholder="e.g. Portable Gas Detector (4-Gas)" value={form.name} onChange={e => set('name', e.target.value)}/>
          </div>

          <div style={eqStyles.fieldRow}>
            <div style={eqStyles.field}>
              <label style={eqStyles.label}>Brand / Model</label>
              <input style={eqStyles.input} placeholder="e.g. Honeywell BW Clip4" value={form.brand_model || ''} onChange={e => set('brand_model', e.target.value)}/>
            </div>
            <div style={eqStyles.field}>
              <label style={eqStyles.label}>Serial Number<span style={eqStyles.required}>*</span></label>
              <input style={eqStyles.input} placeholder="e.g. GD-001" value={form.serial_number} onChange={e => set('serial_number', e.target.value)}/>
            </div>
          </div>

          <div style={eqStyles.fieldRow}>
            <div style={eqStyles.field}>
              <label style={eqStyles.label}>Category</label>
              <select style={eqStyles.selectInput} value={form.category || ''} onChange={e => set('category', e.target.value)}>
                <option value="">— Select —</option>
                {CATEGORIES.map(c => <option key={c} value={c}>{c}</option>)}
              </select>
            </div>
            <div style={eqStyles.field}>
              <label style={eqStyles.label}>Status</label>
              <select style={eqStyles.selectInput} value={form.status} onChange={e => set('status', e.target.value)}>
                {STATUS_OPTIONS.map(o => <option key={o.value} value={o.value}>{o.label}</option>)}
              </select>
            </div>
          </div>

          <div style={eqStyles.fieldRow}>
            <div style={eqStyles.field}>
              <label style={eqStyles.label}>Location</label>
              <input style={eqStyles.input} placeholder="e.g. Oil & Gas Site A" value={form.location || ''} onChange={e => set('location', e.target.value)}/>
            </div>
            <div style={eqStyles.field}>
              <label style={eqStyles.label}>Department</label>
              <input style={eqStyles.input} placeholder="e.g. HSE" value={form.department || ''} onChange={e => set('department', e.target.value)}/>
            </div>
          </div>

          <div style={eqStyles.fieldRow}>
            <div style={eqStyles.field}>
              <label style={eqStyles.label}>Last Calibration Date</label>
              <input style={eqStyles.input} type="date" value={form.last_cal_date || ''} onChange={e => set('last_cal_date', e.target.value)}/>
            </div>
            <div style={eqStyles.field}>
              <label style={eqStyles.label}>Next Calibration Due</label>
              <input style={eqStyles.input} type="date" value={form.calibration_due || ''} onChange={e => set('calibration_due', e.target.value)}/>
            </div>
          </div>

          <div style={eqStyles.fieldRow}>
            <div style={eqStyles.field}>
              <label style={eqStyles.label}>Certificate No.</label>
              <input style={eqStyles.input} placeholder="e.g. CAL-2025-GD001" value={form.cert_number || ''} onChange={e => set('cert_number', e.target.value)}/>
            </div>
            <div style={eqStyles.field}>
              <label style={eqStyles.label}>Verified By</label>
              <input style={eqStyles.input} placeholder="Name of lab/technician" value={form.verified_by || ''} onChange={e => set('verified_by', e.target.value)}/>
            </div>
          </div>

          <div style={eqStyles.field}>
            <label style={eqStyles.label}>Certificate File (PDF, max 10 MB)</label>
            <div style={eqStyles.fileWrap}>
              <label style={eqStyles.fileBtn}>
                {file ? 'Change file…' : 'Choose PDF…'}
                <input type="file" accept="application/pdf,.pdf" style={{ display: 'none' }} onChange={handleFile}/>
              </label>
              <span style={eqStyles.fileName}>
                {file ? file.name : (form.cert_url ? '✓ Existing certificate uploaded' : 'No file selected')}
              </span>
            </div>
          </div>

          <div style={eqStyles.field}>
            <label style={eqStyles.label}>Remark</label>
            <textarea style={eqStyles.textarea} placeholder="Any notes about this equipment…" value={form.remark || ''} onChange={e => set('remark', e.target.value)}/>
          </div>
        </div>

        <div style={eqStyles.modalFooter}>
          <button style={eqStyles.btnSecondary} onClick={onClose} disabled={saving}>Cancel</button>
          <button
            style={{ ...eqStyles.btnPrimary, ...(!valid || saving ? eqStyles.btnPrimaryDisabled : {}) }}
            onClick={handleSubmit}
            disabled={!valid || saving}
          >
            {saving ? 'Saving…' : (isEdit ? 'Save Changes' : 'Add Equipment')}
          </button>
        </div>
      </div>
    </div>
  );
}

// ── View Equipment Modal ─────────────────────────────────────────────────────
function EquipmentViewModal({ equipment, certUrl, onClose, onEdit }) {
  return (
    <div style={eqStyles.modalOverlay} onClick={onClose}>
      <div style={eqStyles.modal} onClick={e => e.stopPropagation()}>
        <div style={eqStyles.modalHeader}>
          <div style={eqStyles.modalTitle}>{equipment.name}</div>
          <button style={eqStyles.modalClose} onClick={onClose}>
            <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>
          </button>
        </div>
        <div style={eqStyles.modalBody}>
          <div style={{ marginBottom: 14 }}><EqBadge status={equipment.status}/></div>
          {[
            ['Brand / Model', equipment.brand_model],
            ['Serial Number', equipment.serial_number],
            ['Category', equipment.category],
            ['Location', equipment.location],
            ['Department', equipment.department],
            ['Last Cal. Date', fmtDate(equipment.last_cal_date)],
            ['Next Cal. Due', fmtDate(equipment.calibration_due)],
            ['Certificate No.', equipment.cert_number],
            ['Verified By', equipment.verified_by],
            ['Remark', equipment.remark],
          ].map(([label, value]) => (
            <div key={label} style={eqStyles.detailRow}>
              <div style={eqStyles.detailLabel}>{label}</div>
              <div style={eqStyles.detailValue}>{value || <span style={{ color: '#CBD5E1' }}>—</span>}</div>
            </div>
          ))}
          {certUrl && (
            <div style={eqStyles.detailRow}>
              <div style={eqStyles.detailLabel}>Certificate</div>
              <div style={eqStyles.detailValue}>
                <a href={certUrl} target="_blank" rel="noopener noreferrer" style={eqStyles.certLink}>📄 View certificate PDF →</a>
              </div>
            </div>
          )}
        </div>
        <div style={eqStyles.modalFooter}>
          <button style={eqStyles.btnSecondary} onClick={onClose}>Close</button>
          <button style={eqStyles.btnPrimary} onClick={onEdit}>Edit</button>
        </div>
      </div>
    </div>
  );
}

// ── Delete Confirmation Modal ────────────────────────────────────────────────
function DeleteConfirmModal({ equipment, onConfirm, onCancel, busy }) {
  return (
    <div style={eqStyles.modalOverlay} onClick={!busy ? onCancel : undefined}>
      <div style={{ ...eqStyles.modal, maxWidth: 440 }} onClick={e => e.stopPropagation()}>
        <div style={eqStyles.modalHeader}>
          <div style={eqStyles.modalTitle}>Delete Equipment?</div>
        </div>
        <div style={eqStyles.modalBody}>
          <div style={{ fontSize: 13, color: '#475569', lineHeight: 1.6 }}>
            Are you sure you want to delete <strong>{equipment.name}</strong> (<span style={{ fontFamily: "'JetBrains Mono', monospace" }}>{equipment.serial_number}</span>)?
            <br/><br/>
            This action cannot be undone. Related calibration records will also be removed.
          </div>
        </div>
        <div style={eqStyles.modalFooter}>
          <button style={eqStyles.btnSecondary} onClick={onCancel} disabled={busy}>Cancel</button>
          <button style={eqStyles.btnDanger} onClick={onConfirm} disabled={busy}>
            {busy ? 'Deleting…' : 'Delete'}
          </button>
        </div>
      </div>
    </div>
  );
}

// ── Import Excel Modal ───────────────────────────────────────────────────────
function ImportExcelModal({ user, onClose, onImported }) {
  const [file, setFile] = React.useState(null);
  const [busy, setBusy] = React.useState(false);
  const [result, setResult] = React.useState(null); // {inserted, skipped, errors} | {error}
  const [error, setError] = React.useState('');

  const handleFile = (e) => {
    const f = e.target.files?.[0];
    if (!f) return;
    if (!/\.(xlsx|xls)$/i.test(f.name)) { setError('Please choose an .xlsx or .xls file.'); return; }
    setFile(f); setError(''); setResult(null);
  };

  const runImport = async () => {
    if (!file) return;
    setBusy(true); setError(''); setResult(null);
    try {
      if (typeof window.XLSX === 'undefined') throw new Error('Excel library not loaded.');
      const buf = await file.arrayBuffer();
      const wb  = window.XLSX.read(buf, { type: 'array' });
      const ws  = wb.Sheets[wb.SheetNames[0]];
      const rows = window.XLSX.utils.sheet_to_json(ws, { header: 1, raw: false, defval: '' });

      // Find the header row
      let headerIdx = -1;
      for (let i = 0; i < Math.min(10, rows.length); i++) {
        const cells = rows[i].map(c => String(c || '').toLowerCase());
        if (cells.some(c => c.includes('device name') || c.includes('equipment name') || c.includes('serial no'))) {
          headerIdx = i; break;
        }
      }
      if (headerIdx === -1) throw new Error('Could not find a header row. Expected columns like "Device Name" and "Serial No.".');

      const header = rows[headerIdx].map(c => String(c || '').trim().toLowerCase());
      const col = (...keys) => {
        for (const k of keys) {
          const idx = header.findIndex(h => h.includes(k));
          if (idx !== -1) return idx;
        }
        return -1;
      };
      const c = {
        name:    col('device name', 'equipment name', 'equipment'),
        brand:   col('model', 'brand'),
        serial:  col('serial'),
        lastCal: col('last cal'),
        due:     col('next due', 'due date', 'calibration due'),
        certNo:  col('certificate no', 'cert no'),
        status:  col('status'),
        loc:     col('location'),
        dept:    col('department'),
        remark:  col('remark', 'note'),
        verify:  col('verified', 'verified by'),
        cat:     col('category'),
      };
      if (c.name === -1 || c.serial === -1) throw new Error('Missing required columns: "Device Name" and "Serial No."');

      const records = [];
      for (let i = headerIdx + 1; i < rows.length; i++) {
        const r = rows[i];
        const name = r[c.name], serial = r[c.serial];
        if (!name || !serial) continue;
        records.push({
          user_id:         user.id,
          name:            String(name).trim(),
          brand_model:     c.brand   !== -1 && r[c.brand]   ? String(r[c.brand]).trim()   : null,
          serial_number:   String(serial).trim(),
          category:        c.cat     !== -1 && r[c.cat]     ? String(r[c.cat]).trim()    : null,
          last_cal_date:   parseExcelDate(r[c.lastCal]),
          calibration_due: parseExcelDate(r[c.due]),
          cert_number:     c.certNo  !== -1 && r[c.certNo]  ? String(r[c.certNo]).trim() : null,
          status:          mapStatusFromExcel(r[c.status]),
          location:        c.loc     !== -1 && r[c.loc]     ? String(r[c.loc]).trim()    : null,
          department:      c.dept    !== -1 && r[c.dept]    ? String(r[c.dept]).trim()   : null,
          remark:          c.remark  !== -1 && r[c.remark]  ? String(r[c.remark]).trim() : null,
          verified_by:     c.verify  !== -1 && r[c.verify]  ? String(r[c.verify]).trim() : null,
        });
      }
      if (records.length === 0) throw new Error('No valid data rows found in the file.');

      // Detect duplicates by serial_number (skip them)
      const sb = window.supabaseClient;
      const incomingSerials = records.map(r => r.serial_number);
      const { data: existing } = await sb.from('equipment').select('serial_number').in('serial_number', incomingSerials);
      const existingSet = new Set((existing || []).map(e => e.serial_number));
      const toInsert = records.filter(r => !existingSet.has(r.serial_number));
      const skipped  = records.length - toInsert.length;

      if (toInsert.length === 0) {
        setResult({ inserted: 0, skipped, total: records.length });
        setBusy(false);
        return;
      }

      // Insert in batches of 100
      let inserted = 0;
      for (let i = 0; i < toInsert.length; i += 100) {
        const batch = toInsert.slice(i, i + 100);
        const { error: insErr } = await sb.from('equipment').insert(batch);
        if (insErr) throw insErr;
        inserted += batch.length;
      }
      setResult({ inserted, skipped, total: records.length });
      onImported?.();
    } catch (err) {
      console.error('[Equipment Import] error:', err);
      setError(err.message || 'Import failed.');
    } finally {
      setBusy(false);
    }
  };

  return (
    <div style={eqStyles.modalOverlay} onClick={busy ? undefined : onClose}>
      <div style={{ ...eqStyles.modal, maxWidth: 520 }} onClick={e => e.stopPropagation()}>
        <div style={eqStyles.modalHeader}>
          <div style={eqStyles.modalTitle}>Import Equipment from Excel</div>
          <button style={eqStyles.modalClose} onClick={onClose} disabled={busy}>
            <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>
          </button>
        </div>
        <div style={eqStyles.modalBody}>
          {error && <div style={eqStyles.errorBox}>{error}</div>}
          {result && (
            <div style={eqStyles.infoBox}>
              <strong>Import complete.</strong><br/>
              ✓ Inserted: {result.inserted}<br/>
              ⊝ Skipped (duplicate serial): {result.skipped}<br/>
              Total rows read: {result.total}
            </div>
          )}
          {!result && (
            <>
              <div style={{ fontSize: 13, color: '#475569', marginBottom: 14, lineHeight: 1.6 }}>
                Upload an Excel file with equipment data. Expected columns:
                <ul style={{ margin: '8px 0 0 18px', padding: 0, fontSize: 12, color: '#64748B', lineHeight: 1.8 }}>
                  <li><strong>Required:</strong> Device Name, Serial No.</li>
                  <li><strong>Optional:</strong> Model / Brand, Last Cal. Date, Next Due Date, Certificate No., Status, Location, Department, Remark, Verified By, Category</li>
                </ul>
                <div style={{ marginTop: 10, fontSize: 12, color: '#94A3B8' }}>
                  Dates in DD/MM/YYYY format. Duplicate Serial Numbers are skipped.
                </div>
              </div>
              <div style={eqStyles.field}>
                <label style={eqStyles.label}>Excel File (.xlsx)</label>
                <div style={eqStyles.fileWrap}>
                  <label style={eqStyles.fileBtn}>
                    {file ? 'Change file…' : 'Choose Excel…'}
                    <input type="file" accept=".xlsx,.xls,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" style={{ display: 'none' }} onChange={handleFile}/>
                  </label>
                  <span style={eqStyles.fileName}>{file ? file.name : 'No file selected'}</span>
                </div>
              </div>
            </>
          )}
        </div>
        <div style={eqStyles.modalFooter}>
          {result ? (
            <button style={eqStyles.btnPrimary} onClick={onClose}>Done</button>
          ) : (
            <>
              <button style={eqStyles.btnSecondary} onClick={onClose} disabled={busy}>Cancel</button>
              <button
                style={{ ...eqStyles.btnPrimary, ...((!file || busy) ? eqStyles.btnPrimaryDisabled : {}) }}
                onClick={runImport}
                disabled={!file || busy}
              >
                {busy ? 'Importing…' : 'Import Now'}
              </button>
            </>
          )}
        </div>
      </div>
    </div>
  );
}

// ── Main Equipment Screen ────────────────────────────────────────────────────
function EquipmentScreen({ user, isFrozen }) {
  const [items, setItems] = React.useState([]);
  const [totalCount, setTotalCount] = React.useState(0);
  const [loading, setLoading] = React.useState(false);
  const [error, setError] = React.useState('');
  const [search, setSearch] = React.useState('');
  const [statusFilter, setStatusFilter] = React.useState('all');
  const [categoryFilter, setCategoryFilter] = React.useState('all');
  const [page, setPage] = React.useState(0);
  const [hovered, setHovered] = React.useState(null);
  const [sort, setSort] = React.useState({ field: 'created_at', dir: 'desc' });

  const [editing, setEditing] = React.useState(null); // null | 'new' | equipment object
  const [viewing, setViewing] = React.useState(null);
  const [viewingCertUrl, setViewingCertUrl] = React.useState('');
  const [deleting, setDeleting] = React.useState(null);
  const [deleteBusy, setDeleteBusy] = React.useState(false);
  const [showImport, setShowImport] = React.useState(false);
  const [exporting, setExporting] = React.useState(false);

  const fetchEquipment = React.useCallback(async () => {
    setLoading(true); setError('');
    try {
      const sb = window.supabaseClient;
      let query = sb.from('equipment').select('*', { count: 'exact' });
      if (statusFilter !== 'all')   query = query.eq('status', statusFilter);
      if (categoryFilter !== 'all') query = query.eq('category', categoryFilter);
      if (search.trim()) {
        const term = search.trim();
        query = query.or(`name.ilike.%${term}%,serial_number.ilike.%${term}%`);
      }
      const from = page * PAGE_SIZE;
      const to   = from + PAGE_SIZE - 1;
      query = query.order(sort.field, { ascending: sort.dir === 'asc', nullsFirst: false }).range(from, to);

      const { data, error: qErr, count } = await query;
      if (qErr) throw qErr;
      setItems(data || []);
      setTotalCount(count || 0);
    } catch (err) {
      console.error('[Equipment] Fetch error:', err);
      setError(err.message || 'Failed to load equipment.');
    } finally {
      setLoading(false);
    }
  }, [search, statusFilter, categoryFilter, page, sort]);

  React.useEffect(() => { fetchEquipment(); }, [fetchEquipment]);

  // Reset to page 0 when filters or sort change
  React.useEffect(() => { setPage(0); }, [search, statusFilter, categoryFilter, sort]);

  // Live updates via Supabase Realtime — table refreshes on any change
  React.useEffect(() => {
    if (!user) return;
    const sb = window.supabaseClient;
    if (!sb) return;
    const channel = sb.channel(`equipment-list-${user.id}`)
      .on('postgres_changes',
        { event: '*', schema: 'public', table: 'equipment', filter: `user_id=eq.${user.id}` },
        () => { fetchEquipment(); }
      )
      .subscribe();
    return () => { sb.removeChannel(channel); };
  }, [user, fetchEquipment]);

  const handleView = async (eq) => {
    setViewing(eq);
    setViewingCertUrl('');
    if (eq.cert_url) {
      try {
        const sb = window.supabaseClient;
        const { data, error: urlErr } = await sb.storage.from('certificates').createSignedUrl(eq.cert_url, 3600);
        if (!urlErr && data?.signedUrl) setViewingCertUrl(data.signedUrl);
      } catch (e) { /* ignore — cert just won't show */ }
    }
  };

  const handleDelete = async () => {
    if (!deleting) return;
    setDeleteBusy(true);
    try {
      const sb = window.supabaseClient;
      // Try deleting cert file (ignore errors)
      if (deleting.cert_url) {
        try { await sb.storage.from('certificates').remove([deleting.cert_url]); } catch (e) {}
      }
      const { error: delErr } = await sb.from('equipment').delete().eq('id', deleting.id);
      if (delErr) throw delErr;
      setDeleting(null);
      fetchEquipment();
    } catch (err) {
      console.error('[Equipment] Delete error:', err);
      alert('Delete failed: ' + err.message);
    } finally {
      setDeleteBusy(false);
    }
  };

  // ── Export current filtered view to Excel ────────────────────────────────
  const handleExport = async () => {
    if (typeof window.XLSX === 'undefined') { alert('Excel library not loaded. Refresh the page.'); return; }
    setExporting(true);
    try {
      const sb = window.supabaseClient;
      // Build same query as fetchEquipment, but without pagination — export everything that matches filters
      let q = sb.from('equipment').select('*').order('created_at', { ascending: false });
      if (statusFilter !== 'all')   q = q.eq('status', statusFilter);
      if (categoryFilter !== 'all') q = q.eq('category', categoryFilter);
      if (search.trim()) {
        const term = search.trim();
        q = q.or(`name.ilike.%${term}%,serial_number.ilike.%${term}%`);
      }
      const { data, error: expErr } = await q;
      if (expErr) throw expErr;
      if (!data || data.length === 0) { alert('No equipment to export with current filters.'); return; }

      const rows = data.map((eq, i) => ({
        'No.':              i + 1,
        'Device Name':      eq.name,
        'Model / Brand':    eq.brand_model || '',
        'Serial No.':       eq.serial_number,
        'Last Cal. Date':   isoToDMY(eq.last_cal_date),
        'Next Due Date':    isoToDMY(eq.calibration_due),
        'Certificate No.':  eq.cert_number || '',
        'Certificate File / Ref.': eq.cert_url ? 'Uploaded' : '',
        'Status':           STATUS_TO_EXCEL[eq.status] || eq.status || '',
        'Location':         eq.location || '',
        'Department':       eq.department || '',
        'Remark':           eq.remark || '',
        'Verified By':      eq.verified_by || '',
        'Category':         eq.category || '',
      }));

      const ws = window.XLSX.utils.json_to_sheet(rows);
      const wb = window.XLSX.utils.book_new();
      window.XLSX.utils.book_append_sheet(wb, ws, 'Calibration Register');
      const today = new Date().toISOString().slice(0, 10);
      window.XLSX.writeFile(wb, `AegisComply_Equipment_${today}.xlsx`);
    } catch (err) {
      console.error('[Equipment Export] error:', err);
      alert('Export failed: ' + err.message);
    } finally {
      setExporting(false);
    }
  };

  const totalPages = Math.max(1, Math.ceil(totalCount / PAGE_SIZE));
  const showingFrom = totalCount === 0 ? 0 : page * PAGE_SIZE + 1;
  const showingTo   = Math.min((page + 1) * PAGE_SIZE, totalCount);

  return (
    <div style={eqStyles.page}>
      <div style={eqStyles.toolbar}>
        <div style={eqStyles.searchWrap}>
          <svg style={eqStyles.searchIcon} width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/></svg>
          <input
            style={eqStyles.searchInput}
            placeholder="Search by name or serial number…"
            value={search}
            onChange={e => setSearch(e.target.value)}
          />
        </div>
        <select style={eqStyles.select} value={categoryFilter} onChange={e => setCategoryFilter(e.target.value)}>
          <option value="all">All Categories</option>
          {CATEGORIES.map(c => <option key={c} value={c}>{c}</option>)}
        </select>
        <select style={eqStyles.select} value={statusFilter} onChange={e => setStatusFilter(e.target.value)}>
          <option value="all">All Statuses</option>
          {STATUS_OPTIONS.map(o => <option key={o.value} value={o.value}>{o.label}</option>)}
        </select>
        <button
          style={{ ...eqStyles.addBtn, marginLeft: 'auto', background: 'white', color: '#475569', border: '1px solid #CBD5E1', ...(isFrozen ? { color: '#CBD5E1', cursor: 'not-allowed' } : {}) }}
          onClick={() => !isFrozen && setShowImport(true)}
          disabled={isFrozen}
          title={isFrozen ? 'Subscription lapsed — read-only mode' : 'Import equipment from Excel'}
        >
          <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" y1="15" x2="12" y2="3"/></svg>
          Import
        </button>
        <button
          style={{ ...eqStyles.addBtn, marginLeft: 0, background: 'white', color: '#475569', border: '1px solid #CBD5E1', ...(exporting ? { color: '#CBD5E1' } : {}) }}
          onClick={handleExport}
          disabled={exporting}
          title="Export current filtered view to Excel"
        >
          <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="17 8 12 3 7 8"/><line x1="12" y1="3" x2="12" y2="15"/></svg>
          {exporting ? 'Exporting…' : 'Export'}
        </button>
        <button
          style={{ ...eqStyles.addBtn, marginLeft: 0, ...(isFrozen ? eqStyles.addBtnDisabled : {}) }}
          onClick={() => !isFrozen && setEditing('new')}
          disabled={isFrozen}
          title={isFrozen ? 'Subscription lapsed — read-only mode' : ''}
        >
          <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round"><line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/></svg>
          Add Equipment
        </button>
      </div>

      {error && <div style={eqStyles.errorBox}>{error}</div>}

      <div style={eqStyles.tableCard}>
        <div style={eqStyles.tableHead}>
          <SortHeader label="Equipment"  field="name"            sort={sort} setSort={setSort} style={eqStyles.thCell}/>
          <SortHeader label="Category"   field="category"        sort={sort} setSort={setSort} style={eqStyles.thCell}/>
          <SortHeader label="Location"   field="location"        sort={sort} setSort={setSort} style={eqStyles.thCell}/>
          <SortHeader label="Department" field="department"      sort={sort} setSort={setSort} style={eqStyles.thCell}/>
          <SortHeader label="Cal. Due"   field="calibration_due" sort={sort} setSort={setSort} style={eqStyles.thCell}/>
          <SortHeader label="Status"     field="status"          sort={sort} setSort={setSort} style={eqStyles.thCell}/>
          <div style={eqStyles.thCell}></div>
        </div>

        {loading && items.length === 0 ? (
          <div style={eqStyles.emptyState}>
            <div style={eqStyles.emptyTitle}>Loading equipment…</div>
          </div>
        ) : items.length === 0 ? (
          <div style={eqStyles.emptyState}>
            <div style={eqStyles.emptyIcon}>
              <svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="#94A3B8" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"><rect x="3" y="3" width="18" height="18" rx="2"/><line x1="9" y1="9" x2="15" y2="9"/><line x1="9" y1="13" x2="15" y2="13"/><line x1="9" y1="17" x2="12" y2="17"/></svg>
            </div>
            <div style={eqStyles.emptyTitle}>No equipment yet</div>
            <div style={eqStyles.emptySub}>
              {search || statusFilter !== 'all' || categoryFilter !== 'all'
                ? 'No results match your filters. Try clearing them.'
                : 'Click "Add Equipment" above to register your first item.'}
            </div>
          </div>
        ) : (
          items.map((r, i) => (
            <div
              key={r.id}
              style={{ ...eqStyles.tableRow, background: hovered === i ? '#F8FAFC' : 'white' }}
              onMouseEnter={() => setHovered(i)}
              onMouseLeave={() => setHovered(null)}
              onClick={() => handleView(r)}
            >
              <div>
                <div style={eqStyles.tdName}>{r.name}</div>
                <div style={eqStyles.tdMono}>{r.serial_number}</div>
              </div>
              <div style={eqStyles.tdCell}>{r.category || '—'}</div>
              <div style={eqStyles.tdCell}>{r.location || '—'}</div>
              <div style={eqStyles.tdCell}>{r.department || '—'}</div>
              <div style={{ ...eqStyles.tdCell, fontSize: 12 }}>{fmtDate(r.calibration_due)}</div>
              <div style={eqStyles.tdCell}><EqBadge status={r.status} /></div>
              <div style={eqStyles.rowActions} onClick={e => e.stopPropagation()}>
                <button style={eqStyles.iconBtn} title="Edit" onClick={() => !isFrozen && setEditing(r)} disabled={isFrozen}>
                  <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"/><path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z"/></svg>
                </button>
                <button style={{ ...eqStyles.iconBtn, color: '#DC2626' }} title="Delete" onClick={() => !isFrozen && setDeleting(r)} disabled={isFrozen}>
                  <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><polyline points="3 6 5 6 21 6"/><path d="M19 6l-2 14a2 2 0 0 1-2 2H9a2 2 0 0 1-2-2L5 6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"/></svg>
                </button>
              </div>
            </div>
          ))
        )}

        <div style={eqStyles.pagination}>
          <span style={eqStyles.pageInfo}>
            {totalCount === 0
              ? 'No equipment'
              : `Showing ${showingFrom}–${showingTo} of ${totalCount}`}
          </span>
          <div style={eqStyles.pageButtons}>
            <button
              style={{ ...eqStyles.pageBtn, ...(page === 0 ? eqStyles.pageBtnDisabled : {}) }}
              onClick={() => page > 0 && setPage(p => p - 1)}
              disabled={page === 0}
            >‹ Prev</button>
            <span style={{ ...eqStyles.pageBtn, ...eqStyles.pageBtnActive }}>
              {page + 1} / {totalPages}
            </span>
            <button
              style={{ ...eqStyles.pageBtn, ...(page + 1 >= totalPages ? eqStyles.pageBtnDisabled : {}) }}
              onClick={() => page + 1 < totalPages && setPage(p => p + 1)}
              disabled={page + 1 >= totalPages}
            >Next ›</button>
          </div>
        </div>
      </div>

      {/* Add / Edit Modal */}
      {editing && (
        <EquipmentFormModal
          initial={editing === 'new' ? null : editing}
          user={user}
          onClose={() => setEditing(null)}
          onSave={() => { setEditing(null); fetchEquipment(); }}
        />
      )}

      {/* View Modal */}
      {viewing && !editing && (
        <EquipmentViewModal
          equipment={viewing}
          certUrl={viewingCertUrl}
          onClose={() => setViewing(null)}
          onEdit={() => { setEditing(viewing); setViewing(null); }}
        />
      )}

      {/* Delete Confirm Modal */}
      {deleting && (
        <DeleteConfirmModal
          equipment={deleting}
          busy={deleteBusy}
          onCancel={() => !deleteBusy && setDeleting(null)}
          onConfirm={handleDelete}
        />
      )}

      {/* Import Excel Modal */}
      {showImport && (
        <ImportExcelModal
          user={user}
          onClose={() => setShowImport(false)}
          onImported={() => fetchEquipment()}
        />
      )}
    </div>
  );
}

Object.assign(window, { EquipmentScreen });
