// Budget Management Screen — ניהול תקציב פרויקט
(function(){
const { useState, useMemo, useRef } = React;

// 13 default categories — מקור-אמת ב-budget-store.js (v3.9.0.41).
const DEFAULT_SECTIONS_V36 = (window.BudgetStore && window.BudgetStore.DEFAULT_BUDGET_SECTIONS) || [];

// נעילה ברמת המודול — מונעת זריעה כפולה אם ה-useEffect מופעל פעמיים
// (StrictMode / שינוי projectId/reloadTick תוך-כדי-זריעה).
const _seedingProjects = new Set();

// Lookup table: category name → default icon (for category headers when rendering server-side categories)
const ICON_BY_NAME = Object.fromEntries(DEFAULT_SECTIONS_V36.map(s => [s.name, s.icon]));

// Build sections[] from DB rows (lines[] from BudgetStore). Groups by `category`, preserves sort_order.
function groupLinesToSections(lines) {
  const map = new Map(); // category → { id, name, icon, items[] }
  lines.forEach(r => {
    const cat = r.category || 'אחר';
    if (!map.has(cat)) {
      // Try to find a stable id from DEFAULT_SECTIONS_V36 by name; otherwise hash from name.
      const def = DEFAULT_SECTIONS_V36.find(s => s.name === cat);
      map.set(cat, {
        id:   def?.id || ('custom_' + cat.replace(/\s+/g, '_')),
        name: cat,
        icon: ICON_BY_NAME[cat] || '📦',
        items: [],
      });
    }
    map.get(cat).items.push({
      id: r.id, name: r.name || '', supplier: r.supplier || '',
      notes: r.notes || '', estimate: +r.estimate || 0,
      offer: +r.offer || 0, actual: +r.actual || 0,
      offer_manual: !!r.offer_manual, actual_manual: !!r.actual_manual,
    });
  });
  // סדר יציב: לפי DEFAULT_SECTIONS_V36, קטגוריות מותאמות אחריו, "בלתי צפוי-חריגים" תמיד אחרון.
  const orderKey = (nm) => {
    if (nm === 'בלתי צפוי-חריגים') return 999;
    const i = DEFAULT_SECTIONS_V36.findIndex(s => s.name === nm);
    return i >= 0 ? i : 900;
  };
  const out = Array.from(map.values());
  out.sort((a, b) => orderKey(a.name) - orderKey(b.name));
  return out;
}

const fmtNum = (n) => {
  const num = Number(n) || 0;
  if (num === 0) return '—';
  return num.toLocaleString('he-IL') + ' ₪';
};

const numColor = (actual, estimate) => {
  if (!actual || !estimate) return 'var(--ybp-ink)';
  const ratio = actual / estimate;
  if (ratio > 1.05) return '#dc2626';
  if (ratio > 0.95) return '#d97706';
  return '#16a34a';
};

// ============================================================
// BUDGET SCREEN
// ============================================================
const BudgetScreen = ({ projectId, onBack, readOnly = false }) => {
  const project = YBP_DATA.projects.find(p => p.id === projectId);
  const [data, setData] = useState({ sections: [], contingency: 10 });
  const [loading, setLoading] = useState(true);
  const [quoteCountByLine, setQuoteCountByLine] = useState({}); // { lineId: count }
  const [expandedSections, setExpandedSections] = useState(new Set(['consultants','construction']));
  const [editingCell, setEditingCell] = useState(null);
  const [view, setView] = useState('summary');
  const [showSendModal, setShowSendModal] = useState(false);
  const [pdfPrinted, setPdfPrinted] = useState(false);
  const { useEffect: ueLoad, useRef: urLoad } = React;

  // Reload counter: bumping this triggers a fresh load from cloud
  const [reloadTick, setReloadTick] = useState(0);

  // ── Load from cloud — also seeds 13 default categories if project is empty ──
  ueLoad(() => {
    let cancelled = false;
    if (!window.BudgetStore) { setLoading(false); return; }
    (async () => {
      setLoading(true);
      try {
        const { lines, meta } = await window.BudgetStore.getForProject(projectId);
        if (cancelled) return;

        if (lines.length === 0 && !readOnly && !_seedingProjects.has(projectId)) {
          // Seed once per project — single bulk insert (אטומי, ~80 שורות במכה).
          _seedingProjects.add(projectId);
          let seeded = [];
          try {
            seeded = await window.BudgetStore.seedDefaults(projectId, DEFAULT_SECTIONS_V36);
          } catch (e) {
            console.warn('[BudgetScreen] seedDefaults failed:', e);
            _seedingProjects.delete(projectId); // אפשר ניסיון חוזר בעת רענון
          }
          if (cancelled) return;
          setData({
            sections: groupLinesToSections(seeded),
            contingency: meta.contingency,
            areaSqm: meta.areaSqm, projType: meta.projType,
          });
        } else {
          setData({
            sections: groupLinesToSections(lines),
            contingency: meta.contingency,
            areaSqm: meta.areaSqm, projType: meta.projType,
          });
        }
        // טען ספירת הצעות לכל שורה — לאינדיקציה ב-UI (📑)
        if (window.QuotesStore) {
          try {
            const qs = await window.QuotesStore.listForProject(projectId);
            if (cancelled) return;
            const counts = {};
            (qs || []).forEach(q => {
              if (q.budget_line_id) counts[q.budget_line_id] = (counts[q.budget_line_id] || 0) + 1;
            });
            setQuoteCountByLine(counts);
          } catch (e) { console.warn('[BudgetScreen] quotes count load:', e); }
        }
      } catch (err) {
        console.warn('[BudgetScreen] load failed:', err);
      } finally {
        if (!cancelled) setLoading(false);
      }
    })();
    return () => { cancelled = true; };
  }, [projectId, reloadTick]);

  // ── listener לעדכון actual מ-payments (stage 2) — מרענן מהענן ────────────
  const { useEffect: ue2 } = React;
  ue2(() => {
    const h = () => setReloadTick(t => t + 1);
    window.addEventListener('ybp-budget-change', h);
    return () => window.removeEventListener('ybp-budget-change', h);
  }, [projectId]);

  // ── CRUD handlers ────────────────────────────────────────────────────────
  const handleAddLine = async (categoryId, categoryName) => {
    try {
      const row = await window.BudgetStore.addLine(projectId, {
        category: categoryName, name: '', supplier: '', notes: '',
        estimate: 0, offer: 0, actual: 0,
      });
      setData(d => ({
        ...d,
        sections: d.sections.map(s => s.id === categoryId
          ? { ...s, items: [...s.items, { id: row.id, name:'', supplier:'', notes:'', estimate:0, offer:0, actual:0 }] }
          : s),
      }));
    } catch (err) { alert('שגיאה בהוספת שורה: ' + (err?.message || err)); }
  };

  const handleDeleteLine = async (categoryId, lineId) => {
    if (!confirm('האם למחוק את השורה?')) return;
    try {
      await window.BudgetStore.deleteLine(lineId);
      setData(d => ({
        ...d,
        sections: d.sections.map(s => s.id === categoryId
          ? { ...s, items: s.items.filter(i => i.id !== lineId) }
          : s).filter(s => s.items.length > 0 || s.id === categoryId),
      }));
    } catch (err) { alert('שגיאה במחיקת שורה: ' + (err?.message || err)); }
  };

  const handleAddCategory = async () => {
    const name = (prompt('שם הקטגוריה החדשה:') || '').trim();
    if (!name) return;
    if (data.sections.some(s => s.name === name)) {
      alert('קטגוריה בשם זה כבר קיימת');
      return;
    }
    try {
      const row = await window.BudgetStore.addLine(projectId, {
        category: name, name: '', supplier: '', notes: '',
        estimate: 0, offer: 0, actual: 0,
      });
      const sectionId = 'custom_' + name.replace(/\s+/g, '_');
      setData(d => ({
        ...d,
        sections: [...d.sections, {
          id: sectionId, name, icon: '📦',
          items: [{ id: row.id, name:'', supplier:'', notes:'', estimate:0, offer:0, actual:0 }],
        }],
      }));
      setExpandedSections(prev => new Set([...prev, sectionId]));
    } catch (err) { alert('שגיאה בהוספת קטגוריה: ' + (err?.message || err)); }
  };

  // ── Excel export ─────────────────────────────────────────────────────────
  const handleExportExcel = () => {
    if (!window.XLSX) return alert('XLSX לא זמין');
    const projName = project?.name || projectId;
    const rows = [];
    data.sections.forEach(sec => {
      sec.items.forEach(it => rows.push({
        'קטגוריה': sec.name,
        'סעיף': it.name,
        'ספק': it.supplier,
        'הערות': it.notes,
        'אומדן': +it.estimate || 0,
        'הצעת מחיר': +it.offer || 0,
        'עלות בפועל': +it.actual || 0,
      }));
      const sum = sec.items.reduce((a, b) => ({
        estimate: a.estimate + (+b.estimate || 0),
        offer:    a.offer    + (+b.offer    || 0),
        actual:   a.actual   + (+b.actual   || 0),
      }), { estimate: 0, offer: 0, actual: 0 });
      rows.push({
        'קטגוריה': `סה"כ ${sec.name}`, 'סעיף': '', 'ספק': '', 'הערות': '',
        'אומדן': sum.estimate, 'הצעת מחיר': sum.offer, 'עלות בפועל': sum.actual,
      });
      rows.push({});
    });
    const ws = XLSX.utils.json_to_sheet(rows);
    const wb = XLSX.utils.book_new();
    XLSX.utils.book_append_sheet(wb, ws, 'תקציב');
    const today = new Date().toISOString().slice(0, 10);
    XLSX.writeFile(wb, `תקציב_${projName}_${today}.xlsx`);
  };

  // ── PDF export on YBP letterhead ─────────────────────────────────────────
  const getLogoSrc = () => (window.YBP_DATA && window.YBP_DATA.company && window.YBP_DATA.company.logoFull) || 'assets/ybp-logo-new.png';

  const handleExportPdf = () => {
    if (!window.YBPPdf) return alert('מודול PDF לא טעון');
    const projName = project?.name || '';
    const dateStr  = new Date().toLocaleDateString('he-IL');
    const fmt      = (n) => (Number(n) || 0).toLocaleString('he-IL');
    const pct      = Number(data.contingency) || 0;

    const headerMetaHtml = `
      <div style="font-size:13px;color:#374151;display:flex;gap:24px;flex-wrap:wrap">
        <div><b>פרויקט:</b> ${projName}</div>
        <div><b>תאריך הפקה:</b> ${dateStr}</div>
        <div><b>בלתי צפוי:</b> ${pct}%</div>
      </div>`;

    const tables = data.sections.map(sec => {
      const st = sectionTotal(sec);
      const rows = sec.items.map(it => `
        <tr>
          <td style="padding:6px 8px;border-bottom:1px solid #f3f4f6">${it.name||''}</td>
          <td style="padding:6px 8px;border-bottom:1px solid #f3f4f6">${it.supplier||''}</td>
          <td style="padding:6px 8px;text-align:center;border-bottom:1px solid #f3f4f6">${fmt(it.estimate)} ₪</td>
          <td style="padding:6px 8px;text-align:center;border-bottom:1px solid #f3f4f6">${fmt(it.offer)} ₪</td>
          <td style="padding:6px 8px;text-align:center;border-bottom:1px solid #f3f4f6">${fmt(it.actual)} ₪</td>
        </tr>`).join('');
      return `
        <div style="margin-bottom:14px">
          <h3 style="margin:0 0 6px;font-size:13px;color:#1a2c4a">${sec.icon||''} ${sec.name}</h3>
          <table style="width:100%;border-collapse:collapse;font-size:11px;border:1px solid #e5e7eb">
            <thead><tr style="background:#1a2c4a;color:#fff">
              <th style="padding:6px 8px;text-align:right">פריט</th>
              <th style="padding:6px 8px;text-align:right">ספק</th>
              <th style="padding:6px 8px;text-align:center">אומדן</th>
              <th style="padding:6px 8px;text-align:center">הצעת מחיר</th>
              <th style="padding:6px 8px;text-align:center">בפועל</th>
            </tr></thead>
            <tbody>${rows || `<tr><td colspan="5" style="padding:8px;text-align:center;color:#9ca3af">— ללא שורות —</td></tr>`}</tbody>
            <tfoot><tr style="background:#f9fafb;font-weight:700">
              <td colspan="2" style="padding:6px 8px">סה"כ ${sec.name}</td>
              <td style="padding:6px 8px;text-align:center">${fmt(st.estimate)} ₪</td>
              <td style="padding:6px 8px;text-align:center">${fmt(st.offer)} ₪</td>
              <td style="padding:6px 8px;text-align:center">${fmt(st.actual)} ₪</td>
            </tr></tfoot>
          </table>
        </div>`;
    }).join('');

    const summary = `
      <div style="margin-top:18px;padding:14px;background:#f9fafb;border:1px solid #e5e7eb;border-radius:8px">
        <h3 style="margin:0 0 8px;font-size:14px;color:#1a2c4a">ריכוז עלויות</h3>
        <table style="width:100%;border-collapse:collapse;font-size:12px">
          <tr><td style="padding:4px 8px">סה"כ ביניים (אומדן / הצעה / בפועל)</td>
            <td style="padding:4px 8px;text-align:center">${fmt(totals.estimate)} ₪</td>
            <td style="padding:4px 8px;text-align:center">${fmt(totals.offer)} ₪</td>
            <td style="padding:4px 8px;text-align:center">${fmt(totals.actual)} ₪</td></tr>
          <tr style="background:#fffbeb"><td style="padding:4px 8px">בלתי צפוי ${pct}%</td>
            <td style="padding:4px 8px;text-align:center">${fmt(totals.estimate*pct/100)} ₪</td>
            <td style="padding:4px 8px;text-align:center">${fmt(totals.offer*pct/100)} ₪</td>
            <td style="padding:4px 8px;text-align:center">${fmt(totals.actual*pct/100)} ₪</td></tr>
          <tr style="background:#1a2c4a;color:#fff;font-weight:700"><td style="padding:6px 8px">סה"כ כולל בלתי-צפוי</td>
            <td style="padding:6px 8px;text-align:center">${fmt(totals.estimateWithContingency)} ₪</td>
            <td style="padding:6px 8px;text-align:center">${fmt(totals.offerWithContingency)} ₪</td>
            <td style="padding:6px 8px;text-align:center">${fmt(totals.actualWithContingency)} ₪</td></tr>
        </table>
      </div>`;

    window.YBPPdf.generatePdf({
      orientation:   'landscape',
      logoSrc:       getLogoSrc(),
      fileName:      `תקציב_${projName}_${dateStr}.pdf`,
      headerMetaHtml,
      bodyHtml:      tables + summary,
      sigHtml:       '',
      projectId,
      uploadToDrive: false,
    });
  };

  // Drive — שמירת PDF ב-Make → Drive
  const MAKE_BUDGET_WEBHOOK = 'https://hook.eu2.make.com/cwhco2m6u2m48ey692n7n7wagoz8cg0i';
  const MAKE_SK = '1h4M4SEXbhoYF1YVW1mS6YJZs84yxSVHaBjPDDxMpbak';
  const saveBudgetToDrive = async () => {
    const pmName = ((window.YBP_AUTH && window.YBP_AUTH.getCurrentUser) ? window.YBP_AUTH.getCurrentUser().name : YBP_DATA.user?.name) || 'מנהל';
    const projectName = project?.name || projectId;
    const date = new Date().toISOString().slice(0, 10);
    try {
      const resp = await fetch(MAKE_BUDGET_WEBHOOK, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          _sk: MAKE_SK,
          manager: pmName,
          project: projectName,
          type_name: 'תקציב',
          date,
          format: 'html',
          html: `<h2>תקציב — ${projectName}</h2><p>תאריך: ${date}</p><p>סה"כ: ${totalAmt?.toLocaleString?.() || 0} ₪</p>`,
        }),
      });
      if (resp.ok) {
        const data = await resp.json().catch(() => ({}));
        alert('✓ התקציב נשלח ל-Drive!\n📁 ' + (data.file_url || projectName));
      } else alert('שגיאה בשליחה ל-Drive — בדוק webhook');
    } catch {
      alert('⚠️ שגיאת חיבור ל-Drive');
    }
  };

  // ── Smart Estimation ────────────────────────────────────────────────────
  const [showEstModal, setShowEstModal] = useState(false);
  const [area, setArea] = useState(() => {
    return project?.area || localStorage.getItem(`ybp_area_${projectId}`) || '';
  });
  const [projType, setProjType] = useState(() => {
    return localStorage.getItem(`ybp_projtype_${projectId}`) || 'restaurant';
  });
  // After cloud load completes, prefer cloud meta over localStorage
  const { useEffect: ueMetaSync } = React;
  ueMetaSync(() => {
    if (loading) return;
    if (data.areaSqm > 0) setArea(String(data.areaSqm));
    if (data.projType) setProjType(data.projType);
  }, [loading]);
  const RATE = 15000; // ₪ למ"ר (ברירת מחדל — מסעדות)

  // טמפלייטים לפי סוג פרויקט
  const TEMPLATES = {
    restaurant: {
      label: 'מסעדה / F&B',
      rate: 15000,
      map: {
        construction: 36,   // בינוי
        crafts: 14,         // בעלי מקצוע (נגרות, מסגרות, אלומיניום, שיש)
        kitchen: 15,        // מטבח ובר
        hvac: 10.5,         // מיזוג ואוויר
        finishes: 10,       // חיפויים + תאורה
        consultants: 4.5,   // יועצים
        furniture: 3,       // ריהוט + חוץ
        lowvoltage: 2.5,    // מתח נמוך
        fire: 0.8,          // גילוי אש
        fees: 0.5,          // אגרות
      }
    },
    commercial: {
      label: 'משרדים / מסחרי',
      rate: 7000, // מבוסס על פרויקט אמיתי: ~4.68M ₪ / 670 מ"ר = ~6,991 ₪/מ"ר
      map: {
        construction: 46.5, // בינוי (קבלן ראשי, הריסה, חשמל, אינסטלציה, איטום, ניקיון)
        crafts: 12.7,       // בעלי מקצוע (נגרות, מסגרות, אלומיניום, דלתות אש)
        hvac: 10.5,         // מערכות אוויר (מיזוג, אוויר צח, שחרור עשן)
        consultants: 10.3,  // יועצים + מתכננים (בינוי + רישוי)
        fees: 11.1,         // אגרות 4.8% + חריגים תכנוניים 6.3%
        lowvoltage: 5.4,    // מתח נמוך (בקרים, מצלמות, תקשורת, מסכים)
        finishes: 2.3,      // חיפויים וסניטריה 1.7% + שילוט 0.6%
        fire: 1.1,          // גילוי אש וכיבוי
        furniture: 0,       // ריהוט — לא תוקצב (להוסיף ידנית)
        kitchen: 0,         // מטבחון — לא תוקצב (להוסיף ידנית)
      }
    }
  };

  // מיפוי section id (v3.9.0.36 — 13 קטגוריות) → template key (שמורות בטמפלייטים שלמעלה)
  const SECTION_TO_TEMPLATE = {
    consultants:        'consultants',
    construction:       'construction',
    crafts:             'crafts',
    kitchen_bar:        'kitchen',
    hvac:               'hvac',
    finishes_san:       'finishes',
    furniture:          'furniture',
    lowvoltage:         'lowvoltage',
    fire:               'fire',
    fees:               'fees',
    // lighting / exterior / contingency_items — לא בטמפלייט; יהיו 0% באומדן החכם.
  };

  const applyEstimation = () => {
    const sqm = parseFloat(area);
    if (!sqm || sqm <= 0) return;
    localStorage.setItem(`ybp_area_${projectId}`, sqm);
    localStorage.setItem(`ybp_projtype_${projectId}`, projType);

    const tmpl = TEMPLATES[projType];
    const total = sqm * (tmpl.rate || RATE);

    // חלוקה מותאמת לכל פרק
    // יועצים — חלוקה לפי אחוז ריאלי לכל יועץ
    const CONSULTANT_WEIGHTS_RESTAURANT = {
      'מנהל פרויקט':          20,
      'עיצוב פנים / אדריכל':  25,
      'אדריכל רישוי':         12,
      'מתכנן מטבחים':         12,  // F&B — משמעותי!
      'יועץ מיזוג':            8,
      'יועץ אינסטלציה':        6,
      'יועץ חשמל':             6,
      'קונסטרוקטור':           4,
      'יועץ בטיחות':           3,
      'יועץ נגישות':           2,
      'יועץ תאורה':            2,
      'מודד':                  1,
    };
    const CONSULTANT_WEIGHTS_COMMERCIAL = {
      'מנהל פרויקט':          25,
      'עיצוב פנים / אדריכל':  30,
      'אדריכל רישוי':         15,
      'יועץ מיזוג':            8,
      'יועץ אינסטלציה':        6,
      'יועץ חשמל':             6,
      'קונסטרוקטור':           5,
      'מתכנן מטבחים':          1,  // מסחרי — מינימלי (מטבחון בלבד)
      'יועץ בטיחות':           2,
      'יועץ נגישות':           2,
      'יועץ תאורה':            2,
      'מודד':                  1,
    };
    const CONSULTANT_WEIGHTS = projType === 'restaurant'
      ? CONSULTANT_WEIGHTS_RESTAURANT
      : CONSULTANT_WEIGHTS_COMMERCIAL;

    const newData = {
      ...data,
      sections: data.sections.map(s => {
        const tKey = SECTION_TO_TEMPLATE[s.id];
        const pct = tmpl.map[tKey] || 0;
        const sectionBudget = Math.round(total * pct / 100);
        if (!pct || s.items.length === 0) return s;

        // ── יועצים — חלוקה לפי משקל ריאלי ──
        if (s.id === 'consultants') {
          const totalWeight = s.items.reduce((sum, it) => {
            return sum + (CONSULTANT_WEIGHTS[it.name] || 1);
          }, 0);
          return {
            ...s,
            items: s.items.map(it => ({
              ...it,
              estimate: Math.round(sectionBudget * ((CONSULTANT_WEIGHTS[it.name] || 1) / totalWeight)),
            }))
          };
        }

        // ── שאר הפרקים — חלק שווה בין כל הפריטים ──
        const perItem = Math.round(sectionBudget / s.items.length);
        return {
          ...s,
          items: s.items.map((it, idx) => ({
            ...it,
            estimate: idx === 0 ? sectionBudget - perItem * (s.items.length - 1) : perItem,
          }))
        };
      })
    };
    setData(newData);
    // batch write all new estimates to cloud
    if (window.BudgetStore) {
      const updates = [];
      newData.sections.forEach(s => s.items.forEach(it => {
        updates.push(window.BudgetStore.updateLine(it.id, { estimate: it.estimate }));
      }));
      window.BudgetStore.setMeta(projectId, { contingency: data.contingency, areaSqm: sqm, projType });
      Promise.all(updates).catch(err => console.warn('[applyEstimation] batch:', err));
    }
    setShowEstModal(false);
  };

  const updateItem = (sectionId, itemId, field, value) => {
    if (readOnly) return;
    // עריכה ידנית של offer/actual → גם הדגל manual כדי שסנכרון הצעות לא ידרוס.
    const extra = field === 'offer'  ? { offer_manual: true }
                : field === 'actual' ? { actual_manual: true }
                : {};
    const patch = { [field]: value, ...extra };
    setData(prev => ({
      ...prev,
      sections: prev.sections.map(s => s.id === sectionId ? {
        ...s,
        items: s.items.map(it => it.id === itemId ? { ...it, ...patch } : it)
      } : s)
    }));
    // Write-through to cloud (fire-and-forget; errors logged but don't block UI).
    if (window.BudgetStore) {
      window.BudgetStore.updateLine(itemId, patch)
        .catch(err => console.warn('[updateItem]', err));
    }
  };

  // ↻ חזרה לאוטומט — מאפס דגל ידני ומריץ סנכרון הצעות לשורה.
  const clearManualFlag = async (sectionId, itemId, which /* 'offer' | 'actual' */) => {
    if (readOnly) return;
    const fld = which === 'offer' ? 'offer_manual' : 'actual_manual';
    try {
      await window.BudgetStore.updateLine(itemId, { [fld]: false });
      if (window.QuotesStore) await window.QuotesStore.syncBudgetLine(itemId);
      setReloadTick(t => t + 1);
    } catch (e) { alert('שגיאה: ' + (e?.message || e)); }
  };

  const toggleSection = (id) => {
    const next = new Set(expandedSections);
    if (next.has(id)) next.delete(id); else next.add(id);
    setExpandedSections(next);
  };

  // Count locked suppliers (items with offer > 0)
  const lockedSuppliers = useMemo(() => {
    let total = 0, locked = 0;
    data.sections.forEach(s => s.items.forEach(it => {
      total++;
      if (Number(it.offer) > 0) locked++;
    }));
    return { total, locked, ratio: total > 0 ? locked / total : 0 };
  }, [data]);

  // Contingency: starts at 10%, drops to 5% as suppliers are locked
  const effectiveContingency = useMemo(() => {
    const base = 10, floor = 5;
    return Math.max(floor, base - (base - floor) * lockedSuppliers.ratio);
  }, [lockedSuppliers.ratio]);

  // דינמי גם לאומדן המודל
  const dynamicReserve = Math.max(5, Math.round(10 - 5 * lockedSuppliers.ratio));

  // Totals — contingency applies to all 3 columns
  const totals = useMemo(() => {
    let estimate = 0, offer = 0, actual = 0;
    data.sections.forEach(s => s.items.forEach(it => {
      estimate += Number(it.estimate) || 0;
      offer += Number(it.offer) || 0;
      actual += Number(it.actual) || 0;
    }));
    const c = (Number(data.contingency) || 0) / 100;
    return {
      estimate, offer, actual,
      estimateWithContingency: estimate * (1 + c),
      offerWithContingency: offer > 0 ? offer * (1 + c) : 0,
      actualWithContingency: actual > 0 ? actual * (1 + c) : 0,
    };
  }, [data]);

  const sectionTotal = (s) => {
    let estimate = 0, offer = 0, actual = 0;
    s.items.forEach(it => {
      estimate += Number(it.estimate) || 0;
      offer += Number(it.offer) || 0;
      actual += Number(it.actual) || 0;
    });
    return { estimate, offer, actual };
  };

  const openSheets = () => {
    const url = project?.budgetSheetUrl ||
      `https://docs.google.com/spreadsheets/d/new?title=${encodeURIComponent('תקציב - ' + project?.name)}`;
    window.open(url, '_blank');
  };

  const CellInput = ({ sectionId, itemId, field, value, style = {} }) => {
    const key = `${sectionId}-${itemId}-${field}`;
    const isEditing = !readOnly && editingCell === key;
    const isNumber = field === 'estimate' || field === 'offer' || field === 'actual';

    if (isEditing) {
      return (
        <input
          autoFocus
          type={isNumber ? 'number' : 'text'}
          defaultValue={value}
          onBlur={e => { updateItem(sectionId, itemId, field, isNumber ? Number(e.target.value) : e.target.value); setEditingCell(null); }}
          onKeyDown={e => { if (e.key === 'Enter' || e.key === 'Escape') e.target.blur(); }}
          style={{
            width: '100%', border: 'none', outline: '2px solid #1d4ed8', borderRadius: 4,
            padding: '4px 8px', fontSize: 12, fontFamily: 'inherit', background: 'var(--ybp-sb-active-bg)',
            textAlign: isNumber ? 'center' : 'right', direction: 'rtl', boxSizing: 'border-box', ...style,
          }}
        />
      );
    }

    return (
      <div
        onClick={() => !readOnly && setEditingCell(key)}
        style={{
          padding: '6px 8px', cursor: readOnly ? 'default' : 'text', fontSize: 12, borderRadius: 4,
          textAlign: isNumber ? 'center' : 'right',
          color: isNumber && field === 'actual' ? numColor(value, data.sections.find(s=>s.id===sectionId)?.items.find(it=>it.id===itemId)?.estimate) : 'var(--ybp-ink)',
          background: 'transparent', ...style,
        }}
        title={readOnly ? '' : 'לחץ לעריכה'}
      >
        {isNumber ? (Number(value) > 0 ? fmtNum(value) : <span style={{ color: '#d1d5db' }}>—</span>) : (value || <span style={{ color: '#d1d5db' }}>—</span>)}
      </div>
    );
  };

  if (loading) return (
    <div style={{ minHeight: '100%', background: '#f6f7f9', display: 'flex', alignItems: 'center', justifyContent: 'center', fontFamily: 'Assistant, sans-serif', direction: 'rtl' }}>
      <div style={{ color: 'var(--ybp-ink-soft)', fontSize: 14 }}>טוען תקציב מהענן…</div>
    </div>
  );

  return (
    <div style={{ minHeight: '100%', background: '#f6f7f9', fontFamily: 'Assistant, sans-serif', direction: 'rtl', paddingBottom: 40 }}>
      {/* Send PDF Modal */}
      {showSendModal && (() => {
        const dist = (() => { try { return JSON.parse(localStorage.getItem('ybp_dist_' + projectId) || '{}'); } catch { return {}; } })();
        const totalAmt = data.sections.reduce((s, sec) => s + sec.items.reduce((a, it) => a + (Number(it.actual) || Number(it.offer) || Number(it.estimate) || 0), 0), 0);
        const sendWA = () => {
          const lines = data.sections.map(s => '*' + s.name + '*: ' + s.items.reduce((a,it)=>a+(Number(it.actual)||Number(it.offer)||Number(it.estimate)||0),0).toLocaleString('he-IL') + ' ₪').join('\n');
          const txt = '💰 *תקציב פרויקט — ' + (project?.name||'') + '*\n\nסה"כ: ' + totalAmt.toLocaleString('he-IL') + ' ₪\n\n' + lines + '\n\n(מצורף PDF)\n\nYBPROJECTS';
          const phone = dist.waPhone || '';
          const url = phone ? 'https://wa.me/' + phone.replace(/\D/g,'') + '?text=' + encodeURIComponent(txt) : 'https://wa.me/?text=' + encodeURIComponent(txt);
          window.open(url, '_blank');
        };
        const sendGmail = () => {
          const emails = (dist.emails||'').split(',').map(e=>e.trim()).filter(Boolean);
          const lines = data.sections.map(s => s.name + ': ' + s.items.reduce((a,it)=>a+(Number(it.actual)||Number(it.offer)||Number(it.estimate)||0),0).toLocaleString('he-IL') + ' ₪').join('\n');
          const body = 'שלום,\n\nסיכום תקציב פרויקט ' + (project?.name||'') + ':\n\nסה"כ: ' + totalAmt.toLocaleString('he-IL') + ' ₪\n\n' + lines + '\n\n(מצורף PDF)\n\nYBPROJECTS · ניהול פרויקטים בבנייה';
          const params = new URLSearchParams();
          if (emails.length) params.set('to', emails.join(','));
          params.set('su', 'תקציב פרויקט — ' + (project?.name||''));
          params.set('body', body);
          window.open('https://mail.google.com/mail/?view=cm&' + params.toString(), '_blank');
        };
        return (
          <div style={{ position:'fixed', inset:0, background:'rgba(0,0,0,0.55)', zIndex:10000, display:'flex', alignItems:'center', justifyContent:'center' }}
            onClick={e => e.target === e.currentTarget && setShowSendModal(false)}>
            <div style={{ background:'var(--ybp-panel)', borderRadius:14, width:360, direction:'rtl', fontFamily:'Assistant,sans-serif', boxShadow:'0 24px 64px rgba(0,0,0,0.35)', overflow:'hidden' }}>
              <div style={{ background:'var(--ybp-navy)', padding:'14px 18px', display:'flex', alignItems:'center', gap:10 }}>
                <span style={{ flex:1, fontSize:15, fontWeight:700, color:'#fff' }}>📤 שליחת תקציב PDF</span>
                <button onClick={() => setShowSendModal(false)} style={{ background:'transparent', border:'none', color:'rgba(255,255,255,0.6)', fontSize:18, cursor:'pointer', lineHeight:1 }}>✕</button>
              </div>
              <div style={{ padding:18, display:'flex', flexDirection:'column', gap:14 }}>
                {/* Step 1 */}
                <div style={{ background: pdfPrinted ? '#f0fdf4' : '#f8fafc', border:`1px solid ${pdfPrinted?'#86efac':'#e2e8f0'}`, borderRadius:10, padding:14 }}>
                  <div style={{ fontSize:12, fontWeight:700, color:'var(--ybp-ink-soft)', marginBottom:8, display:'flex', alignItems:'center', gap:6 }}>
                    <span style={{ width:20, height:20, borderRadius:10, background: pdfPrinted ? '#16a34a' : 'var(--ybp-navy)', color:'#fff', display:'flex', alignItems:'center', justifyContent:'center', fontSize:11, fontWeight:800, flexShrink:0 }}>{pdfPrinted ? '✓' : '1'}</span>
                    {pdfPrinted ? 'PDF מוכן לשליחה ✓' : 'שמור קודם את התקציב כ-PDF'}
                  </div>
                  {!pdfPrinted && <div style={{ fontSize:11, color:'var(--ybp-ink-soft)', marginBottom:10 }}>לחץ "הדפס / שמור PDF", המתן לחלון ההדפסה, שמור כ-PDF.</div>}
                  <button onClick={() => { handleExportPdf(); setPdfPrinted(true); }} style={{ width:'100%', padding:'9px', borderRadius:7, border:'none', background:'var(--ybp-navy)', color:'#fff', fontSize:12, fontWeight:700, cursor:'pointer', fontFamily:'inherit' }}>
                    🖨️ {pdfPrinted ? 'הדפס שוב' : 'הדפס / שמור PDF'}
                  </button>
                </div>
                {/* Step 2 */}
                <div style={{ background: pdfPrinted ? 'var(--ybp-panel)' : '#f8fafc', border:'1px solid #e2e8f0', borderRadius:10, padding:14, opacity: pdfPrinted ? 1 : 0.5 }}>
                  <div style={{ fontSize:12, fontWeight:700, color:'var(--ybp-ink-soft)', marginBottom:10, display:'flex', alignItems:'center', gap:6 }}>
                    <span style={{ width:20, height:20, borderRadius:10, background:'var(--ybp-navy)', color:'#fff', display:'flex', alignItems:'center', justifyContent:'center', fontSize:11, fontWeight:800, flexShrink:0 }}>2</span>
                    שתף את ה-PDF
                  </div>
                  <div style={{ fontSize:11, color:'var(--ybp-ink-faint)', marginBottom:10 }}>
                    {dist.waPhone ? `📱 ${dist.waPhone}` : 'לא הוגדר טלפון'} · {dist.emails || 'לא הוגדרו מיילים'}
                  </div>
                  <div style={{ display:'flex', gap:8 }}>
                    <button onClick={() => pdfPrinted && sendWA()} style={{ flex:1, padding:'10px', borderRadius:7, border:'none', background: pdfPrinted?'#25d366':'var(--ybp-border)', color: pdfPrinted?'#fff':'var(--ybp-ink-faint)', fontSize:12, fontWeight:700, cursor: pdfPrinted?'pointer':'not-allowed', fontFamily:'inherit' }}>💬 WhatsApp</button>
                    <button onClick={() => pdfPrinted && sendGmail()} style={{ flex:1, padding:'10px', borderRadius:7, border:'none', background: pdfPrinted?'#ea4335':'var(--ybp-border)', color: pdfPrinted?'#fff':'var(--ybp-ink-faint)', fontSize:12, fontWeight:700, cursor: pdfPrinted?'pointer':'not-allowed', fontFamily:'inherit' }}>✉️ Gmail</button>
                  </div>
                  {!pdfPrinted && <div style={{ fontSize:10, color:'var(--ybp-ink-faint)', marginTop:8, textAlign:'center' }}>שמור PDF קודם כדי להפעיל שליחה</div>}
                </div>
              </div>
            </div>
          </div>
        );
      })()}
      {/* Smart Estimation Modal */}
      {showEstModal && (
        <EstimationModal
          area={area} setArea={setArea}
          projType={projType} setProjType={setProjType}
          onApply={applyEstimation}
          onClose={() => setShowEstModal(false)}
          TEMPLATES={TEMPLATES}
          RATE={RATE}
          lockedRatio={lockedSuppliers.ratio}
        />
      )}
      {/* Header */}
      <header style={{
        background: 'var(--ybp-panel)', borderBottom: '1px solid var(--ybp-border)', padding: '12px 20px',
        display: 'flex', alignItems: 'center', gap: 12, 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)' }}/>
        <div style={{ flex: 1 }}>
          <div style={{ fontSize: 11, color: 'var(--ybp-ink-soft)', fontWeight: 600 }}>{project?.name}</div>
          <div style={{ fontSize: 16, fontWeight: 700, color: 'var(--ybp-ink)' }}>
            ניהול תקציב
            {readOnly && <span style={{ fontSize: 11, background: '#fef3c7', color: '#b45309', padding: '2px 8px', borderRadius: 4, marginRight: 8, fontWeight: 600 }}>תצוגת לקוח — קריאה בלבד</span>}
          </div>
        </div>
        {/* Drive history indicator */}
        <div style={{ fontSize: 11, color: 'var(--ybp-ink-faint)', display: 'flex', alignItems: 'center', gap: 4 }}>
          <span style={{ width: 6, height: 6, background: '#10b981', borderRadius: 3 }}/>
          {(() => {
            const h = JSON.parse(localStorage.getItem(`ybp_budget_history_${projectId}`) || '[]');
            return `${h.length} גרסאות שמורות`;
          })()}
        </div>
        {!readOnly && (
          <button onClick={() => setShowEstModal(true)} style={{
            background: 'var(--ybp-navy)', color: '#fff', border: 'none',
            padding: '6px 12px', borderRadius: 6, fontSize: 12, fontWeight: 700, cursor: 'pointer',
            fontFamily: 'inherit', display: 'flex', alignItems: 'center', gap: 6,
          }}>
            🧮 אומדן חכם
          </button>
        )}
        {!readOnly && (
          <button onClick={openSheets} 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', display: 'flex', alignItems: 'center', gap: 6,
          }}>
            <svg width="14" height="14" viewBox="0 0 24 24" fill="#0f9d58"><path d="M19 3H5a2 2 0 00-2 2v14a2 2 0 002 2h14a2 2 0 002-2V5a2 2 0 00-2-2zm-7 14H7v-2h5v2zm5-4H7v-2h10v2zm0-4H7V7h10v2z"/></svg>
            פתח ב-Sheets
          </button>
        )}
        {/* + הוסף קטגוריה */}
        {!readOnly && (
          <button onClick={handleAddCategory} 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', display:'flex', alignItems:'center', gap:6,
          }}>+ הוסף קטגוריה</button>
        )}
        {/* ייצוא לאקסל */}
        <button onClick={handleExportExcel} style={{
          background:'var(--ybp-panel)', border:'1px solid #10b981', color:'#059669', padding:'6px 12px', borderRadius:6,
          fontSize:12, fontWeight:600, cursor:'pointer', fontFamily:'inherit', display:'flex', alignItems:'center', gap:6,
        }}>📥 אקסל</button>
        {/* ייצוא ל-PDF */}
        <button onClick={handleExportPdf} 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', display:'flex', alignItems:'center', gap:6,
        }}>🖨️ PDF</button>
        {/* שלח PDF */}
        <button onClick={() => { setPdfPrinted(false); setShowSendModal(true); }} style={{
          background:'var(--ybp-navy)', color:'#fff', border:'none', padding:'6px 14px', borderRadius:6,
          fontSize:12, fontWeight:700, cursor:'pointer', fontFamily:'inherit', display:'flex', alignItems:'center', gap:6,
        }}>📤 שלח PDF</button>
        {/* שמור ב-Drive */}
        {!readOnly && (
          <button onClick={saveBudgetToDrive} style={{
            background:'var(--ybp-panel)', border:'1px solid var(--ybp-border)', color:'var(--ybp-ink-soft)', padding:'6px 14px', borderRadius:6,
            fontSize:12, fontWeight:600, cursor:'pointer', fontFamily:'inherit', display:'flex', alignItems:'center', gap:6,
          }}>
            <svg width="13" height="11" viewBox="0 0 87.3 78" fill="none">
              <path d="M6.6 66.85l3.85 6.65c.8 1.4 1.95 2.5 3.3 3.3L29.5 48H0c0 1.55.4 3.1 1.2 4.5z" fill="#0066da"/>
              <path d="M43.65 25L29.5 48l16.15 28.8L87.3 48c0-1.55-.4-3.1-1.2-4.5L62.1 4.15c-.8-1.4-1.95-2.5-3.3-3.3z" fill="#00ac47"/>
              <path d="M73.55 76.8c1.35-.8 2.5-1.9 3.3-3.3L79.7 69l4.4-7.55c.8-1.4 1.2-2.95 1.2-4.5H45.65L73.55 76.8z" fill="#ea4335"/>
              <path d="M43.65 25L57.8 2.1C56.45 1.3 54.9.9 53.25.9H34.05c-1.65 0-3.2.4-4.55 1.2z" fill="#00832d"/>
              <path d="M45.65 48H29.5L13.85 76.8c1.35.8 2.9 1.2 4.55 1.2H68.9c1.65 0 3.2-.4 4.55-1.2z" fill="#2684fc"/>
              <path d="M73.4 25.9L59.1.85C58.3-.55 57.15-1.65 55.8-2.45L43.65 25H87.3c0-1.55-.4-3.1-1.2-4.5z" fill="#ffba00"/>
            </svg>
            שמור ב-Drive
          </button>
        )}
        <div style={{ display: 'flex', background: 'var(--ybp-row-hover)', borderRadius: 6, padding: 3, gap: 2 }}>
          <button onClick={() => setView('summary')} style={{
            padding: '6px 14px', borderRadius: 4, fontSize: 12, fontWeight: 600, border: 'none', cursor: 'pointer', fontFamily: 'inherit',
            background: view === 'summary' ? 'var(--ybp-panel)' : 'transparent', color: view === 'summary' ? 'var(--ybp-ink)' : 'var(--ybp-ink-soft)',
            boxShadow: view === 'summary' ? '0 1px 3px rgba(0,0,0,0.1)' : 'none',
          }}>סיכום</button>
          <button onClick={() => setView('detail')} style={{
            padding: '6px 14px', borderRadius: 4, fontSize: 12, fontWeight: 600, border: 'none', cursor: 'pointer', fontFamily: 'inherit',
            background: view === 'detail' ? 'var(--ybp-panel)' : 'transparent', color: view === 'detail' ? 'var(--ybp-ink)' : 'var(--ybp-ink-soft)',
            boxShadow: view === 'detail' ? '0 1px 3px rgba(0,0,0,0.1)' : 'none',
          }}>פירוט</button>
        </div>
      </header>

      <div style={{ maxWidth: 1100, margin: '0 auto', padding: '20px 16px' }}>

        {/* Contingency indicator */}
        <div style={{
          background: 'var(--ybp-panel)', border: '1px solid var(--ybp-border)', borderRadius: 10,
          padding: '12px 20px', marginBottom: 14,
          display: 'flex', alignItems: 'center', gap: 16, fontSize: 12,
        }}>
          <div style={{ flex: 1 }}>
            <div style={{ fontWeight: 700, color: 'var(--ybp-ink)', marginBottom: 4 }}>
              {`בלתי צפוי: ${(Number(data.contingency) || 0).toFixed(1)}%`}
            </div>
            <div style={{ height: 6, background: 'var(--ybp-row-hover)', borderRadius: 3, overflow: 'hidden', maxWidth: 300 }}>
              <div style={{
                height: '100%',
                width: `${Math.min(100, Math.max(0, ((Number(data.contingency)||0) / 30) * 100))}%`,
                background: (Number(data.contingency)||0) <= 6 ? '#10b981' : (Number(data.contingency)||0) <= 12 ? '#f59e0b' : '#ef4444',
                transition: 'all 0.3s',
              }}/>
            </div>
          </div>
          <div style={{ color: 'var(--ybp-ink-soft)' }}>
            <b style={{ color: 'var(--ybp-ink)' }}>{lockedSuppliers.locked}</b> מתוך {lockedSuppliers.total} ספקים נסגרו
            {lockedSuppliers.ratio === 1 && <span style={{ color: '#10b981', marginRight: 8 }}> · הגעת ל-5% מינימום ✓</span>}
          </div>
          <div style={{ fontSize: 11, color: 'var(--ybp-ink-faint)' }}>מתחיל ב-10% · יורד ל-5% עם נעילת כל הספקים</div>
        </div>

        {/* KPI cards */}
        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: 14, marginBottom: 20 }}>
          {[
            { label: 'אומדן', value: totals.estimateWithContingency, base: totals.estimate, color: 'var(--ybp-navy)' },
            { label: 'הצעת מחיר', value: totals.offerWithContingency, base: totals.offer, color: totals.offer > totals.estimate * 1.05 ? '#dc2626' : 'var(--ybp-navy)' },
            { label: 'עלות בפועל', value: totals.actualWithContingency, base: totals.actual, color: totals.actual > totals.estimate * 1.05 ? '#dc2626' : '#16a34a' },
          ].map(kpi => (
            <div key={kpi.label} style={{
              background: 'var(--ybp-panel)', border: '1px solid var(--ybp-border)', borderRadius: 10,
              padding: '16px 20px', borderTop: `3px solid ${kpi.color}`,
            }}>
              <div style={{ fontSize: 11, color: 'var(--ybp-ink-soft)', fontWeight: 600, marginBottom: 4 }}>{kpi.label}</div>
              <div style={{ fontSize: 26, fontWeight: 800, color: kpi.color, letterSpacing: -0.5 }}>
                {kpi.value > 0 ? fmtNum(kpi.value) : <span style={{ color: '#d1d5db' }}>—</span>}
              </div>
              {kpi.base > 0 && (
                <div style={{ fontSize: 11, color: 'var(--ybp-ink-faint)', marginTop: 4 }}>
                  {`לפני בלתי צפוי: ${fmtNum(kpi.base)}`}
                </div>
              )}
            </div>
          ))}
        </div>

        {/* Section totals strip */}
        <div style={{
          background: 'var(--ybp-panel)', border: '1px solid var(--ybp-border)', borderRadius: 10,
          padding: '12px 16px', marginBottom: 14,
        }}>
          <div style={{ fontSize: 11, fontWeight: 700, color: 'var(--ybp-ink-soft)', marginBottom: 10, letterSpacing: 0.3, textTransform: 'uppercase' }}>
            סה"כ לפי קטגוריה
          </div>
          <div style={{ display: 'flex', flexWrap: 'wrap', gap: 8 }}>
            {data.sections.map(s => {
              const st = sectionTotal(s);
              if (st.estimate === 0 && st.offer === 0 && st.actual === 0) return null;
              return (
                <div key={s.id} style={{
                  display: 'flex', alignItems: 'center', gap: 8, padding: '6px 12px',
                  background: 'var(--ybp-bg)', borderRadius: 8, border: '1px solid var(--ybp-border-soft)',
                  fontSize: 12,
                }}>
                  <span style={{ fontSize: 16 }}>{s.icon}</span>
                  <div>
                    <div style={{ fontWeight: 600, color: 'var(--ybp-ink)' }}>{s.name}</div>
                    <div style={{ color: 'var(--ybp-ink-soft)', fontSize: 11 }}>
                      {`א׳ ${fmtNum(st.estimate)}`}
                      {st.offer > 0 && <span style={{ color: '#3b82f6' }}> · הצ׳ {fmtNum(st.offer)}</span>}
                      {st.actual > 0 && <span style={{ color: numColor(st.actual, st.estimate) }}> · פ׳ {fmtNum(st.actual)}</span>}
                    </div>
                  </div>
                </div>
              );
            })}
          </div>
        </div>

        {/* Progress bar */}
        {totals.estimate > 0 && (
          <div style={{ background: 'var(--ybp-panel)', border: '1px solid var(--ybp-border)', borderRadius: 10, padding: '14px 20px', marginBottom: 20 }}>
            <div style={{ display: 'flex', justifyContent: 'space-between', fontSize: 12, color: 'var(--ybp-ink-soft)', marginBottom: 8, fontWeight: 600 }}>
              <span>ניצול תקציב (כולל בלתי צפוי)</span>
              <span>{Math.round((totals.actualWithContingency / totals.estimateWithContingency) * 100)}%</span>
            </div>
            <div style={{ height: 10, background: 'var(--ybp-row-hover)', borderRadius: 5, overflow: 'hidden', position: 'relative' }}>
              <div style={{
                position: 'absolute', top: 0, right: 0, height: '100%',
                width: `${Math.min(100, (totals.offerWithContingency / totals.estimateWithContingency) * 100)}%`,
                background: '#dbeafe', transition: 'width 0.5s',
              }}/>
              <div style={{
                position: 'absolute', top: 0, right: 0, height: '100%',
                width: `${Math.min(100, (totals.actualWithContingency / totals.estimateWithContingency) * 100)}%`,
                background: totals.actualWithContingency > totals.estimateWithContingency ? '#dc2626' : 'var(--ybp-navy)',
                transition: 'width 0.5s', borderRadius: 5,
              }}/>
            </div>
          </div>
        )}

        {/* Summary view */}
        {view === 'summary' && (
          <div style={{ background: 'var(--ybp-panel)', border: '1px solid var(--ybp-border)', borderRadius: 10, overflow: 'hidden' }}>
            <div style={{ display: 'grid', gridTemplateColumns: '1fr 130px 130px 130px', gap: 0, padding: '10px 16px', background: 'var(--ybp-row-hover)', color: 'var(--ybp-ink-soft)', borderBottom: '1px solid var(--ybp-border)', fontSize: 11, fontWeight: 700, letterSpacing: 0.3, textTransform: 'uppercase' }}>
              <div>קטגוריה</div>
              <div style={{ textAlign: 'center' }}>אומדן</div>
              <div style={{ textAlign: 'center' }}>הצעת מחיר</div>
              <div style={{ textAlign: 'center' }}>עלות בפועל</div>
            </div>
            {data.sections.map((s, i) => {
              const st = sectionTotal(s);
              const overBudget = st.actual > 0 && st.actual > st.estimate * 1.05;
              return (
                <div key={s.id} style={{
                  display: 'grid', gridTemplateColumns: '1fr 130px 130px 130px',
                  borderBottom: '1px solid var(--ybp-border-soft)', alignItems: 'center',
                  background: overBudget ? '#fef2f2' : i % 2 ? 'var(--ybp-row-hover)' : 'var(--ybp-panel)',
                  cursor: 'pointer', transition: 'background 0.1s',
                }}
                onClick={() => { setView('detail'); toggleSection(s.id); }}
                onMouseEnter={e => e.currentTarget.style.background = 'var(--ybp-sb-active-bg)'}
                onMouseLeave={e => e.currentTarget.style.background = overBudget ? '#fef2f2' : i % 2 ? 'var(--ybp-row-hover)' : 'var(--ybp-panel)'}
                >
                  <div style={{ padding: '12px 16px', display: 'flex', alignItems: 'center', gap: 10 }}>
                    <span style={{ fontSize: 18 }}>{s.icon}</span>
                    <span style={{ fontSize: 13, fontWeight: 600, color: 'var(--ybp-ink)' }}>{s.name}</span>
                    <span style={{ fontSize: 11, color: 'var(--ybp-ink-faint)' }}>{s.items.length} פריטים</span>
                    {overBudget && <span style={{ fontSize: 10, background: '#fee2e2', color: '#dc2626', padding: '2px 6px', borderRadius: 4, fontWeight: 700 }}>חריגה!</span>}
                  </div>
                  <div style={{ textAlign: 'center', fontSize: 13, fontWeight: 600, color: 'var(--ybp-navy)', padding: '0 8px' }}>{fmtNum(st.estimate)}</div>
                  <div style={{ textAlign: 'center', fontSize: 13, fontWeight: 600, color: 'var(--ybp-ink-soft)', padding: '0 8px' }}>{fmtNum(st.offer)}</div>
                  <div style={{ textAlign: 'center', fontSize: 13, fontWeight: 700, color: numColor(st.actual, st.estimate), padding: '0 8px' }}>{fmtNum(st.actual)}</div>
                </div>
              );
            })}
            {/* Contingency row */}
            <div style={{ display: 'grid', gridTemplateColumns: '1fr 130px 130px 130px', borderBottom: '1px solid var(--ybp-border)', background: '#fffbeb', alignItems: 'center' }}>
              <div style={{ padding: '12px 16px', fontSize: 13, fontWeight: 600, color: '#92400e' }}>
                <span>{'בלתי צפוי '}<input type="number" value={data.contingency} min="0" max="30"
                  onChange={e => {
                    const c = Number(e.target.value);
                    setData(prev => ({ ...prev, contingency: c }));
                    const nextMeta = { contingency: c, areaSqm: parseFloat(area)||0, projType };
                    if (window.BudgetStore) window.BudgetStore.setMeta(projectId, nextMeta)
                      .catch(err => console.warn('[contingency] setMeta:', err));
                    // v3.9.0.47 — mirror ל-YBP_DATA.projects[*].budgetMeta כדי ששמירת פרויקט עתידית
                    // לא תכתוב ערך ישן (mapProject->stripKnown משמר רק שדות top-level באובייקט).
                    try {
                      const arr = (window.YBP_DATA && window.YBP_DATA.projects) || [];
                      const idx = arr.findIndex(x => x.id === projectId);
                      if (idx !== -1) {
                        arr[idx] = { ...arr[idx], budgetMeta: { ...(arr[idx].budgetMeta || {}), ...nextMeta } };
                      }
                    } catch {}
                  }}
                  style={{ width: 42, marginRight: 8, padding: '2px 6px', borderRadius: 4, border: '1px solid #fde68a', fontSize: 12, textAlign: 'center', fontFamily: 'inherit' }}
                />{'%'}</span>
              </div>
              <div style={{ textAlign: 'center', fontSize: 13, fontWeight: 600, color: '#92400e', padding: '0 8px' }}>{fmtNum(totals.estimate * data.contingency / 100)}</div>
              <div style={{ textAlign: 'center', fontSize: 13, fontWeight: 600, color: '#92400e', padding: '0 8px' }}>{fmtNum(totals.offer * data.contingency / 100)}</div>
              <div style={{ textAlign: 'center', fontSize: 13, fontWeight: 600, color: '#92400e', padding: '0 8px' }}>{fmtNum(totals.actual * data.contingency / 100)}</div>
            </div>
            {/* Total */}
            <div style={{ display: 'grid', gridTemplateColumns: '1fr 130px 130px 130px', background: 'var(--ybp-navy)', color: '#ffffff', alignItems: 'center' }}>
              <div style={{ padding: '14px 16px', fontSize: 14, fontWeight: 700 }}>סה"כ כולל בלתי צפוי</div>
              <div style={{ textAlign: 'center', fontSize: 15, fontWeight: 800, padding: '0 8px' }}>{fmtNum(totals.estimateWithContingency)}</div>
              <div style={{ textAlign: 'center', fontSize: 15, fontWeight: 800, padding: '0 8px' }}>{fmtNum(totals.offerWithContingency)}</div>
              <div style={{ textAlign: 'center', fontSize: 15, fontWeight: 800, padding: '0 8px' }}>{fmtNum(totals.actualWithContingency)}</div>
            </div>
          </div>
        )}

        {/* Detail view */}
        {view === 'detail' && (
          <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
            {data.sections.map(s => {
              const isOpen = expandedSections.has(s.id);
              const st = sectionTotal(s);
              return (
                <div key={s.id} style={{ background: 'var(--ybp-panel)', border: '1px solid var(--ybp-border)', borderRadius: 10, overflow: 'hidden' }}>
                  {/* Section header */}
                  <div onClick={() => toggleSection(s.id)} style={{
                    display: 'flex', alignItems: 'center', gap: 12, padding: '14px 16px',
                    cursor: 'pointer',
                    background: isOpen ? 'var(--ybp-sb-active-bg)' : 'var(--ybp-panel)',
                    color: isOpen ? 'var(--ybp-navy)' : 'var(--ybp-ink)',
                    borderBottom: isOpen ? '1px solid var(--ybp-border)' : 'none',
                    transition: 'all 0.15s',
                  }}>
                    <span style={{ fontSize: 20 }}>{s.icon}</span>
                    <div style={{ flex: 1 }}>
                      <div style={{ fontSize: 14, fontWeight: 700 }}>{s.name}</div>
                      <div style={{ fontSize: 11, opacity: 0.7 }}>{s.items.length} פריטים</div>
                    </div>
                    <div style={{ display: 'flex', gap: 24, fontSize: 12, fontWeight: 600 }}>
                      <span>{`א׳: ${fmtNum(st.estimate)}`}</span>
                      <span>{`הצ׳: ${fmtNum(st.offer)}`}</span>
                      <span style={{ color: isOpen ? 'var(--ybp-navy)' : numColor(st.actual, st.estimate) }}>
                        {`פ׳: ${fmtNum(st.actual)}`}
                      </span>
                    </div>
                    <Icon name="chevronD" size={16} color={isOpen ? 'var(--ybp-navy)' : 'var(--ybp-ink-soft)'}
                      style={{ transform: isOpen ? 'rotate(0deg)' : 'rotate(-90deg)', transition: 'transform 0.15s' }}
                    />
                  </div>

                  {/* Items table */}
                  {isOpen && (
                    <>
                      <div style={{ display: 'grid', gridTemplateColumns: '2fr 1.3fr 1.5fr 120px 120px 120px 40px', gap: 0, padding: '8px 12px', background: 'var(--ybp-bg)', fontSize: 10, fontWeight: 700, color: 'var(--ybp-ink-soft)', letterSpacing: 0.5 }}>
                        <div>פריט</div><div>ספק</div><div>הערות</div>
                        <div style={{ textAlign: 'center' }}>אומדן</div>
                        <div style={{ textAlign: 'center' }}>הצעת מחיר</div>
                        <div style={{ textAlign: 'center' }}>בפועל</div>
                        <div/>
                      </div>
                      {s.items.map(item => {
                        const qCount = quoteCountByLine[item.id] || 0;
                        return (
                        <div key={item.id} style={{
                          display: 'grid', gridTemplateColumns: '2fr 1.3fr 1.5fr 120px 120px 120px 40px',
                          gap: 0, borderTop: '1px solid var(--ybp-border-soft)', alignItems: 'center',
                        }}>
                          <div style={{ display:'flex', alignItems:'center', gap:4 }}>
                            <div style={{ flex:1, minWidth:0 }}>
                              <CellInput sectionId={s.id} itemId={item.id} field="name" value={item.name}/>
                            </div>
                            {qCount > 0 && (
                              <span title={`${qCount} הצעות מחיר משויכות לשורה זו`}
                                style={{ fontSize:11, color:'#7c3aed', fontWeight:700, background:'#f3e8ff',
                                  padding:'2px 6px', borderRadius:10, whiteSpace:'nowrap' }}>
                                📑 {qCount}
                              </span>
                            )}
                          </div>
                          <CellInput sectionId={s.id} itemId={item.id} field="supplier" value={item.supplier}/>
                          <CellInput sectionId={s.id} itemId={item.id} field="notes" value={item.notes}/>
                          <CellInput sectionId={s.id} itemId={item.id} field="estimate" value={item.estimate}/>
                          <div style={{ position:'relative' }}>
                            <CellInput sectionId={s.id} itemId={item.id} field="offer" value={item.offer}/>
                            {item.offer_manual && !readOnly && (
                              <button onClick={()=>clearManualFlag(s.id, item.id, 'offer')}
                                title="ידני — חזור לחישוב אוטומטי מהצעות"
                                style={{ position:'absolute', top:2, left:2, background:'#fef3c7', color:'#92400e',
                                  border:'1px solid #fde68a', borderRadius:4, fontSize:9, fontWeight:700,
                                  padding:'1px 4px', cursor:'pointer', fontFamily:'inherit', lineHeight:1.2 }}>
                                ↻ ידני
                              </button>
                            )}
                          </div>
                          <div style={{ position:'relative' }}>
                            <CellInput sectionId={s.id} itemId={item.id} field="actual" value={item.actual}/>
                            {item.actual_manual && !readOnly && (
                              <button onClick={()=>clearManualFlag(s.id, item.id, 'actual')}
                                title="ידני — חזור לחישוב אוטומטי מהצעה סגורה"
                                style={{ position:'absolute', top:2, left:2, background:'#fef3c7', color:'#92400e',
                                  border:'1px solid #fde68a', borderRadius:4, fontSize:9, fontWeight:700,
                                  padding:'1px 4px', cursor:'pointer', fontFamily:'inherit', lineHeight:1.2 }}>
                                ↻ ידני
                              </button>
                            )}
                          </div>
                          {!readOnly && (
                            <button onClick={() => handleDeleteLine(s.id, item.id)}
                              title="מחק שורה"
                              style={{ width: 28, height: 28, justifySelf: 'center', background:'transparent', border:'none', cursor:'pointer', color:'#ef4444', fontSize:14, padding:0 }}>
                              🗑
                            </button>
                          )}
                        </div>
                        );
                      })}
                      {/* + הוסף שורה */}
                      {!readOnly && (
                        <div style={{ padding: '8px 12px', borderTop: '1px solid var(--ybp-border-soft)', background: 'var(--ybp-panel)' }}>
                          <button onClick={() => handleAddLine(s.id, s.name)}
                            style={{ background:'var(--ybp-sb-active-bg)', color:'#1d4ed8', border:'1px dashed #93c5fd', padding:'5px 12px', borderRadius:6, fontSize:11, fontWeight:600, cursor:'pointer', fontFamily:'inherit' }}>
                            + הוסף שורה
                          </button>
                        </div>
                      )}
                      {/* Section total */}
                      <div style={{ display: 'grid', gridTemplateColumns: '2fr 1.3fr 1.5fr 120px 120px 120px 40px', gap: 0, borderTop: '2px solid var(--ybp-border)', background: 'var(--ybp-bg)', alignItems: 'center' }}>
                        <div style={{ padding: '8px 12px', fontSize: 12, fontWeight: 700, color: 'var(--ybp-navy)', gridColumn: 'span 3' }}>סה"כ {s.name}</div>
                        <div style={{ textAlign: 'center', fontSize: 12, fontWeight: 700, color: 'var(--ybp-navy)', padding: '8px 0' }}>{fmtNum(st.estimate)}</div>
                        <div style={{ textAlign: 'center', fontSize: 12, fontWeight: 700, color: 'var(--ybp-ink-soft)', padding: '8px 0' }}>{fmtNum(st.offer)}</div>
                        <div style={{ textAlign: 'center', fontSize: 12, fontWeight: 700, color: numColor(st.actual, st.estimate), padding: '8px 0' }}>{fmtNum(st.actual)}</div>
                        <div/>
                      </div>
                    </>
                  )}
                </div>
              );
            })}
          </div>
        )}

        <div style={{ marginTop: 12, fontSize: 11, color: 'var(--ybp-ink-faint)', textAlign: 'center' }}>
          {'💾 כל עריכה נשמרת אוטומטית · לחץ על תא לעריכה'}
        </div>
      </div>
    </div>
  );
};

window.BudgetScreen = BudgetScreen;

// ── Smart Estimation Modal ────────────────────────────────────────────────
function EstimationModal({ area, setArea, projType, setProjType, onApply, onClose, TEMPLATES, RATE, lockedRatio = 0 }) {
  const sqm = parseFloat(area) || 0;
  const tmpl = TEMPLATES[projType];
  const effectiveRate = tmpl.rate || RATE;
  const total = sqm * effectiveRate;

  // רזרבה דינמית: מתחיל ב-10%, יורד ל-5% ככל שנסגרים ספקים
  const dynamicReserve = Math.max(5, Math.round(10 - 5 * lockedRatio));

  return (
    <div style={{
      position: 'fixed', inset: 0, background: 'rgba(0,0,0,0.5)', zIndex: 9999,
      display: 'flex', alignItems: 'center', justifyContent: 'center', padding: 16,
      fontFamily: 'Assistant, sans-serif', direction: 'rtl',
    }} onClick={e => e.target === e.currentTarget && onClose()}>
      <div style={{ background: 'var(--ybp-panel)', borderRadius: 16, width: '100%', maxWidth: 480, maxHeight: '90vh', overflowY: 'auto', boxShadow: '0 20px 60px rgba(0,0,0,0.25)' }}>
        {/* Header */}
        <div style={{ padding: '20px 24px 16px', borderBottom: '1px solid var(--ybp-border-soft)' }}>
          <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
            <div style={{ fontSize: 18, fontWeight: 800, color: 'var(--ybp-navy)' }}>🧮 אומדן תקציב חכם</div>
            <button onClick={onClose} style={{ background: 'none', border: 'none', fontSize: 20, cursor: 'pointer', color: 'var(--ybp-ink-faint)' }}>✕</button>
          </div>
          <div style={{ fontSize: 12, color: 'var(--ybp-ink-soft)', marginTop: 4 }}>
            מבוסס על {effectiveRate.toLocaleString('he-IL')} ₪/מ"ר × התפלגות אמיתית לפי סוג פרויקט
          </div>
        </div>

        <div style={{ padding: '20px 24px', display: 'flex', flexDirection: 'column', gap: 18 }}>
          {/* Area input */}
          <div>
            <label style={{ fontSize: 12, fontWeight: 700, color: 'var(--ybp-ink-soft)', display: 'block', marginBottom: 6 }}>
              גודל הנכס (מ"ר)
            </label>
            <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
              <input
                type="number" value={area} onChange={e => setArea(e.target.value)}
                placeholder="למשל: 250"
                style={{ flex: 1, padding: '10px 14px', borderRadius: 8, border: '1.5px solid #e5e7eb', fontSize: 16, fontFamily: 'inherit', outline: 'none', textAlign: 'center' }}
              />
              <div style={{ fontSize: 13, color: 'var(--ybp-ink-soft)', whiteSpace: 'nowrap' }}>מ"ר</div>
            </div>
          </div>

          {/* Project type */}
          <div>
            <label style={{ fontSize: 12, fontWeight: 700, color: 'var(--ybp-ink-soft)', display: 'block', marginBottom: 8 }}>סוג פרויקט</label>
            <div style={{ display: 'flex', gap: 8 }}>
              {Object.entries(TEMPLATES).map(([k, t]) => (
                <button key={k} onClick={() => setProjType(k)} style={{
                  flex: 1, padding: '10px', borderRadius: 10, cursor: 'pointer', fontFamily: 'inherit',
                  fontWeight: 700, fontSize: 13, transition: 'all 0.15s',
                  background: projType === k ? 'var(--ybp-navy)' : 'var(--ybp-row-hover)',
                  color: projType === k ? '#fff' : 'var(--ybp-ink-soft)',
                  border: projType === k ? '2px solid #1a2c4a' : '2px solid var(--ybp-border)',
                }}>{t.label}</button>
              ))}
            </div>
          </div>

          {/* Total preview */}
          {sqm > 0 && (
            <div style={{ background: '#f0f9ff', border: '1px solid #bae6fd', borderRadius: 10, padding: '14px 16px' }}>
              <div style={{ fontSize: 11, color: '#0369a1', fontWeight: 700, marginBottom: 8 }}>תקציב בסיס</div>
              <div style={{ fontSize: 24, fontWeight: 800, color: 'var(--ybp-navy)' }}>
                {total.toLocaleString('he-IL')} ₪
              </div>
              <div style={{ fontSize: 11, color: 'var(--ybp-ink-soft)', marginTop: 4 }}>
                {sqm} מ"ר × {effectiveRate.toLocaleString('he-IL')} ₪/מ"ר
              </div>
            </div>
          )}

          {/* Breakdown preview */}
          {sqm > 0 && (
            <div>
              <div style={{ fontSize: 12, fontWeight: 700, color: 'var(--ybp-ink-soft)', marginBottom: 8 }}>
                פילוח לפי פרקים — {tmpl.label}
              </div>
              <div style={{ display: 'flex', flexDirection: 'column', gap: 4 }}>
                {Object.entries(tmpl.map).filter(([,pct]) => pct > 0).sort((a,b) => b[1]-a[1]).map(([key, pct]) => {
                  const sectionNames = {
                    construction: 'בינוי', crafts: 'בעלי מקצוע', kitchen: 'מטבח ובר',
                    hvac: 'מיזוג ואוויר', finishes: 'חיפויים + תאורה',
                    consultants: 'יועצים', furniture: 'ריהוט + חוץ', lowvoltage: 'מתח נמוך',
                    fire: 'גילוי אש', fees: 'אגרות',
                  };
                  const amount = Math.round(total * pct / 100);
                  return (
                    <div key={key} style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
                      <div style={{ width: 90, fontSize: 11, color: 'var(--ybp-ink-soft)', flexShrink: 0 }}>{sectionNames[key] || key}</div>
                      <div style={{ flex: 1, height: 6, background: 'var(--ybp-row-hover)', borderRadius: 3, overflow: 'hidden' }}>
                        <div style={{ height: '100%', width: `${pct}%`, background: 'var(--ybp-navy)', borderRadius: 3 }}/>
                      </div>
                      <div style={{ fontSize: 11, fontWeight: 700, color: 'var(--ybp-navy)', width: 40, textAlign: 'left' }}>{pct}%</div>
                      <div style={{ fontSize: 11, color: 'var(--ybp-ink-soft)', width: 80, textAlign: 'left' }}>{amount.toLocaleString('he-IL')} ₪</div>
                    </div>
                  );
                })}
                {/* Reserve */}
                <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginTop: 4, paddingTop: 8, borderTop: '1px dashed #e5e7eb' }}>
                  <div style={{ width: 90, fontSize: 11, color: '#dc2626', fontWeight: 700, flexShrink: 0 }}>רזרבה ⚠️</div>
                  <div style={{ flex: 1, height: 6, background: '#fee2e2', borderRadius: 3, overflow: 'hidden' }}>
                    <div style={{ height: '100%', width: `${dynamicReserve}%`, background: '#dc2626', borderRadius: 3 }}/>
                  </div>
                  <div style={{ fontSize: 11, fontWeight: 700, color: '#dc2626', width: 40, textAlign: 'left' }}>{dynamicReserve}%</div>
                  <div style={{ fontSize: 11, color: '#dc2626', width: 80, textAlign: 'left' }}>{Math.round(total * dynamicReserve / 100).toLocaleString('he-IL')} ₪</div>
                </div>
                <div style={{ fontSize: 10, color: 'var(--ybp-ink-faint)', marginTop: 2 }}>
                  {lockedRatio > 0
                    ? `רזרבה ירדה ל-${dynamicReserve}% — ${Math.round(lockedRatio*100)}% מהספקים נסגרו`
                    : 'רזרבה מתחילה ב-10% · יורדת ל-5% ככל שספקים נסגרים'}
                </div>
                <div style={{ fontSize: 12, fontWeight: 800, color: 'var(--ybp-navy)', textAlign: 'left', marginTop: 6 }}>
                  סה"כ כולל רזרבה: {Math.round(total * (1 + dynamicReserve / 100)).toLocaleString('he-IL')} ₪
                </div>
              </div>
            </div>
          )}

          {/* Apply button */}
          <button
            onClick={onApply}
            disabled={!sqm || sqm <= 0}
            style={{
              padding: '13px', borderRadius: 10, border: 'none', fontFamily: 'inherit',
              background: sqm > 0 ? 'var(--ybp-navy)' : 'var(--ybp-border)',
              color: sqm > 0 ? '#fff' : 'var(--ybp-ink-faint)',
              fontWeight: 800, fontSize: 15, cursor: sqm > 0 ? 'pointer' : 'not-allowed',
            }}
          >
            ✅ הפעל אומדן — מלא עמודת "הערכה"
          </button>
          <div style={{ fontSize: 11, color: 'var(--ybp-ink-faint)', textAlign: 'center', marginTop: -10 }}>
            הפעולה תמלא את עמודת האומדן בלבד · הצעות ועלויות בפועל לא ישונו
          </div>
        </div>
      </div>
    </div>
  );
}

window.BudgetScreen = BudgetScreen;
})();
