// Dashboard — the hero page

function Dashboard() {
  const { setPage, setDrawerTxn, dataVersion } = useApp();
  const [scrapeOpen, setScrapeOpen] = useState(false);
  const [scrapeProvider, setScrapeProvider] = useState('max');
  const [aiBusy, setAiBusy] = useState(false);

  const openConnect = (provider) => {
    setScrapeProvider(provider);
    setScrapeOpen(true);
  };
  const [range, setRange] = useState('1m');                 // '1m' | '3m' | '1y'
  const monthsAll = D.months || [];
  // Default end-month = most recent month that actually has transactions
  // (so the user lands on real data instead of an empty current month).
  const initialIdx = useMemo(() => {
    for (let i = monthsAll.length - 1; i >= 0; i--) {
      if ((monthsAll[i].txns?.length || 0) > 0) return i;
    }
    return Math.max(0, monthsAll.length - 1);
  }, [dataVersion]);
  const [monthIdx, setMonthIdx] = useState(initialIdx);

  // Re-clamp on data refresh (lengths may change after a scrape).
  useEffect(() => {
    if (monthIdx >= monthsAll.length) setMonthIdx(Math.max(0, monthsAll.length - 1));
  }, [dataVersion]);

  // Compute the list of months in the active range, ending at monthIdx.
  const rangeLen = range === '1y' ? 12 : range === '3m' ? 3 : 1;
  const activeMonths = useMemo(() => {
    const end = monthIdx + 1;
    const start = Math.max(0, end - rangeLen);
    return monthsAll.slice(start, end);
  }, [monthIdx, range, dataVersion]);

  const endMonth = monthsAll[monthIdx] || D.current;
  const startMonth = activeMonths[0] || endMonth;

  // Aggregate stats across activeMonths.
  const agg = useMemo(() => {
    const expenses = activeMonths.reduce((s, m) => s + (m.summary?.expenses || 0), 0);
    const income = activeMonths.reduce((s, m) => s + (m.summary?.income || 0), 0);
    const txns = activeMonths.flatMap(m => m.txns || []);
    const byCat = {};
    txns.filter(t => t.amount < 0).forEach(t => {
      byCat[t.category] = (byCat[t.category] || 0) + (-t.amount);
    });
    return { expenses, income, net: income - expenses, byCat, txns, count: txns.length };
  }, [activeMonths]);

  // Previous comparable period (same length, immediately before start).
  const prevPeriod = useMemo(() => {
    const endIdx = Math.max(0, monthIdx - rangeLen + 1);
    const startIdx = Math.max(0, endIdx - rangeLen);
    const prevMs = monthsAll.slice(startIdx, endIdx);
    const expenses = prevMs.reduce((s, m) => s + (m.summary?.expenses || 0), 0);
    return { expenses, months: prevMs };
  }, [monthIdx, range, dataVersion]);

  const now = new Date();
  const isCurrentMonth = endMonth?.year === now.getFullYear() && endMonth?.month === now.getMonth() + 1;
  const daysInMonth = endMonth ? new Date(endMonth.year, endMonth.month, 0).getDate() : 30;
  const today = isCurrentMonth ? Math.min(now.getDate(), daysInMonth) : daysInMonth;
  const daily = useDailyPace(endMonth || { txns: [] }, today);
  // Projection only meaningful for current month, single-month view.
  const showProjection = range === '1m' && isCurrentMonth && today > 0 && today < daysInMonth;
  const projected = showProjection ? (daily[today-1] || 0) / today * daysInMonth : 0;
  const projectedDelta = prevPeriod.expenses
    ? (((showProjection ? projected : agg.expenses) - prevPeriod.expenses) / prevPeriod.expenses) * 100
    : 0;

  const topCats = useMemo(
    () => Object.entries(agg.byCat).sort((a,b) => b[1]-a[1]).slice(0, 5),
    [agg]
  );
  const recent = useMemo(
    () => agg.txns.slice().sort((a,b) => b.date.localeCompare(a.date)).slice(0, 6),
    [agg]
  );
  const featuredInsight = D.insights?.bullets?.[0];
  const hasSavings = (D.savings?.items?.length || 0) > 0;
  const hasAccounts = (D.accounts?.length || 0) > 0;

  // Title text depends on the active range.
  const HEB_MONTHS = ['ינואר','פברואר','מרץ','אפריל','מאי','יוני','יולי','אוגוסט','ספטמבר','אוקטובר','נובמבר','דצמבר'];
  const heroLabel = range === '1m'
    ? (endMonth ? `${HEB_MONTHS[endMonth.month-1]} ${endMonth.year}` : '')
    : range === '3m'
      ? `3 חודשים אחרונים`
      : `12 חודשים אחרונים`;
  const titleText = range === '1m'
    ? (isCurrentMonth ? `הנה איך ${HEB_MONTHS[endMonth.month-1]} הולך` : `סקירת ${HEB_MONTHS[endMonth.month-1]} ${endMonth.year}`)
    : range === '3m'
      ? 'סקירת 3 החודשים האחרונים'
      : 'סקירת 12 החודשים האחרונים';

  return (
    <div className="fade-in" style={{ padding: '32px 40px 60px', maxWidth: 1280, margin: '0 auto' }}>
      {/* Page header */}
      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-end', marginBottom: 18 }}>
        <div>
          <div style={{ fontSize: 12, color: 'var(--ink-soft)', marginBottom: 4 }}>{(() => {
            const h = new Date().getHours();
            const greet = h < 5 ? 'לילה טוב' : h < 12 ? 'בוקר טוב' : h < 17 ? 'צהריים טובים' : h < 21 ? 'ערב טוב' : 'לילה טוב';
            const name = (window.APP_USER?.name || '').split(' ')[0] || '';
            return name ? `${greet}, ${name}` : greet;
          })()}</div>
          <h1 style={{ fontSize: 28, fontWeight: 600, letterSpacing: '-0.02em', margin: 0 }}>
            {titleText}
          </h1>
        </div>
        <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
          <Segmented
            options={[{value:'1m',label:'חודש'},{value:'3m',label:'3 חודשים'},{value:'1y',label:'שנה'}]}
            value={range}
            onChange={setRange}
          />
          {D.aiStatus?.configured && (
            <button onClick={async () => {
              if (aiBusy) return;
              if (!confirm("Cai יסווג מחדש את העסקאות שעדיין נמצאות ב-'אחר'. להמשיך?")) return;
              setAiBusy(true);
              try {
                const r = await apiFetch('/api/ai/recategorize', { method: 'POST' });
                if (!r.ok) {
                  const err = await r.json().catch(() => ({}));
                  throw new Error(err.detail?.message || 'הסיווג נכשל');
                }
                const d = await r.json();
                await window.APP_DATA_REFRESH();
                alert(`עודכנו ${d.updated} עסקאות (${d.rules_added} חוקים נשמרו).`);
              } catch (err) {
                alert('AI: ' + err.message);
              } finally {
                setAiBusy(false);
              }
            }} style={{
              background: 'var(--surface)', color: 'var(--ink)', border: '0.5px solid var(--rule)',
              padding: '8px 14px', borderRadius: 10, fontSize: 12.5, fontWeight: 500,
              cursor: aiBusy ? 'wait' : 'pointer', boxShadow: 'var(--shadow-sm)',
              display: 'flex', alignItems: 'center', gap: 6, opacity: aiBusy ? 0.6 : 1,
            }}>
              <span style={{ fontSize: 12 }}>✦</span>{aiBusy ? 'מסווג…' : 'סווג עם AI'}
            </button>
          )}
          <button onClick={() => setScrapeOpen(true)} style={{
            background: 'var(--ink)', color: 'var(--bg)', border: 'none', padding: '8px 14px',
            borderRadius: 10, fontSize: 12.5, fontWeight: 500, cursor: 'pointer',
            display: 'flex', alignItems: 'center', gap: 6,
          }}>
            <span style={{ fontSize: 11 }}>↻</span>סנכרון עכשיו
          </button>
          {scrapeOpen && <ScrapeModal defaultProvider={scrapeProvider} onClose={() => setScrapeOpen(false)} />}
        </div>
      </div>

      {/* Month picker — selects single month (1m) or end-month of range (3m/1y) */}
      <div style={{
        display: 'flex', gap: 6, marginBottom: 20, overflowX: 'auto', paddingBottom: 4,
        scrollbarWidth: 'thin',
      }}>
        {monthsAll.map((m, i) => {
          const active = i === monthIdx;
          const isEmpty = (m.txns?.length || 0) === 0;
          // Highlight months that are part of the current range (not just the end month).
          const inRange = !active && i >= Math.max(0, monthIdx - rangeLen + 1) && i <= monthIdx;
          return (
            <button
              key={`${m.year}-${m.month}`}
              onClick={() => setMonthIdx(i)}
              disabled={isEmpty && !active}
              title={isEmpty ? 'אין עסקאות בחודש זה' : m.label}
              style={{
                padding: '6px 12px', borderRadius: 8,
                background: active
                  ? 'var(--ink)'
                  : inRange ? 'rgba(10,132,255,0.12)' : 'var(--surface)',
                color: active ? 'var(--bg)' : (isEmpty ? 'var(--ink-soft)' : 'var(--ink)'),
                border: '0.5px solid var(--rule)',
                fontSize: 12, fontWeight: active ? 600 : 500,
                cursor: (isEmpty && !active) ? 'not-allowed' : 'pointer',
                opacity: (isEmpty && !active) ? 0.4 : 1,
                whiteSpace: 'nowrap',
                fontFeatureSettings: '"tnum"',
              }}>
              {m.shortLabel} {String(m.year).slice(-2)}
              {!isEmpty && (
                <span style={{ marginInlineStart: 6, fontSize: 10.5, opacity: .7 }}>·{m.txns.length}</span>
              )}
            </button>
          );
        })}
      </div>

      {/* Hero — chart adapts: pace (1m) or multi-month line (3m/1y) */}
      <Surface style={{ marginBottom: 16, padding: 0, overflow: 'hidden' }} padded={false}>
        <div style={{ display: 'grid', gridTemplateColumns: '1.6fr 1fr' }}>
          <div style={{ padding: '28px 32px', borderInlineEnd: '0.5px solid var(--rule)' }}>
            <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', marginBottom: 4 }}>
              <div>
                <div style={{ fontSize: 11.5, color: 'var(--ink-soft)', fontWeight: 500, letterSpacing: '0.02em' }}>
                  {range === '1m' ? `הוצאות מצטברות · ${heroLabel}` : `סך הוצאות · ${heroLabel}`}
                </div>
                <Money
                  value={range === '1m' ? (daily[today-1] || 0) : agg.expenses}
                  size={48}
                  weight={600}
                />
                <div style={{ display: 'flex', alignItems: 'center', gap: 10, marginTop: 6, fontSize: 12 }}>
                  {showProjection ? (
                    <>
                      <span style={{ color: 'var(--ink-soft)' }}>צפי לסוף החודש</span>
                      <span className="tnum" style={{ fontWeight: 600 }}>{fmtILS(projected)}</span>
                    </>
                  ) : prevPeriod.expenses > 0 ? (
                    <>
                      <span style={{ color: 'var(--ink-soft)' }}>תקופה קודמת</span>
                      <span className="tnum" style={{ fontWeight: 600 }}>{fmtILS(prevPeriod.expenses)}</span>
                    </>
                  ) : (
                    <span style={{ color: 'var(--ink-soft)' }}>אין השוואה זמינה</span>
                  )}
                  {(showProjection || prevPeriod.expenses > 0) && (
                    <span style={{
                      padding: '2px 8px', borderRadius: 6, fontSize: 11, fontWeight: 600,
                      background: projectedDelta > 0 ? 'rgba(216,58,58,0.1)' : 'rgba(48,164,108,0.1)',
                      color: projectedDelta > 0 ? 'var(--alert)' : 'var(--positive)',
                    }}>
                      {projectedDelta > 0 ? '↑' : '↓'} {Math.abs(projectedDelta).toFixed(1)}%
                    </span>
                  )}
                </div>
              </div>
              {range === '1m' && (
                <div style={{ display: 'flex', gap: 12, fontSize: 11, color: 'var(--ink-soft)' }}>
                  <LegendDot label="בפועל" filled />
                  {showProjection && <LegendDot label="קצב חודשי" dashed />}
                </div>
              )}
            </div>
            <div style={{ marginTop: 18 }}>
              {range === '1m' ? (
                <PaceChart daily={daily} today={today} projected={projected} height={170} />
              ) : (
                <MultiMonthChart months={activeMonths} height={170} />
              )}
            </div>
          </div>
          <div style={{ padding: '28px 32px', display: 'flex', flexDirection: 'column', justifyContent: 'space-between', gap: 16 }}>
            <SideStat label={range === '1m' ? 'נטו לחודש' : 'נטו לתקופה'} value={agg.net} positive />
            <SideStat label="הכנסה" value={agg.income} muted />
            <SideStat label="הוצאה" value={agg.expenses} muted />
            <div style={{ height: 0.5, background: 'var(--rule)', margin: '4px 0' }} />
            {range === '1m' ? (
              <div>
                <div style={{ fontSize: 11.5, color: 'var(--ink-soft)', marginBottom: 4 }}>
                  {isCurrentMonth ? 'ימים שנותרו בחודש' : 'מספר עסקאות'}
                </div>
                <div className="tnum" style={{ fontSize: 20, fontWeight: 600, color: 'var(--accent)' }}>
                  {isCurrentMonth ? `${Math.max(0, daysInMonth - today)} ימים` : `${agg.count}`}
                </div>
                <div style={{ fontSize: 11, color: 'var(--ink-soft)', marginTop: 2 }}>{endMonth?.label}</div>
              </div>
            ) : (
              <div>
                <div style={{ fontSize: 11.5, color: 'var(--ink-soft)', marginBottom: 4 }}>טווח</div>
                <div className="tnum" style={{ fontSize: 14, fontWeight: 600, color: 'var(--accent)' }}>
                  {startMonth?.label} – {endMonth?.label}
                </div>
                <div style={{ fontSize: 11, color: 'var(--ink-soft)', marginTop: 2 }}>{agg.count} עסקאות</div>
              </div>
            )}
          </div>
        </div>
      </Surface>

      {/* Savings opportunity teaser — only show if Cai found something */}
      {hasSavings && <Surface
        onClick={() => setPage('savings')}
        style={{
          cursor: 'pointer', marginBottom: 16, padding: 0, overflow: 'hidden',
        }}
        padded={false}
      >
        <div style={{
          display: 'grid', gridTemplateColumns: '1fr auto auto auto',
          alignItems: 'center', gap: 22, padding: '18px 24px',
        }}>
          <div style={{ display: 'flex', alignItems: 'center', gap: 14 }}>
            <div style={{
              width: 38, height: 38, borderRadius: 11,
              background: 'linear-gradient(135deg, var(--positive), #2a8b5b)',
              color: 'white', display: 'flex', alignItems: 'center', justifyContent: 'center',
              fontSize: 16, fontWeight: 700,
              boxShadow: '0 4px 10px -2px rgba(48,164,108,0.3)',
            }}>↓</div>
            <div>
              <div style={{ fontSize: 11.5, color: 'var(--ink-soft)', fontWeight: 500, letterSpacing: '0.02em', marginBottom: 2 }}>
                Cai מצא איפה אפשר לחסוך
              </div>
              <div style={{ fontSize: 14.5, fontWeight: 600 }}>
                {D.savings.items.length} הזדמנויות זוהו · עד <span className="tnum" style={{ color: 'var(--positive)' }}>{fmtILS(D.savings.annualPotential)}</span> בשנה
              </div>
            </div>
          </div>

          {/* Quick wins highlight */}
          {D.savings.items.slice(0, 3).map((s) => {
            const cat = D.categories[s.category] || { icon: '·', color: 'var(--ink-soft)' };
            return (
              <div key={s.id} style={{
                display: 'flex', alignItems: 'center', gap: 8,
                padding: '8px 12px', background: 'var(--bg-deep)', borderRadius: 9,
              }}>
                <span style={{ fontSize: 14 }}>{cat.icon}</span>
                <div style={{ minWidth: 0 }}>
                  <div style={{ fontSize: 11.5, fontWeight: 500, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis', maxWidth: 130 }}>{s.title}</div>
                  <div className="tnum" style={{ fontSize: 10.5, color: 'var(--positive)', fontWeight: 600 }}>{fmtILS(s.annual)}/שנה</div>
                </div>
              </div>
            );
          })}
          <div style={{ fontSize: 12, color: 'var(--accent)', fontWeight: 500, paddingInlineStart: 4 }}>
            ראה הכל ‹
          </div>
        </div>
      </Surface>}

      {/* Featured AI insight + Accounts */}
      <div style={{ display: 'grid', gridTemplateColumns: '1.2fr 1fr', gap: 16, marginBottom: 16 }}>
        <Surface onClick={() => setPage('ai')} style={{ cursor: 'pointer', position: 'relative', overflow: 'hidden' }}>
          <div style={{ display: 'flex', alignItems: 'center', gap: 10, marginBottom: 14 }}>
            <SparkBadge size={28} />
            <div style={{ fontSize: 11.5, color: 'var(--ink-soft)', fontWeight: 500, letterSpacing: '0.02em', flex: 1 }}>
              דוח Cai · {(() => {
                const c = D.insights?.createdAt;
                if (!c) return 'עוד לא נוצר';
                const diff = Math.max(0, Date.now() - new Date(c).getTime());
                const m = Math.round(diff / 60000);
                if (m < 1) return 'עודכן זה עתה';
                if (m < 60) return `עודכן לפני ${m} דקות`;
                const h = Math.round(m / 60);
                if (h < 24) return `עודכן לפני ${h} שעות`;
                const d = Math.round(h / 24);
                return d === 1 ? 'עודכן אתמול' : `עודכן לפני ${d} ימים`;
              })()}
            </div>
            <span style={{ fontSize: 13, color: 'var(--ink-soft)' }}>‹</span>
          </div>
          <div style={{ fontSize: 15, fontWeight: 500, lineHeight: 1.5, color: 'var(--ink-2)', marginBottom: featuredInsight ? 14 : 0 }}>
            {D.insights?.summary}
          </div>
          {featuredInsight && (
            <div style={{
              background: 'var(--bg-deep)', borderRadius: 12, padding: 14,
              display: 'flex', gap: 12, alignItems: 'flex-start',
            }}>
              <span style={{
                width: 22, height: 22, borderRadius: 7,
                background: featuredInsight.kind === 'warning' ? 'var(--alert)' : featuredInsight.kind === 'good' ? 'var(--positive)' : 'var(--accent)',
                color: 'white',
                display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: 12, flexShrink: 0,
              }}>{featuredInsight.kind === 'warning' ? '!' : featuredInsight.kind === 'good' ? '✓' : 'i'}</span>
              <div style={{ flex: 1, fontSize: 12.5, lineHeight: 1.5 }}>
                <div style={{ fontWeight: 600, marginBottom: 2 }}>{featuredInsight.title}</div>
                <div style={{ color: 'var(--ink-2)' }}>{featuredInsight.text}</div>
              </div>
            </div>
          )}
        </Surface>

        <Surface>
          <ConnectionsCard accounts={D.accounts || []} onConnect={openConnect} />
        </Surface>
      </div>

      {/* Cats + Recent */}
      <div style={{ display: 'grid', gridTemplateColumns: '1fr 1.2fr', gap: 16 }}>
        <Surface>
          <div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: 16 }}>
            <div>
              <div style={{ fontSize: 13, fontWeight: 600 }}>איפה הכסף הולך</div>
              <div style={{ fontSize: 11, color: 'var(--ink-soft)', marginTop: 2 }}>5 קטגוריות מובילות</div>
            </div>
            <span onClick={() => setPage('budgets')} style={{ fontSize: 11, color: 'var(--accent)', cursor: 'pointer' }}>הצג הכל ‹</span>
          </div>
          <div style={{ display: 'flex', flexDirection: 'column', gap: 14 }}>
            {topCats.map(([cat, val]) => {
              const lim = D.budgets[cat];
              const pct = lim ? val/lim : 0;
              const c = D.categories[cat] || {};
              const over = pct > 1;
              return (
                <div key={cat} className="slide-up">
                  <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline', marginBottom: 6 }}>
                    <span style={{ display: 'flex', alignItems: 'center', gap: 9, fontSize: 13 }}>
                      <span style={{ width: 26, height: 26, borderRadius: 7, background: `${c.color}22`, display: 'inline-flex', alignItems: 'center', justifyContent: 'center', fontSize: 13 }}>{c.icon}</span>
                      <span style={{ fontWeight: 500 }}>{cat}</span>
                    </span>
                    <span className="tnum" style={{ fontWeight: 600, fontSize: 13, color: over ? 'var(--alert)' : 'var(--ink)' }}>
                      {fmtILS(val)}
                    </span>
                  </div>
                  <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
                    <div style={{ flex: 1, height: 6, background: 'var(--bg-deep)', borderRadius: 99, overflow: 'hidden' }}>
                      <div style={{ width: `${Math.min(100, pct*100)}%`, height: '100%', background: over ? 'var(--alert)' : c.color, borderRadius: 99, transition: 'width .6s cubic-bezier(.2,.8,.3,1)' }} />
                    </div>
                    {lim && <span className="tnum" style={{ fontSize: 10.5, color: 'var(--ink-soft)', minWidth: 36, textAlign: 'left', fontFamily: 'var(--font-mono)' }}>{Math.round(pct*100)}%</span>}
                  </div>
                </div>
              );
            })}
          </div>
        </Surface>

        <Surface padded={false}>
          <div style={{ padding: '20px 22px 14px', display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
            <div>
              <div style={{ fontSize: 13, fontWeight: 600 }}>פעילות אחרונה</div>
              <div style={{ fontSize: 11, color: 'var(--ink-soft)', marginTop: 2 }}>
                {agg.count} עסקאות {range === '1m' ? 'החודש' : 'בתקופה'}
              </div>
            </div>
            <span onClick={() => setPage('txns')} style={{ fontSize: 11, color: 'var(--accent)', cursor: 'pointer' }}>הצג הכל ‹</span>
          </div>
          <div>
            {recent.map((t, i) => {
              const c = D.categories[t.category] || {};
              return (
                <div key={t.id} onClick={() => setDrawerTxn(t)} style={{
                  display: 'flex', alignItems: 'center', gap: 12, padding: '10px 22px',
                  cursor: 'pointer', borderTop: i === 0 ? '0.5px solid var(--rule)' : '0.5px solid var(--rule)',
                  transition: 'background .14s',
                }} onMouseEnter={(e) => e.currentTarget.style.background = 'var(--bg-deep)'}
                   onMouseLeave={(e) => e.currentTarget.style.background = 'transparent'}>
                  <div style={{ width: 32, height: 32, borderRadius: 9, background: `${c.color}22`, display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: 13 }}>{c.icon}</div>
                  <div style={{ flex: 1, minWidth: 0 }}>
                    <div style={{ fontSize: 12.5, fontWeight: 500, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>
                      {t.anomaly && <span style={{ color: 'var(--alert)', marginInlineEnd: 5 }}>!</span>}
                      {t.description}
                    </div>
                    <div style={{ fontSize: 10.5, color: 'var(--ink-soft)' }}>{fmtDate(t.date)} · {t.category}</div>
                  </div>
                  <div className="tnum" style={{ fontSize: 13, fontWeight: 600, color: t.amount > 0 ? 'var(--positive)' : 'var(--ink)' }}>
                    {fmtILS(t.amount)}
                  </div>
                </div>
              );
            })}
          </div>
        </Surface>
      </div>
    </div>
  );
}

// Per-provider connection list with Sync/Connect buttons.
// All 4 supported providers always render — connected ones with their accounts,
// disconnected ones with a "התחבר" CTA that opens the modal pre-selected.
function ConnectionsCard({ accounts, onConnect }) {
  const PROVIDERS = [
    { id: 'max',      label: 'Max',              color: '#0a84ff', sub: 'מקס' },
    { id: 'visaCal',  label: 'Visa Cal',         color: '#5856d6', sub: 'ויזה כאל' },
    { id: 'isracard', label: 'Isracard',         color: '#ff375f', sub: 'ישראכרט (כולל Visa)' },
    { id: 'amex',     label: 'American Express', color: '#1a73e8', sub: 'אמריקן אקספרס' },
  ];
  // Group accounts by source
  const byProv = {};
  accounts.forEach(a => { (byProv[a.source] ||= []).push(a); });
  const connectedCount = PROVIDERS.filter(p => byProv[p.id]).length;

  return (
    <>
      <div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: 14 }}>
        <div style={{ fontSize: 13, fontWeight: 600 }}>חיבורים</div>
        <span style={{ fontSize: 11, color: 'var(--ink-soft)' }}>{connectedCount} מתוך {PROVIDERS.length} מחוברים</span>
      </div>
      <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
        {PROVIDERS.map(p => {
          const accts = byProv[p.id] || [];
          const isConnected = accts.length > 0;
          const totalBalance = accts.reduce((s, a) => s + a.balance, 0);
          return (
            <div key={p.id} style={{
              padding: '10px 12px',
              background: isConnected ? 'var(--bg-deep)' : 'transparent',
              border: isConnected ? 'none' : '0.5px dashed var(--rule)',
              borderRadius: 10,
              display: 'flex', alignItems: 'center', gap: 10,
            }}>
              <div style={{
                width: 36, height: 24, borderRadius: 5, background: p.color,
                display: 'flex', alignItems: 'center', justifyContent: 'center', color: 'white',
                fontSize: 9, fontWeight: 700, letterSpacing: '0.02em', flexShrink: 0,
                opacity: isConnected ? 1 : 0.5,
              }}>{p.label.slice(0,3).toUpperCase()}</div>

              <div style={{ flex: 1, minWidth: 0 }}>
                <div style={{ fontSize: 12.5, fontWeight: 500, display: 'flex', alignItems: 'center', gap: 6 }}>
                  {p.label}
                  {isConnected && <span style={{ fontSize: 9, color: 'var(--positive)' }}>●</span>}
                </div>
                <div style={{ fontSize: 10.5, color: 'var(--ink-soft)', fontFamily: 'var(--font-mono)' }}>
                  {isConnected
                    ? accts.map(a => a.holder).join(' · ')
                    : p.sub}
                </div>
              </div>

              {isConnected ? (
                <>
                  <div className="tnum" style={{ fontSize: 12, fontWeight: 600, color: totalBalance < 0 ? 'var(--ink)' : 'var(--positive)' }}>
                    {fmtILS(totalBalance)}
                  </div>
                  <button
                    onClick={() => onConnect(p.id)}
                    title="סנכרן עכשיו"
                    style={{
                      padding: '4px 8px', borderRadius: 7,
                      background: 'transparent', color: 'var(--ink-soft)',
                      border: '0.5px solid var(--rule)', cursor: 'pointer',
                      fontSize: 11, fontWeight: 500,
                    }}>↻</button>
                </>
              ) : (
                <button
                  onClick={() => onConnect(p.id)}
                  style={{
                    padding: '5px 11px', borderRadius: 7,
                    background: p.color, color: 'white', border: 'none',
                    cursor: 'pointer', fontSize: 11.5, fontWeight: 600,
                    whiteSpace: 'nowrap',
                  }}>↗ התחבר</button>
              )}
            </div>
          );
        })}
      </div>
    </>
  );
}

function LegendDot({ label, filled, dashed }) {
  return (
    <span style={{ display: 'inline-flex', alignItems: 'center', gap: 5 }}>
      {filled && <span style={{ width: 14, height: 2, background: 'var(--ink)', borderRadius: 1 }} />}
      {dashed && <span style={{ width: 14, height: 0, borderTop: '1.5px dashed var(--ink-soft)' }} />}
      {label}
    </span>
  );
}

function SideStat({ label, value, positive, muted }) {
  return (
    <div>
      <div style={{ fontSize: 11.5, color: 'var(--ink-soft)', marginBottom: 4 }}>{label}</div>
      <Money value={value} size={muted ? 16 : 24} weight={600} sign={positive} color={positive ? 'var(--positive)' : 'var(--ink)'} />
    </div>
  );
}

window.Dashboard = Dashboard;
