// quotes.jsx — מרכז הצעות מחיר (cloud-backed, מקושר לתקציב).
// v3.9.0.39: localStorage → QuotesStore; כל הצעה משויכת ל-budget_line_id.
// סטטוסים: open (במרוץ) / closed (נסגרה — נבחרת) / rejected (נדחתה). חתימה = תכונה (sig).
(function(){
// ── Edge Function URL ──────────────────────────────────────────────────────
const EXTRACT_QUOTE_FN = 'https://ifppalksavexjrjsngeh.supabase.co/functions/v1/extract-quote';
const AI_CHAT_FN = 'https://ifppalksavexjrjsngeh.supabase.co/functions/v1/ai-chat';
// ── מע"מ ──────────────────────────────────────────────────────────────────
const VAT_RATE = 0.18; // 18% — ישראל 2025
const addVat    = (net)   => Math.round(net * (1 + VAT_RATE));
const removeVat = (gross) => Math.round(gross / (1 + VAT_RATE));
const fmtVat    = (n)     => Number(n).toLocaleString('he-IL') + ' ₪';
const { useState, useEffect, useRef, useMemo } = React;

const STATUS_MAP = {
  open:     { label:'במרוץ',  color:'#f59e0b', bg:'#fef3c7' },
  closed:   { label:'נסגרה',  color:'#16a34a', bg:'#dcfce7' },
  rejected: { label:'נדחתה',  color:'#ef4444', bg:'#fee2e2' },
};

const fmtMoney = v => v ? Number(v).toLocaleString('he-IL') + ' ₪' : '—';
const fmtDate  = iso => { if(!iso) return '—'; const d=new Date(iso); return String(d.getDate()).padStart(2,'0')+'/'+String(d.getMonth()+1).padStart(2,'0')+'/'+d.getFullYear(); };

// ═══════════════════════════════════════════════════════════════════════════════
//  QuotesScreen — ראשי
// ═══════════════════════════════════════════════════════════════════════════════
const QuotesScreen = ({ projectId, onBack }) => {
  const [quotes, setQuotes]               = useState([]);
  const [budgetLines, setBudgetLines]     = useState([]);  // [{id, category, name, supplier}]
  const [loading, setLoading]             = useState(true);
  const [view, setView]                   = useState('list');    // list | compare | detail
  const [selectedLineId, setSelectedLineId] = useState(null);    // for compare
  const [activeQuote, setActiveQuote]     = useState(null);
  const [showAddModal, setShowAddModal]   = useState(false);
  const [editingQuote, setEditingQuote]   = useState(null);
  const [filterCategory, setFilterCategory] = useState('all');
  const [toast, setToast]                 = useState(null);
  const seedTriedRef                      = React.useRef(null);

  const showToast = (msg, ok=true) => { setToast({msg, ok}); setTimeout(()=>setToast(null), 3000); };

  // ── טעינת הצעות + שורות תקציב ────────────────────────────────────────────
  const refresh = async () => {
    if (!window.QuotesStore || !window.BudgetStore) { setLoading(false); return; }
    setLoading(true);
    try {
      const [qs, bgInit] = await Promise.all([
        window.QuotesStore.listForProject(projectId),
        window.BudgetStore.getForProject(projectId),
      ]);
      let bg = bgInit;
      // אם אין שורות תקציב — זרע ברירות-מחדל פעם אחת לפרויקט, כדי שיהיה מה לשייך אליו
      if ((!bg.lines || bg.lines.length === 0) && seedTriedRef.current !== projectId
          && window.BudgetStore.ensureSeeded) {
        seedTriedRef.current = projectId;
        bg = await window.BudgetStore.ensureSeeded(projectId);
      }
      setQuotes(qs || []);
      // שטח את שורות התקציב לרשימה שמתאימה לבורר.
      const lines = (bg.lines || []).map(r => ({
        id: r.id, category: r.category || '', name: r.name || '', supplier: r.supplier || '',
      }));
      setBudgetLines(lines);
    } catch (err) {
      console.warn('[QuotesScreen] refresh:', err);
    } finally { setLoading(false); }
  };
  useEffect(() => { refresh(); }, [projectId]);

  // v3.9.0.45 — טעינה מחודשת של שורות התקציב בלבד (אחרי יצירת שורה מתוך טופס ההצעה)
  const reloadBudgetLines = async () => {
    if (!window.BudgetStore) return;
    try {
      const bg = await window.BudgetStore.getForProject(projectId);
      setBudgetLines((bg.lines || []).map(r => ({
        id: r.id, category: r.category || '', name: r.name || '', supplier: r.supplier || '',
      })));
    } catch (e) { console.warn('[QuotesScreen] reloadBudgetLines:', e); }
  };

  // קבוצות תקציב (לסינון + ויזואל)
  const categories = useMemo(() => {
    const set = new Set();
    budgetLines.forEach(l => l.category && set.add(l.category));
    return ['all', ...Array.from(set)];
  }, [budgetLines]);

  // קבוץ הצעות לפי category → budget_line_id → quote[]
  const grouped = useMemo(() => {
    const out = {};
    quotes.forEach(q => {
      const cat = q.category || (q.budget_line_id ? '—' : 'לא משויכות');
      if (!out[cat]) out[cat] = {};
      const key = q.budget_line_id || '__unlinked__';
      if (!out[cat][key]) out[cat][key] = [];
      out[cat][key].push(q);
    });
    return out;
  }, [quotes]);

  const stats = useMemo(() => ({
    total:        quotes.length,
    open:         quotes.filter(q => q.status === 'open').length,
    closed:       quotes.filter(q => q.status === 'closed').length,
    rejected:     quotes.filter(q => q.status === 'rejected').length,
    totalClosed:  quotes.filter(q => q.status === 'closed').reduce((s,q)=>s + (+q.price||0), 0),
    unlinked:     quotes.filter(q => !q.budget_line_id).length,
  }), [quotes]);

  const lineLabel = (lineId) => {
    const l = budgetLines.find(x => x.id === lineId);
    return l ? `${l.name || '(ללא שם)'}${l.category ? ' · ' + l.category : ''}` : '—';
  };

  // ── handlers (ענן) ───────────────────────────────────────────────────────
  const handleCreate = async (form) => {
    try {
      await window.QuotesStore.create(projectId, form);
      showToast('✓ הצעה נוספה');
      setShowAddModal(false);
      await refresh();
    } catch (err) { alert('שגיאה ביצירת הצעה: ' + (err?.message || err)); }
  };

  const handleUpdate = async (id, patch) => {
    try {
      await window.QuotesStore.update(id, patch);
      showToast('✓ עודכן');
      await refresh();
      // עדכן activeQuote ב-detail אם פתוח
      setActiveQuote(prev => prev && prev.id === id ? { ...prev, ...patch } : prev);
    } catch (err) { alert('שגיאה בעדכון: ' + (err?.message || err)); }
  };

  const handleDelete = async (id) => {
    if (!confirm('למחוק את ההצעה?')) return;
    try {
      await window.QuotesStore.remove(id);
      showToast('✓ נמחק');
      setView('list'); setActiveQuote(null);
      await refresh();
    } catch (err) { alert('שגיאה במחיקה: ' + (err?.message || err)); }
  };

  const handleSetStatus = async (id, status) => {
    try {
      await window.QuotesStore.setStatus(id, status);
      showToast(`✓ ${status === 'closed' ? 'נסגרה' : status === 'rejected' ? 'נדחתה' : 'במרוץ'}`);
      await refresh();
      setActiveQuote(prev => prev && prev.id === id ? { ...prev, status } : prev);
    } catch (err) { alert('שגיאה: ' + (err?.message || err)); }
  };

  // ── תצוגות משניות ────────────────────────────────────────────────────────
  if (loading) return (
    <div style={{ minHeight:'100%', display:'flex', alignItems:'center', justifyContent:'center',
      fontFamily:'Assistant,sans-serif', direction:'rtl', color:'var(--ybp-ink-soft)', fontSize:14 }}>
      טוען הצעות מחיר…
    </div>
  );

  if (view === 'detail' && activeQuote) {
    return <QuoteDetail
      quote={activeQuote}
      budgetLines={budgetLines}
      reloadBudgetLines={reloadBudgetLines}
      lineLabel={lineLabel}
      onBack={() => { setView('list'); setActiveQuote(null); }}
      onUpdate={(patch) => handleUpdate(activeQuote.id, patch)}
      onDelete={() => handleDelete(activeQuote.id)}
      onSetStatus={(s) => handleSetStatus(activeQuote.id, s)}
    />;
  }

  if (view === 'compare' && selectedLineId) {
    const lineQuotes = quotes.filter(q => q.budget_line_id === selectedLineId);
    return <CompareView
      lineLabel={lineLabel(selectedLineId)}
      quotes={lineQuotes}
      onBack={() => { setView('list'); setSelectedLineId(null); }}
      onSelect={(q) => handleSetStatus(q.id, 'closed')}
      onReject={(q) => handleSetStatus(q.id, 'rejected')}
    />;
  }

  return (
    <div style={{ minHeight:'100%', background:'#f5f6f8', fontFamily:'Assistant,sans-serif', direction:'rtl' }}>

      {toast && (
        <div style={{ position:'fixed', top:16, left:'50%', transform:'translateX(-50%)', zIndex:9999,
          background: toast.ok ? 'var(--ybp-navy)' : '#dc2626', color:'#fff', padding:'10px 20px',
          borderRadius:8, fontSize:14, fontWeight:600, boxShadow:'0 4px 16px rgba(0,0,0,0.2)' }}>
          {toast.msg}
        </div>
      )}

      {/* Header */}
      <div style={{ background:'var(--ybp-panel)', borderBottom:'1px solid var(--ybp-border)', padding:'12px 16px',
        display:'flex', alignItems:'center', gap:10, position:'sticky', top:0, zIndex:10 }}>
        <button onClick={onBack} style={{ background:'transparent', border:'none', cursor:'pointer',
          color:'var(--ybp-ink-soft)', display:'flex', alignItems:'center', gap:4, fontSize:14, padding:6, fontFamily:'inherit' }}>
          <Icon name="chevron" size={18}/> חזרה
        </button>
        <div style={{ width:1, height:24, background:'var(--ybp-border)' }}/>
        <span style={{ fontSize:16, fontWeight:700, color:'var(--ybp-ink)', flex:1 }}>הצעות מחיר</span>
        <button onClick={()=>{ setEditingQuote(null); setShowAddModal(true); }} style={{
          background:'var(--ybp-navy)', color:'#fff', border:'none', borderRadius:8,
          padding:'8px 14px', fontSize:13, fontWeight:700, cursor:'pointer', fontFamily:'inherit',
          display:'flex', alignItems:'center', gap:6 }}>+ הוסף הצעה</button>
      </div>

      {/* Stats */}
      <div style={{ background:'var(--ybp-panel)', borderBottom:'1px solid var(--ybp-border-soft)', padding:'12px 16px',
        display:'grid', gridTemplateColumns:'repeat(4,1fr)', gap:8 }}>
        {[
          { label:'סה"כ הצעות', value:stats.total, color:'var(--ybp-navy)' },
          { label:'במרוץ',      value:stats.open,  color:'#f59e0b' },
          { label:'נסגרו',      value:stats.closed, color:'#16a34a' },
          { label:'סה"כ נסגר',  value:fmtMoney(stats.totalClosed), color:'var(--ybp-navy)', small:true },
        ].map(s => (
          <div key={s.label} style={{ textAlign:'center', padding:'8px 4px', background:'var(--ybp-row-hover)', borderRadius:8 }}>
            <div style={{ fontSize: s.small ? 13 : 20, fontWeight:800, color:s.color, lineHeight:1.2 }}>{s.value}</div>
            <div style={{ fontSize:10, color:'var(--ybp-ink-soft)', marginTop:2 }}>{s.label}</div>
          </div>
        ))}
      </div>

      {stats.unlinked > 0 && (
        <div style={{ background:'#fffbeb', color:'#92400e', padding:'8px 16px', fontSize:12, fontWeight:600,
          borderBottom:'1px solid #fde68a' }}>
          ⚠️ {stats.unlinked} הצעות ללא שיוך לשורת תקציב. פתח כל אחת ושייך כדי שתשפיע על התקציב.
        </div>
      )}

      {/* Filter */}
      <div style={{ padding:'10px 16px', overflowX:'auto', display:'flex', gap:8, background:'var(--ybp-panel)',
        borderBottom:'1px solid var(--ybp-border-soft)' }}>
        {categories.map(c => (
          <button key={c} onClick={()=>setFilterCategory(c)} style={{
            padding:'5px 12px', borderRadius:20, border:'1px solid',
            borderColor: filterCategory===c?'var(--ybp-navy)':'var(--ybp-border)',
            background: filterCategory===c?'var(--ybp-navy)':'var(--ybp-panel)',
            color: filterCategory===c?'#fff':'var(--ybp-ink-soft)',
            fontSize:12, fontWeight:600, cursor:'pointer', fontFamily:'inherit', whiteSpace:'nowrap',
          }}>{c === 'all' ? 'הכל' : c}</button>
        ))}
      </div>

      {/* List */}
      <div style={{ padding:'12px 16px', display:'flex', flexDirection:'column', gap:12 }}>
        {Object.entries(grouped)
          .filter(([cat]) => filterCategory === 'all' || cat === filterCategory)
          .map(([cat, byLine]) => (
            <div key={cat}>
              <div style={{ fontSize:12, fontWeight:700, color:'var(--ybp-ink-soft)', marginBottom:6, letterSpacing:0.5 }}>
                {cat}
              </div>
              {Object.entries(byLine).map(([lineId, qs]) => {
                const line   = budgetLines.find(l => l.id === lineId);
                const header = line ? (line.name || '(ללא שם)') : 'לא משויכות לשורה';
                const minP   = Math.min(...qs.filter(q=>q.status!=='rejected').map(q=>+q.price||Infinity));
                return (
                  <div key={lineId} style={{ background:'var(--ybp-panel)', borderRadius:10, border:'1px solid var(--ybp-border)',
                    overflow:'hidden', marginBottom:8, boxShadow:'0 1px 3px rgba(0,0,0,0.04)' }}>
                    <div style={{ padding:'10px 14px', borderBottom:'1px solid var(--ybp-border-soft)',
                      display:'flex', alignItems:'center', gap:8 }}>
                      <span style={{ fontSize:14, fontWeight:700, color:'var(--ybp-ink)', flex:1 }}>{header}</span>
                      <span style={{ fontSize:11, color:'var(--ybp-ink-soft)' }}>{qs.length} הצעות</span>
                      {qs.length > 1 && line && (
                        <button onClick={()=>{ setSelectedLineId(lineId); setView('compare'); }} style={{
                          padding:'4px 10px', borderRadius:6, border:'1px solid #c7d2fe',
                          background:'var(--ybp-sb-active-bg)', color:'#4338ca', fontSize:11, fontWeight:700,
                          cursor:'pointer', fontFamily:'inherit' }}>⚖️ השווה</button>
                      )}
                    </div>
                    {/* v76.9 — השוואת פירוט פריטים כשיש יותר מהצעה אחת עם items */}
                    {qs.filter(q => q.items && q.items.length > 0).length > 1 && (
                      <div style={{ padding:'8px 14px 0' }}>
                        <QuoteItemsCompare quotes={qs.filter(q => q.items && q.items.length > 0)} />
                      </div>
                    )}
                    {qs.map(q => {
                      const st = STATUS_MAP[q.status] || STATUS_MAP.open;
                      const isCheapest = (+q.price === minP) && minP !== Infinity && q.status !== 'rejected' && qs.length > 1;
                      return (
                        <div key={q.id} onClick={()=>{ setActiveQuote(q); setView('detail'); }}
                          style={{ padding:'10px 14px', borderBottom:'1px solid #f9fafb',
                            display:'flex', alignItems:'center', gap:10, cursor:'pointer',
                            background: q.status==='closed' ? '#f0fdf4' : isCheapest ? '#fefce8' : 'var(--ybp-panel)' }}
                          onMouseEnter={e=>e.currentTarget.style.background = q.status==='closed' ? '#dcfce7' : 'var(--ybp-row-hover)'}
                          onMouseLeave={e=>e.currentTarget.style.background = q.status==='closed' ? '#f0fdf4' : isCheapest ? '#fefce8' : 'var(--ybp-panel)'}>
                          <div style={{ flex:1, minWidth:0 }}>
                            <div style={{ fontSize:13, fontWeight:600, color:'var(--ybp-ink)', marginBottom:2 }}>{q.supplier || '(ספק)'}</div>
                            <div style={{ fontSize:11, color:'var(--ybp-ink-soft)' }}>{q.contact || '—'} · {q.phone || ''}</div>
                          </div>
                          <div style={{ textAlign:'left' }}>
                            <div style={{ fontSize:14, fontWeight:800, color: isCheapest ? '#16a34a' : 'var(--ybp-navy)' }}>{fmtMoney(q.price)}</div>
                            <div style={{ fontSize:10, color:'var(--ybp-ink-faint)', marginTop:1 }}>{fmtDate(q.created_at)}</div>
                          </div>
                          <span style={{ padding:'3px 10px', borderRadius:12, fontSize:11, fontWeight:700,
                            background:st.bg, color:st.color }}>{st.label}</span>
                          <span style={{ color:'var(--ybp-ink-faint)', fontSize:18 }}>›</span>
                        </div>
                      );
                    })}
                  </div>
                );
              })}
            </div>
          ))}
        {quotes.length === 0 && (
          <div style={{ textAlign:'center', padding:'60px 20px', color:'var(--ybp-ink-faint)' }}>
            <div style={{ fontSize:40, marginBottom:12 }}>📋</div>
            <div style={{ fontSize:15, fontWeight:600 }}>אין הצעות מחיר עדיין</div>
            <div style={{ fontSize:13, marginTop:4 }}>לחץ "+ הוסף הצעה" להתחיל</div>
          </div>
        )}
      </div>

      {showAddModal && (
        <QuoteFormModal
          mode="create" projectId={projectId}
          budgetLines={budgetLines}
          reloadBudgetLines={reloadBudgetLines}
          onClose={()=>setShowAddModal(false)}
          onSave={handleCreate}
        />
      )}
    </div>
  );
};

// ═══════════════════════════════════════════════════════════════════════════════
//  CompareView — השוואת הצעות לאותה שורת תקציב
// ═══════════════════════════════════════════════════════════════════════════════
const CompareView = ({ lineLabel, quotes, onBack, onSelect, onReject }) => {
  const sorted   = [...quotes].sort((a,b) => (+a.price||0) - (+b.price||0));
  const nonRej   = quotes.filter(q => q.status !== 'rejected');
  const minPrice = nonRej.length ? Math.min(...nonRej.map(q=>+q.price||Infinity)) : Infinity;

  return (
    <div style={{ minHeight:'100%', background:'#f5f6f8', fontFamily:'Assistant,sans-serif', direction:'rtl' }}>
      <div style={{ background:'var(--ybp-panel)', borderBottom:'1px solid var(--ybp-border)', padding:'12px 16px',
        display:'flex', alignItems:'center', gap:10, position:'sticky', top:0, zIndex:10 }}>
        <button onClick={onBack} style={{ background:'transparent', border:'none', cursor:'pointer',
          color:'var(--ybp-ink-soft)', display:'flex', alignItems:'center', gap:4, fontSize:14, padding:6, fontFamily:'inherit' }}>
          <Icon name="chevron" size={18}/> חזרה
        </button>
        <div style={{ width:1, height:24, background:'var(--ybp-border)' }}/>
        <span style={{ fontSize:15, fontWeight:700, color:'var(--ybp-ink)' }}>⚖️ השוואה — {lineLabel}</span>
      </div>

      <div style={{ padding:16, display:'flex', flexDirection:'column', gap:12 }}>
        <div style={{ background:'var(--ybp-panel)', borderRadius:10, border:'1px solid var(--ybp-border)', overflow:'hidden' }}>
          <div style={{ overflowX:'auto' }}>
            <table style={{ width:'100%', borderCollapse:'collapse', fontSize:12 }}>
              <thead>
                <tr style={{ background:'var(--ybp-row-hover)' }}>
                  {['ספק','מחיר','תנאים','אחריות','הערות','סטטוס'].map(h => (
                    <th key={h} style={{ padding:'8px 10px', textAlign:'right', fontWeight:700,
                      color:'var(--ybp-ink-soft)', borderBottom:'1px solid var(--ybp-border-soft)', whiteSpace:'nowrap' }}>{h}</th>
                  ))}
                </tr>
              </thead>
              <tbody>
                {sorted.map(q => {
                  const isCheapest = (+q.price === minPrice) && q.status !== 'rejected';
                  const st = STATUS_MAP[q.status] || STATUS_MAP.open;
                  return (
                    <tr key={q.id} style={{ borderBottom:'1px solid #f9fafb',
                      background: q.status==='closed' ? '#f0fdf4' : isCheapest ? '#fefce8' : 'var(--ybp-panel)' }}>
                      <td style={{ padding:'10px' }}>
                        <div style={{ fontWeight:700, color:'var(--ybp-ink)', fontSize:13 }}>{q.supplier || '—'}</div>
                        <div style={{ fontSize:11, color:'var(--ybp-ink-soft)' }}>{q.contact || ''}</div>
                      </td>
                      <td style={{ padding:'10px' }}>
                        <div style={{ fontWeight:800, color: isCheapest ? '#16a34a' : 'var(--ybp-navy)', fontSize:14 }}>
                          {Number(q.price || 0).toLocaleString('he-IL')} ₪
                        </div>
                        {isCheapest && <div style={{ fontSize:10, color:'#16a34a', fontWeight:700 }}>✓ הכי זול</div>}
                      </td>
                      <td style={{ padding:'10px', color:'var(--ybp-ink-soft)' }}>{q.terms || '—'}</td>
                      <td style={{ padding:'10px', color:'var(--ybp-ink-soft)' }}>{q.warranty || '—'}</td>
                      <td style={{ padding:'10px', color:'var(--ybp-ink-soft)', fontSize:11 }}>{q.notes || '—'}</td>
                      <td style={{ padding:'10px' }}>
                        <span style={{ padding:'2px 8px', borderRadius:10, fontSize:10, fontWeight:700,
                          background:st.bg, color:st.color }}>{st.label}</span>
                      </td>
                    </tr>
                  );
                })}
              </tbody>
            </table>
          </div>
        </div>

        <div style={{ background:'var(--ybp-panel)', borderRadius:10, border:'1px solid var(--ybp-border)', padding:14 }}>
          <div style={{ fontSize:13, fontWeight:700, color:'var(--ybp-ink)', marginBottom:10 }}>בחר ספק זוכה / דחה:</div>
          <div style={{ display:'flex', flexDirection:'column', gap:8 }}>
            {sorted.map(q => {
              const isClosed = q.status === 'closed';
              const isRej    = q.status === 'rejected';
              return (
                <div key={q.id} style={{ display:'flex', alignItems:'center', gap:10,
                  padding:'10px 12px', borderRadius:8,
                  border:`1px solid ${isClosed ? '#16a34a' : isRej ? '#fecaca' : 'var(--ybp-border)'}`,
                  background: isClosed ? '#f0fdf4' : isRej ? '#fef2f2' : 'var(--ybp-panel)' }}>
                  <div style={{ flex:1 }}>
                    <div style={{ fontSize:13, fontWeight:700 }}>{q.supplier || '—'}</div>
                    <div style={{ fontSize:12, color:'var(--ybp-ink-soft)' }}>{Number(q.price||0).toLocaleString('he-IL')} ₪ · {q.terms || '—'}</div>
                  </div>
                  {isClosed
                    ? <span style={{ fontSize:13, fontWeight:700, color:'#16a34a' }}>✓ נסגרה</span>
                    : (
                      <div style={{ display:'flex', gap:6 }}>
                        <button onClick={()=>onSelect(q)} style={{ padding:'7px 14px', borderRadius:7, border:'none',
                          background:'var(--ybp-navy)', color:'#fff', fontSize:12, fontWeight:700, cursor:'pointer', fontFamily:'inherit' }}>
                          סגור עם זה
                        </button>
                        {!isRej && (
                          <button onClick={()=>onReject(q)} style={{ padding:'7px 14px', borderRadius:7,
                            border:'1px solid #fecaca', background:'var(--ybp-panel)', color:'#dc2626', fontSize:12,
                            fontWeight:700, cursor:'pointer', fontFamily:'inherit' }}>
                            דחה
                          </button>
                        )}
                      </div>
                    )
                  }
                </div>
              );
            })}
          </div>
        </div>
      </div>
    </div>
  );
};

// ═══════════════════════════════════════════════════════════════════════════════
//  QuoteDetail — פרטי הצעה + חתימה + שליחה לספק
// ═══════════════════════════════════════════════════════════════════════════════
const QuoteDetail = ({ quote, budgetLines, reloadBudgetLines, lineLabel, onBack, onUpdate, onDelete, onSetStatus }) => {
  const [showSigPad, setShowSigPad]     = useState(false);
  const [showSendMenu, setShowSendMenu] = useState(false);
  const [editing, setEditing]           = useState(false);
  const canvasRef = useRef(null);
  const drawing   = useRef(false);
  const sigUrl    = quote.sig || null;
  const st        = STATUS_MAP[quote.status] || STATUS_MAP.open;

  const handleSign = () => {
    const url = canvasRef.current.toDataURL('image/png');
    onUpdate({ sig: url });
    setShowSigPad(false);
  };

  const buildShareText = () =>
    `הצעת מחיר — ${lineLabel(quote.budget_line_id) || '(לא משויכת)'}\nספק: ${quote.supplier || ''}\nמחיר: ${Number(quote.price||0).toLocaleString('he-IL')} ₪\nתנאים: ${quote.terms || '—'}\nאחריות: ${quote.warranty || '—'}\n\nYBPROJECTS`;

  return (
    <div style={{ minHeight:'100%', background:'#f5f6f8', fontFamily:'Assistant,sans-serif', direction:'rtl' }}>

      {showSigPad && (
        <div style={{ position:'fixed', inset:0, background:'rgba(0,0,0,0.5)', zIndex:1000,
          display:'flex', alignItems:'center', justifyContent:'center' }} onClick={()=>setShowSigPad(false)}>
          <div style={{ background:'var(--ybp-panel)', borderRadius:12, padding:24, width:380, maxWidth:'95vw',
            boxShadow:'0 20px 60px rgba(0,0,0,0.3)' }} onClick={e=>e.stopPropagation()}>
            <div style={{ fontSize:15, fontWeight:700, color:'var(--ybp-ink)', marginBottom:4 }}>חתימה דיגיטלית</div>
            <div style={{ fontSize:12, color:'var(--ybp-ink-faint)', marginBottom:12 }}>חתום בתוך המסגרת</div>
            <canvas ref={canvasRef} width={332} height={120}
              style={{ border:'1px solid var(--ybp-border)', borderRadius:8, display:'block', cursor:'crosshair',
                background:'#fafafa', touchAction:'none' }}
              onMouseDown={e=>{ drawing.current=true; const r=canvasRef.current.getBoundingClientRect(); const ctx=canvasRef.current.getContext('2d'); ctx.beginPath(); ctx.moveTo(e.clientX-r.left,e.clientY-r.top); }}
              onMouseMove={e=>{ if(!drawing.current)return; const r=canvasRef.current.getBoundingClientRect(); const ctx=canvasRef.current.getContext('2d'); ctx.lineTo(e.clientX-r.left,e.clientY-r.top); ctx.strokeStyle='#1a2c4a'; ctx.lineWidth=2.5; ctx.lineCap='round'; ctx.stroke(); }}
              onMouseUp={()=>{ drawing.current=false; }}
              onMouseLeave={()=>{ drawing.current=false; }}
              onTouchStart={e=>{ e.preventDefault(); drawing.current=true; const r=canvasRef.current.getBoundingClientRect(); const t=e.touches[0]; const ctx=canvasRef.current.getContext('2d'); ctx.beginPath(); ctx.moveTo(t.clientX-r.left,t.clientY-r.top); }}
              onTouchMove={e=>{ e.preventDefault(); if(!drawing.current)return; const r=canvasRef.current.getBoundingClientRect(); const t=e.touches[0]; const ctx=canvasRef.current.getContext('2d'); ctx.lineTo(t.clientX-r.left,t.clientY-r.top); ctx.strokeStyle='#1a2c4a'; ctx.lineWidth=2.5; ctx.lineCap='round'; ctx.stroke(); }}
              onTouchEnd={()=>{ drawing.current=false; }}
            />
            <div style={{ display:'flex', gap:8, marginTop:12, justifyContent:'space-between' }}>
              <button onClick={()=>{ const ctx=canvasRef.current.getContext('2d'); ctx.clearRect(0,0,332,120); }}
                style={{ padding:'7px 14px', borderRadius:6, border:'1px solid var(--ybp-border)', background:'var(--ybp-panel)',
                  color:'var(--ybp-ink-soft)', fontSize:12, fontWeight:600, cursor:'pointer', fontFamily:'inherit' }}>נקה</button>
              <div style={{ display:'flex', gap:8 }}>
                <button onClick={()=>setShowSigPad(false)} style={{ padding:'7px 14px', borderRadius:6,
                  border:'1px solid var(--ybp-border)', background:'var(--ybp-panel)', color:'var(--ybp-ink-soft)', fontSize:12,
                  fontWeight:600, cursor:'pointer', fontFamily:'inherit' }}>ביטול</button>
                <button onClick={handleSign} style={{ padding:'7px 18px', borderRadius:6, border:'none',
                  background:'var(--ybp-navy)', color:'#fff', fontSize:12, fontWeight:700,
                  cursor:'pointer', fontFamily:'inherit' }}>שמור חתימה</button>
              </div>
            </div>
          </div>
        </div>
      )}

      {editing && (
        <QuoteFormModal
          mode="edit" projectId={quote.project_id}
          budgetLines={budgetLines}
          reloadBudgetLines={reloadBudgetLines}
          initial={quote}
          onClose={()=>setEditing(false)}
          onSave={(form) => { onUpdate(form); setEditing(false); }}
        />
      )}

      <div style={{ background:'var(--ybp-panel)', borderBottom:'1px solid var(--ybp-border)', padding:'12px 16px',
        display:'flex', alignItems:'center', gap:10, position:'sticky', top:0, zIndex:10 }}>
        <button onClick={onBack} style={{ background:'transparent', border:'none', cursor:'pointer',
          color:'var(--ybp-ink-soft)', display:'flex', alignItems:'center', gap:4, fontSize:14, padding:6, fontFamily:'inherit' }}>
          <Icon name="chevron" size={18}/> חזרה
        </button>
        <div style={{ flex:1 }}>
          <div style={{ fontSize:15, fontWeight:700, color:'var(--ybp-ink)' }}>{quote.supplier || '(ספק)'}</div>
          <span style={{ padding:'2px 10px', borderRadius:12, fontSize:11, fontWeight:700,
            background:st.bg, color:st.color }}>{st.label}</span>
        </div>
        <button onClick={()=>setEditing(true)} style={{ background:'var(--ybp-panel)', border:'1px solid var(--ybp-border)',
          color:'var(--ybp-ink-soft)', padding:'6px 12px', borderRadius:6, fontSize:12, fontWeight:600,
          cursor:'pointer', fontFamily:'inherit' }}>✏️ ערוך</button>
      </div>

      <div style={{ padding:16, display:'flex', flexDirection:'column', gap:12 }}>

        {/* שיוך לתקציב */}
        <div style={{ background:'var(--ybp-panel)', borderRadius:10, border:'1px solid var(--ybp-border)', padding:14 }}>
          <div style={{ fontSize:11, fontWeight:700, color:'var(--ybp-ink-soft)', textTransform:'uppercase', letterSpacing:0.5, marginBottom:6 }}>
            שיוך לשורת תקציב
          </div>
          {quote.budget_line_id ? (
            <div style={{ fontSize:13, color:'var(--ybp-ink)', fontWeight:600 }}>📑 {lineLabel(quote.budget_line_id)}</div>
          ) : (
            <div style={{ fontSize:13, color:'#dc2626', fontWeight:600 }}>
              ⚠️ לא משויכת — ההצעה לא תשפיע על התקציב עד שתשייך
              <button onClick={()=>setEditing(true)} style={{ marginRight:8, padding:'4px 10px',
                borderRadius:6, border:'1px solid var(--ybp-navy)', background:'var(--ybp-navy)', color:'#fff',
                fontSize:11, fontWeight:700, cursor:'pointer', fontFamily:'inherit' }}>
                שייך עכשיו
              </button>
            </div>
          )}
        </div>

        {/* פרטים */}
        <div style={{ background:'var(--ybp-panel)', borderRadius:10, border:'1px solid var(--ybp-border)', overflow:'hidden' }}>
          <div style={{ padding:'14px 16px', borderBottom:'1px solid var(--ybp-border-soft)', background:'var(--ybp-row-hover)' }}>
            <div style={{ fontSize:11, color:'var(--ybp-ink-soft)', fontWeight:700, textTransform:'uppercase', letterSpacing:0.5 }}>פרטי הצעה</div>
          </div>
          {[
            ['ספק', quote.supplier],
            ['איש קשר', quote.contact],
            ['טלפון', quote.phone],
            ['מחיר לתקציב (ללא מע"מ)', fmtMoney(quote.price)],
            ...(quote.vat_included !== false && quote.price ? [['כולל מע"מ', fmtMoney(addVat(quote.price))]] : []),
            ...(quote.validity ? [['תוקף הצעה', quote.validity]] : []),
            ['תנאי תשלום', quote.terms],
            ['אחריות', quote.warranty],
            ['הערות', quote.notes],
            ['תאריך', fmtDate(quote.created_at)],
          ].filter(([,v]) => v).map(([k,v]) => (
            <div key={k} style={{ padding:'10px 16px', borderBottom:'1px solid #f9fafb',
              display:'flex', gap:12, alignItems:'flex-start' }}>
              <div style={{ fontSize:12, color:'var(--ybp-ink-soft)', fontWeight:600, width:90, flexShrink:0 }}>{k}</div>
              <div style={{ fontSize:13, color:'var(--ybp-ink)', flex:1 }}>{v}</div>
            </div>
          ))}
        </div>

        {/* פירוט פריטים — מוצג תמיד אם יש items */}
        {quote.items && quote.items.length > 0 && (
          <div style={{ background:'var(--ybp-panel)', borderRadius:10, border:'1px solid var(--ybp-border)', overflow:'hidden' }}>
            <div style={{ padding:'12px 16px', borderBottom:'1px solid var(--ybp-border)', background:'var(--ybp-row-hover)',
              display:'flex', alignItems:'center', justifyContent:'space-between' }}>
              <div style={{ fontSize:11, color:'var(--ybp-ink-soft)', fontWeight:700, textTransform:'uppercase', letterSpacing:0.5 }}>
                📋 פירוט פריטים
              </div>
              <div style={{ fontSize:11, color:'var(--ybp-ink-faint)' }}>
                {quote.vat_included !== false ? 'כולל מע"מ' : 'ללא מע"מ'}
                {quote.validity ? ` · תוקף: ${quote.validity}` : ''}
              </div>
            </div>
            <div style={{ overflowX:'auto' }}>
              <table style={{ width:'100%', borderCollapse:'collapse', fontSize:12, minWidth:360 }}>
                <thead>
                  <tr style={{ background:'#f8fafc' }}>
                    <th style={{ padding:'8px 12px', textAlign:'right', fontWeight:600, color:'var(--ybp-ink-soft)', borderBottom:'1px solid var(--ybp-border)' }}>תיאור</th>
                    <th style={{ padding:'8px 10px', textAlign:'center', fontWeight:600, color:'var(--ybp-ink-soft)', borderBottom:'1px solid var(--ybp-border)', whiteSpace:'nowrap' }}>כמות</th>
                    <th style={{ padding:'8px 10px', textAlign:'center', fontWeight:600, color:'var(--ybp-ink-soft)', borderBottom:'1px solid var(--ybp-border)' }}>יחידה</th>
                    <th style={{ padding:'8px 10px', textAlign:'left', fontWeight:600, color:'var(--ybp-ink-soft)', borderBottom:'1px solid var(--ybp-border)', whiteSpace:'nowrap' }}>מחיר יח׳</th>
                    <th style={{ padding:'8px 12px', textAlign:'left', fontWeight:700, color:'var(--ybp-navy)', borderBottom:'1px solid var(--ybp-border)' }}>סה"כ</th>
                  </tr>
                </thead>
                <tbody>
                  {quote.items.map((item, i) => (
                    <tr key={i} style={{ borderBottom:'1px solid #f1f5f9' }}>
                      <td style={{ padding:'9px 12px', color:'var(--ybp-ink)' }}>{item.name}</td>
                      <td style={{ padding:'9px 10px', textAlign:'center', color:'var(--ybp-ink-soft)' }}>
                        {item.qty != null ? item.qty : <span style={{ color:'#d1d5db' }}>—</span>}
                      </td>
                      <td style={{ padding:'9px 10px', textAlign:'center', color:'var(--ybp-ink-soft)' }}>
                        {item.unit || <span style={{ color:'#d1d5db' }}>—</span>}
                      </td>
                      <td style={{ padding:'9px 10px', textAlign:'left', color:'var(--ybp-ink-soft)', fontSize:11 }}>
                        {item.unit_price ? Number(item.unit_price).toLocaleString('he-IL') + ' ₪' : <span style={{ color:'#d1d5db' }}>—</span>}
                      </td>
                      <td style={{ padding:'9px 12px', textAlign:'left', fontWeight:600, color:'var(--ybp-navy)' }}>
                        {item.total ? Number(item.total).toLocaleString('he-IL') + ' ₪'
                          : <span style={{ background:'#fef3c7', color:'#d97706', padding:'2px 6px', borderRadius:4, fontSize:11, fontWeight:600 }}>חסר מחיר</span>}
                      </td>
                    </tr>
                  ))}
                </tbody>
                <tfoot>
                  <tr style={{ background:'#f8fafc', borderTop:'2px solid var(--ybp-border)' }}>
                    <td colSpan={4} style={{ padding:'10px 12px', fontWeight:700, color:'var(--ybp-ink-soft)', textAlign:'right' }}>
                      סה"כ פריטים
                    </td>
                    <td style={{ padding:'10px 12px', fontWeight:800, color:'var(--ybp-navy)', fontSize:14, textAlign:'left' }}>
                      {Number(quote.items.reduce((s, it) => s + (+it.total || 0), 0)).toLocaleString('he-IL')} ₪
                    </td>
                  </tr>
                </tfoot>
              </table>
            </div>
          </div>
        )}

        {/* חתימה */}
        <div style={{ background:'var(--ybp-panel)', borderRadius:10, border:'1px solid var(--ybp-border)', padding:14 }}>
          <div style={{ fontSize:12, fontWeight:700, color:'var(--ybp-ink-soft)', marginBottom:10, textTransform:'uppercase', letterSpacing:0.5 }}>חתימה על ההצעה</div>
          {sigUrl
            ? <div style={{ display:'flex', alignItems:'center', gap:12 }}>
                <img src={sigUrl} style={{ height:50, maxWidth:160, objectFit:'contain', border:'1px solid var(--ybp-border)', borderRadius:6, background:'#fafafa' }}/>
                <div>
                  <div style={{ fontSize:12, color:'#16a34a', fontWeight:700 }}>✓ חתומה</div>
                  <button onClick={()=>setShowSigPad(true)} style={{ fontSize:11, color:'var(--ybp-ink-soft)', background:'none', border:'none', cursor:'pointer', padding:0, fontFamily:'inherit' }}>חתום מחדש</button>
                </div>
              </div>
            : <button onClick={()=>setShowSigPad(true)} style={{ width:'100%', padding:'10px', borderRadius:8,
                border:'2px dashed var(--ybp-border)', background:'#fafafa', color:'var(--ybp-ink-soft)', fontSize:13,
                fontWeight:600, cursor:'pointer', fontFamily:'inherit' }}>✍️ חתום על ההצעה</button>
          }
        </div>

        {/* פעולות סטטוס */}
        <div style={{ background:'var(--ybp-panel)', borderRadius:10, border:'1px solid var(--ybp-border)', padding:14 }}>
          <div style={{ fontSize:12, fontWeight:700, color:'var(--ybp-ink-soft)', marginBottom:10, textTransform:'uppercase', letterSpacing:0.5 }}>סטטוס</div>
          <div style={{ display:'flex', gap:8, flexWrap:'wrap' }}>
            {[['open','במרוץ','#f59e0b'],['closed','סגור / נבחר','#16a34a'],['rejected','דחה','#ef4444']].map(([k,label,col]) => {
              const active = quote.status === k;
              return (
                <button key={k} onClick={()=>onSetStatus(k)} disabled={active}
                  style={{ padding:'8px 14px', borderRadius:8,
                    border: active ? `2px solid ${col}` : '1px solid var(--ybp-border)',
                    background: active ? col : 'var(--ybp-panel)',
                    color: active ? '#fff' : col, fontSize:12, fontWeight:700,
                    cursor: active ? 'default' : 'pointer', fontFamily:'inherit' }}>
                  {label}{active ? ' ✓' : ''}
                </button>
              );
            })}
          </div>
          {quote.status === 'closed' && (
            <div style={{ fontSize:11, color:'#16a34a', marginTop:8, fontWeight:600 }}>
              ✓ הצעה זו נקבעה כעלות בפועל בשורת התקציב
            </div>
          )}
          {!quote.budget_line_id && (
            <div style={{ fontSize:11, color:'#dc2626', marginTop:8, fontWeight:600 }}>
              ⚠️ ההצעה לא משויכת לשורת תקציב — סטטוס לא משפיע על תקציב
            </div>
          )}
        </div>

        {/* שליחה / מחיקה */}
        <div style={{ display:'flex', gap:8 }}>
          <button onClick={()=>setShowSendMenu(v=>!v)} style={{ flex:1, padding:'11px', borderRadius:8,
            background:'var(--ybp-navy)', color:'#fff', border:'none', fontSize:13, fontWeight:700,
            cursor:'pointer', fontFamily:'inherit', position:'relative' }}>
            📤 שלח לספק
            {showSendMenu && (
              <div style={{ position:'absolute', bottom:'calc(100% + 8px)', right:0, background:'var(--ybp-panel)',
                borderRadius:10, boxShadow:'0 8px 32px rgba(0,0,0,0.15)', border:'1px solid var(--ybp-border)',
                minWidth:200, zIndex:100, overflow:'hidden', textAlign:'right' }}
                onClick={e=>e.stopPropagation()}>
                {[
                  ['💬 WhatsApp', ()=>{ const t=buildShareText(); window.open(`https://wa.me/${(quote.phone||'').replace(/\D/g,'')}?text=${encodeURIComponent(t)}`, '_blank'); setShowSendMenu(false); }],
                  ['✉️ Gmail',   ()=>{ window.open(`https://mail.google.com/mail/?view=cm&su=${encodeURIComponent('הצעת מחיר — '+(quote.supplier||''))}&body=${encodeURIComponent(buildShareText())}`, '_blank'); setShowSendMenu(false); }],
                ].map(([label, fn]) => (
                  <button key={label} onClick={fn} style={{ width:'100%', padding:'11px 14px', background:'transparent',
                    border:'none', cursor:'pointer', fontSize:14, fontFamily:'inherit', textAlign:'right',
                    color:'var(--ybp-ink)', borderBottom:'1px solid var(--ybp-border-soft)', display:'block' }}>{label}</button>
                ))}
              </div>
            )}
          </button>
          <button onClick={onDelete} style={{ padding:'11px 18px', borderRadius:8,
            background:'var(--ybp-panel)', color:'#dc2626', border:'1px solid #fecaca', fontSize:13,
            fontWeight:700, cursor:'pointer', fontFamily:'inherit' }}>🗑 מחק</button>
        </div>
      </div>
    </div>
  );
};

// ── DropZone — אזור גרירה + לחיצה ────────────────────────────────────────
const DropZone = ({ loading, onFile }) => {
  const [dragging, setDragging] = React.useState(false);
  const fileRef = React.useRef();

  const handleDrop = (e) => {
    e.preventDefault();
    setDragging(false);
    const file = e.dataTransfer.files?.[0];
    if (file) onFile(file);
  };

  const handleChange = (e) => {
    const file = e.target.files?.[0];
    if (file) onFile(file);
    e.target.value = '';
  };

  return (
    <div
      onDragOver={(e) => { e.preventDefault(); setDragging(true); }}
      onDragEnter={(e) => { e.preventDefault(); setDragging(true); }}
      onDragLeave={() => setDragging(false)}
      onDrop={handleDrop}
      onClick={() => !loading && fileRef.current?.click()}
      style={{
        border: `2px dashed ${dragging ? 'var(--ybp-navy)' : 'var(--ybp-border)'}`,
        borderRadius: 10,
        background: dragging ? 'rgba(59,130,246,0.06)' : 'transparent',
        padding: '18px 12px',
        textAlign: 'center',
        cursor: loading ? 'wait' : 'pointer',
        transition: 'all .15s',
      }}>
      <input ref={fileRef} type="file"
        accept=".pdf,.jpg,.jpeg,.png,.webp,.xlsx,.xls"
        style={{ display: 'none' }}
        onChange={handleChange}/>
      {loading ? (
        <div style={{ fontSize: 13, color: 'var(--ybp-ink-soft)' }}>⏳ מחלץ נתונים...</div>
      ) : dragging ? (
        <div>
          <div style={{ fontSize: 22, marginBottom: 4 }}>📂</div>
          <div style={{ fontSize: 13, fontWeight: 700, color: 'var(--ybp-navy)' }}>שחרר כאן</div>
        </div>
      ) : (
        <div>
          <div style={{ fontSize: 20, marginBottom: 6 }}>📂</div>
          <div style={{ fontSize: 13, fontWeight: 600, color: 'var(--ybp-ink-soft)' }}>
            גרור לכאן או <span style={{ color: 'var(--ybp-navy)', textDecoration: 'underline' }}>לחץ לבחירה</span>
          </div>
          <div style={{ fontSize: 10, color: 'var(--ybp-ink-faint)', marginTop: 5 }}>
            PDF · JPG · PNG · XLSX — עד 10MB
          </div>
        </div>
      )}
    </div>
  );
};

// ═══════════════════════════════════════════════════════════════════════════════
//  QuoteAIExtractor — חילוץ AI מקובץ או טקסט (שלב B)
// ═══════════════════════════════════════════════════════════════════════════════
const QuoteAIExtractor = ({ onExtracted }) => {
  const [mode, setMode]       = React.useState('file'); // 'file' | 'text'
  const [loading, setLoading] = React.useState(false);
  const [error, setError]     = React.useState('');
  const [pasteText, setPasteText] = React.useState('');
  const fileRef = React.useRef();

  const callEdge = async (payload) => {
    setLoading(true); setError('');
    try {
      const headers = { 'Content-Type': 'application/json' };
      // v76.8 — window.YBP_SUPABASE = { getClient } (Promise→client). קבל session דרך getClient; אופציונלי (verify_jwt off).
      try {
        const sbClient = (window.YBP_SUPABASE && window.YBP_SUPABASE.getClient)
          ? await window.YBP_SUPABASE.getClient()
          : (window._supabaseClient || null);
        const session = sbClient ? (await sbClient.auth.getSession()).data?.session : null;
        if (session?.access_token) headers['Authorization'] = 'Bearer ' + session.access_token;
      } catch (_) { /* auth אופציונלי — הפונקציה פרוסה עם verify_jwt off */ }

      const res = await fetch(EXTRACT_QUOTE_FN, {
        method: 'POST', headers, body: JSON.stringify(payload),
      });
      const data = await res.json();
      if (data.error) { setError('שגיאה: ' + data.error); return; }
      onExtracted(data);
      window.toastSuccess && window.toastSuccess('נתונים חולצו בהצלחה ✓');
    } catch (e) {
      setError('שגיאת רשת — נסה שוב');
    } finally { setLoading(false); }
  };

  const handleFile = async (e) => {
    const file = e.target.files?.[0];
    if (!file) return;
    setError('');

    // Excel — חלץ טקסט בדפדפן עם SheetJS
    if (file.name.match(/\.xlsx?$/i) && window.XLSX) {
      const ab = await file.arrayBuffer();
      const wb = window.XLSX.read(ab, { type: 'array' });
      let text = '';
      wb.SheetNames.forEach(name => {
        const ws = wb.Sheets[name];
        text += window.XLSX.utils.sheet_to_csv(ws) + '\n';
      });
      await callEdge({ text: text.slice(0, 8000) });
      return;
    }

    // PDF / תמונה — שלח כ-base64
    const allowed = ['application/pdf', 'image/jpeg', 'image/png', 'image/webp'];
    if (!allowed.includes(file.type)) {
      setError('פורמט לא נתמך. השתמש ב-PDF, JPG, PNG או XLSX.');
      return;
    }
    const reader = new FileReader();
    reader.onload = async (ev) => {
      const b64 = ev.target.result.split(',')[1];
      await callEdge({ file: b64, fileType: file.type });
    };
    reader.readAsDataURL(file);
  };

  const handleText = async () => {
    if (!pasteText.trim()) { setError('הדבק טקסט מהמסמך'); return; }
    await callEdge({ text: pasteText });
  };

  return (
    <div style={{ background: 'var(--ybp-row-hover)', border: '1px solid var(--ybp-border)',
      borderRadius: 8, padding: '12px 14px', marginBottom: 14 }}>
      {/* כותרת + toggle */}
      <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 10 }}>
        <div style={{ fontSize: 13, fontWeight: 700, color: 'var(--ybp-navy)', display: 'flex', alignItems: 'center', gap: 6 }}>
          <span>✦</span> חילוץ AI
        </div>
        <div style={{ display: 'flex', gap: 4 }}>
          {['file', 'text'].map(m => (
            <button key={m} onClick={() => { setMode(m); setError(''); }}
              style={{ padding: '3px 10px', borderRadius: 20, fontSize: 11, fontWeight: 600, cursor: 'pointer', fontFamily: 'inherit',
                background: mode === m ? 'var(--ybp-navy)' : 'transparent',
                color: mode === m ? '#fff' : 'var(--ybp-ink-soft)',
                border: `1px solid ${mode === m ? 'var(--ybp-navy)' : 'var(--ybp-border)'}` }}>
              {m === 'file' ? '📎 קובץ' : '📋 טקסט'}
            </button>
          ))}
        </div>
      </div>

      {mode === 'file' ? (
        <div>
          <input ref={fileRef} type="file" accept=".pdf,.jpg,.jpeg,.png,.webp,.xlsx,.xls"
            style={{ display: 'none' }} onChange={handleFile}/>
          <DropZone loading={loading} onFile={async (file) => {
            setError('');
            // Excel
            if (file.name.match(/\.xlsx?$/i) && window.XLSX) {
              const ab = await file.arrayBuffer();
              const wb = window.XLSX.read(ab, { type: 'array' });
              let text = '';
              wb.SheetNames.forEach(name => {
                text += window.XLSX.utils.sheet_to_csv(wb.Sheets[name]) + '\n';
              });
              await callEdge({ text: text.slice(0, 8000) });
              return;
            }
            // PDF / תמונה
            const allowed = ['application/pdf','image/jpeg','image/png','image/webp'];
            if (!allowed.includes(file.type)) {
              setError('פורמט לא נתמך. השתמש ב-PDF, JPG, PNG או XLSX.');
              return;
            }
            const reader = new FileReader();
            reader.onload = async (ev) => {
              const b64 = ev.target.result.split(',')[1];
              await callEdge({ file: b64, fileType: file.type });
            };
            reader.readAsDataURL(file);
          }}/>
        </div>
      ) : (
        <div>
          <textarea value={pasteText} onChange={e => setPasteText(e.target.value)}
            placeholder="הדבק כאן את טקסט ההצעה (מאימייל, מסמך וכד׳)..."
            rows={4} style={{ width: '100%', boxSizing: 'border-box', padding: '8px 10px', borderRadius: 7,
              border: '1px solid var(--ybp-border)', fontFamily: 'inherit', fontSize: 12,
              resize: 'vertical', background: 'var(--ybp-panel)', color: 'var(--ybp-ink)',
              direction: 'rtl' }}/>
          <button onClick={handleText} disabled={loading || !pasteText.trim()}
            style={{ width: '100%', marginTop: 6, padding: '9px', borderRadius: 7, border: 'none',
              background: pasteText.trim() ? 'var(--ybp-navy)' : 'var(--ybp-border)',
              color: pasteText.trim() ? '#fff' : 'var(--ybp-ink-soft)',
              cursor: loading ? 'wait' : 'pointer', fontSize: 12, fontWeight: 700, fontFamily: 'inherit' }}>
            {loading ? '⏳ מחלץ נתונים...' : '✦ חלץ נתונים'}
          </button>
        </div>
      )}

      {error && (
        <div style={{ marginTop: 8, padding: '6px 10px', background: '#fee2e2', borderRadius: 6,
          fontSize: 11, color: '#dc2626' }}>{error}</div>
      )}
    </div>
  );
};

// ── ייצוא השוואת הצעות ──────────────────────────────────────────────────────
const exportCompareExcel = (quotes, allNames) => {
  if (!window.XLSX) { window.toastError?.('XLSX לא זמין'); return; }
  const wb = window.XLSX.utils.book_new();

  const headers = ['פריט', ...quotes.map(q => q.supplier || 'ספק')];
  const rows = [headers];

  allNames.forEach(name => {
    const row = [name];
    quotes.forEach(q => {
      const it = (q.items || []).find(x => x.name === name);
      if (!it) row.push('לא צוין');
      else if (!it.total) row.push('חסר מחיר');
      else {
        let cell = Number(it.total).toLocaleString('he-IL') + ' ₪';
        if (it.qty && it.unit_price) cell += ` (${it.qty} ${it.unit || ''} × ${Number(it.unit_price).toLocaleString('he-IL')} ₪)`;
        row.push(cell);
      }
    });
    rows.push(row);
  });

  const totRow = ['סה"כ'];
  quotes.forEach(q => {
    const tot = q.price || (q.items || []).reduce((s, it) => s + (+it.total || 0), 0);
    const vatNote = q.vat_included !== false ? ' (כולל מע"מ)' : ' (ללא מע"מ)';
    totRow.push(tot ? Number(tot).toLocaleString('he-IL') + ' ₪' + vatNote : '—');
  });
  rows.push(totRow);
  rows.push([]);
  rows.push(['תנאי תשלום', ...quotes.map(q => q.terms || '—')]);
  rows.push(['אחריות',     ...quotes.map(q => q.warranty || '—')]);
  rows.push(['תוקף הצעה',  ...quotes.map(q => q.validity || '—')]);

  const ws = window.XLSX.utils.aoa_to_sheet(rows);
  ws['!cols'] = [{ wch: 30 }, ...quotes.map(() => ({ wch: 22 }))];
  window.XLSX.utils.book_append_sheet(wb, ws, 'השוואת הצעות');
  window.XLSX.writeFile(wb, `השוואת_הצעות_${new Date().toLocaleDateString('he-IL').replace(/\//g, '-')}.xlsx`);
  window.toastSuccess?.('קובץ Excel הורד ✓');
};

const exportComparePDF = (quotes, allNames, aiSummary) => {
  const vatLabel = (q) => q.vat_included !== false ? 'כולל מע"מ' : 'ללא מע"מ';
  const allTotals = quotes.map(q => q.price || (q.items || []).reduce((s, it) => s + (+it.total || 0), 0));
  const minTot = Math.min(...allTotals.filter(Boolean));

  const logoSrc = (window.YBP_DATA?.company?.logoFull) || 'assets/ybp-logo-new.png';
  const html = `<html dir="rtl"><head><meta charset="UTF-8"><style>
    body{font-family:Arial,sans-serif;font-size:11px;direction:rtl;margin:20px}
    .pdf-header{display:flex;align-items:center;justify-content:space-between;padding-bottom:8px;margin-bottom:14px;border-bottom:3px solid #b5a882}
    .pdf-header img{height:52px;object-fit:contain}
    .pdf-header-title{text-align:right;color:#1a2c4a}
    .pdf-header-title .main{font-size:14px;font-weight:800}
    .pdf-header-title .sub{font-size:10px;color:#6b7280;margin-top:2px}
    h2{color:#1a2c4a;font-size:14px;margin-bottom:16px}
    table{width:100%;border-collapse:collapse;margin-bottom:16px}
    th{background:#1a2c4a;color:#fff;padding:7px 10px;text-align:right;font-size:11px}
    td{padding:6px 10px;border-bottom:1px solid #e5e7eb;text-align:right}
    tr:nth-child(even){background:#f9fafb}
    .cheap{background:rgba(22,163,74,0.1)!important;font-weight:700;color:#16a34a}
    .missing{color:#d97706;font-style:italic}
    .absent{color:#9ca3af;font-style:italic}
    .total-row{background:#f3f4f6!important;font-weight:700;border-top:2px solid #1a2c4a}
    .meta{margin-top:12px;font-size:10px;color:#6b7280}
    @media print{body{margin:10mm}}
  </style></head><body>
    <div class="pdf-header">
      <div class="pdf-header-title">
        <div class="main">השוואת הצעות מחיר</div>
        <div class="sub">${new Date().toLocaleDateString('he-IL')}</div>
      </div>
      <img src="${logoSrc}" alt="YBP" />
    </div>
    <table>
      <thead><tr>
        <th style="min-width:140px">פריט</th>
        ${quotes.map(q => `<th style="min-width:130px">${q.supplier || 'ספק'}<br><span style="font-weight:400;font-size:10px">${vatLabel(q)}</span></th>`).join('')}
      </tr></thead>
      <tbody>
        ${allNames.map(name => {
          const rowItems = quotes.map(q => (q.items || []).find(it => it.name === name));
          const validTots = rowItems.map(it => it?.total).filter(Boolean);
          const minItem = validTots.length ? Math.min(...validTots) : null;
          return `<tr><td>${name}</td>${rowItems.map(it => {
            if (!it) return `<td class="absent">לא צוין</td>`;
            if (!it.total) return `<td class="missing">חסר מחיר</td>`;
            const cheap = it.total === minItem && validTots.length > 1;
            const detail = it.qty && it.unit_price ? `<br><span style="font-size:9px;color:#6b7280">${it.qty} ${it.unit || ''} × ${Number(it.unit_price).toLocaleString('he-IL')}₪</span>` : '';
            return `<td${cheap ? ' class="cheap"' : ''}>${Number(it.total).toLocaleString('he-IL')} ₪${detail}${cheap ? ' ✓' : ''}</td>`;
          }).join('')}</tr>`;
        }).join('')}
        <tr class="total-row"><td>סה"כ</td>${quotes.map((q, i) => {
          const tot = allTotals[i];
          const cheapest = tot && tot === minTot;
          return `<td${cheapest ? ' class="cheap"' : ''}>${tot ? Number(tot).toLocaleString('he-IL') + ' ₪' : '—'}${cheapest ? ' ✓ הזול' : ''}</td>`;
        }).join('')}</tr>
      </tbody>
    </table>
    <div class="meta">${quotes.map(q => `<div><strong>${q.supplier || 'ספק'}:</strong> תנאים: ${q.terms || '—'} · אחריות: ${q.warranty || '—'} · תוקף: ${q.validity || '—'}</div>`).join('')}</div>
    ${aiSummary ? `
    <div style="margin-top:18px;padding:12px 14px;border-radius:6px;border:1px solid #c7d2fe;background:#f5f3ff;direction:rtl">
      <div style="font-size:11px;font-weight:700;color:#4338ca;margin-bottom:8px">🤖 ניתוח AI</div>
      <div style="font-size:11px;color:#1e1b4b;line-height:1.7;white-space:pre-wrap">${aiSummary}</div>
    </div>` : ''}
  </body></html>`;

  const w = window.open('', '_blank');
  if (!w) { window.toastError?.('אפשר חלונות פופ-אפ בדפדפן'); return; }
  w.document.write(html);
  w.document.close();
  w.focus();
  setTimeout(() => w.print(), 300);
};

// ═══════════════════════════════════════════════════════════════════════════════
//  QuoteItemsCompare — טבלת השוואה צד-לצד בין הצעות
// ═══════════════════════════════════════════════════════════════════════════════
const QuoteItemsCompare = ({ quotes }) => {
  const [open, setOpen] = React.useState(false);
  const [aiAnalysis, setAiAnalysis]   = React.useState('');
  const [aiLoading, setAiLoading]     = React.useState(false);
  const [aiOpen, setAiOpen]           = React.useState(false);
  const [aiContext, setAiContext]     = React.useState('');
  const [showContext, setShowContext] = React.useState(false);
  const [aiFollowUp, setAiFollowUp]   = React.useState('');
  const [aiChatLoading, setAiChatLoading] = React.useState(false);
  if (!quotes || quotes.length < 2) return null;

  const quotesWithItems = quotes.filter(q => q.items && q.items.length > 0);
  if (quotesWithItems.length < 2) return null;

  // כל שמות הפריטים מכל ההצעות (ייחודיים, שמירת סדר)
  const allNames = [...new Map(
    quotesWithItems.flatMap(q => q.items.map(it => [it.name, it.name]))
  ).keys()];

  // חישוב התרעות אי-התאמה
  const warnings = [];
  allNames.forEach(name => {
    const present = quotesWithItems.filter(q => q.items.some(it => it.name === name));
    const missing = quotesWithItems.filter(q => !q.items.some(it => it.name === name));
    const noPrice = quotesWithItems.filter(q => {
      const it = q.items.find(x => x.name === name);
      return it && !it.total;
    });
    if (missing.length > 0) {
      warnings.push(`⚠️ "${name}" — לא צוין אצל: ${missing.map(q => q.supplier || 'ספק').join(', ')}`);
    }
    if (noPrice.length > 0) {
      warnings.push(`🔴 "${name}" — חסר מחיר אצל: ${noPrice.map(q => q.supplier || 'ספק').join(', ')}`);
    }
  });

  // v77 — בדוק אי-עקביות מע"מ (חלק כולל / חלק ללא)
  const vatMix = quotesWithItems.filter(q => q.vat_included !== false).length > 0
              && quotesWithItems.filter(q => q.vat_included === false).length > 0;
  if (vatMix) {
    warnings.unshift('⚠️ השוואה מעורבת: חלק מההצעות כולל מע"מ וחלק ללא — כל המחירים בטבלה הם ללא מע"מ (נטו)');
  }

  const runAiAnalysis = async () => {
    setAiLoading(true);
    setAiOpen(true);
    setAiAnalysis('');
    try {
      // בנה תקציר ההצעות לשליחה ל-AI
      const summary = quotesWithItems.map(q => {
        const tot = q.price || (q.items||[]).reduce((s,it) => s+(+it.total||0), 0);
        const vatNote = q.vat_included !== false ? 'כולל מע"מ' : 'ללא מע"מ';
        const itemsText = (q.items||[]).map(it =>
          `  - ${it.name}: ${it.total ? Number(it.total).toLocaleString('he-IL') + ' ₪' : 'חסר מחיר'}${it.qty ? ` (${it.qty} ${it.unit||''})` : ''}`
        ).join('\n');
        return `ספק: ${q.supplier || 'לא ידוע'}
סה"כ: ${tot ? Number(tot).toLocaleString('he-IL') + ' ₪ ' + vatNote : 'לא צוין'}
תנאי תשלום: ${q.terms || 'לא צוין'}
אחריות: ${q.warranty || 'לא צוין'}
תוקף: ${q.validity || 'לא צוין'}
פריטים:\n${itemsText || '  (אין פירוט)'}`;
      }).join('\n\n---\n\n');

      const prompt = `אתה יועץ רכש לפרויקטי בנייה. נתח את הצעות המחיר הבאות והצג ניתוח קצר ומעשי בעברית.

הצעות המחיר:
${summary}
${aiContext.trim() ? `\nהקשר נוסף מהמשתמש: ${aiContext.trim()}` : ''}

חשוב: הספקים לא תמיד מנסחים פריטים אותו הדבר. "ריצוף" ו"עבודות ריצוף קרמיקה" עשויים להיות אותו פריט. "אינסטלציה" ו"עבודות צנרת" — כנראה אותו דבר. השתמש בהבנת שפה טבעית כדי לזהות פריטים זהים בניסוח שונה.

הצג:
1. **מי הכי זול** — הפרש מחיר בין ההצעות (בש"ח ובאחוזים). אם יש מע"מ לא אחיד — השווה נטו.
2. **פריטים זהים בניסוח שונה** — אם ספקים ניסחו אותו פריט אחרת, ציין זאת ועשה השוואת מחיר בין הניסוחים.
3. **פריטים חסרים באמת** — פריטים שספק אחד לא כלל כלל (לא רק ניסוח שונה).
4. **דגלים אדומים** — תנאי תשלום לא סבירים, אחריות קצרה מדי, מחיר נמוך חשוד שעשוי להסתיר חריגות.
5. **המלצה** — איזה ספק מומלץ ולמה (שקלל מחיר, תנאים, אחריות, שלמות ההצעה).

תשובה ממוקדת ומעשית בעברית.`;

      const res = await fetch(AI_CHAT_FN, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ messages: [{ role: 'user', content: prompt }] }),
      });
      const data = await res.json();
      setAiAnalysis(data.reply || 'לא התקבלה תשובה.');
    } catch (e) {
      setAiAnalysis('שגיאה בחיבור ל-AI. נסה שוב.');
    }
    setAiLoading(false);
  };

  const sendFollowUp = async () => {
    const q = aiFollowUp.trim();
    if (!q || aiChatLoading || !aiAnalysis) return;
    setAiChatLoading(true);
    setAiFollowUp('');
    try {
      const res = await fetch(AI_CHAT_FN, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          messages: [
            { role: 'user', content: `הניתוח הנוכחי:\n${aiAnalysis}\n\nשאלה: ${q}` }
          ],
        }),
      });
      const data = await res.json();
      if (data.reply) setAiAnalysis(prev => prev + '\n\n---\n' + data.reply);
    } catch (e) {
      setAiAnalysis(prev => prev + '\n\n[שגיאה בחיבור]');
    }
    setAiChatLoading(false);
  };

  return (
    <div style={{ marginBottom:12 }}>
      {/* שדה הקשר לניתוח */}
      <div style={{ marginBottom:6 }}>
        <button onClick={() => setShowContext(c => !c)}
          style={{ background:'none', border:'none', padding:'2px 0', cursor:'pointer',
            fontSize:11.5, color:'#6b7280', fontFamily:'inherit', textDecoration:'underline',
            textDecorationStyle:'dotted' }}>
          {showContext ? '▲ הסתר הקשר' : '▼ הוסף הקשר לניתוח (אופציונלי)'}
        </button>
        {showContext && (
          <textarea
            value={aiContext}
            onChange={e => setAiContext(e.target.value)}
            placeholder='לדוגמה: "פרויקט מסעדה, תקציב מוגבל, חשוב לנו אחריות ארוכה ותנאי תשלום נוחים"'
            rows={2}
            style={{ display:'block', width:'100%', marginTop:4, padding:'7px 10px',
              borderRadius:7, border:'1px solid #e5e7eb', fontSize:12,
              fontFamily:'inherit', direction:'rtl', resize:'vertical',
              boxSizing:'border-box', color:'#374151' }}
          />
        )}
      </div>

      {/* כפתור ניתוח AI */}
      <button onClick={runAiAnalysis} disabled={aiLoading}
        style={{ width:'100%', marginBottom:6, padding:'9px 14px', borderRadius:7,
          border:'1px solid #c7d2fe', background: aiLoading ? '#e0e7ff' : '#eef2ff',
          color:'#4338ca', cursor: aiLoading ? 'default' : 'pointer', fontSize:13,
          fontWeight:600, fontFamily:'inherit', display:'flex', alignItems:'center',
          justifyContent:'center', gap:6 }}>
        {aiLoading ? '🤖 מנתח...' : '🤖 ניתוח AI — מי הכי משתלם?'}
      </button>

      {/* פאנל תוצאת ניתוח */}
      {aiOpen && (
        <div style={{ marginBottom:10, padding:'12px 14px', borderRadius:8,
          border:'1px solid #c7d2fe', background:'#f5f3ff', direction:'rtl' }}>
          <div style={{ display:'flex', justifyContent:'space-between', alignItems:'center', marginBottom:8 }}>
            <span style={{ fontSize:12, fontWeight:700, color:'#4338ca' }}>🤖 ניתוח AI</span>
            <button onClick={() => setAiOpen(false)}
              style={{ background:'none', border:'none', cursor:'pointer', fontSize:14, color:'#6b7280' }}>×</button>
          </div>
          {aiLoading ? (
            <div style={{ fontSize:12, color:'#6b7280', textAlign:'center', padding:'8px 0' }}>
              מנתח את ההצעות...
            </div>
          ) : (
            <textarea
              value={aiAnalysis}
              onChange={e => setAiAnalysis(e.target.value)}
              rows={Math.max(6, (aiAnalysis.match(/\n/g)||[]).length + 2)}
              style={{
                width:'100%', fontSize:12.5, color:'#1e1b4b', lineHeight:1.7,
                border:'1px solid #c7d2fe', borderRadius:6, padding:'8px',
                fontFamily:'Assistant, Arial, sans-serif', direction:'rtl',
                resize:'vertical', background:'#faf9ff', boxSizing:'border-box',
              }}
            />
          )}
          {/* שדה שיחת המשך */}
          <div style={{ display:'flex', gap:6, marginTop:8 }}>
            <input
              value={aiFollowUp}
              onChange={e => setAiFollowUp(e.target.value)}
              onKeyDown={e => e.key === 'Enter' && sendFollowUp()}
              placeholder='שאל שאלה נוספת... (לדוגמה: "תתמקד באחריות")'
              disabled={aiChatLoading || !aiAnalysis}
              style={{
                flex:1, padding:'7px 10px', borderRadius:7,
                border:'1px solid #c7d2fe', fontSize:12, fontFamily:'inherit',
                direction:'rtl', background: aiAnalysis ? '#fff' : '#f5f3ff',
              }}
            />
            <button
              onClick={sendFollowUp}
              disabled={!aiFollowUp.trim() || aiChatLoading || !aiAnalysis}
              style={{
                background:'#4338ca', color:'#fff', border:'none',
                borderRadius:7, padding:'7px 12px', cursor:'pointer',
                fontSize:13, opacity: (!aiFollowUp.trim() || aiChatLoading || !aiAnalysis) ? 0.4 : 1,
              }}>
              {aiChatLoading ? '...' : '↑'}
            </button>
          </div>
        </div>
      )}

      <div style={{ display:'flex', gap:6, marginBottom:6 }}>
        <button onClick={() => exportCompareExcel(quotesWithItems, allNames)}
          style={{ flex:1, padding:'7px', borderRadius:7, border:'1px solid #e5e7eb',
            background:'#f0fdf4', color:'#16a34a', cursor:'pointer', fontSize:12,
            fontWeight:600, fontFamily:'inherit', display:'flex', alignItems:'center',
            justifyContent:'center', gap:4 }}>
          📊 Excel
        </button>
        <button onClick={() => exportComparePDF(quotesWithItems, allNames, aiAnalysis)}
          style={{ flex:1, padding:'7px', borderRadius:7, border:'1px solid #e5e7eb',
            background:'#eff6ff', color:'#2563eb', cursor:'pointer', fontSize:12,
            fontWeight:600, fontFamily:'inherit', display:'flex', alignItems:'center',
            justifyContent:'center', gap:4 }}>
          📄 PDF
        </button>
      </div>
      <button onClick={() => setOpen(o => !o)}
        style={{ width:'100%', padding:'9px 14px', borderRadius:7,
          border:'1px solid var(--ybp-border)',
          background: open ? 'var(--ybp-navy)' : 'var(--ybp-row-hover)',
          color: open ? '#fff' : 'var(--ybp-ink)', cursor:'pointer', fontFamily:'inherit',
          fontSize:12, fontWeight:700, display:'flex', alignItems:'center', justifyContent:'center', gap:6 }}>
        📊 {open ? 'סגור השוואה' : `השוואת פירוט — ${quotesWithItems.length} הצעות`}
        {warnings.length > 0 && !open && (
          <span style={{ background:'#fef3c7', color:'#d97706', borderRadius:10, padding:'1px 8px', fontSize:10, fontWeight:700 }}>
            {warnings.length} אי-התאמות
          </span>
        )}
      </button>

      {open && (
        <div style={{ marginTop:8, display:'flex', flexDirection:'column', gap:8 }}>

          {/* התרעות אי-התאמה */}
          {warnings.length > 0 && (
            <div style={{ border:'1px solid #fde68a', borderRadius:8, background:'#fffbeb', padding:'10px 14px' }}>
              <div style={{ fontSize:12, fontWeight:700, color:'#92400e', marginBottom:6 }}>
                ⚠️ אי-התאמות בין ההצעות ({warnings.length})
              </div>
              {warnings.map((w, i) => (
                <div key={i} style={{ fontSize:11, color:'#78350f', padding:'3px 0', borderTop: i > 0 ? '1px solid #fde68a' : 'none' }}>
                  {w}
                </div>
              ))}
            </div>
          )}

          {/* טבלת השוואה */}
          <div style={{ border:'1px solid var(--ybp-border)', borderRadius:8, overflow:'auto' }}>
            <table style={{ width:'100%', borderCollapse:'collapse', fontSize:11, minWidth: quotesWithItems.length * 170 + 160 }}>
              <thead>
                <tr style={{ background:'var(--ybp-row-hover)' }}>
                  <th style={{ padding:'9px 12px', textAlign:'right', fontWeight:700,
                    color:'var(--ybp-ink-soft)', minWidth:150, position:'sticky', right:0,
                    background:'var(--ybp-row-hover)', zIndex:2, borderBottom:'2px solid var(--ybp-border)' }}>
                    פריט
                  </th>
                  {quotesWithItems.map((q, i) => (
                    <th key={i} style={{ padding:'9px 12px', textAlign:'center', fontWeight:700,
                      color:'var(--ybp-navy)', minWidth:155, borderBottom:'2px solid var(--ybp-border)' }}>
                      <div>{q.supplier || `הצעה ${i+1}`}</div>
                      <div style={{ fontSize:10, fontWeight:400, color:'var(--ybp-ink-soft)' }}>
                        {q.vat_included !== false ? 'כולל מע"מ' : 'ללא מע"מ'}
                        {q.validity ? ` · ${q.validity}` : ''}
                      </div>
                    </th>
                  ))}
                </tr>
              </thead>
              <tbody>
                {allNames.map((name, ri) => {
                  const rowItems = quotesWithItems.map(q => (q.items || []).find(it => it.name === name));
                  const validTotals = rowItems.map(it => it?.total).filter(v => v && v > 0);
                  const minTotal = validTotals.length ? Math.min(...validTotals) : null;

                  return (
                    <tr key={ri} style={{ borderBottom:'1px solid var(--ybp-border)' }}>
                      {/* שם פריט */}
                      <td style={{ padding:'8px 12px', color:'var(--ybp-ink)', fontWeight:500,
                        position:'sticky', right:0, background:'var(--ybp-panel)', zIndex:1 }}>
                        {name}
                      </td>
                      {rowItems.map((it, ci) => {
                        // קבע צבע תא
                        const isCheap  = it?.total && it.total === minTotal && validTotals.length > 1;
                        const noPrice  = it && !it.total;
                        const absent   = !it;
                        const bg = isCheap ? 'rgba(22,163,74,0.08)'
                                 : noPrice  ? 'rgba(251,191,36,0.12)'
                                 : absent   ? 'rgba(209,213,219,0.15)'
                                 : 'transparent';

                        return (
                          <td key={ci} style={{ padding:'8px 10px', textAlign:'center', background: bg }}>
                            {absent ? (
                              <span style={{ fontSize:10, color:'#9ca3af', fontStyle:'italic' }}>לא צוין</span>
                            ) : noPrice ? (
                              <span style={{ background:'#fef3c7', color:'#d97706', padding:'2px 7px',
                                borderRadius:4, fontSize:10, fontWeight:700 }}>חסר מחיר</span>
                            ) : (
                              <div>
                                <div style={{ fontWeight: isCheap ? 700 : 400, color: isCheap ? '#16a34a' : 'var(--ybp-ink)' }}>
                                  {Number(it.total).toLocaleString('he-IL')} ₪
                                  {isCheap && <span style={{ marginRight:4, fontSize:10 }}>✓</span>}
                                </div>
                                {it.qty && it.unit_price && (
                                  <div style={{ fontSize:10, color:'var(--ybp-ink-faint)' }}>
                                    {it.qty} {it.unit} × {Number(it.unit_price).toLocaleString('he-IL')} ₪
                                  </div>
                                )}
                              </div>
                            )}
                          </td>
                        );
                      })}
                    </tr>
                  );
                })}
              </tbody>
              {/* שורת סכום */}
              <tfoot>
                <tr style={{ borderTop:'2px solid var(--ybp-border)', background:'var(--ybp-row-hover)' }}>
                  <td style={{ padding:'10px 12px', fontWeight:700, color:'var(--ybp-ink)',
                    position:'sticky', right:0, background:'var(--ybp-row-hover)', zIndex:1 }}>
                    סה"כ
                  </td>
                  {quotesWithItems.map((q, i) => {
                    const tot = q.price || (q.items||[]).reduce((s,it)=>s+(+it.total||0),0);
                    const allTots = quotesWithItems.map(x => x.price || (x.items||[]).reduce((s,it)=>s+(+it.total||0),0));
                    const isCheapest = tot > 0 && tot === Math.min(...allTots.filter(Boolean));
                    return (
                      <td key={i} style={{ padding:'10px 12px', textAlign:'center',
                        fontWeight:800, fontSize:13,
                        color: isCheapest ? '#16a34a' : 'var(--ybp-navy)',
                        background: isCheapest ? 'rgba(22,163,74,0.1)' : 'transparent' }}>
                        {tot ? Number(tot).toLocaleString('he-IL') + ' ₪' : '—'}
                        {isCheapest && <div style={{ fontSize:10, fontWeight:600 }}>✓ הזול ביותר</div>}
                        {/* v77 — כולל/ללא מע"מ */}
                        <div style={{ fontSize:10, color:'var(--ybp-ink-soft)', marginTop:2, fontWeight:400 }}>
                          {q.vat_included !== false
                            ? `+מע"מ: ${Number(addVat(tot)).toLocaleString('he-IL')} ₪`
                            : 'ללא מע"מ'}
                        </div>
                      </td>
                    );
                  })}
                </tr>
              </tfoot>
            </table>
          </div>

          {/* מקרא */}
          <div style={{ display:'flex', gap:12, flexWrap:'wrap', fontSize:10, color:'var(--ybp-ink-soft)' }}>
            <span style={{ display:'flex', alignItems:'center', gap:4 }}>
              <span style={{ width:12, height:12, borderRadius:2, background:'rgba(22,163,74,0.15)', display:'inline-block' }}/>
              המחיר הנמוך
            </span>
            <span style={{ display:'flex', alignItems:'center', gap:4 }}>
              <span style={{ width:12, height:12, borderRadius:2, background:'rgba(251,191,36,0.2)', display:'inline-block' }}/>
              חסר מחיר
            </span>
            <span style={{ display:'flex', alignItems:'center', gap:4 }}>
              <span style={{ width:12, height:12, borderRadius:2, background:'rgba(209,213,219,0.3)', display:'inline-block' }}/>
              לא צוין בהצעה
            </span>
          </div>

        </div>
      )}
    </div>
  );
};

// ═══════════════════════════════════════════════════════════════════════════════
//  QuoteFormModal — טופס יצירה / עריכה (ידני בלבד; AI = שלב B)
// ═══════════════════════════════════════════════════════════════════════════════
const QuoteFormModal = ({ mode='create', projectId, budgetLines, reloadBudgetLines, initial, onClose, onSave }) => {
  const [form, setForm] = useState(() => initial ? {
    supplier:       initial.supplier || '',
    contact:        initial.contact  || '',
    phone:          initial.phone    || '',
    price:          initial.price    || '',
    _priceGross:    '',
    terms:          initial.terms    || '',
    warranty:       initial.warranty || '',
    notes:          initial.notes    || '',
    validity:       initial.validity || '',
    vat_included:   initial.vat_included !== false,
    items:          Array.isArray(initial.items) ? initial.items : [],
    budget_line_id: initial.budget_line_id || '',
    category:       initial.category || '',
    status:         initial.status   || 'open',
  } : {
    supplier:'', contact:'', phone:'', price:'', _priceGross:'', terms:'', warranty:'', notes:'',
    validity:'', vat_included: true, items:[],
    budget_line_id:'', category:'', status:'open',
  });

  const set = (k, v) => setForm(f => ({ ...f, [k]: v }));

  // קיבוץ שורות תקציב לפי קטגוריה לטובת optgroup
  const groupedLines = useMemo(() => {
    const g = {};
    budgetLines.forEach(l => {
      const cat = l.category || '(ללא קטגוריה)';
      if (!g[cat]) g[cat] = [];
      g[cat].push(l);
    });
    return g;
  }, [budgetLines]);

  const handleLineChange = (lineId) => {
    const l = budgetLines.find(x => x.id === lineId);
    set('budget_line_id', lineId);
    set('category', l?.category || '');
  };

  // v3.9.0.45 — מצב "שורה חדשה" inline (בלי לצאת מהמודאל)
  const [newLineMode, setNewLineMode] = useState(false);
  const [newLineForm, setNewLineForm] = useState({ category:'', newCategory:'', name:'' });
  const [creatingLine, setCreatingLine] = useState(false);

  const handleCreateLine = async () => {
    const cat = newLineForm.category === '__new__' ? newLineForm.newCategory.trim() : newLineForm.category;
    const nm  = newLineForm.name.trim();
    if (!cat) { alert('חובה: קטגוריה'); return; }
    if (!nm)  { alert('חובה: שם השורה'); return; }
    if (!window.BudgetStore) { alert('BudgetStore לא זמין'); return; }
    setCreatingLine(true);
    try {
      const newLine = await window.BudgetStore.addLine(projectId, { category: cat, name: nm });
      if (reloadBudgetLines) await reloadBudgetLines();
      set('budget_line_id', newLine.id);
      set('category', cat);
      setNewLineMode(false);
      setNewLineForm({ category:'', newCategory:'', name:'' });
    } catch (e) {
      alert('שגיאה ביצירת שורה: ' + (e?.message || e));
    } finally { setCreatingLine(false); }
  };

  const handleSave = () => {
    if (!form.supplier.trim()) { alert('חובה: שם ספק'); return; }
    if (!form.budget_line_id)  { alert('חובה: שיוך לשורת תקציב — מנהל הפרויקט מאשר את התחום'); return; }
    const out = {
      ...form,
      price: Number(String(form.price).replace(/[^0-9.]/g, '')) || 0,
      items: form.items || [],
      validity: form.validity || '',
      vat_included: form.vat_included !== false,
    };
    onSave(out);
  };

  return (
    <div style={{ position:'fixed', inset:0, background:'rgba(0,0,0,0.5)', zIndex:500,
      display:'flex', alignItems:'flex-end', justifyContent:'center' }} onClick={onClose}>
      <div style={{ background:'var(--ybp-panel)', borderRadius:'16px 16px 0 0', width:'100%', maxWidth:480,
        maxHeight:'92vh', overflowY:'auto', padding:'20px 16px 32px' }} onClick={e=>e.stopPropagation()}>

        <div style={{ display:'flex', alignItems:'center', justifyContent:'space-between', marginBottom:16 }}>
          <div style={{ fontSize:16, fontWeight:700, color:'var(--ybp-ink)' }}>
            {mode === 'create' ? 'הוסף הצעת מחיר' : 'ערוך הצעת מחיר'}
          </div>
          <button onClick={onClose} style={{ background:'none', border:'none', fontSize:20, cursor:'pointer', color:'var(--ybp-ink-soft)' }}>×</button>
        </div>

        <QuoteAIExtractor onExtracted={(data) => {
          if (data.supplier)  set('supplier',  data.supplier);
          if (data.contact)   set('contact',   data.contact);
          if (data.phone)     set('phone',     data.phone);
          // המחיר שנשמר הוא תמיד ללא מע"מ (נטו) — בסיס לתקציב
          if (data.price) {
            const netPrice = (data.vat_included !== false)
              ? removeVat(data.price)   // חולץ "כולל מע"מ" → הסר מע"מ
              : data.price;             // כבר ללא מע"מ
            set('price', String(netPrice));
            set('_priceGross', String(data.price)); // שמור גם את הברוטו להצגה
          }
          if (data.terms)     set('terms',     data.terms);
          if (data.warranty)  set('warranty',  data.warranty);
          if (data.notes)     set('notes',     data.notes);
          if (data.validity)  set('validity',  data.validity);
          if (data.vat_included !== undefined) set('vat_included', data.vat_included);
          if (Array.isArray(data.items) && data.items.length > 0) set('items', data.items);
        }}/>

        <div style={{ display:'flex', flexDirection:'column', gap:10 }}>

          {/* שורת תקציב — קודם, הכי חשוב */}
          <div>
            <label style={{ fontSize:12, fontWeight:700, color:'var(--ybp-ink-soft)', display:'block', marginBottom:4 }}>
              שיוך לשורת תקציב <span style={{ color:'#dc2626' }}>*</span>
            </label>
            <select value={newLineMode ? '__new_line__' : form.budget_line_id}
              onChange={e => {
                if (e.target.value === '__new_line__') {
                  setNewLineMode(true);
                  set('budget_line_id', '');
                  set('category', '');
                } else {
                  setNewLineMode(false);
                  handleLineChange(e.target.value);
                }
              }}
              style={{ width:'100%', padding:'9px 10px', borderRadius:8,
                border:`1px solid ${(form.budget_line_id || newLineMode) ? 'var(--ybp-border)' : '#fca5a5'}`,
                fontFamily:'inherit', fontSize:13, direction:'rtl', background:'var(--ybp-panel)' }}>
              <option value="">— בחר שורת תקציב —</option>
              {Object.entries(groupedLines).map(([cat, lines]) => (
                <optgroup key={cat} label={cat}>
                  {lines.map(l => (
                    <option key={l.id} value={l.id}>
                      {l.name || '(ללא שם)'}{l.supplier ? ` · ${l.supplier}` : ''}
                    </option>
                  ))}
                </optgroup>
              ))}
              <option value="__new_line__">➕ הוסף שורת תקציב חדשה…</option>
            </select>
            <div style={{ fontSize:10, color:'var(--ybp-ink-faint)', marginTop:4 }}>
              מנהל הפרויקט מאשר את התחום. אם השורה לא קיימת — בחר '➕ הוסף שורת תקציב חדשה'.
            </div>

            {/* v3.9.0.45 — טופס-מיני ליצירת שורת תקציב inline */}
            {newLineMode && (
              <div style={{ marginTop:10, padding:12, background:'#f8fafc', border:'1px dashed #c7d2fe', borderRadius:8 }}>
                <div style={{ fontSize:12, fontWeight:700, marginBottom:8, color:'var(--ybp-ink-soft)' }}>שורת תקציב חדשה</div>
                <div style={{ display:'flex', flexDirection:'column', gap:8 }}>
                  <select value={newLineForm.category}
                    onChange={e => setNewLineForm(f => ({ ...f, category: e.target.value,
                      newCategory: e.target.value === '__new__' ? '' : f.newCategory }))}
                    style={{ padding:'7px 9px', borderRadius:6, border:'1px solid var(--ybp-border)',
                      fontSize:12, fontFamily:'inherit', direction:'rtl', background:'var(--ybp-panel)' }}>
                    <option value="">— בחר קטגוריה —</option>
                    {Object.keys(groupedLines).map(c => <option key={c} value={c}>{c}</option>)}
                    <option value="__new__">➕ קטגוריה חדשה…</option>
                  </select>
                  {newLineForm.category === '__new__' && (
                    <input value={newLineForm.newCategory}
                      onChange={e => setNewLineForm(f => ({ ...f, newCategory: e.target.value }))}
                      placeholder="שם הקטגוריה החדשה"
                      style={{ padding:'7px 9px', borderRadius:6, border:'1px solid var(--ybp-border)',
                        fontSize:12, fontFamily:'inherit', direction:'rtl' }}/>
                  )}
                  <input value={newLineForm.name}
                    onChange={e => setNewLineForm(f => ({ ...f, name: e.target.value }))}
                    placeholder="שם השורה (חובה)"
                    style={{ padding:'7px 9px', borderRadius:6, border:'1px solid var(--ybp-border)',
                      fontSize:12, fontFamily:'inherit', direction:'rtl' }}/>
                  <div style={{ display:'flex', gap:6, justifyContent:'flex-end' }}>
                    <button onClick={() => { setNewLineMode(false); setNewLineForm({ category:'', newCategory:'', name:'' }); }}
                      disabled={creatingLine}
                      style={{ padding:'6px 12px', borderRadius:6, border:'1px solid var(--ybp-border)',
                        background:'var(--ybp-panel)', fontSize:12, fontFamily:'inherit', cursor:'pointer' }}>
                      ביטול
                    </button>
                    <button onClick={handleCreateLine} disabled={creatingLine}
                      style={{ padding:'6px 14px', borderRadius:6, border:'none',
                        background: creatingLine ? 'var(--ybp-ink-faint)' : 'var(--ybp-navy)', color:'#fff',
                        fontSize:12, fontWeight:700, fontFamily:'inherit',
                        cursor: creatingLine ? 'wait' : 'pointer' }}>
                      {creatingLine ? 'יוצר…' : 'צור ושייך'}
                    </button>
                  </div>
                </div>
              </div>
            )}
          </div>

          {[
            ['supplier','שם ספק *','text'],
            ['contact','איש קשר','text'],
            ['phone','טלפון','tel'],
            ['price','מחיר ₪','number'],
            ['terms','תנאי תשלום','text'],
            ['warranty','אחריות','text'],
            ['notes','הערות','text'],
          ].map(([k, label, type]) => (
            <div key={k}>
              <label style={{ fontSize:12, fontWeight:700, color:'var(--ybp-ink-soft)', display:'block', marginBottom:4 }}>{label}</label>
              <input type={type} value={form[k]} onChange={e => set(k, e.target.value)}
                style={{ width:'100%', padding:'9px 10px', borderRadius:8, border:'1px solid var(--ybp-border)',
                  fontFamily:'inherit', fontSize:13, direction:'rtl', boxSizing:'border-box' }}/>
              {/* v77 — הצגת מחיר נטו+ברוטו מתחת לשדה המחיר */}
              {k === 'price' && form.vat_included !== false && form._priceGross && (
                <div style={{ marginTop:4, fontSize:11, color:'var(--ybp-ink-soft)', display:'flex', gap:12 }}>
                  <span>כולל מע"מ: <strong>{fmtVat(form._priceGross)}</strong></span>
                  <span style={{ color:'#16a34a' }}>ללא מע"מ (לתקציב): <strong>{fmtVat(form.price)}</strong></span>
                </div>
              )}
              {k === 'price' && form.vat_included === false && form.price && (
                <div style={{ marginTop:4, fontSize:11, color:'#16a34a' }}>
                  ✓ ללא מע"מ — ישיר לתקציב: <strong>{fmtVat(form.price)}</strong>
                </div>
              )}
            </div>
          ))}

          {/* תוקף + מע"מ */}
          <div style={{ display:'flex', gap:8 }}>
            <div style={{ flex:1 }}>
              <label style={{ fontSize:12, fontWeight:700, color:'var(--ybp-ink-soft)', display:'block', marginBottom:4 }}>
                תוקף הצעה
              </label>
              <input value={form.validity} onChange={e => set('validity', e.target.value)}
                placeholder="לדוגמה: 30 יום"
                style={{ width:'100%', boxSizing:'border-box', padding:'9px 10px', borderRadius:8,
                  border:'1px solid var(--ybp-border)', fontFamily:'inherit', fontSize:13,
                  background:'var(--ybp-panel)', color:'var(--ybp-ink)', direction:'rtl' }}/>
            </div>
            <div style={{ flex:1 }}>
              <label style={{ fontSize:12, fontWeight:700, color:'var(--ybp-ink-soft)', display:'block', marginBottom:4 }}>
                מע"מ
              </label>
              <select value={form.vat_included ? 'yes' : 'no'} onChange={e => set('vat_included', e.target.value === 'yes')}
                style={{ width:'100%', padding:'9px 10px', borderRadius:8, border:'1px solid var(--ybp-border)',
                  fontFamily:'inherit', fontSize:13, background:'var(--ybp-panel)', color:'var(--ybp-ink)' }}>
                <option value="yes">כולל מע"מ</option>
                <option value="no">ללא מע"מ</option>
              </select>
            </div>
          </div>

          {/* פירוט פריטים — מוצג כשיש items */}
          {form.items && form.items.length > 0 && (
            <div>
              <div style={{ fontSize:12, fontWeight:700, color:'var(--ybp-ink-soft)', marginBottom:6, display:'flex', alignItems:'center', justifyContent:'space-between' }}>
                <span>📋 פירוט פריטים ({form.items.length})</span>
                <button onClick={() => set('items', [])} style={{ background:'none', border:'none', cursor:'pointer', color:'var(--ybp-ink-faint)', fontSize:11 }}>✕ נקה</button>
              </div>
              <div style={{ border:'1px solid var(--ybp-border)', borderRadius:8, overflow:'hidden' }}>
                <table style={{ width:'100%', borderCollapse:'collapse', fontSize:11 }}>
                  <thead>
                    <tr style={{ background:'var(--ybp-row-hover)' }}>
                      <th style={{ padding:'6px 8px', textAlign:'right', fontWeight:600, color:'var(--ybp-ink-soft)' }}>תיאור</th>
                      <th style={{ padding:'6px 8px', textAlign:'center', fontWeight:600, color:'var(--ybp-ink-soft)', whiteSpace:'nowrap' }}>כמות</th>
                      <th style={{ padding:'6px 8px', textAlign:'center', fontWeight:600, color:'var(--ybp-ink-soft)' }}>יחידה</th>
                      <th style={{ padding:'6px 8px', textAlign:'left', fontWeight:600, color:'var(--ybp-ink-soft)', whiteSpace:'nowrap' }}>מחיר יח׳</th>
                      <th style={{ padding:'6px 8px', textAlign:'left', fontWeight:600, color:'var(--ybp-ink-soft)' }}>סה"כ</th>
                    </tr>
                  </thead>
                  <tbody>
                    {form.items.map((item, i) => (
                      <tr key={i} style={{ borderTop:'1px solid var(--ybp-border)' }}>
                        <td style={{ padding:'6px 8px', color:'var(--ybp-ink)' }}>{item.name}</td>
                        <td style={{ padding:'6px 8px', textAlign:'center', color:'var(--ybp-ink-soft)' }}>{item.qty ?? '—'}</td>
                        <td style={{ padding:'6px 8px', textAlign:'center', color:'var(--ybp-ink-soft)' }}>{item.unit ?? '—'}</td>
                        <td style={{ padding:'6px 8px', textAlign:'left', color:'var(--ybp-ink-soft)' }}>{item.unit_price ? Number(item.unit_price).toLocaleString('he-IL') + ' ₪' : '—'}</td>
                        <td style={{ padding:'6px 8px', textAlign:'left', fontWeight:600, color:'var(--ybp-navy)' }}>{item.total ? Number(item.total).toLocaleString('he-IL') + ' ₪' : '—'}</td>
                      </tr>
                    ))}
                  </tbody>
                  <tfoot>
                    <tr style={{ borderTop:'2px solid var(--ybp-border)', background:'var(--ybp-row-hover)' }}>
                      <td colSpan={4} style={{ padding:'6px 8px', fontWeight:700, color:'var(--ybp-ink-soft)', textAlign:'right' }}>סה"כ פריטים</td>
                      <td style={{ padding:'6px 8px', fontWeight:700, color:'var(--ybp-navy)', textAlign:'left' }}>
                        {Number(form.items.reduce((s, it) => s + (+it.total || 0), 0)).toLocaleString('he-IL')} ₪
                      </td>
                    </tr>
                  </tfoot>
                </table>
              </div>
            </div>
          )}

          {mode === 'edit' && (
            <div>
              <label style={{ fontSize:12, fontWeight:700, color:'var(--ybp-ink-soft)', display:'block', marginBottom:4 }}>סטטוס</label>
              <select value={form.status} onChange={e => set('status', e.target.value)}
                style={{ width:'100%', padding:'9px 10px', borderRadius:8, border:'1px solid var(--ybp-border)',
                  fontFamily:'inherit', fontSize:13, direction:'rtl', background:'var(--ybp-panel)' }}>
                <option value="open">במרוץ</option>
                <option value="closed">נסגרה (נבחרת)</option>
                <option value="rejected">נדחתה</option>
              </select>
            </div>
          )}
        </div>

        <button onClick={handleSave} style={{ width:'100%', marginTop:16, padding:'13px',
          borderRadius:8, border:'none', background:'var(--ybp-navy)', color:'#fff',
          fontSize:14, fontWeight:700, cursor:'pointer', fontFamily:'inherit' }}>
          {mode === 'create' ? 'שמור הצעה' : 'שמור שינויים'}
        </button>
      </div>
    </div>
  );
};

window.QuotesScreen = QuotesScreen;
})();
