// ──────────────────────────────────────────────────────────────────────────────
// ProcurementScreen — מודול ניהול רכש (v3.9.0.99 + v3.9.0.99.1 תיקוני פידבק)
// Cloud-first: קריאה/כתיבה ישירה ל-Supabase (procurement_*). אין shadow-write.
// ספקים = טבלת contacts הקיימת (B8). אומדן מתחבר ל-budget_lines (B9). יעד: procurement-prototype.html
// ──────────────────────────────────────────────────────────────────────────────
(function(){
const { useState, useEffect, useMemo, useCallback } = React;

// ── סטטוסים קנוניים (תואמים בדיוק ל-CHECK ב-DB; 'רכש חו״ל' עם גרשיים U+05F4) ──
const STATUS = {
  'טיוטה':        { cls:'proc-s-draft',    lbl:'טיוטה' },
  'מכרז':         { cls:'proc-s-tender',   lbl:'מכרז' },
  'ממתין לאישור': { cls:'proc-s-pending',  lbl:'ממתין לאישור' },
  'מאושר':        { cls:'proc-s-closed',   lbl:'מאושר — ספק נבחר' },
  'הוזמן':        { cls:'proc-s-ordered',  lbl:'הוזמן' },
  'בדרך':         { cls:'proc-s-transit',  lbl:'בדרך' },
  'התקבל':        { cls:'proc-s-received', lbl:'התקבל ✓' },
  'רכש חו״ל':     { cls:'proc-s-foreign',  lbl:'רכש חו״ל' },
  'נדחה':         { cls:'proc-s-rejected', lbl:'נדחה' },
  'סגור':         { cls:'proc-s-closed',   lbl:'סגור' },
};
const OVERDUE = { cls:'proc-s-overdue', lbl:'⚠ בפיגור' };
const CATEGORIES = ['נגרות','ריצוף','חשמל','גבס','מיזוג','אינסטלציה','צבע','ריהוט','תאורה','מטבח מקצועי','שיש','זכוכית','שילוט','אוטומציה','חוץ / פרגולה','שונות'];

const fm  = (n) => (n != null && n !== '') ? '₪' + Number(n).toLocaleString('he-IL') : '—';
const num = (n) => Number(n) || 0;
// v99.1 A1 — אחוז שינוי בלי חלוקה באפס (מחזיר null אם אין אומדן)
const pctDelta = (act, est) => (act && est) ? ((act-est)/est*100).toFixed(1) : null;
const fmtWithDelta = (act, est) => {
  if (!act) return '—';
  const d = pctDelta(act, est);
  return fm(act) + (d !== null ? ` (${d>0?'+':''}${d}%)` : '');
};

function todayISO() { return new Date().toISOString().slice(0,10); }
function isOverdue(it) {
  return it.required_on_site && it.required_on_site < todayISO()
    && !['התקבל','סגור','נדחה'].includes(it.status);
}
function displayStatus(it) { return isOverdue(it) ? 'בפיגור' : it.status; }
function pillFor(statusKey) {
  const c = statusKey === 'בפיגור' ? OVERDUE : (STATUS[statusKey] || { cls:'proc-s-draft', lbl:statusKey });
  return { cls:c.cls, lbl:c.lbl };
}
function fmtDate(d) { if (!d) return '—'; const [y,m,day] = d.split('-'); return `${day}/${m}/${y}`; }
// כמות להזמנה = נטו × (1 + פחת%)
function grossQty(net, wastePct) { return num(net) * (1 + num(wastePct)/100); }

// supplier = contact. תווית: חברה · סוכן
function supLabel(c) { if (!c) return '—'; return c.company || c.name || 'ספק'; }
function supAgent(c) { if (!c) return ''; return (c.company && c.name && c.company !== c.name) ? c.name : ''; }

// ── Supabase helpers ─────────────────────────────────────────────────────────
async function sbClient() {
  if (!window.YBP_SUPABASE) return null;
  try { return await window.YBP_SUPABASE.getClient(); } catch { return null; }
}
async function uid(sb) {
  try { const { data:{ user } } = await sb.auth.getUser(); return user?.id || null; } catch { return null; }
}

// ── v99.3 B7 — milestone גאנט לפריט רכש ──────────────────────────────────────
// המשימה נכתבת דרך מערכת ה-tasks (LWW מ-v95) כדי שה-FK gantt_task_id יחזיק וה-גאנט יציג.
async function archiveMilestone(sb, taskId, projectId) {
  try {
    await sb.rpc('upsert_tasks', { rows:[{ id:taskId, user_id:await uid(sb), project_id:projectId, title:'אספקה (נמחק)', status:'archived', source:'procurement', data:{ milestone:true }, version:1, client_updated_at:new Date().toISOString() }] });
  } catch {}
  try { if (window.SyncStore) window.SyncStore.updateTask(taskId, { status:'archived' }); } catch {}
}
async function syncMilestone(sb, item, prevGanttId) {
  try {
    if (!item.required_on_site) { if (prevGanttId) await archiveMilestone(sb, prevGanttId, item.project_id); return null; }
    const taskId = prevGanttId || ('task-proc-' + item.id);
    const title = 'אספקה: ' + String(item.description||'').slice(0,40);
    const row = { id:taskId, user_id:await uid(sb), project_id:item.project_id, title, status:'open',
      source:'procurement', due:item.required_on_site, original_due:item.required_on_site,
      data:{ milestone:true, procurement_item_id:item.id }, version:1, client_updated_at:new Date().toISOString() };
    const { error } = await sb.rpc('upsert_tasks', { rows:[row] });   // ב-DB → ה-FK מחזיק
    if (error) { console.warn('[Procurement] milestone rpc:', error.message); return prevGanttId||null; }
    try {  // עותק מקומי לתצוגה מיידית בגאנט
      const st = window.SyncStore;
      if (st) {
        const payload = { title, due:item.required_on_site, startDate:item.required_on_site, status:'open', source:'procurement', data:{ milestone:true, procurement_item_id:item.id } };
        if ((st.get().tasks||[]).some(t=>t.id===taskId)) st.updateTask(taskId, payload);
        else st.addTask({ id:taskId, projectId:item.project_id, ...payload });
      }
    } catch {}
    return taskId;
  } catch (e) { console.warn('[Procurement] syncMilestone:', e.message); return prevGanttId||null; }
}

async function loadContacts() {
  try { if (window.ContactsStore) return await window.ContactsStore.listAll(); } catch {}
  const sb = await sbClient(); if (!sb) return [];
  const { data } = await sb.from('contacts').select('*').order('full_name');
  return (data||[]).map(r => ({ id:r.id, name:r.full_name||'', company:r.company||'', phone:r.phone||'', email:r.email||'', role:r.role||'', active:r.active!==false }));
}
// find-or-create a contact (for import / quick add). Returns contact id.
async function ensureContact({ company, name, phone, email }, projectId, existing) {
  const key = (company||name||'').trim().toLowerCase();
  if (key && existing) {
    const hit = existing.find(c => (c.company||'').toLowerCase()===key || (c.name||'').toLowerCase()===key);
    if (hit) return hit.id;
  }
  if (window.ContactsStore) {
    const c = await window.ContactsStore.create({
      name: name || company || 'ספק', company: company || name || '', phone: phone||'', email: email||'',
      role: 'ספק', specialty: 'ספק', scope: 'project', scope_id: projectId,
    });
    try { if (projectId) await window.ContactsStore.attachToProject(projectId, c.id); } catch {}
    return c.id;
  }
  return null;
}

// ── CSS (scoped under .proc-root) ────────────────────────────────────────────
const PROC_CSS = `
.proc-root { font-family:'Assistant',sans-serif; color:#1a2c4a; direction:rtl; background:#f0f2f5; min-height:100%; }
.proc-bar { display:flex; align-items:center; padding:14px 20px 0; gap:12px; }
.proc-back { color:#b5a882; font-size:24px; cursor:pointer; user-select:none; line-height:1; padding:2px 6px; border-radius:6px; }
.proc-back:hover { background:#eceae3; }
.proc-bar h2 { font-size:18px; font-weight:700; color:#1a2c4a; }
.proc-bar .proc-actions { margin-right:auto; display:flex; gap:8px; }
.proc-btn-gold { background:#b5a882; color:#1a2c4a; border:none; border-radius:6px; padding:7px 14px; font-family:inherit; font-size:13px; font-weight:600; cursor:pointer; }
.proc-btn-outline { background:transparent; color:#8a7d55; border:1.5px solid #b5a882; border-radius:6px; padding:6px 12px; font-family:inherit; font-size:13px; cursor:pointer; }
.proc-summary { display:flex; gap:12px; padding:16px 20px 0; flex-wrap:wrap; }
.proc-scard { background:#fff; border-radius:10px; padding:14px 18px; flex:1; min-width:150px; border-top:3px solid #e0ddd6; box-shadow:0 1px 4px rgba(0,0,0,.06); }
.proc-scard.warn{border-top-color:#f59e0b}.proc-scard.danger{border-top-color:#ef4444}.proc-scard.ok{border-top-color:#22c55e}.proc-scard.blue{border-top-color:#3b82f6}
.proc-slabel{font-size:11.5px;color:#6b7280;margin-bottom:3px}.proc-sval{font-size:21px;font-weight:700;color:#1a2c4a;line-height:1.1}.proc-ssub{font-size:11.5px;color:#9ca3af;margin-top:2px}.proc-ssub.red{color:#ef4444;font-weight:600}
.proc-filter{padding:14px 20px 0;display:flex;gap:10px;align-items:flex-end;flex-wrap:wrap}
.proc-fg{display:flex;flex-direction:column;gap:3px}.proc-fg label{font-size:11px;color:#9ca3af;font-weight:600}
.proc-sel,.proc-search{border:1.5px solid #e5e7eb;border-radius:8px;padding:6px 12px;font-family:inherit;font-size:13px;color:#374151;background:#fff;outline:none}
.proc-sel{cursor:pointer;min-width:130px}.proc-search{width:200px}
.proc-sel:focus,.proc-search:focus{border-color:#b5a882}
.proc-reset{background:none;border:none;color:#9ca3af;font-size:12px;font-family:inherit;cursor:pointer;padding:6px 8px}.proc-reset:hover{color:#ef4444}
.proc-tablewrap{margin:14px 20px 20px;background:#fff;border-radius:12px;box-shadow:0 1px 6px rgba(0,0,0,.07);overflow:hidden}
.proc-table{width:100%;border-collapse:collapse;font-size:13.5px}
.proc-table thead th{background:#f8f8f6;color:#6b7280;font-weight:700;font-size:11px;padding:10px 12px;text-align:right;border-bottom:1px solid #eee;white-space:nowrap;letter-spacing:.04em}
.proc-table tbody tr{border-bottom:1px solid #f3f4f6;cursor:pointer;transition:background .1s}
.proc-table tbody tr:last-child{border-bottom:none}.proc-table tbody tr:hover{background:#f9f8f5}
.proc-table td{padding:10px 12px;vertical-align:middle}
.proc-main{font-weight:600;font-size:13.5px}.proc-sub{font-size:11.5px;color:#9ca3af;margin-top:1px}
.proc-catbadge{display:inline-block;background:#f3f4f6;color:#6b7280;font-size:11px;padding:2px 8px;border-radius:6px}
.proc-numc{text-align:left;direction:ltr;font-variant-numeric:tabular-nums;font-size:13px}
.proc-date{font-size:12.5px;white-space:nowrap}.proc-date.late{color:#ef4444;font-weight:700}.proc-date.soon{color:#f59e0b;font-weight:600}
.proc-pill{display:inline-flex;align-items:center;gap:5px;padding:3px 10px;border-radius:12px;font-size:12px;font-weight:600;white-space:nowrap}
.proc-dot{width:6px;height:6px;border-radius:50%;flex-shrink:0}
.proc-s-tender{background:#f3e8ff;color:#6b21a8}.proc-s-tender .proc-dot{background:#a855f7}
.proc-s-pending{background:#fef3c7;color:#92400e}.proc-s-pending .proc-dot{background:#f59e0b}
.proc-s-closed{background:#dbeafe;color:#1e40af}.proc-s-closed .proc-dot{background:#3b82f6}
.proc-s-ordered{background:#d1fae5;color:#065f46}.proc-s-ordered .proc-dot{background:#22c55e}
.proc-s-transit{background:#dcfce7;color:#166534}.proc-s-transit .proc-dot{background:#4ade80}
.proc-s-foreign{background:#ccfbf1;color:#134e4a}.proc-s-foreign .proc-dot{background:#14b8a6}
.proc-s-overdue{background:#fee2e2;color:#991b1b}.proc-s-overdue .proc-dot{background:#ef4444}
.proc-s-rejected{background:#fee2e2;color:#991b1b}.proc-s-rejected .proc-dot{background:#ef4444}
.proc-s-draft{background:#f3f4f6;color:#6b7280}.proc-s-draft .proc-dot{background:#9ca3af}
.proc-s-received{background:#bbf7d0;color:#14532d}.proc-s-received .proc-dot{background:#16a34a}
.proc-gb{display:inline-flex;align-items:center;gap:3px;font-size:10.5px;border:1px solid #e5e7eb;border-radius:8px;padding:1px 6px}
.proc-gb.risk{color:#ef4444;border-color:#fca5a5;background:#fef2f2}.proc-gb.ok{color:#22c55e;border-color:#bbf7d0;background:#f0fdf4}
.proc-delta{font-size:11px;margin-top:1px}.proc-delta.over{color:#ef4444}.proc-delta.under{color:#22c55e}
.proc-noresults{text-align:center;padding:40px;color:#9ca3af;font-size:14px}
.proc-overlay{position:fixed;inset:0;background:rgba(26,44,74,.2);z-index:200}
.proc-drawer{position:fixed;top:0;left:0;width:460px;max-width:94vw;height:100vh;background:#fff;z-index:201;display:flex;flex-direction:column;overflow:hidden;box-shadow:4px 0 30px rgba(0,0,0,.18)}
.proc-dhead{background:#1a2c4a;padding:16px 18px 14px;flex-shrink:0}
.proc-dhead-top{display:flex;gap:10px;align-items:flex-start;margin-bottom:10px}
.proc-dclose{color:#b5a882;font-size:20px;cursor:pointer;margin-right:auto}
.proc-dtitle{color:#fff;font-size:15px;font-weight:600;line-height:1.3;flex:1}
.proc-dmeta{color:#8899aa;font-size:12px;margin-top:2px}
.proc-dstatus-row{display:flex;align-items:center;gap:8px}.proc-dts{font-size:11px;color:#8899aa}
.proc-dhead-tools{display:flex;gap:8px;margin-top:8px}
.proc-tool{font-size:11.5px;color:#b5a882;background:rgba(181,168,130,.12);border:1px solid rgba(181,168,130,.3);border-radius:6px;padding:3px 9px;cursor:pointer}
.proc-tool.danger{color:#fca5a5;background:rgba(239,68,68,.1);border-color:rgba(239,68,68,.3)}
.proc-dtabs{display:flex;border-bottom:1px solid #f3f4f6;background:#fafafa;flex-shrink:0}
.proc-dtab{flex:1;padding:10px;font-size:13px;font-weight:600;text-align:center;cursor:pointer;color:#9ca3af;border-bottom:2px solid transparent;transition:all .15s}
.proc-dtab.active{color:#1a2c4a;border-bottom-color:#b5a882}.proc-dtab:hover:not(.active){color:#374151}
.proc-dbody{flex:1;overflow-y:auto;padding:16px 18px}
.proc-sectitle{font-size:11px;font-weight:700;color:#9ca3af;letter-spacing:.06em;margin:16px 0 8px}.proc-sectitle:first-child{margin-top:0}
.proc-infogrid{display:grid;grid-template-columns:1fr 1fr;gap:10px}
.proc-ii label{display:block;font-size:11px;color:#9ca3af;margin-bottom:2px}.proc-ii span{font-size:14px;color:#1a2c4a;font-weight:500}.proc-ii span.red{color:#ef4444}.proc-ii span.green{color:#22c55e}
.proc-progbg{height:6px;background:#f3f4f6;border-radius:3px;overflow:hidden;margin-top:6px}.proc-progfill{height:100%;background:linear-gradient(90deg,#b5a882,#1a2c4a);border-radius:3px}
.proc-proglabels{display:flex;justify-content:space-between;font-size:11px;color:#9ca3af;margin-top:3px}
.proc-divider{height:1px;background:#f3f4f6;margin:14px 0}
.proc-qcard{border:1.5px solid #e5e7eb;border-radius:10px;padding:12px 14px;margin-bottom:10px}
.proc-qcard.winner{border-color:#22c55e;background:#f0fdf4}
.proc-qc-top{display:flex;align-items:center;gap:10px;margin-bottom:8px}
.proc-qc-supplier{font-weight:700;font-size:14px;color:#1a2c4a}.proc-qc-agent{font-size:12px;color:#9ca3af}
.proc-qc-badge{margin-right:auto}
.proc-winner-badge{background:#22c55e;color:#fff;font-size:11px;font-weight:700;padding:2px 10px;border-radius:10px}
.proc-draft-badge{background:#f3f4f6;color:#9ca3af;font-size:11px;padding:2px 10px;border-radius:10px}
.proc-qc-rows{display:grid;grid-template-columns:1fr 1fr 1fr;gap:6px;margin-bottom:10px}
.proc-qc-field label{font-size:10.5px;color:#9ca3af}.proc-qc-field span{font-size:13px;font-weight:600;color:#1a2c4a}.proc-qc-field span.green{color:#22c55e}
.proc-qc-note{font-size:11.5px;color:#6b7280;margin-top:6px}
.proc-qc-actions{display:flex;gap:6px;margin-top:10px}
.proc-qbtn{flex:1;padding:7px;border-radius:7px;border:none;font-family:inherit;font-size:12px;font-weight:600;cursor:pointer}
.proc-qb-select{background:#1a2c4a;color:#b5a882}.proc-qb-po{background:#22c55e;color:#fff}.proc-qb-view{background:#f3f4f6;color:#374151}.proc-qb-del{background:#fee2e2;color:#991b1b;flex:0 0 auto;padding:7px 10px}
.proc-add{background:#b5a882;color:#1a2c4a;width:100%;padding:9px;border-radius:8px;border:none;font-family:inherit;font-size:13px;font-weight:600;cursor:pointer;margin-top:4px}
.proc-pocard{border:1.5px solid #e5e7eb;border-radius:10px;padding:14px}.proc-pocard.generated{border-color:#22c55e;background:#f0fdf4}
.proc-po-top{display:flex;align-items:center;gap:10px;margin-bottom:12px}.proc-po-num{font-size:16px;font-weight:700;color:#1a2c4a}.proc-po-supplier{font-size:12.5px;color:#6b7280}
.proc-po-status{margin-right:auto;background:#d1fae5;color:#065f46;padding:3px 10px;border-radius:10px;font-size:12px;font-weight:600}
.proc-po-lines{border-top:1px solid #f3f4f6;padding-top:10px}
.proc-po-line{display:flex;justify-content:space-between;padding:5px 0;font-size:13px;border-bottom:1px solid #f9f8f5}.proc-po-line:last-child{border-bottom:none}
.proc-po-total{display:flex;justify-content:space-between;padding-top:10px;margin-top:6px;border-top:2px solid #e5e7eb;font-weight:700;font-size:15px}
.proc-nopo{text-align:center;padding:30px 20px;color:#9ca3af}.proc-nopo-icon{font-size:36px;margin-bottom:10px}.proc-nopo-text{font-size:14px;margin-bottom:8px}.proc-nopo-sub{font-size:12px;margin-bottom:16px}
.proc-tl{display:flex;flex-direction:column;gap:10px}.proc-tl-item{display:flex;gap:10px}
.proc-tl-dot{width:8px;height:8px;border-radius:50%;background:#b5a882;margin-top:5px;flex-shrink:0}
.proc-tl-text{font-size:13px;color:#374151}.proc-tl-text strong{color:#1a2c4a}.proc-tl-ts{font-size:11px;color:#9ca3af;margin-top:2px}
.proc-comment-wrap{display:flex;gap:8px;margin-top:12px}
.proc-comment-input{flex:1;border:1.5px solid #e5e7eb;border-radius:8px;padding:8px 12px;font-family:inherit;font-size:13px;color:#374151;resize:none;outline:none}.proc-comment-input:focus{border-color:#b5a882}
.proc-comment-send{background:#1a2c4a;color:#b5a882;border:none;border-radius:8px;padding:8px 14px;font-family:inherit;font-size:13px;font-weight:600;cursor:pointer}
.proc-dfooter{padding:12px 18px;border-top:1px solid #f3f4f6;display:flex;gap:8px;flex-shrink:0;flex-wrap:wrap}
.proc-af{flex:1;padding:9px;border-radius:8px;border:none;font-family:inherit;font-size:13px;font-weight:600;cursor:pointer;min-width:90px}
.proc-af-approve{background:#22c55e;color:#fff}.proc-af-reject{background:#fee2e2;color:#991b1b}.proc-af-order{background:#1a2c4a;color:#b5a882}.proc-af-attach{background:#f3f4f6;color:#374151}.proc-af-close{background:#dbeafe;color:#1e40af}
.proc-modal-bg{position:fixed;inset:0;background:rgba(26,44,74,.35);z-index:300;display:flex;align-items:center;justify-content:center}
.proc-modal{background:#fff;border-radius:14px;padding:22px;width:460px;max-width:94vw;max-height:90vh;overflow-y:auto;box-shadow:0 20px 60px rgba(0,0,0,.25)}
.proc-modal h3{font-size:17px;font-weight:700;margin-bottom:14px;color:#1a2c4a}
.proc-field{margin-bottom:12px}.proc-field label{display:block;font-size:12px;color:#6b7280;margin-bottom:4px;font-weight:600}
.proc-input{width:100%;border:1.5px solid #e5e7eb;border-radius:8px;padding:8px 12px;font-family:inherit;font-size:14px;color:#1a2c4a;outline:none;box-sizing:border-box}.proc-input:focus{border-color:#b5a882}
.proc-row2{display:grid;grid-template-columns:1fr 1fr;gap:10px}
.proc-row3{display:grid;grid-template-columns:1fr 1fr 1fr;gap:8px;align-items:end}
.proc-modal-actions{display:flex;gap:8px;margin-top:18px}
.proc-loading{text-align:center;padding:60px 20px;color:#9ca3af;font-size:14px}
.proc-seg{display:flex;gap:6px;margin-bottom:14px}
.proc-seg button{flex:1;padding:8px;border:1.5px solid #e5e7eb;background:#fff;border-radius:8px;font-family:inherit;font-size:12.5px;cursor:pointer;color:#6b7280}
.proc-seg button.active{border-color:#b5a882;background:#fdf8ef;color:#1a2c4a;font-weight:700}
.proc-picker-row{display:flex;gap:6px;align-items:end}
.proc-combo-list{position:absolute;top:calc(100% + 2px);right:0;left:0;background:#fff;border:1.5px solid #e5e7eb;border-radius:8px;box-shadow:0 8px 24px rgba(0,0,0,.12);max-height:220px;overflow-y:auto;z-index:50}
.proc-combo-item{padding:8px 12px;font-size:13px;cursor:pointer;color:#1a2c4a;border-bottom:1px solid #f3f4f6}
.proc-combo-item:last-child{border-bottom:none}.proc-combo-item:hover{background:#fdf8ef}
.proc-combo-agent{color:#9ca3af;font-size:12px}
.proc-combo-empty{padding:10px 12px;font-size:12.5px;color:#9ca3af}
.proc-combo-clear{color:#ef4444;font-weight:600}
.proc-import-row{display:flex;justify-content:space-between;align-items:center;padding:9px 10px;border:1px solid #eee;border-radius:8px;margin-bottom:6px;font-size:13px;cursor:pointer}
.proc-import-row:hover{background:#f9f8f5;border-color:#e5d9bf}
.proc-hint{font-size:11.5px;color:#9ca3af;margin-top:4px}
`;
function StyleOnce() {
  useEffect(() => {
    if (document.getElementById('proc-styles')) return;
    const el = document.createElement('style'); el.id = 'proc-styles'; el.textContent = PROC_CSS;
    document.head.appendChild(el);
  }, []);
  return null;
}

function Pill({ statusKey }) {
  const p = pillFor(statusKey);
  return <span className={'proc-pill ' + p.cls}><span className="proc-dot"></span>{p.lbl}</span>;
}

// v99.6 — pill לחיץ = בורר סטטוס ידני (כל 10 הסטטוסים). fixed-positioning כדי לא להיחתך ע"י overflow.
function StatusPickerPill({ current, onPick }) {
  const [open, setOpen] = useState(false);
  const [pos, setPos] = useState({ top:0, right:0 });
  const ref = React.useRef(null);
  const toggle = (e) => {
    e.stopPropagation();
    if (!open && ref.current) {
      const r = ref.current.getBoundingClientRect();
      setPos({ top: r.bottom + 4, right: Math.max(8, window.innerWidth - r.right) });
    }
    setOpen(o => !o);
  };
  return <span ref={ref} onClick={toggle} title="שנה סטטוס" style={{ display:'inline-flex', alignItems:'center', gap:3, cursor:'pointer' }}>
    <Pill statusKey={current}/><span style={{ fontSize:10, color:'#8899aa' }}>▾</span>
    {open && <>
      <div style={{ position:'fixed', inset:0, zIndex:400 }} onClick={(e)=>{ e.stopPropagation(); setOpen(false); }}/>
      <div style={{ position:'fixed', top:pos.top, right:pos.right, zIndex:401, background:'#fff', border:'1.5px solid #e5e7eb', borderRadius:8, boxShadow:'0 8px 24px rgba(0,0,0,.15)', padding:4, maxHeight:320, overflowY:'auto' }}>
        {Object.keys(STATUS).map(s => <div key={s} style={{ padding:'5px 8px', cursor:'pointer', borderRadius:6 }}
          onClick={(e)=>{ e.stopPropagation(); setOpen(false); onPick(s); }}
          onMouseEnter={e=>e.currentTarget.style.background='#f9f8f5'} onMouseLeave={e=>e.currentTarget.style.background='transparent'}>
          <Pill statusKey={s}/></div>)}
      </div>
    </>}
  </span>;
}

// ── Add-contact (supplier) modal — B2/B8: יוצר איש קשר ב-contacts ─────────────
function AddContactModal({ projectId, onClose, onCreated }) {
  const [f, setF] = useState({ company:'', name:'', phone:'', email:'' });
  const [busy, setBusy] = useState(false);
  const up = (k,v) => setF(s => ({ ...s, [k]:v }));
  const save = async () => {
    if (!f.company.trim() && !f.name.trim()) { alert('נא להזין שם חברה או סוכן'); return; }
    setBusy(true);
    try {
      const id = await ensureContact({ company:f.company.trim(), name:f.name.trim(), phone:f.phone.trim(), email:f.email.trim() }, projectId, null);
      await onCreated(id); onClose();
    } catch (e) { alert('שגיאה ביצירת ספק: ' + (e.message||e)); }
    finally { setBusy(false); }
  };
  return <div className="proc-modal-bg" onClick={onClose}>
    <div className="proc-modal" onClick={e=>e.stopPropagation()}>
      <h3>ספק חדש (נכנס לאנשי הקשר)</h3>
      <div className="proc-field"><label>שם חברה</label><input className="proc-input" value={f.company} onChange={e=>up('company',e.target.value)}/></div>
      <div className="proc-field"><label>שם סוכן</label><input className="proc-input" value={f.name} onChange={e=>up('name',e.target.value)}/></div>
      <div className="proc-row2">
        <div className="proc-field"><label>טלפון סוכן</label><input className="proc-input" value={f.phone} onChange={e=>up('phone',e.target.value)}/></div>
        <div className="proc-field"><label>מייל</label><input className="proc-input" value={f.email} onChange={e=>up('email',e.target.value)}/></div>
      </div>
      <div className="proc-modal-actions">
        <button className="proc-af proc-af-order" disabled={busy} onClick={save}>{busy?'שומר...':'הוסף ספק'}</button>
        <button className="proc-af proc-af-attach" onClick={onClose}>ביטול</button>
      </div>
    </div>
  </div>;
}

// ── Supplier picker — typeahead combobox מ-contacts + ➕ ספק חדש (B3/B8; v99.2 חיפוש) ──
function SupplierPicker({ contacts, value, onChange, projectId, onRefresh }) {
  const [adding, setAdding] = useState(false);
  const [query, setQuery] = useState('');
  const [open, setOpen] = useState(false);
  const selected = value ? contacts.find(c => c.id === value) : null;
  const selLabel = selected ? supLabel(selected) + (supAgent(selected)?` · ${supAgent(selected)}`:'') : '';
  const matches = useMemo(() => {
    const active = contacts.filter(c => c.active !== false);
    const q = query.trim().toLowerCase();
    if (!q) return active.slice(0, 50);
    return active.filter(c => (
      `${c.company||''} ${c.name||''} ${c.full_name||''} ${c.contact_name||''} ${c.phone||''}`
    ).toLowerCase().includes(q)).slice(0, 50);
  }, [query, contacts]);
  const pick = (c) => { onChange(c.id); setQuery(''); setOpen(false); };
  return <div className="proc-picker-row">
    <div style={{flex:1, position:'relative'}}>
      <input className="proc-input" value={open ? query : selLabel}
        placeholder={selLabel ? selLabel : '🔍 חפש ספק...'}
        onFocus={()=>{ setOpen(true); setQuery(''); }}
        onChange={e=>{ setQuery(e.target.value); setOpen(true); }}
        onBlur={()=>setTimeout(()=>setOpen(false), 150)} />
      {open && <div className="proc-combo-list">
        {value && <div className="proc-combo-item proc-combo-clear" onMouseDown={()=>{ onChange(null); setOpen(false); }}>× נקה בחירה</div>}
        {matches.map(c => <div key={c.id} className="proc-combo-item" onMouseDown={()=>pick(c)}>
          {supLabel(c)}{supAgent(c)?<span className="proc-combo-agent"> · {supAgent(c)}</span>:null}{c.phone?<span className="proc-combo-agent"> · {c.phone}</span>:null}
        </div>)}
        {!matches.length && <div className="proc-combo-empty">אין תוצאות — לחץ ➕ ספק חדש</div>}
      </div>}
    </div>
    <button className="proc-btn-outline" style={{whiteSpace:'nowrap'}} onMouseDown={e=>e.preventDefault()} onClick={()=>setAdding(true)}>➕ חדש</button>
    {adding && <AddContactModal projectId={projectId} onClose={()=>setAdding(false)} onCreated={async (id)=>{ await onRefresh(); onChange(id); }}/>}
  </div>;
}

// ── Item modal (create + edit) — waste (B1) + budget import (B9) ──────────────
function ItemModal({ projectId, initial, onClose, onSave }) {
  const edit = !!initial;
  const [f, setF] = useState(initial ? {
    category:initial.category, description:initial.description, unit:initial.unit,
    quantity_needed:String(initial.quantity_needed??''), waste_pct:String(initial.waste_pct??0),
    noWaste: !num(initial.waste_pct), unit_price_estimate:String(initial.unit_price_estimate??''),
    required_on_site:initial.required_on_site||'', budget_line_id:initial.budget_line_id||null, status:initial.status||'טיוטה',
  } : { category:'נגרות', description:'', unit:"יח'", quantity_needed:'', waste_pct:'0', noWaste:true, unit_price_estimate:'', required_on_site:'', budget_line_id:null });
  const [budgetLines, setBudgetLines] = useState([]);
  const [showBudget, setShowBudget] = useState(false);
  const [busy, setBusy] = useState(false);
  const up = (k,v) => setF(s => ({ ...s, [k]:v }));

  useEffect(() => { (async () => {
    const sb = await sbClient(); if (!sb) return;
    const { data } = await sb.from('budget_lines').select('*').eq('project_id', projectId).order('sort_order');
    setBudgetLines(data||[]);
  })(); }, [projectId]);

  const gross = grossQty(f.quantity_needed, f.noWaste ? 0 : f.waste_pct);
  const pickBudget = (line) => {
    setF(s => ({ ...s, description: line.name || s.description, category: line.category || s.category,
      unit_price_estimate: line.estimate != null ? String(line.estimate) : s.unit_price_estimate, budget_line_id: line.id }));
    setShowBudget(false);
  };
  const save = async () => {
    if (!f.description.trim() || !f.quantity_needed) { alert('נא למלא תיאור וכמות'); return; }
    setBusy(true);
    try {
      await onSave({
        category:f.category, description:f.description.trim(), unit:f.unit||"יח'",
        quantity_needed:num(f.quantity_needed), waste_pct: f.noWaste ? 0 : num(f.waste_pct),
        quantity_gross: grossQty(f.quantity_needed, f.noWaste?0:f.waste_pct),
        unit_price_estimate: f.unit_price_estimate ? num(f.unit_price_estimate) : null,
        required_on_site: f.required_on_site || null, budget_line_id: f.budget_line_id || null,
        ...(edit ? { status: f.status } : {}),
      });
      onClose();
    } catch (e) { alert('שגיאה בשמירה: ' + (e.message||e)); }
    finally { setBusy(false); }
  };
  return <div className="proc-modal-bg" onClick={onClose}>
    <div className="proc-modal" onClick={e=>e.stopPropagation()}>
      <h3>{edit ? 'עריכת פריט רכש' : 'פריט רכש חדש'}</h3>
      {!edit && budgetLines.length > 0 && <>
        <button className="proc-btn-outline" style={{width:'100%',marginBottom:12}} onClick={()=>setShowBudget(v=>!v)}>📥 ייבא מהתקציב (אומדן)</button>
        {showBudget && <div style={{maxHeight:160,overflowY:'auto',marginBottom:12}}>
          {budgetLines.map(l => <div key={l.id} className="proc-import-row" onClick={()=>pickBudget(l)}>
            <span>{l.category} · {l.name}</span><span style={{direction:'ltr',color:'#6b7280'}}>{fm(l.estimate)}</span></div>)}
        </div>}
      </>}
      <div className="proc-row2">
        <div className="proc-field"><label>קטגוריה</label>
          <select className="proc-input" value={f.category} onChange={e=>up('category',e.target.value)}>{CATEGORIES.map(c => <option key={c} value={c}>{c}</option>)}</select></div>
        {edit && <div className="proc-field"><label>סטטוס</label>
          <select className="proc-input" value={f.status} onChange={e=>up('status',e.target.value)}>{Object.keys(STATUS).map(s => <option key={s} value={s}>{STATUS[s].lbl}</option>)}</select></div>}
      </div>
      <div className="proc-field"><label>תיאור הפריט</label>
        <input className="proc-input" value={f.description} onChange={e=>up('description',e.target.value)} placeholder="לדוגמה: ריצוף פורצלן 60×60"/></div>
      <div className="proc-row3">
        <div className="proc-field" style={{margin:0}}><label>יחידה</label><input className="proc-input" value={f.unit} onChange={e=>up('unit',e.target.value)}/></div>
        <div className="proc-field" style={{margin:0}}><label>כמות נטו</label><input className="proc-input" type="number" value={f.quantity_needed} onChange={e=>up('quantity_needed',e.target.value)}/></div>
        <div className="proc-field" style={{margin:0}}><label>פחת %</label><input className="proc-input" type="number" disabled={f.noWaste} value={f.noWaste?'':f.waste_pct} onChange={e=>up('waste_pct',e.target.value)}/></div>
      </div>
      <label style={{display:'flex',alignItems:'center',gap:6,fontSize:12.5,color:'#6b7280',margin:'2px 0 12px'}}>
        <input type="checkbox" checked={f.noWaste} onChange={e=>up('noWaste',e.target.checked)}/> ללא פחת
        <span style={{marginRight:'auto',color:'#1a2c4a',fontWeight:600}}>כמות להזמנה: {gross ? gross.toLocaleString('he-IL') : '—'} {f.unit}</span>
      </label>
      <div className="proc-row2">
        <div className="proc-field"><label>מחיר יח׳ (אומדן)</label><input className="proc-input" type="number" value={f.unit_price_estimate} onChange={e=>up('unit_price_estimate',e.target.value)}/></div>
        <div className="proc-field"><label>חייב באתר עד</label><input className="proc-input" type="date" value={f.required_on_site} onChange={e=>up('required_on_site',e.target.value)}/></div>
      </div>
      {f.budget_line_id && <div className="proc-hint">🔗 מקושר לשורת תקציב</div>}
      <div className="proc-modal-actions">
        <button className="proc-af proc-af-order" disabled={busy} onClick={save}>{busy?'שומר...':(edit?'שמור':'צור פריט')}</button>
        <button className="proc-af proc-af-attach" onClick={onClose}>ביטול</button>
      </div>
    </div>
  </div>;
}

// ── Add-quote modal — 3 מקורות (B4): ידני / קובץ דרייב / ייבוא מהצעות קיימות ──
function AddQuoteModal({ projectId, contacts, onRefreshContacts, existingQuotes, onClose, onSave, onImport }) {
  const [mode, setMode] = useState('manual'); // manual | file | import
  const [f, setF] = useState({ supplier_id:'', unit_price:'', delivery_days:'', notes:'', attached_file_url:'' });
  const [busy, setBusy] = useState(false);
  const up = (k,v) => setF(s => ({ ...s, [k]:v }));
  const save = async () => {
    if (!f.unit_price) { alert('נא למלא מחיר יחידה'); return; }
    if (!f.supplier_id) { alert('נא לבחור ספק'); return; }
    setBusy(true);
    try { await onSave(f); onClose(); }
    catch (e) { alert('שגיאה: ' + (e.message||e)); }
    finally { setBusy(false); }
  };
  return <div className="proc-modal-bg" onClick={onClose}>
    <div className="proc-modal" onClick={e=>e.stopPropagation()}>
      <h3>הוסף הצעת מחיר</h3>
      <div className="proc-seg">
        <button className={mode==='manual'?'active':''} onClick={()=>setMode('manual')}>הזנה ידנית</button>
        <button className={mode==='file'?'active':''} onClick={()=>setMode('file')}>📎 קובץ דרייב</button>
        <button className={mode==='import'?'active':''} onClick={()=>setMode('import')}>📋 מהצעות קיימות</button>
      </div>

      {mode==='import' ? <>
        {!existingQuotes.length ? <div className="proc-hint">אין הצעות מחיר קיימות בפרויקט (מודול השוואת הצעות).</div>
         : existingQuotes.map(q => <div key={q.id} className="proc-import-row" onClick={async()=>{ setBusy(true); try{ await onImport(q); onClose(); }catch(e){ alert('שגיאה: '+(e.message||e)); } finally{ setBusy(false);} }}>
            <span>{q.supplier||'ספק'}{q.contact?` · ${q.contact}`:''}</span><span style={{direction:'ltr',color:'#6b7280'}}>{fm(q.price)}</span></div>)}
      </> : <>
        <div className="proc-field"><label>ספק</label>
          <SupplierPicker contacts={contacts} value={f.supplier_id} onChange={id=>up('supplier_id',id)} projectId={projectId} onRefresh={onRefreshContacts}/></div>
        <div className="proc-row2">
          <div className="proc-field"><label>מחיר יחידה</label><input className="proc-input" type="number" value={f.unit_price} onChange={e=>up('unit_price',e.target.value)}/></div>
          <div className="proc-field"><label>זמן אספקה (ימים)</label><input className="proc-input" type="number" value={f.delivery_days} onChange={e=>up('delivery_days',e.target.value)}/></div>
        </div>
        {mode==='file' && <div className="proc-field"><label>קישור קובץ (Drive)</label><input className="proc-input" value={f.attached_file_url} onChange={e=>up('attached_file_url',e.target.value)} placeholder="https://drive.google.com/..."/></div>}
        <div className="proc-field"><label>הערות</label><input className="proc-input" value={f.notes} onChange={e=>up('notes',e.target.value)}/></div>
        <div className="proc-modal-actions">
          <button className="proc-af proc-af-order" disabled={busy} onClick={save}>{busy?'שומר...':'הוסף הצעה'}</button>
          <button className="proc-af proc-af-attach" onClick={onClose}>ביטול</button>
        </div>
      </>}
    </div>
  </div>;
}

// ── v99.4 C1/C2 — PO על נייר מכתבים YBP: בנייה, תצוגה מקדימה, שליחה במייל ─────
function buildPOHtml(po, poLines, supplierC, item, projectName) {
  const today = new Date().toLocaleDateString('he-IL');
  const sName = supLabel(supplierC), sAgent = supAgent(supplierC);
  const sPhone = (supplierC && (supplierC.phone || supplierC.office_phone)) || '';
  const sEmail = (supplierC && (supplierC.email || supplierC.office_email)) || '';
  const headerMetaHtml = `
    <div style="display:flex;justify-content:space-between;align-items:flex-start;margin-bottom:18px;border-bottom:2px solid #b5a882;padding-bottom:12px">
      <div><div style="font-size:22px;font-weight:700;color:#1a2c4a">הזמנת רכש</div>
        <div style="font-size:14px;color:#6b7280;margin-top:2px">${po.po_number||''}</div></div>
      <div style="text-align:left;font-size:12px;color:#6b7280;line-height:1.7">
        <div>תאריך: ${today}</div><div>פרויקט: ${projectName||''}</div></div>
    </div>`;
  const bodyHtml = `
    <table style="width:100%;font-size:13px;margin-bottom:16px"><tr>
      <td style="vertical-align:top;width:50%">
        <div style="font-weight:700;color:#1a2c4a;margin-bottom:4px">לכבוד הספק</div>
        <div>${sName}</div>${sAgent?`<div style="color:#6b7280">לידי: ${sAgent}</div>`:''}
        ${sPhone?`<div style="color:#6b7280">טל׳: ${sPhone}</div>`:''}${sEmail?`<div style="color:#6b7280">${sEmail}</div>`:''}
      </td>
      <td style="vertical-align:top">
        <div style="font-weight:700;color:#1a2c4a;margin-bottom:4px">פרטי הזמנה</div>
        <div>סטטוס: ${po.status||'טיוטה'}</div>
        <div>אספקה נדרשת: ${item.required_on_site?fmtDate(item.required_on_site):'—'}</div>
      </td></tr></table>
    <table style="width:100%;border-collapse:collapse;font-size:13px;margin-bottom:14px">
      <thead><tr style="background:#f8f8f6;color:#6b7280">
        <th style="text-align:right;padding:8px;border-bottom:1px solid #e5e7eb">תיאור</th>
        <th style="text-align:center;padding:8px;border-bottom:1px solid #e5e7eb">כמות</th>
        <th style="text-align:left;padding:8px;border-bottom:1px solid #e5e7eb">מחיר יח׳</th>
        <th style="text-align:left;padding:8px;border-bottom:1px solid #e5e7eb">סה״כ</th></tr></thead>
      <tbody>${(poLines||[]).map(l=>`<tr>
        <td style="padding:8px;border-bottom:1px solid #f3f4f6">${l.description}</td>
        <td style="padding:8px;border-bottom:1px solid #f3f4f6;text-align:center">${num(l.quantity)} ${l.unit}</td>
        <td style="padding:8px;border-bottom:1px solid #f3f4f6;text-align:left;direction:ltr">${fm(l.unit_price)}</td>
        <td style="padding:8px;border-bottom:1px solid #f3f4f6;text-align:left;direction:ltr">${fm(l.line_total)}</td></tr>`).join('')}</tbody>
    </table>
    <div style="text-align:left;font-size:16px;font-weight:700;color:#1a2c4a;margin-bottom:18px">סה״כ להזמנה: <span style="direction:ltr;display:inline-block">${fm(po.total_amount)}</span></div>
    <div style="font-size:11px;color:#9ca3af;line-height:1.7;border-top:1px solid #f3f4f6;padding-top:10px">
      הזמנה זו נשלחת בכפוף להצעת המחיר המאושרת. נא לאשר קבלת ההזמנה ולעדכן מועד אספקה.</div>`;
  return { headerMetaHtml, bodyHtml };
}

// v99.5 C3 — משימת מעקב אחרי PO (דרך מערכת ה-tasks; LWW מ-v95)
async function createTrackingTask(sb, po, item, supplierC) {
  const taskId = po.tracking_task_id || ('task-potrack-' + po.id);
  const title = 'מעקב הזמנה: ' + supLabel(supplierC) + ' (' + (po.po_number||'') + ')';
  const due = new Date(Date.now()+7*864e5).toISOString().slice(0,10);
  const data = { procurement_po_id:po.id, procurement_item_id:item.id, po_number:po.po_number||'' };
  const row = { id:taskId, user_id:await uid(sb), project_id:item.project_id, title, status:'open',
    source:'procurement-tracking', due, original_due:due, data, version:1, client_updated_at:new Date().toISOString() };
  try { await sb.rpc('upsert_tasks', { rows:[row] }); } catch (e) { console.warn('[Procurement] tracking task:', e.message); }
  try {
    const st = window.SyncStore;
    if (st) { const p = { title, due, startDate:due, status:'open', source:'procurement-tracking', data };
      if ((st.get().tasks||[]).some(t=>t.id===taskId)) st.updateTask(taskId, p); else st.addTask({ id:taskId, projectId:item.project_id, ...p }); }
  } catch {}
  return taskId;
}

function POPreviewModal({ po, poLines, supplierC, item, projectName, onClose, onSent }) {
  const [busy, setBusy] = useState(false);
  const [overseas, setOverseas] = useState(!!po.is_overseas);
  const logoSrc = (document.querySelector('img[alt="YBP"]') && document.querySelector('img[alt="YBP"]').src)
    || (window.YBP_DATA && window.YBP_DATA.company && window.YBP_DATA.company.logoFull) || 'assets/ybp-logo-new.png';
  const { headerMetaHtml, bodyHtml } = useMemo(() => buildPOHtml(po, poLines, supplierC, item, projectName), [po, poLines, supplierC, item, projectName]);
  const fileName = ('הזמנת רכש ' + (po.po_number||'')).trim();
  const previewHtml = useMemo(() => window.YBPPdf ? window.YBPPdf.buildLetterheadHtml({ orientation:'portrait', logoSrc, fileName, headerMetaHtml, bodyHtml }) : '<p style="padding:20px">מנוע ה-PDF לא נטען</p>', [headerMetaHtml, bodyHtml, logoSrc]);
  async function makePdf() {
    if (!window.YBPPdf) { alert('מנוע ה-PDF לא נטען'); return null; }
    setBusy(true);
    try {
      const data = await window.YBPPdf.generatePdf({ orientation:'portrait', logoSrc, fileName, headerMetaHtml, bodyHtml, projectId:item.project_id, projectName, typeName:'הזמנת רכש', uploadToDrive:true });
      const url = (data && data.driveUrl) ? data.driveUrl : null;
      if (url) { try { const sb=await sbClient(); await sb.from('purchase_orders').update({ drive_doc_url:url }).eq('id', po.id); } catch {} }
      return url;
    } finally { setBusy(false); }
  }
  async function send() {
    const email = supplierC && (supplierC.email || supplierC.office_email);
    if (!email) { alert('לספק אין כתובת מייל באנשי הקשר — עדכן את איש הקשר'); return; }
    setBusy(true);
    try {
      const sb = await sbClient();
      let url = po.drive_doc_url;
      if (!url) url = await makePdf();
      const subject = `הזמנת רכש ${po.po_number||''} — YBP`;
      const body = `שלום${supAgent(supplierC)?' '+supAgent(supplierC):''},\n\nמצורפת הזמנת רכש ${po.po_number||''} עבור פרויקט ${projectName||''}.\n${url?('קישור למסמך: '+url+'\n'):''}\nנא לאשר קבלת ההזמנה ולעדכן מועד אספקה.\n\nתודה,\nYBPROJECTS`;
      // v99.5 C3 — משימת מעקב + שדות תזכורת (Make ירוץ עליהם)
      const today = new Date().toISOString().slice(0,10);
      const nextRem = new Date(Date.now()+7*864e5).toISOString().slice(0,10);
      const trackId = await createTrackingTask(sb, po, item, supplierC);
      await sb.from('purchase_orders').update({ status:'נשלח', issue_date:today, drive_doc_url: url || po.drive_doc_url || null,
        is_overseas:overseas, last_supplier_ping:today, next_reminder:nextRem, tracking_task_id:trackId }).eq('id', po.id);
      const gmail = (window.buildGmailUrl ? window.buildGmailUrl({ to:email, subject, body }) : `https://mail.google.com/mail/?view=cm&fs=1&to=${encodeURIComponent(email)}&su=${encodeURIComponent(subject)}&body=${encodeURIComponent(body)}`);
      window.open(gmail, '_blank');
      onSent(); onClose();
    } catch (e) { alert('שגיאה בשליחה: ' + (e.message||e)); }
    finally { setBusy(false); }
  }
  return <div className="proc-modal-bg" onClick={onClose}>
    <div className="proc-modal" style={{width:720, maxWidth:'96vw'}} onClick={e=>e.stopPropagation()}>
      <h3>תצוגה מקדימה — {po.po_number}</h3>
      <iframe title="po-preview" srcDoc={previewHtml} style={{width:'100%', height:'52vh', border:'1px solid #e5e7eb', borderRadius:8, background:'#fff'}}/>
      <label style={{display:'flex',alignItems:'center',gap:7,fontSize:13,color:'#374151',margin:'10px 0 2px'}}>
        <input type="checkbox" checked={overseas} onChange={e=>setOverseas(e.target.checked)} style={{width:16,height:16,accentColor:'#14b8a6'}}/>
        🌍 הזמנה מחו"ל (תזכורות ומיילי סטטוס אוטומטיים חובה)
      </label>
      <div className="proc-hint">בדוק לפני שליחה. "הפק PDF" שומר לדרייב; "שלח לספק" פותח מייל Gmail עם קישור למסמך, מסמן PO כ"נשלח", ופותח משימת מעקב + תזכורת בעוד 7 ימים.</div>
      <div className="proc-modal-actions">
        <button className="proc-af proc-af-attach" disabled={busy} onClick={makePdf}>📄 הפק PDF + דרייב</button>
        <button className="proc-af proc-af-approve" disabled={busy} onClick={send}>✉️ שלח לספק</button>
        <button className="proc-af proc-af-attach" onClick={onClose}>סגור</button>
      </div>
    </div>
  </div>;
}

// ── Drawer ───────────────────────────────────────────────────────────────────
function Drawer({ item, contacts, contactById, projectId, onClose, onChanged, onEdit, onRefreshContacts }) {
  const [tab, setTab] = useState('details');
  const [quotes, setQuotes] = useState([]);
  const [po, setPo] = useState(null);
  const [poLines, setPoLines] = useState([]);
  const [comments, setComments] = useState([]);
  const [existingQuotes, setExistingQuotes] = useState([]);
  const [commentText, setCommentText] = useState('');
  const [showAddQuote, setShowAddQuote] = useState(false);
  const [showPOPreview, setShowPOPreview] = useState(false);
  const [loading, setLoading] = useState(true);
  const projectName = (window.YBP_DATA && window.YBP_DATA.projects && (window.YBP_DATA.projects.find(p=>p.id===projectId)||{}).name) || '';

  const loadAll = useCallback(async () => {
    setLoading(true);
    const sb = await sbClient(); if (!sb) { setLoading(false); return; }
    try {
      const [{ data:q }, { data:c }, { data:eq }] = await Promise.all([
        sb.from('procurement_quotes').select('*').eq('procurement_item_id', item.id).order('created_at',{ascending:true}),
        sb.from('procurement_comments').select('*').eq('procurement_item_id', item.id).order('created_at',{ascending:false}),
        sb.from('quotes').select('id,supplier,contact,phone,price').eq('project_id', projectId),
      ]);
      setQuotes(q || []); setComments(c || []); setExistingQuotes(eq || []);
      const { data: pli } = await sb.from('po_line_items').select('*, purchase_orders(*)').eq('procurement_item_id', item.id);
      if (pli && pli.length) {
        const poRow = pli[0].purchase_orders; setPo(poRow || null);
        if (poRow) { const { data: lines } = await sb.from('po_line_items').select('*').eq('po_id', poRow.id); setPoLines(lines || []); }
      } else { setPo(null); setPoLines([]); }
    } catch (e) { console.warn('[Procurement] drawer load:', e.message); }
    finally { setLoading(false); }
  }, [item.id, projectId]);
  useEffect(() => { setTab('details'); loadAll(); }, [item.id, loadAll]);

  const supplierC = item.supplier_id ? contactById[item.supplier_id] : null;
  const tEst = num(item.unit_price_estimate) * num(item.quantity_needed);
  const tAct = item.unit_price_actual ? num(item.unit_price_actual) * num(item.quantity_needed) : null;
  const recvPct = num(item.quantity_needed) > 0 ? Math.round(num(item.quantity_received)/num(item.quantity_needed)*100) : 0;

  async function refresh() { await loadAll(); onChanged(); }
  async function setStatus(status, note) {
    const sb = await sbClient(); if (!sb) return;
    const { error } = await sb.from('procurement_items').update({ status }).eq('id', item.id);
    if (error) { alert(error.message); return; }
    if (note) await addStatusComment(sb, item.status, status, note);
    await refresh();
  }
  async function addStatusComment(sb, oldS, newS, body) {
    try { await sb.from('procurement_comments').insert({ procurement_item_id:item.id, user_id:await uid(sb), body, is_status_change:true, old_status:oldS, new_status:newS }); } catch {}
  }
  async function setSupplier(id) {
    const sb = await sbClient(); if (!sb) return;
    const { error } = await sb.from('procurement_items').update({ supplier_id: id || null }).eq('id', item.id);
    if (error) { alert(error.message); return; }
    await refresh();
  }
  async function pickWinner(q) {
    const sb = await sbClient(); if (!sb) return;
    await sb.from('procurement_quotes').update({ is_winner:false }).eq('procurement_item_id', item.id);
    const { error } = await sb.from('procurement_quotes').update({ is_winner:true }).eq('id', q.id);
    if (error) { alert(error.message); return; }
    await sb.from('procurement_items').update({ supplier_id:q.supplier_id||null, unit_price_actual:q.unit_price, status:'ממתין לאישור' }).eq('id', item.id);
    await addStatusComment(sb, item.status, 'ממתין לאישור', 'נבחרה הצעת ' + supLabel(contactById[q.supplier_id]) + ' — נשלח לאישור');
    await refresh();
  }
  async function deleteQuote(q) {
    if (!confirm('למחוק הצעת מחיר זו?')) return;
    const sb = await sbClient(); if (!sb) return;
    await sb.from('procurement_quotes').delete().eq('id', q.id); await refresh();
  }
  async function generatePO() {
    const sb = await sbClient(); if (!sb) return;
    const winner = quotes.find(q => q.is_winner);
    if (!winner) { alert('יש לבחור הצעה מנצחת תחילה'); return; }
    const defQty = num(item.quantity_gross) || num(item.quantity_needed);
    const qStr = prompt('כמות שהוזמנה', String(defQty));      // B6 — קליטת כמות שהוזמן
    if (qStr == null) return;
    const ordered = num(qStr) || defQty;
    // v99.4 — מספור רץ לפי פרויקט/שנה (PO-YYYY-NNN)
    const yr = new Date().getFullYear();
    let next = 1;
    try {
      const { data: ex } = await sb.from('purchase_orders').select('po_number').eq('project_id', item.project_id);
      const nums = (ex||[]).map(r=>{ const m=String(r.po_number||'').match(/PO-(\d{4})-(\d+)/); return (m && +m[1]===yr)?+m[2]:0; });
      next = (nums.length?Math.max(...nums):0) + 1;
    } catch {}
    const poNum = 'PO-' + yr + '-' + String(next).padStart(3,'0');
    const total = num(winner.unit_price) * ordered;
    const { data: poRow, error } = await sb.from('purchase_orders').insert({
      project_id:item.project_id, supplier_id:winner.supplier_id||null, quote_id:winner.id,
      po_number:poNum, status:'טיוטה', total_amount:total, created_by:await uid(sb),
    }).select('*').single();
    if (error) { alert(error.message); return; }
    await sb.from('po_line_items').insert({ po_id:poRow.id, procurement_item_id:item.id, description:item.description, unit:item.unit, quantity:ordered, unit_price:winner.unit_price });
    await sb.from('procurement_items').update({ status:'הוזמן', quantity_ordered:ordered }).eq('id', item.id);
    await addStatusComment(sb, item.status, 'הוזמן', poNum + ' נוצר מהצעת ' + supLabel(contactById[winner.supplier_id]));
    await refresh();
  }
  async function deletePO() {
    if (!po || !confirm('למחוק את הזמנת הרכש?')) return;
    const sb = await sbClient(); if (!sb) return;
    await sb.from('purchase_orders').delete().eq('id', po.id); // cascade deletes lines
    await sb.from('procurement_items').update({ status:'מאושר', quantity_ordered:0 }).eq('id', item.id);
    await refresh();
  }
  async function markReceived() {
    const sb = await sbClient(); if (!sb) return;
    if (!po) { alert('אין הזמנת רכש לסימון קבלה'); return; }
    const remaining = num(item.quantity_ordered||item.quantity_needed) - num(item.quantity_received);
    const qStr = prompt('כמות שהתקבלה (נותר ' + remaining + ' ' + item.unit + ')', String(remaining));
    if (qStr == null) return;
    const qty = num(qStr); if (!qty || qty <= 0) return;
    const { data: deliv, error } = await sb.from('deliveries').insert({ po_id:po.id, received_by:await uid(sb) }).select('*').single();
    if (error) { alert(error.message); return; }
    await sb.from('delivery_line_items').insert({ delivery_id:deliv.id, procurement_item_id:item.id, quantity_received:qty });
    await refresh();
  }
  async function addQuoteSave(f) {
    const sb = await sbClient(); if (!sb) return;
    const { error } = await sb.from('procurement_quotes').insert({
      procurement_item_id:item.id, supplier_id:f.supplier_id||null, unit_price:num(f.unit_price),
      delivery_days:f.delivery_days?num(f.delivery_days):null, notes:f.notes||null, attached_file_url:f.attached_file_url||null,
    });
    if (error) throw error;
    if (item.status === 'טיוטה') await sb.from('procurement_items').update({ status:'מכרז' }).eq('id', item.id);
    await refresh();
  }
  async function importQuote(eq) {
    const sb = await sbClient(); if (!sb) return;
    const supId = await ensureContact({ company:eq.supplier, name:eq.contact, phone:eq.phone }, projectId, contacts);
    await onRefreshContacts();
    const { error } = await sb.from('procurement_quotes').insert({ procurement_item_id:item.id, supplier_id:supId, unit_price:num(eq.price), notes:'יובא מהשוואת הצעות' });
    if (error) throw error;
    if (item.status === 'טיוטה') await sb.from('procurement_items').update({ status:'מכרז' }).eq('id', item.id);
    await refresh();
  }
  async function sendComment() {
    if (!commentText.trim()) return;
    const sb = await sbClient(); if (!sb) return;
    await sb.from('procurement_comments').insert({ procurement_item_id:item.id, user_id:await uid(sb), body:commentText.trim() });
    setCommentText(''); await loadAll();
  }

  function footerButtons() {
    const s = displayStatus(item);
    const B = (cls,txt,fn) => <button key={txt} className={'proc-af '+cls} onClick={fn}>{txt}</button>;
    switch (s) {
      case 'טיוטה':        return [B('proc-af-order','📤 שלח למכרז',()=>setStatus('מכרז')), B('proc-af-attach','+ הצעה',()=>setShowAddQuote(true))];
      case 'מכרז':         return [B('proc-af-attach','+ הוסף הצעה',()=>setShowAddQuote(true)), ...(quotes.some(q=>q.is_winner)?[B('proc-af-approve','📤 העבר לאישור',()=>setStatus('ממתין לאישור'))]:[])];
      case 'ממתין לאישור': return [B('proc-af-approve','✓ אשר',()=>setStatus('מאושר')), B('proc-af-reject','✕ דחה',()=>setStatus('נדחה'))];
      case 'מאושר':        return [B('proc-af-order','📋 הפק PO',generatePO)];
      case 'הוזמן':        return [B('proc-af-approve','📦 סמן קבלה',markReceived)];
      case 'רכש חו״ל':     return [B('proc-af-approve','📦 סמן קבלה',markReceived)];
      case 'בדרך':         return [B('proc-af-approve','📦 סמן קבלה',markReceived)];
      case 'בפיגור':       return [B('proc-af-approve','📦 סמן קבלה',markReceived)];
      case 'התקבל':        return [B('proc-af-close','✓ סגור פריט',()=>setStatus('סגור'))];
      default: return [];
    }
  }

  return <>
    <div className="proc-overlay" onClick={onClose}></div>
    <div className="proc-drawer">
      <div className="proc-dhead">
        <div className="proc-dhead-top">
          <div style={{flex:1}}>
            <div className="proc-dtitle">{item.description}</div>
            <div className="proc-dmeta">{item.category} · {supplierC ? supLabel(supplierC) : 'ספק טרם נבחר'}</div>
          </div>
          <span className="proc-dclose" onClick={onClose}>✕</span>
        </div>
        <div className="proc-dstatus-row"><StatusPickerPill current={item.status} onPick={(s)=>setStatus(s)}/>{isOverdue(item) && <span className="proc-dts" style={{color:'#fca5a5'}}>⚠ בפיגור</span>}</div>
        <div className="proc-dhead-tools">
          <span className="proc-tool" onClick={()=>onEdit(item)}>✏️ ערוך פריט</span>
          <span className="proc-tool danger" onClick={async()=>{ if(confirm('למחוק את פריט הרכש? פעולה בלתי הפיכה.')){ const sb=await sbClient(); if(item.gantt_task_id) await archiveMilestone(sb, item.gantt_task_id, item.project_id); await sb.from('procurement_items').delete().eq('id',item.id); onChanged(); onClose(); } }}>🗑 מחק</span>
        </div>
      </div>

      <div className="proc-dtabs">
        {[['details','פרטים'],['quotes','הצעות מחיר'],['po','הזמנת רכש'],['history','היסטוריה']].map(([k,l]) =>
          <div key={k} className={'proc-dtab'+(tab===k?' active':'')} onClick={()=>setTab(k)}>{l}</div>)}
      </div>

      <div className="proc-dbody">
        {loading && <div className="proc-loading">טוען...</div>}

        {!loading && tab==='details' && <>
          <div className="proc-sectitle">ספק נבחר</div>
          <SupplierPicker contacts={contacts} value={item.supplier_id} onChange={setSupplier} projectId={projectId} onRefresh={onRefreshContacts}/>
          <div className="proc-infogrid" style={{marginTop:14}}>
            <div className="proc-ii"><label>קטגוריה</label><span>{item.category}</span></div>
            <div className="proc-ii"><label>חייב באתר</label><span className={isOverdue(item)?'red':''}>{fmtDate(item.required_on_site)}</span></div>
            <div className="proc-ii"><label>כמות נטו</label><span>{num(item.quantity_needed)} {item.unit}</span></div>
            <div className="proc-ii"><label>פחת / להזמנה</label><span>{num(item.waste_pct)}% · {(num(item.quantity_gross)||grossQty(item.quantity_needed,item.waste_pct)).toLocaleString('he-IL')} {item.unit}</span></div>
            <div className="proc-ii"><label>הוזמן / התקבל</label><span>{num(item.quantity_ordered)} / {num(item.quantity_received)} {item.unit}</span></div>
            <div className="proc-ii"><label>מחיר יח׳ (אומדן)</label><span>{fm(item.unit_price_estimate)}</span></div>
            <div className="proc-ii"><label>מחיר נסגר</label><span>{item.unit_price_actual?fm(item.unit_price_actual):'— (טרם נסגר)'}</span></div>
            <div className="proc-ii"><label>סה"כ אומדן</label><span>{fm(tEst)}</span></div>
            <div className="proc-ii"><label>סה"כ בפועל</label><span className={tAct?(tAct>tEst?'red':'green'):''}>{fmtWithDelta(tAct, tEst)}</span></div>
          </div>
          <div style={{marginTop:14}}>
            <div className="proc-ii" style={{marginBottom:4}}><label>התקדמות קבלה</label></div>
            <div className="proc-progbg"><div className="proc-progfill" style={{width:recvPct+'%'}}></div></div>
            <div className="proc-proglabels"><span>{num(item.quantity_received)} {item.unit} התקבלו</span><span>{recvPct}%</span></div>
          </div>
          {item.budget_line_id && <div className="proc-hint" style={{marginTop:10}}>🔗 מקושר לשורת תקציב (אומדן)</div>}
        </>}

        {!loading && tab==='quotes' && <>
          <div className="proc-sectitle">הצעות מחיר שהתקבלו</div>
          {!quotes.length && <div style={{textAlign:'center',padding:24,color:'#9ca3af',fontSize:13}}>טרם התקבלו הצעות מחיר</div>}
          {quotes.map(q => {
            const c = contactById[q.supplier_id];
            return <div key={q.id} className={'proc-qcard'+(q.is_winner?' winner':'')}>
              <div className="proc-qc-top">
                <div><div className="proc-qc-supplier">{supLabel(c)}</div>{supAgent(c)&&<div className="proc-qc-agent">👤 {supAgent(c)}</div>}</div>
                <div className="proc-qc-badge">{q.is_winner ? <span className="proc-winner-badge">✓ מנצחת</span> : <span className="proc-draft-badge">הצעה</span>}</div>
              </div>
              <div className="proc-qc-rows">
                <div className="proc-qc-field"><label>מחיר יחידה</label><span className={q.is_winner?'green':''}>{fm(q.unit_price)}</span></div>
                <div className="proc-qc-field"><label>זמן אספקה</label><span>{q.delivery_days?q.delivery_days+' ימים':'—'}</span></div>
                <div className="proc-qc-field"><label>סה"כ משוער</label><span>{fm(num(q.unit_price)*num(item.quantity_needed))}</span></div>
              </div>
              {q.notes && <div className="proc-qc-note">📝 {q.notes}</div>}
              <div className="proc-qc-actions">
                {q.attached_file_url && <button className="proc-qbtn proc-qb-view" onClick={()=>window.open(q.attached_file_url,'_blank')}>📎 קובץ</button>}
                {!q.is_winner && <button className="proc-qbtn proc-qb-select" onClick={()=>pickWinner(q)}>בחר הצעה זו</button>}
                <button className="proc-qbtn proc-qb-del" onClick={()=>deleteQuote(q)}>🗑</button>
              </div>
            </div>;
          })}
          <button className="proc-add" onClick={()=>setShowAddQuote(true)}>+ הוסף הצעת מחיר</button>
        </>}

        {!loading && tab==='po' && <>
          {po ? <div className="proc-pocard generated">
            <div className="proc-po-top">
              <div><div className="proc-po-num">{po.po_number}</div><div className="proc-po-supplier">📅 {fmtDate(po.issue_date)} · אספקה: {fmtDate(po.expected_delivery_date)}</div></div>
              <span className="proc-po-status">{po.status}</span>
            </div>
            <div className="proc-po-lines">
              {poLines.map(l => <div key={l.id} className="proc-po-line"><span>{l.description} — {num(l.quantity)} {l.unit}</span><span style={{fontWeight:600,direction:'ltr'}}>{fm(l.line_total)}</span></div>)}
              <div className="proc-po-total"><span>סה"כ להזמנה</span><span style={{direction:'ltr'}}>{fm(po.total_amount)}</span></div>
            </div>
            <div className="proc-qc-actions" style={{marginTop:12}}>
              <button className="proc-qbtn proc-qb-po" onClick={()=>setShowPOPreview(true)}>📄 PDF / שלח לספק</button>
              <button className="proc-qbtn proc-qb-del" onClick={deletePO}>🗑</button>
            </div>
          </div> : <div className="proc-nopo">
            <div className="proc-nopo-icon">📋</div>
            <div className="proc-nopo-text">אין הזמנת רכש עדיין</div>
            <div className="proc-nopo-sub">{quotes.some(q=>q.is_winner) ? 'הצעה אושרה — אפשר להפיק PO' : 'יש לבחור הצעת מחיר מנצחת תחילה'}</div>
            <button className="proc-btn-gold" style={{opacity:quotes.some(q=>q.is_winner)?1:.4,cursor:quotes.some(q=>q.is_winner)?'pointer':'not-allowed'}} onClick={()=>quotes.some(q=>q.is_winner)?generatePO():alert('בחר קודם הצעת מחיר')}>📋 הפק הזמנת רכש</button>
          </div>}
        </>}

        {!loading && tab==='history' && <>
          <div className="proc-sectitle">יומן פעולות</div>
          <div className="proc-tl">
            {!comments.length && <div style={{color:'#9ca3af',fontSize:13}}>אין פעולות עדיין</div>}
            {comments.map((h,i) => <div key={h.id} className="proc-tl-item">
              <div style={{display:'flex',flexDirection:'column',alignItems:'center',width:18,flexShrink:0}}>
                <div className="proc-tl-dot"></div>{i<comments.length-1 && <div style={{flex:1,width:1,background:'#e5e7eb'}}></div>}
              </div>
              <div><div className="proc-tl-text">{h.is_status_change?'':'💬 '}<span>{h.body}</span></div><div className="proc-tl-ts">{new Date(h.created_at).toLocaleString('he-IL')}</div></div>
            </div>)}
          </div>
          <div className="proc-comment-wrap">
            <textarea className="proc-comment-input" rows="2" placeholder="הוסף הערה..." value={commentText} onChange={e=>setCommentText(e.target.value)}></textarea>
            <button className="proc-comment-send" onClick={sendComment}>שלח</button>
          </div>
        </>}
      </div>

      <div className="proc-dfooter">{footerButtons()}</div>
    </div>
    {showAddQuote && <AddQuoteModal projectId={projectId} contacts={contacts} onRefreshContacts={onRefreshContacts} existingQuotes={existingQuotes} onClose={()=>setShowAddQuote(false)} onSave={addQuoteSave} onImport={importQuote}/>}
    {showPOPreview && po && <POPreviewModal po={po} poLines={poLines} supplierC={contactById[po.supplier_id]} item={item} projectName={projectName} onClose={()=>setShowPOPreview(false)} onSent={refresh}/>}
  </>;
}

// ── Main screen ──────────────────────────────────────────────────────────────
const ProcurementScreen = ({ projectId, onBack }) => {
  const [items, setItems] = useState([]);
  const [contacts, setContacts] = useState([]);
  const [loading, setLoading] = useState(true);
  const [err, setErr] = useState(null);
  const [sel, setSel] = useState(null);
  const [modalItem, setModalItem] = useState(undefined); // undefined=closed, null=new, obj=edit
  const [fStatus, setFStatus] = useState('');
  const [fCat, setFCat] = useState('');
  const [fSup, setFSup] = useState('');
  const [fSearch, setFSearch] = useState('');

  const contactById = useMemo(() => Object.fromEntries(contacts.map(c => [c.id, c])), [contacts]);

  const refreshContacts = useCallback(async () => { setContacts(await loadContacts()); }, []);
  const load = useCallback(async () => {
    setLoading(true); setErr(null);
    const sb = await sbClient();
    if (!sb) { setErr('Supabase לא זמין'); setLoading(false); return; }
    try {
      const [{ data:its, error:e1 }, cts] = await Promise.all([
        sb.from('procurement_items').select('*').eq('project_id', projectId).order('created_at',{ascending:false}),
        loadContacts(),
      ]);
      if (e1) throw e1;
      setItems(its || []); setContacts(cts || []);
    } catch (e) { console.warn('[Procurement] load:', e.message); setErr(e.message); }
    finally { setLoading(false); }
  }, [projectId]);
  useEffect(() => { load(); }, [load]);
  useEffect(() => { if (sel) { const fresh = items.find(i => i.id === sel.id); if (fresh && fresh !== sel) setSel(fresh); } }, [items]); // eslint-disable-line

  async function saveItem(f) {
    const sb = await sbClient(); if (!sb) throw new Error('Supabase לא זמין');
    if (modalItem) { // edit
      const { error } = await sb.from('procurement_items').update(f).eq('id', modalItem.id);
      if (error) throw error;
      // v99.3 B7 — סנכרן אבן דרך בגאנט (תאריך אספקה)
      const merged = { ...modalItem, ...f };
      const gid = await syncMilestone(sb, merged, modalItem.gantt_task_id || null);
      if (gid !== (modalItem.gantt_task_id || null)) await sb.from('procurement_items').update({ gantt_task_id: gid }).eq('id', modalItem.id);
    } else { // create
      const { data: created, error } = await sb.from('procurement_items').insert({ ...f, project_id:projectId, status:'טיוטה', created_by:await uid(sb) }).select('*').single();
      if (error) throw error;
      const gid = await syncMilestone(sb, created, null);   // אחרי שהפריט קיים → ה-FK מחזיק
      if (gid) await sb.from('procurement_items').update({ gantt_task_id: gid }).eq('id', created.id);
    }
    await load();
  }

  // v99.6 — שינוי סטטוס מהיר מהטבלה (בורר ה-pill בשורה)
  async function setItemStatus(it, status) {
    if (status === it.status) return;
    const sb = await sbClient(); if (!sb) return;
    const { error } = await sb.from('procurement_items').update({ status }).eq('id', it.id);
    if (error) { alert(error.message); return; }
    try { await sb.from('procurement_comments').insert({ procurement_item_id:it.id, user_id:await uid(sb), body:'סטטוס שונה ל-'+status, is_status_change:true, old_status:it.status, new_status:status }); } catch {}
    await load();
  }

  const summary = useMemo(() => {
    const budget = items.reduce((s,i) => s + num(i.unit_price_estimate)*num(i.quantity_needed), 0);
    const committed = items.reduce((s,i) => s + (i.unit_price_actual ? num(i.unit_price_actual)*num(i.quantity_needed) : 0), 0);
    const inTender = items.filter(i => ['מכרז','ממתין לאישור'].includes(i.status)).length;
    const overdue = items.filter(isOverdue).length;
    const foreign = items.filter(i => i.status === 'רכש חו״ל').length;
    const ordered = items.filter(i => ['הוזמן','בדרך','התקבל','רכש חו״ל'].includes(i.status)).length;
    return { budget, committed, inTender, overdue, foreign, ordered, total: items.length };
  }, [items]);

  const filtered = useMemo(() => {
    const q = fSearch.toLowerCase();
    return items.filter(i => {
      if (fStatus && displayStatus(i) !== fStatus) return false;
      if (fCat && i.category !== fCat) return false;
      if (fSup && (supLabel(contactById[i.supplier_id])||'') !== fSup) return false;
      if (q) { const hay = (i.description+' '+i.category+' '+supLabel(contactById[i.supplier_id])).toLowerCase(); if (!hay.includes(q)) return false; }
      return true;
    });
  }, [items, fStatus, fCat, fSup, fSearch, contactById]);

  const supplierOptions = useMemo(() => {
    const set = new Set(); items.forEach(i => { const l = supLabel(contactById[i.supplier_id]); if (i.supplier_id && l !== '—') set.add(l); }); return [...set];
  }, [items, contactById]);

  const resetFilters = () => { setFStatus(''); setFCat(''); setFSup(''); setFSearch(''); };

  return <div className="proc-root">
    <StyleOnce/>
    <div className="proc-bar">
      <span className="proc-back" onClick={onBack} title="חזרה">‹</span>
      <h2>ניהול רכש</h2>
      <div className="proc-actions">
        <button className="proc-btn-outline" onClick={()=>alert('ייבוא BOQ מ-Drive — שלב 6 (Make)')}>📥 ייבא אומדן</button>
        <button className="proc-btn-gold" onClick={()=>setModalItem(null)}>+ פריט חדש</button>
      </div>
    </div>

    <div className="proc-summary">
      <div className="proc-scard ok"><div className="proc-slabel">תקציב מתוכנן</div><div className="proc-sval">{fm(summary.budget)}</div><div className="proc-ssub">מחויב: {fm(summary.committed)}{summary.budget?' ('+Math.round(summary.committed/summary.budget*100)+'%)':''}</div></div>
      <div className="proc-scard warn"><div className="proc-slabel">במכרז / ממתין לאישור</div><div className="proc-sval">{summary.inTender}</div><div className="proc-ssub">פריטים בתהליך</div></div>
      <div className="proc-scard danger"><div className="proc-slabel">בפיגור</div><div className="proc-sval">{summary.overdue}</div><div className="proc-ssub red">{summary.overdue?'חרגו מתאריך אספקה':'—'}</div></div>
      <div className="proc-scard blue"><div className="proc-slabel">רכש חו״ל פתוח</div><div className="proc-sval">{summary.foreign}</div><div className="proc-ssub">פריטי יבוא</div></div>
      <div className="proc-scard"><div className="proc-slabel">הוזמן לשטח</div><div className="proc-sval">{summary.ordered} / {summary.total}</div><div className="proc-ssub">{summary.total?Math.round(summary.ordered/summary.total*100):0}% מהפריטים</div></div>
    </div>

    <div className="proc-filter">
      <div className="proc-fg"><label>סטטוס</label>
        <select className="proc-sel" value={fStatus} onChange={e=>setFStatus(e.target.value)}>
          <option value="">הכל</option>{Object.keys(STATUS).map(s => <option key={s} value={s}>{STATUS[s].lbl}</option>)}<option value="בפיגור">⚠ בפיגור</option>
        </select></div>
      <div className="proc-fg"><label>קטגוריה</label>
        <select className="proc-sel" value={fCat} onChange={e=>setFCat(e.target.value)}><option value="">הכל</option>{CATEGORIES.map(c => <option key={c} value={c}>{c}</option>)}</select></div>
      <div className="proc-fg"><label>ספק</label>
        <select className="proc-sel" value={fSup} onChange={e=>setFSup(e.target.value)}><option value="">כל הספקים</option>{supplierOptions.map(s => <option key={s} value={s}>{s}</option>)}</select></div>
      <div className="proc-fg"><label>חיפוש</label>
        <input className="proc-search" value={fSearch} onChange={e=>setFSearch(e.target.value)} placeholder="🔍 פריט, ספק, קטגוריה..."/></div>
      <button className="proc-reset" onClick={resetFilters}>× נקה</button>
    </div>

    <div className="proc-tablewrap">
      {loading ? <div className="proc-loading">טוען פריטי רכש...</div>
       : err ? <div className="proc-noresults">שגיאה בטעינה: {err}</div>
       : !filtered.length ? <div className="proc-noresults">{items.length ? 'אין פריטים תואמים לסינון' : 'אין עדיין פריטי רכש — לחץ "+ פריט חדש"'}</div>
       : <table className="proc-table">
          <thead><tr>
            <th>תיאור פריט / קטגוריה</th><th>סטטוס</th><th>ספק נבחר / סוכן</th><th>כמות (הוזמן/נדרש)</th><th>אומדן → בפועל</th><th>חייב באתר</th><th>גאנט</th>
          </tr></thead>
          <tbody>
            {filtered.map(it => {
              const tEst = num(it.unit_price_estimate)*num(it.quantity_needed);
              const tAct = it.unit_price_actual ? num(it.unit_price_actual)*num(it.quantity_needed) : null;
              const d = pctDelta(tAct, tEst);
              const dateCls = isOverdue(it) ? 'late' : (it.required_on_site && it.required_on_site <= new Date(Date.now()+10*864e5).toISOString().slice(0,10) ? 'soon' : '');
              const c = contactById[it.supplier_id];
              return <tr key={it.id} onClick={()=>setSel(it)}>
                <td><div className="proc-main">{it.description}</div><div className="proc-sub"><span className="proc-catbadge">{it.category}</span></div></td>
                <td onClick={e=>e.stopPropagation()}><StatusPickerPill current={it.status} onPick={(s)=>setItemStatus(it,s)}/>{isOverdue(it) && <span style={{display:'block',fontSize:10,color:'#ef4444',fontWeight:700,marginTop:1}}>⚠ בפיגור</span>}</td>
                <td><div className="proc-main" style={{fontSize:13}}>{it.supplier_id?supLabel(c):'—'}</div>{supAgent(c)&&<div className="proc-sub">👤 {supAgent(c)}</div>}</td>
                <td className="proc-numc">{num(it.quantity_ordered)}/{num(it.quantity_needed)} {it.unit}</td>
                <td><div style={{fontSize:13}}>{fm(tEst)}</div>{tAct && <div className={'proc-delta '+(tAct>tEst?'over':'under')}>{fm(tAct)}{d!==null?` (${d>0?'+':''}${d}%)`:''}</div>}</td>
                <td className={'proc-date '+dateCls}>{fmtDate(it.required_on_site)}</td>
                <td>{it.gantt_task_id ? <span className="proc-gb ok">✓ גאנט</span> : <span style={{color:'#e5e7eb',fontSize:11}}>—</span>}</td>
              </tr>;
            })}
          </tbody>
        </table>}
    </div>

    {sel && <Drawer item={sel} contacts={contacts} contactById={contactById} projectId={projectId}
      onClose={()=>setSel(null)} onChanged={load} onRefreshContacts={refreshContacts}
      onEdit={(it)=>{ setSel(null); setModalItem(it); }}/>}
    {modalItem !== undefined && <ItemModal projectId={projectId} initial={modalItem} onClose={()=>setModalItem(undefined)} onSave={saveItem}/>}
  </div>;
};

Object.assign(window, { ProcurementScreen });
})();
