// Analytik — KPIs, YoY trends, predictions

function AnalyticsPage({ data, setRoute }) {
  const { properties, transactions, tenants } = data;

  // Empty state — analytics needs real data to render
  if (properties.length === 0 || transactions.length < 5) {
    return (
      <div className="page">
        <div className="page-header"><div><h1 className="page-title">Analytik</h1><div className="page-subtitle">KPIs, Trends, Prognosen</div></div></div>
        <div className="empty" style={{ padding: '60px 20px', textAlign: 'center' }}>
          <div style={{ fontSize: 36, marginBottom: 8 }}>📈</div>
          <div className="empty-title">Noch nicht genug Daten</div>
          <div style={{ color: 'var(--ink-3)', maxWidth: 400, margin: '0 auto' }}>Sobald du einige Objekte und Buchungen erfasst hast, zeigen wir hier Cashflow-Trends, Auslastung, Prognosen und YoY-Vergleiche.</div>
        </div>
      </div>
    );
  }

  // ───── Date helpers ─────
  const today = new Date(2026, 4, 1);
  const monthKey = (d) => `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}`;

  // YTD 2026 (Jan–Apr) vs YTD 2025 (Jan–Apr)
  const inRange = (date, year, monthsCount) => {
    const d = new Date(date);
    return d.getFullYear() === year && d.getMonth() < monthsCount;
  };

  const ytdMonths = 4; // Jan–Apr
  const cur = transactions.filter(t => inRange(t.date, 2026, ytdMonths));
  const prev = transactions.filter(t => inRange(t.date, 2025, ytdMonths));

  const sumIncome = (txns) => txns.filter(t => t.type === 'einnahme').reduce((s, t) => s + t.amount, 0);
  const sumExpense = (txns) => txns.filter(t => t.type === 'ausgabe').reduce((s, t) => s + Math.abs(t.amount), 0);

  const curIncome = sumIncome(cur);
  const prevIncome = sumIncome(prev);
  const curExpense = sumExpense(cur);
  const prevExpense = sumExpense(prev);
  const curNet = curIncome - curExpense;
  const prevNet = prevIncome - prevExpense;

  const pct = (now, then) => then === 0 ? 0 : ((now - then) / then) * 100;

  // Occupancy stats
  const totalUnits = properties.reduce((s, p) => s + p.units.length, 0);
  const occupiedUnits = properties.reduce((s, p) => s + p.units.filter(u => u.status === 'vermietet').length, 0);
  const occupancyRate = (occupiedUnits / totalUnits) * 100;

  // Average rent / m²
  const totalRent = properties.reduce((s, p) => s + p.units.reduce((x, u) => x + u.rent, 0), 0);
  const totalArea = properties.reduce((s, p) => s + p.units.reduce((x, u) => x + u.size, 0), 0);
  const rentPerSqm = totalRent / totalArea;

  // Total portfolio value
  const totalValue = properties.reduce((s, p) => s + p.purchasePrice, 0);
  const grossYield = ((totalRent * 12) / totalValue) * 100;

  // 24-month income/expense for trend chart with prediction
  const histMonths = [];
  for (let i = 23; i >= -7; i--) {
    const d = new Date(today.getFullYear(), today.getMonth() - i, 1);
    const key = monthKey(d);
    const inc = transactions.filter(t => t.date.startsWith(key) && t.type === 'einnahme').reduce((s, t) => s + t.amount, 0);
    const exp = transactions.filter(t => t.date.startsWith(key) && t.type === 'ausgabe').reduce((s, t) => s + Math.abs(t.amount), 0);
    const isFuture = d > today;
    histMonths.push({
      key, label: d.toLocaleDateString('de-DE', { month: 'short' }),
      year: d.getFullYear(),
      date: d,
      income: isFuture ? null : inc,
      expense: isFuture ? null : exp,
      net: isFuture ? null : inc - exp,
      isFuture,
    });
  }

  // Predictions: simple linear extrapolation + occupancy assumption
  const predIncome = totalRent * 0.97; // accounting for vacancy
  const avgMonthlyExp = curExpense / ytdMonths;
  histMonths.forEach(m => {
    if (m.isFuture) {
      // assume rent stays + small seasonal variance for expense
      const seasonal = m.date.getMonth() === 11 ? 1.4 : m.date.getMonth() === 6 ? 1.2 : 0.9;
      m.predIncome = predIncome;
      m.predExpense = avgMonthlyExp * seasonal;
      m.predNet = m.predIncome - m.predExpense;
    }
  });

  // Cashflow projection for full year 2026
  const projAnnualIncome = curIncome + predIncome * (12 - ytdMonths);
  const projAnnualExpense = curExpense + (avgMonthlyExp * (12 - ytdMonths) * 1.05);
  const projAnnualNet = projAnnualIncome - projAnnualExpense;

  // Per-property comparison
  const propStats = properties.map(p => {
    const cur = transactions.filter(t => t.propertyId === p.id && t.date.startsWith('2026') && t.type === 'einnahme').reduce((s, t) => s + t.amount, 0);
    const prev = transactions.filter(t => t.propertyId === p.id && t.date.startsWith('2025') && t.date < '2025-05-01' && t.type === 'einnahme').reduce((s, t) => s + t.amount, 0);
    const occ = p.units.filter(u => u.status === 'vermietet').length / p.units.length;
    return { ...p, curIncome: cur, prevIncome: prev, change: pct(cur, prev), occupancy: occ };
  });

  return (
    <div className="page">
      <div className="page-header">
        <div>
          <div style={{ fontSize: 11, textTransform: 'uppercase', letterSpacing: '0.12em', color: 'var(--ink-4)', marginBottom: 8 }}>Stand 1. Mai 2026</div>
          <h1 className="page-title">Analytik</h1>
          <div className="page-subtitle">Trends, Vergleiche zum Vorjahr und Vorhersagen</div>
        </div>
        <div className="page-actions">
          <button className="btn">Zeitraum: YTD 2026</button>
          <button className="btn btn-primary">Bericht erzeugen</button>
        </div>
      </div>

      <KpiBigGrid
        items={[
          { label: 'Einnahmen YTD', value: fmtEUR(curIncome), delta: pct(curIncome, prevIncome), prevLabel: `${fmtEUR(prevIncome)} VJ` },
          { label: 'Ausgaben YTD', value: fmtEUR(curExpense), delta: pct(curExpense, prevExpense), prevLabel: `${fmtEUR(prevExpense)} VJ`, negativeIsGood: true },
          { label: 'Netto-Cashflow', value: fmtEUR(curNet), delta: pct(curNet, prevNet), prevLabel: `${fmtEUR(prevNet)} VJ` },
          { label: 'Auslastung', value: occupancyRate.toFixed(1) + ' %', delta: 0, prevLabel: `${occupiedUnits} / ${totalUnits} Einheiten`, hideDelta: true },
          { label: 'Ø Miete / m²', value: '€ ' + rentPerSqm.toFixed(2), delta: 3.4, prevLabel: 'Vergleich Q1' },
          { label: 'Bruttorendite', value: grossYield.toFixed(2) + ' %', delta: 0, prevLabel: 'Über alle Objekte', hideDelta: true },
          { label: 'Portfolio-Wert', value: fmtEUR(totalValue), delta: 6.2, prevLabel: 'Marktwert geschätzt' },
          { label: 'Mieter-Fluktuation', value: '8,3 %', delta: -2.1, prevLabel: 'Letzte 12 Monate', negativeIsGood: true },
        ]}
      />

      <div className="section">
        <div className="section-header">
          <h2 className="section-title">Cashflow-Trend mit Prognose</h2>
          <div className="text-muted" style={{ fontSize: 11.5 }}>Mai 2024 – Dez 2026 · ✦ Vorhersage</div>
        </div>
        <TrendChart data={histMonths} today={today} />
      </div>

      <div className="two-col">
        <div className="section" style={{ marginBottom: 0 }}>
          <div className="section-header"><h2 className="section-title">Jahresprognose 2026</h2></div>
          <ProjectionCard
            curIncome={curIncome} curExpense={curExpense}
            projAnnualIncome={projAnnualIncome}
            projAnnualExpense={projAnnualExpense}
            projAnnualNet={projAnnualNet}
            ytdMonths={ytdMonths}
          />
        </div>
        <div className="section" style={{ marginBottom: 0 }}>
          <div className="section-header"><h2 className="section-title">Verteilungen</h2></div>
          <DistributionPanel transactions={transactions} />
        </div>
      </div>

      <div className="section">
        <div className="section-header">
          <h2 className="section-title">Objekte im Vergleich zum Vorjahr</h2>
        </div>
        <YoYTable propStats={propStats} setRoute={setRoute} />
      </div>

      <div className="section">
        <div className="section-header">
          <h2 className="section-title">Vorausschauende Hinweise</h2>
          <div className="text-muted" style={{ fontSize: 11.5 }}>Modell-basiert · 60 Tage Horizont</div>
        </div>
        <PredictionsList />
      </div>
    </div>
  );
}

// ───── KPI Grid ─────

function KpiBigGrid({ items }) {
  return (
    <div className="kpi-big-grid">
      {items.map((k, i) => (
        <div key={i} className="kpi-big">
          <div className="kpi-label">{k.label}</div>
          <div className="kpi-value">{k.value}</div>
          <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline', gap: 8 }}>
            <span className="kpi-meta">{k.prevLabel}</span>
            {!k.hideDelta && k.delta !== 0 && (
              <DeltaBadge delta={k.delta} negativeIsGood={k.negativeIsGood} />
            )}
          </div>
        </div>
      ))}
    </div>
  );
}

function DeltaBadge({ delta, negativeIsGood }) {
  const positive = delta > 0;
  const isGood = negativeIsGood ? !positive : positive;
  const arrow = positive ? '↑' : '↓';
  return (
    <span style={{
      fontSize: 11,
      fontWeight: 500,
      color: isGood ? 'var(--pos)' : 'var(--neg)',
      fontVariantNumeric: 'tabular-nums',
    }}>
      {arrow} {Math.abs(delta).toFixed(1)}%
    </span>
  );
}

// ───── Trend Chart with Prediction ─────

function TrendChart({ data, today }) {
  const W = 1200, H = 320;
  const pad = { l: 50, r: 30, t: 16, b: 36 };
  const cw = W - pad.l - pad.r, ch = H - pad.t - pad.b;

  const allVals = data.flatMap(d => [d.income, d.expense, d.predIncome, d.predExpense].filter(v => v != null));
  const max = Math.max(...allVals) * 1.1;
  const niceMax = Math.ceil(max / 5000) * 5000;
  const ticks = [0, 0.25, 0.5, 0.75, 1].map(t => Math.round(niceMax * t));

  const xFor = (i) => pad.l + (cw / (data.length - 1)) * i;
  const yFor = (v) => pad.t + ch - (v / niceMax) * ch;

  const buildLine = (key) => data.map((d, i) => {
    if (d[key] == null) return null;
    return `${i === 0 || data[i - 1][key] == null ? 'M' : 'L'} ${xFor(i)} ${yFor(d[key])}`;
  }).filter(Boolean).join(' ');

  const incPath = buildLine('income');
  const expPath = buildLine('expense');
  const predIncPath = buildLine('predIncome');
  const predExpPath = buildLine('predExpense');

  // Find today line
  const todayIdx = data.findIndex(d => d.isFuture);
  const todayX = todayIdx > 0 ? xFor(todayIdx - 0.5) : null;

  return (
    <div className="chart-frame">
      <svg viewBox={`0 0 ${W} ${H}`} style={{ width: '100%', height: 'auto', display: 'block' }}>
        {/* gridlines */}
        <g className="chart-grid">
          {ticks.map((t, i) => {
            const y = yFor(t);
            return <line key={i} x1={pad.l} x2={W - pad.r} y1={y} y2={y} />;
          })}
        </g>

        {/* prediction shaded zone */}
        {todayX != null && (
          <rect x={todayX} y={pad.t} width={W - pad.r - todayX} height={ch} fill="var(--bg-sunken)" opacity="0.6" />
        )}

        {/* axes */}
        <g className="chart-axis">
          {ticks.map((t, i) => <text key={i} x={pad.l - 8} y={yFor(t) + 3} textAnchor="end">{(t / 1000).toFixed(0)}k</text>)}
          {data.map((d, i) => {
            if (i % 3 !== 0) return null;
            return (
              <text key={i} x={xFor(i)} y={H - 14} textAnchor="middle">
                {d.label}{d.date.getMonth() === 0 ? ` '${String(d.year).slice(2)}` : ''}
              </text>
            );
          })}
        </g>

        {/* "Heute" marker */}
        {todayX != null && (
          <g>
            <line x1={todayX} x2={todayX} y1={pad.t} y2={pad.t + ch} stroke="var(--ink-3)" strokeWidth="1" strokeDasharray="3 3" />
            <text x={todayX + 6} y={pad.t + 12} fill="var(--ink-3)" fontSize="10" fontFamily="var(--font-sans)">heute</text>
          </g>
        )}

        {/* historical lines */}
        <path d={incPath} stroke="var(--accent)" strokeWidth="2" fill="none" />
        <path d={expPath} stroke="var(--ink-4)" strokeWidth="1.5" fill="none" />

        {/* prediction lines (dashed) */}
        <path d={predIncPath} stroke="var(--accent)" strokeWidth="2" fill="none" strokeDasharray="4 4" opacity="0.7" />
        <path d={predExpPath} stroke="var(--ink-4)" strokeWidth="1.5" fill="none" strokeDasharray="4 4" opacity="0.7" />

        {/* dots on income line */}
        {data.map((d, i) => d.income != null && (
          <circle key={`hi${i}`} cx={xFor(i)} cy={yFor(d.income)} r="2" fill="var(--accent)" />
        ))}
      </svg>
      <div className="chart-legend">
        <span className="chart-legend-item"><span className="chart-legend-swatch" style={{ background: 'var(--accent)' }}></span> Einnahmen</span>
        <span className="chart-legend-item"><span className="chart-legend-swatch" style={{ background: 'var(--ink-4)' }}></span> Ausgaben</span>
        <span className="chart-legend-item"><span style={{ display: 'inline-block', width: 18, borderTop: '2px dashed var(--accent)' }}></span> Prognose</span>
      </div>
    </div>
  );
}

// ───── Projection Card ─────

function ProjectionCard({ curIncome, curExpense, projAnnualIncome, projAnnualExpense, projAnnualNet, ytdMonths }) {
  const completion = (ytdMonths / 12) * 100;
  return (
    <div style={{ border: '1px solid var(--line)', borderRadius: 'var(--radius-lg)', padding: '24px 28px', background: 'var(--bg-elev)' }}>
      <div style={{ marginBottom: 24 }}>
        <div style={{ fontSize: 11, textTransform: 'uppercase', letterSpacing: '0.1em', color: 'var(--ink-3)', marginBottom: 4 }}>Erwarteter Jahresnetto 2026</div>
        <div style={{ fontFamily: 'var(--font-serif)', fontSize: 38, fontWeight: 400, fontVariantNumeric: 'tabular-nums' }}>
          {fmtEUR(projAnnualNet)}
        </div>
        <div style={{ fontSize: 12, color: 'var(--ink-3)', marginTop: 4 }}>Hochrechnung mit aktueller Auslastung</div>
      </div>

      <div className="proj-bar-wrap">
        <div className="proj-bar-track">
          <div className="proj-bar-fill" style={{ width: `${completion}%` }}></div>
        </div>
        <div className="proj-bar-labels">
          <span>YTD ({completion.toFixed(0)} %)</span>
          <span>Prognose Rest</span>
        </div>
      </div>

      <div style={{ marginTop: 24, display: 'flex', flexDirection: 'column', gap: 12, paddingTop: 16, borderTop: '1px solid var(--line)' }}>
        <KvLine k="Einnahmen Prognose" v={fmtEUR(projAnnualIncome)} sub={`${fmtEUR(curIncome)} bereits realisiert`} />
        <KvLine k="Ausgaben Prognose" v={fmtEUR(projAnnualExpense)} sub={`${fmtEUR(curExpense)} bereits realisiert`} tone="neg" />
        <KvLine k="Steuer geschätzt" v={fmtEUR(projAnnualNet * 0.32)} sub="32 % Grenzsteuersatz angenommen" tone="muted" />
      </div>
    </div>
  );
}

function KvLine({ k, v, sub, tone }) {
  return (
    <div>
      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline' }}>
        <span style={{ fontSize: 13, color: 'var(--ink-2)' }}>{k}</span>
        <span style={{
          fontFamily: 'var(--font-serif)',
          fontSize: 17,
          fontVariantNumeric: 'tabular-nums',
          color: tone === 'neg' ? 'var(--neg)' : tone === 'muted' ? 'var(--ink-3)' : 'var(--ink)',
        }}>{v}</span>
      </div>
      {sub && <div style={{ fontSize: 11, color: 'var(--ink-4)', marginTop: 2 }}>{sub}</div>}
    </div>
  );
}

// ───── Distribution Panel ─────

function DistributionPanel({ transactions }) {
  const cats = {};
  transactions.filter(t => t.date.startsWith('2026') && t.type === 'ausgabe').forEach(t => {
    cats[t.category] = (cats[t.category] || 0) + Math.abs(t.amount);
  });
  const total = Object.values(cats).reduce((s, v) => s + v, 0);
  const entries = Object.entries(cats).sort((a, b) => b[1] - a[1]);

  // Donut chart
  const R = 60, r = 36;
  let cumAngle = -Math.PI / 2;
  const colors = ['var(--accent)', 'var(--ink)', 'var(--ink-3)', 'var(--warn)', 'var(--ink-4)', 'var(--ink-5)'];
  const segs = entries.map(([cat, val], i) => {
    const angle = (val / total) * Math.PI * 2;
    const startA = cumAngle;
    cumAngle += angle;
    const endA = cumAngle;
    const x1 = 75 + R * Math.cos(startA), y1 = 75 + R * Math.sin(startA);
    const x2 = 75 + R * Math.cos(endA), y2 = 75 + R * Math.sin(endA);
    const x3 = 75 + r * Math.cos(endA), y3 = 75 + r * Math.sin(endA);
    const x4 = 75 + r * Math.cos(startA), y4 = 75 + r * Math.sin(startA);
    const large = angle > Math.PI ? 1 : 0;
    const path = `M ${x1} ${y1} A ${R} ${R} 0 ${large} 1 ${x2} ${y2} L ${x3} ${y3} A ${r} ${r} 0 ${large} 0 ${x4} ${y4} Z`;
    return { path, cat, val, color: colors[i % colors.length] };
  });

  return (
    <div style={{ border: '1px solid var(--line)', borderRadius: 'var(--radius-lg)', padding: 24, background: 'var(--bg-elev)' }}>
      <div style={{ display: 'flex', alignItems: 'center', gap: 24 }}>
        <div style={{ position: 'relative', flexShrink: 0 }}>
          <svg viewBox="0 0 150 150" style={{ width: 150, height: 150 }}>
            {segs.map((s, i) => <path key={i} d={s.path} fill={s.color} />)}
          </svg>
          <div style={{ position: 'absolute', inset: 0, display: 'flex', alignItems: 'center', justifyContent: 'center', flexDirection: 'column' }}>
            <div style={{ fontSize: 10.5, textTransform: 'uppercase', letterSpacing: '0.08em', color: 'var(--ink-3)' }}>Ausgaben</div>
            <div style={{ fontFamily: 'var(--font-serif)', fontSize: 16, fontVariantNumeric: 'tabular-nums' }}>{fmtEUR(total)}</div>
          </div>
        </div>
        <div style={{ flex: 1, display: 'flex', flexDirection: 'column', gap: 8 }}>
          {segs.map((s, i) => (
            <div key={i} style={{ display: 'flex', alignItems: 'center', gap: 8, fontSize: 12.5 }}>
              <span style={{ width: 8, height: 8, background: s.color, borderRadius: 2, flexShrink: 0 }}></span>
              <span style={{ flex: 1, color: 'var(--ink-2)' }}>{s.cat}</span>
              <span style={{ fontVariantNumeric: 'tabular-nums', color: 'var(--ink)', fontWeight: 500 }}>{fmtEUR(s.val)}</span>
              <span style={{ fontVariantNumeric: 'tabular-nums', color: 'var(--ink-4)', fontSize: 11, minWidth: 36, textAlign: 'right' }}>
                {((s.val / total) * 100).toFixed(0)}%
              </span>
            </div>
          ))}
        </div>
      </div>
    </div>
  );
}

// ───── YoY Table ─────

function YoYTable({ propStats, setRoute }) {
  const maxIncome = Math.max(...propStats.map(p => p.curIncome));
  return (
    <div className="table-wrap">
      <table className="table">
        <thead>
          <tr>
            <th>Objekt</th>
            <th>Auslastung</th>
            <th className="num">Einn. YTD 2026</th>
            <th className="num">Einn. YTD 2025</th>
            <th>Veränderung</th>
            <th>Trend</th>
          </tr>
        </thead>
        <tbody>
          {propStats.map(p => (
            <tr key={p.id} onClick={() => setRoute({ page: 'properties', propertyId: p.id })}>
              <td>
                <div className="strong">{p.name}</div>
                <div className="muted" style={{ fontSize: 11.5 }}>{p.units.length} Einheiten</div>
              </td>
              <td>
                <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
                  <div style={{ width: 60, height: 4, background: 'var(--line)', borderRadius: 2, overflow: 'hidden' }}>
                    <div style={{ width: `${p.occupancy * 100}%`, height: '100%', background: 'var(--accent)' }}></div>
                  </div>
                  <span className="muted" style={{ fontSize: 11.5, fontVariantNumeric: 'tabular-nums' }}>
                    {(p.occupancy * 100).toFixed(0)}%
                  </span>
                </div>
              </td>
              <td className="num strong">{fmtEUR(p.curIncome)}</td>
              <td className="num muted">{fmtEUR(p.prevIncome)}</td>
              <td><DeltaBadge delta={p.change} /></td>
              <td>
                <MiniSpark value={p.curIncome} max={maxIncome} change={p.change} />
              </td>
            </tr>
          ))}
        </tbody>
      </table>
    </div>
  );
}

function MiniSpark({ change }) {
  const positive = change > 0;
  const points = positive
    ? "0,16 8,14 16,12 24,10 32,6 40,4"
    : "0,4 8,5 16,8 24,11 32,13 40,15";
  return (
    <svg viewBox="0 0 40 20" style={{ width: 60, height: 20 }}>
      <polyline points={points} fill="none" stroke={positive ? 'var(--pos)' : 'var(--neg)'} strokeWidth="1.4" />
    </svg>
  );
}

// ───── Predictions list ─────

const PREDICTIONS = [
  {
    title: 'Wohnung 4 Lindenstraße — Neuvermietung Q3',
    prob: 0.82,
    impact: '+1.080 €/Monat',
    horizon: '60 Tage',
    body: 'Modell schätzt Vermarktungsdauer auf 38 Tage basierend auf Vergleichsangeboten. Bei zügiger Renovierung Erstbezug Juli realistisch.',
    tone: 'pos',
  },
  {
    title: 'Mieter Maier (Stadtpark 7 W3) — kein Anschlussvertrag',
    prob: 0.91,
    impact: '−1.290 €/Monat',
    horizon: '31. Juli',
    body: 'Kündigung bereits vorliegend. Neuvermietungsdauer in München Westend liegt bei 14–28 Tagen.',
    tone: 'neg',
  },
  {
    title: 'Heizölpreis-Anstieg erwartet',
    prob: 0.66,
    impact: '+340 € Heizkosten Q4',
    horizon: '120 Tage',
    body: 'Marktdaten zeigen +12 % Großhandelspreis seit März. Frühbestellung im Juni statistisch günstigster Zeitpunkt.',
    tone: 'warn',
  },
  {
    title: 'Café Mira Indexmiete-Anpassung',
    prob: 0.95,
    impact: '+55 €/Monat ab Sept.',
    horizon: 'Sept. 2026',
    body: 'VPI-Anpassung gemäß Mietvertrag automatisch. Anpassung ankündigen empfohlen 2 Monate vorab.',
    tone: 'pos',
  },
];

function PredictionsList() {
  return (
    <div style={{ display: 'grid', gridTemplateColumns: 'repeat(2, 1fr)', gap: 16 }}>
      {PREDICTIONS.map((p, i) => (
        <div key={i} className="prediction-card">
          <div className="prediction-head">
            <div className={`prediction-impact ${p.tone}`}>{p.impact}</div>
            <div className="prediction-prob">
              <span className="l">Wahrscheinlichkeit</span>
              <span className="v">{Math.round(p.prob * 100)} %</span>
            </div>
          </div>
          <div className="prediction-title">{p.title}</div>
          <div className="prediction-body">{p.body}</div>
          <div className="prediction-foot">
            <span style={{ fontSize: 10.5, textTransform: 'uppercase', letterSpacing: '0.1em', color: 'var(--ink-4)' }}>
              Horizont · {p.horizon}
            </span>
            <ProbBar prob={p.prob} />
          </div>
        </div>
      ))}
    </div>
  );
}

function ProbBar({ prob }) {
  return (
    <div style={{ width: 80, height: 3, background: 'var(--line)', borderRadius: 2 }}>
      <div style={{ width: `${prob * 100}%`, height: '100%', background: 'var(--ink)', borderRadius: 2 }}></div>
    </div>
  );
}

Object.assign(window, { AnalyticsPage });
