import { useState, useEffect } from 'react'
import { useNavigate } from 'react-router-dom'
import { LineChart, Line, XAxis, YAxis, Tooltip, ResponsiveContainer, CartesianGrid, Legend } from 'recharts'
import { api } from '../utils/api'
import KpiTilesOverview from './KpiTilesOverview'
import { getStatusColor, getStatusBg } from '../utils/interpret'
import dayjs from 'dayjs'

const fmtDate = (d) => dayjs(d).format('DD.MM.')

function insightBulletStripe(tone) {
  if (tone === 'good') return getStatusColor('good')
  if (tone === 'bad') return getStatusColor('bad')
  if (tone === 'neutral') return '#6B7280'
  return getStatusColor('warn')
}

function ChartCard({ title, loading, error, children }) {
  return (
    <div className="card" style={{ marginBottom: 12 }}>
      <div style={{ fontSize: 12, fontWeight: 600, color: 'var(--text3)', marginBottom: 8 }}>{title}</div>
      {loading && (
        <div style={{ display: 'flex', justifyContent: 'center', padding: 40 }}>
          <div className="spinner" style={{ width: 32, height: 32 }} />
        </div>
      )}
      {error && (
        <div style={{ padding: 20, textAlign: 'center', color: 'var(--text3)', fontSize: 12 }}>{error}</div>
      )}
      {!loading && !error && children}
    </div>
  )
}

/**
 * Layer 2b: Erholung — ein Request GET /api/charts/recovery-dashboard-viz (recovery_metrics).
 */
export default function RecoveryDashboardOverview({
  period: periodProp,
  onPeriodChange,
  hidePeriodSelector = false,
}) {
  const nav = useNavigate()
  const [internalPeriod, setInternalPeriod] = useState(28)
  const controlled = periodProp !== undefined && typeof onPeriodChange === 'function'
  const period = controlled ? periodProp : internalPeriod
  const setPeriod = controlled ? onPeriodChange : setInternalPeriod

  const [viz, setViz] = useState(null)
  const [loading, setLoading] = useState(true)
  const [err, setErr] = useState(null)

  useEffect(() => {
    let cancelled = false
    setLoading(true)
    setErr(null)
    api
      .getRecoveryDashboardViz(period)
      .then((v) => {
        if (!cancelled) setViz(v)
      })
      .catch((e) => {
        if (!cancelled) setErr(e.message || 'Laden fehlgeschlagen')
      })
      .finally(() => {
        if (!cancelled) setLoading(false)
      })
    return () => {
      cancelled = true
    }
  }, [period])

  if (loading) {
    return (
      <div className="card section-gap">
        <div className="card-title">Erholung & Vitalwerte</div>
        <div className="spinner" style={{ margin: 24 }} />
      </div>
    )
  }

  if (err) {
    return (
      <div className="card section-gap">
        <div className="card-title">Erholung & Vitalwerte</div>
        <div style={{ color: 'var(--danger)' }}>{err}</div>
      </div>
    )
  }

  if (!viz?.has_recovery_data) {
    return (
      <div className="card section-gap">
        <div className="card-title">Erholung & Vitalwerte</div>
        <p style={{ fontSize: 12, color: 'var(--text3)', lineHeight: 1.45, marginBottom: 14 }}>
          {viz?.message || 'Noch keine Schlaf- oder Vitaldaten.'} Sobald du Schlaf oder morgendliche Vitalwerte erfasst
          oder importierst, erscheinen Auswertungen hier.
        </p>
        <button type="button" className="btn btn-primary" onClick={() => nav('/vitals')}>
          Zu Vitalwerten
        </button>
      </div>
    )
  }

  const recoveryData = viz.charts?.recovery_score
  const hrvRhrData = viz.charts?.hrv_rhr
  const sleepData = viz.charts?.sleep_duration_quality
  const debtData = viz.charts?.sleep_debt
  const vitalsData = viz.charts?.vital_signs_matrix
  const vitalsHistory = viz.charts?.vitals_history

  const kpiTiles = (viz.kpi_tiles || []).map((t) => ({
    ...t,
    sublabel:
      typeof t.sublabel === 'string' && t.sublabel.length > 42 ? `${t.sublabel.slice(0, 40)}…` : t.sublabel,
  }))
  const insights = viz.progress_insights || []
  const eff = viz.effective_window_days
  const cDays = viz.chart_days_used
  const vDays = viz.vital_matrix_days_used

  const showPeriodDropdown = !hidePeriodSelector && !controlled

  const renderRecoveryScore = () => {
    if (!recoveryData || recoveryData.metadata?.confidence === 'insufficient') {
      return (
        <div style={{ padding: 20, textAlign: 'center', color: 'var(--text3)', fontSize: 12 }}>
          Keine Recovery-Daten im Fenster
        </div>
      )
    }
    const chartData = recoveryData.data.labels.map((label, i) => ({
      date: fmtDate(label),
      score: recoveryData.data.datasets[0]?.data[i],
    }))
    return (
      <>
        <ResponsiveContainer width="100%" height={200}>
          <LineChart data={chartData} margin={{ top: 4, right: 8, bottom: 0, left: -20 }}>
            <CartesianGrid stroke="var(--border)" strokeDasharray="3 3" />
            <XAxis
              dataKey="date"
              tick={{ fontSize: 9, fill: 'var(--text3)' }}
              tickLine={false}
              interval={Math.max(0, Math.floor(chartData.length / 6) - 1)}
            />
            <YAxis tick={{ fontSize: 9, fill: 'var(--text3)' }} tickLine={false} domain={[0, 100]} />
            <Tooltip
              contentStyle={{
                background: 'var(--surface)',
                border: '1px solid var(--border)',
                borderRadius: 8,
                fontSize: 11,
              }}
            />
            <Line type="monotone" dataKey="score" stroke="#1D9E75" strokeWidth={2} name="Recovery Score" dot={{ r: 2 }} />
          </LineChart>
        </ResponsiveContainer>
        <div style={{ marginTop: 8, fontSize: 10, color: 'var(--text3)', textAlign: 'center' }}>
          Aktuell: {recoveryData.metadata.current_score}/100 · {recoveryData.metadata.data_points} Einträge
        </div>
      </>
    )
  }

  const renderHrvRhr = () => {
    if (!hrvRhrData || hrvRhrData.metadata?.confidence === 'insufficient') {
      return (
        <div style={{ padding: 20, textAlign: 'center', color: 'var(--text3)', fontSize: 12 }}>
          Keine Vitalwerte im Fenster
        </div>
      )
    }
    const chartData = hrvRhrData.data.labels.map((label, i) => ({
      date: fmtDate(label),
      hrv: hrvRhrData.data.datasets[0]?.data[i],
      rhr: hrvRhrData.data.datasets[1]?.data[i],
    }))
    return (
      <>
        <ResponsiveContainer width="100%" height={200}>
          <LineChart data={chartData} margin={{ top: 4, right: 8, bottom: 0, left: -20 }}>
            <CartesianGrid stroke="var(--border)" strokeDasharray="3 3" />
            <XAxis
              dataKey="date"
              tick={{ fontSize: 9, fill: 'var(--text3)' }}
              tickLine={false}
              interval={Math.max(0, Math.floor(chartData.length / 6) - 1)}
            />
            <YAxis yAxisId="left" tick={{ fontSize: 9, fill: 'var(--text3)' }} tickLine={false} />
            <YAxis yAxisId="right" orientation="right" tick={{ fontSize: 9, fill: 'var(--text3)' }} tickLine={false} />
            <Tooltip
              contentStyle={{
                background: 'var(--surface)',
                border: '1px solid var(--border)',
                borderRadius: 8,
                fontSize: 11,
              }}
            />
            <Line yAxisId="left" type="monotone" dataKey="hrv" stroke="#1D9E75" strokeWidth={2} name="HRV (ms)" dot={{ r: 2 }} />
            <Line yAxisId="right" type="monotone" dataKey="rhr" stroke="#3B82F6" strokeWidth={2} name="RHR (bpm)" dot={{ r: 2 }} />
          </LineChart>
        </ResponsiveContainer>
        <div style={{ marginTop: 8, fontSize: 10, color: 'var(--text3)', textAlign: 'center' }}>
          HRV Ø {hrvRhrData.metadata.avg_hrv}ms · RHR Ø {hrvRhrData.metadata.avg_rhr}bpm
        </div>
      </>
    )
  }

  const renderSleepQuality = () => {
    if (!sleepData || sleepData.metadata?.confidence === 'insufficient') {
      return (
        <div style={{ padding: 20, textAlign: 'center', color: 'var(--text3)', fontSize: 12 }}>
          Keine Schlafdaten im Fenster
        </div>
      )
    }
    const chartData = sleepData.data.labels.map((label, i) => ({
      date: fmtDate(label),
      duration: sleepData.data.datasets[0]?.data[i],
      quality: sleepData.data.datasets[1]?.data[i],
    }))
    return (
      <>
        <ResponsiveContainer width="100%" height={200}>
          <LineChart data={chartData} margin={{ top: 4, right: 8, bottom: 0, left: -20 }}>
            <CartesianGrid stroke="var(--border)" strokeDasharray="3 3" />
            <XAxis
              dataKey="date"
              tick={{ fontSize: 9, fill: 'var(--text3)' }}
              tickLine={false}
              interval={Math.max(0, Math.floor(chartData.length / 6) - 1)}
            />
            <YAxis yAxisId="left" tick={{ fontSize: 9, fill: 'var(--text3)' }} tickLine={false} />
            <YAxis yAxisId="right" orientation="right" tick={{ fontSize: 9, fill: 'var(--text3)' }} tickLine={false} domain={[0, 100]} />
            <Tooltip
              contentStyle={{
                background: 'var(--surface)',
                border: '1px solid var(--border)',
                borderRadius: 8,
                fontSize: 11,
              }}
            />
            <Line yAxisId="left" type="monotone" dataKey="duration" stroke="#3B82F6" strokeWidth={2} name="Dauer (h)" dot={{ r: 2 }} />
            <Line yAxisId="right" type="monotone" dataKey="quality" stroke="#1D9E75" strokeWidth={2} name="Qualität (%)" dot={{ r: 2 }} />
          </LineChart>
        </ResponsiveContainer>
        <div style={{ marginTop: 8, fontSize: 10, color: 'var(--text3)', textAlign: 'center' }}>
          Ø {sleepData.metadata.avg_duration_hours}h Schlaf
        </div>
      </>
    )
  }

  const renderSleepDebt = () => {
    if (!debtData || debtData.metadata?.confidence === 'insufficient') {
      return (
        <div style={{ padding: 20, textAlign: 'center', color: 'var(--text3)', fontSize: 12 }}>
          Keine Schlafdaten für Schulden-Berechnung
        </div>
      )
    }
    const chartData = debtData.data.labels.map((label, i) => ({
      date: fmtDate(label),
      debt: debtData.data.datasets[0]?.data[i],
    }))
    const curDebt = debtData.metadata?.current_debt_hours
    return (
      <>
        <ResponsiveContainer width="100%" height={200}>
          <LineChart data={chartData} margin={{ top: 4, right: 8, bottom: 0, left: -20 }}>
            <CartesianGrid stroke="var(--border)" strokeDasharray="3 3" />
            <XAxis
              dataKey="date"
              tick={{ fontSize: 9, fill: 'var(--text3)' }}
              tickLine={false}
              interval={Math.max(0, Math.floor(chartData.length / 6) - 1)}
            />
            <YAxis tick={{ fontSize: 9, fill: 'var(--text3)' }} tickLine={false} />
            <Tooltip
              contentStyle={{
                background: 'var(--surface)',
                border: '1px solid var(--border)',
                borderRadius: 8,
                fontSize: 11,
              }}
            />
            <Line type="monotone" dataKey="debt" stroke="#EF4444" strokeWidth={2} name="Schlafschuld (h)" dot={{ r: 2 }} />
          </LineChart>
        </ResponsiveContainer>
        <div style={{ marginTop: 8, fontSize: 10, color: 'var(--text3)', textAlign: 'center' }}>
          Aktuelle Schuld: {curDebt != null ? Number(curDebt).toFixed(1) : '—'}h
        </div>
      </>
    )
  }

  const renderVitalsHistory = () => {
    const vh = vitalsHistory
    if (!vh) {
      return <div style={{ padding: 16, fontSize: 12, color: 'var(--text3)' }}>Keine Verlaufs-Daten (Bundle).</div>
    }
    if (vh.metadata?.confidence === 'insufficient') {
      return (
        <div style={{ padding: 16, fontSize: 12, color: 'var(--text3)', lineHeight: 1.5 }}>
          {vh.metadata?.message || 'Zu wenige Vitaldaten im gewählten Fenster für Verläufe.'}
        </div>
      )
    }
    const series = vh.series || {}
    const keys = Object.keys(series)
    const paragraphs = vh.analytics?.consolidated_paragraphs || []
    const bullets = vh.analytics?.bullets || []
    const showParagraphs = paragraphs.length > 0
    const showBulletsFallback = !showParagraphs && bullets.length > 0

    return (
      <div style={{ width: '100%', minWidth: 0 }}>
        {showParagraphs ? (
          <div style={{ marginBottom: 14 }}>
            <div style={{ fontSize: 12, fontWeight: 600, color: 'var(--text3)', marginBottom: 8 }}>
              Einordnung (Vital & Belastung)
            </div>
            <div
              style={{
                borderRadius: 8,
                padding: '12px 14px',
                border: '1px solid var(--border)',
                background: 'var(--surface2)',
                fontSize: 12,
                color: 'var(--text2)',
                lineHeight: 1.55,
              }}
            >
              {paragraphs.map((text, i) => (
                <p key={i} style={{ margin: i === 0 ? 0 : '10px 0 0' }}>
                  {text}
                </p>
              ))}
            </div>
          </div>
        ) : null}

        {showBulletsFallback ? (
          <div style={{ marginBottom: 14 }}>
            <div style={{ fontSize: 12, fontWeight: 600, color: 'var(--text3)', marginBottom: 8 }}>
              Einordnung (Vital & Belastung)
            </div>
            <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
              {bullets.map((b) => (
                <div
                  key={b.key}
                  style={{
                    borderRadius: 8,
                    padding: '10px 12px',
                    border: '1px solid var(--border)',
                    borderLeft: `4px solid ${insightBulletStripe(b.tone)}`,
                    background: 'var(--surface2)',
                  }}
                >
                  <div style={{ fontSize: 12, fontWeight: 600, marginBottom: 4 }}>{b.title}</div>
                  <div style={{ fontSize: 12, color: 'var(--text2)', lineHeight: 1.45 }}>{b.body}</div>
                </div>
              ))}
            </div>
          </div>
        ) : null}

        <div style={{ fontSize: 11, color: 'var(--text3)', marginBottom: 8 }}>
          Je Kennzahl eigene Skala (physische Einheit). Gestrichelt: gleitender Mittelwert (max. 7 aufeinanderfolgende
          Messungen), glättet starke Einzelschwankungen.
        </div>

        {keys.map((k) => {
          const m = series[k]
          const pts = m.points || []
          const maPts = m.points_ma7 || []
          if (pts.length === 0) return null
          const chartData = pts.map((p, i) => ({
            ...p,
            d: fmtDate(p.date),
            value_ma: maPts[i]?.value != null ? maPts[i].value : null,
          }))
          const vals = []
          pts.forEach((p, i) => {
            vals.push(p.value)
            if (maPts[i]?.value != null) vals.push(maPts[i].value)
          })
          const mn = Math.min(...vals)
          const mx = Math.max(...vals)
          const span = mx - mn
          const pad = span < 1e-9 ? Math.max(Math.abs(mn) * 0.05, 0.5) : span * 0.12
          const hasMa = maPts.length > 0 && maPts.some((x) => x?.value != null)

          return (
            <div key={k} style={{ marginBottom: 16, width: '100%' }}>
              <div style={{ fontSize: 11, fontWeight: 600, color: 'var(--text2)', marginBottom: 4 }}>
                {m.label_de} ({m.unit})
                {m.n != null ? (
                  <span style={{ fontWeight: 400, color: 'var(--text3)' }}> · n = {m.n}</span>
                ) : null}
                {m.mean != null ? (
                  <span style={{ fontWeight: 400, color: 'var(--text3)' }}> · Ø {m.mean}</span>
                ) : null}
              </div>
              {pts.length === 1 ? (
                <div style={{ fontSize: 12, color: 'var(--text3)', padding: '8px 0' }}>
                  Ein Messpunkt ({m.last}) — weiter erfassen, um einen Verlauf zu sehen.
                </div>
              ) : (
                <div style={{ width: '100%', height: hasMa ? 220 : 200, minHeight: hasMa ? 220 : 200 }}>
                  <ResponsiveContainer width="100%" height="100%">
                    <LineChart data={chartData} margin={{ top: 4, right: 12, bottom: 0, left: 0 }}>
                      <CartesianGrid stroke="var(--border)" strokeDasharray="3 3" />
                      <XAxis dataKey="d" tick={{ fontSize: 9, fill: 'var(--text3)' }} interval="preserveStartEnd" />
                      <YAxis
                        domain={[mn - pad, mx + pad]}
                        tick={{ fontSize: 9, fill: 'var(--text3)' }}
                        width={44}
                      />
                      <Tooltip
                        contentStyle={{
                          background: 'var(--surface)',
                          border: '1px solid var(--border)',
                          borderRadius: 8,
                          fontSize: 11,
                        }}
                      />
                      {hasMa ? <Legend wrapperStyle={{ fontSize: 10, paddingTop: 4 }} /> : null}
                      <Line
                        type="monotone"
                        dataKey="value"
                        stroke={m.color || '#1D9E75'}
                        strokeWidth={2}
                        dot={{ r: 3 }}
                        name="Messwert"
                      />
                      {hasMa ? (
                        <Line
                          type="monotone"
                          dataKey="value_ma"
                          stroke={m.color || '#1D9E75'}
                          strokeOpacity={0.55}
                          strokeWidth={2}
                          strokeDasharray="5 5"
                          dot={false}
                          name="Ø (max. 7 Messungen)"
                          connectNulls
                        />
                      ) : null}
                    </LineChart>
                  </ResponsiveContainer>
                </div>
              )}
            </div>
          )
        })}

        {keys.length === 0 ? (
          <div style={{ padding: 12, fontSize: 12, color: 'var(--text3)' }}>Keine Vital-Zeitreihen im Fenster.</div>
        ) : null}
      </div>
    )
  }

  const renderVitalSigns = () => {
    if (!vitalsData) {
      return (
        <div style={{ padding: 20, textAlign: 'center', color: 'var(--text3)', fontSize: 12 }}>
          Keine Snapshot-Daten zur Vital-Matrix.
        </div>
      )
    }
    const meta = vitalsData.metadata || {}
    const items = meta.vital_items || []
    const ins = meta.confidence === 'insufficient'
    if (ins && items.length === 0) {
      return (
        <div style={{ padding: 20, textAlign: 'center', color: 'var(--text3)', fontSize: 12 }}>
          {meta.message || 'Keine zusammengefassten Vitalwerte für die Einordnung.'}
        </div>
      )
    }

    const vitDate = meta.vitals_measured_at
    const bpDate = meta.blood_pressure_measured_at
    const disclaimer = meta.disclaimer_de
    const hasRhrCard = items.some((it) => it.key === 'resting_hr')
    const hasHrvCard = items.some((it) => it.key === 'hrv')

    return (
      <>
        {items.length > 0 && !hasRhrCard && !hasHrvCard ? (
          <p style={{ fontSize: 11, color: 'var(--text3)', lineHeight: 1.45, marginBottom: 10 }}>
            Ruhepuls und HRV sind in diesem Bereich bewusst nicht noch einmal als Zonen-Karten geführt — die Einordnung
            steht oben im Vital-Verlauf und in der KPI-Kachel „Herz & autonomes System“.
          </p>
        ) : null}
        {items.length > 0 ? (
          <div style={{ display: 'flex', flexDirection: 'column', gap: 10, marginBottom: 14 }}>
            {items.map((it) => {
              const stripe =
                it.tone === 'good'
                  ? getStatusColor('good')
                  : it.tone === 'bad'
                    ? getStatusColor('bad')
                    : it.tone === 'warn'
                      ? getStatusColor('warn')
                      : '#6B7280'
              const bg =
                it.tone === 'good'
                  ? getStatusBg('good')
                  : it.tone === 'bad'
                    ? getStatusBg('bad')
                    : it.tone === 'warn'
                      ? getStatusBg('warn')
                      : 'var(--surface2)'
              return (
                <div
                  key={it.key}
                  style={{
                    borderRadius: 8,
                    padding: '10px 12px',
                    border: '1px solid var(--border)',
                    borderLeft: `4px solid ${stripe}`,
                    background: bg,
                  }}
                >
                  <div style={{ display: 'flex', flexWrap: 'wrap', alignItems: 'baseline', gap: 8, marginBottom: 4 }}>
                    <span style={{ fontSize: 12, fontWeight: 600, color: 'var(--text1)' }}>{it.label_de}</span>
                    <span style={{ fontSize: 13, fontWeight: 700, color: 'var(--text1)' }}>{it.value_display}</span>
                    <span
                      style={{
                        fontSize: 11,
                        fontWeight: 600,
                        padding: '2px 8px',
                        borderRadius: 6,
                        background: 'var(--surface)',
                        color: stripe,
                        border: `1px solid ${stripe}`,
                      }}
                    >
                      {it.zone_label_de}
                    </span>
                  </div>
                  <div style={{ fontSize: 11, color: 'var(--text2)', lineHeight: 1.45 }}>{it.hint_de}</div>
                </div>
              )
            })}
          </div>
        ) : null}

        <div style={{ marginTop: 10, fontSize: 10, color: 'var(--text3)', lineHeight: 1.45 }}>
          {vitDate ? (
            <>
              Baseline-Vitals (Snapshot): <strong>{fmtDate(vitDate)}</strong>
            </>
          ) : null}
          {vitDate && bpDate ? ' · ' : null}
          {bpDate ? (
            <>
              Blutdruck: <strong>{fmtDate(bpDate)}</strong>
            </>
          ) : null}
          {!vitDate && !bpDate ? <>Bezug: Vital-Matrix {vDays} Tage</> : null}
        </div>
        {disclaimer ? (
          <div style={{ marginTop: 8, fontSize: 10, color: 'var(--text3)', fontStyle: 'italic' }}>{disclaimer}</div>
        ) : null}
      </>
    )
  }

  return (
    <div className="card section-gap">
      <div className="card-title" style={{ display: 'flex', flexWrap: 'wrap', alignItems: 'center', gap: 12 }}>
        <span>Erholung & Vitalwerte</span>
        {showPeriodDropdown ? (
          <label
            style={{ fontSize: 12, fontWeight: 500, color: 'var(--text3)', display: 'flex', alignItems: 'center', gap: 8 }}
          >
            Zeitraum
            <select
              className="form-input"
              style={{ maxWidth: 140, padding: '6px 10px', fontSize: 13 }}
              value={period}
              onChange={(e) => setPeriod(Number(e.target.value))}
            >
              <option value={7}>7 Tage</option>
              <option value={28}>28 Tage</option>
              <option value={90}>90 Tage</option>
              <option value={9999}>Gesamt</option>
            </select>
          </label>
        ) : null}
      </div>

      <p style={{ fontSize: 11, color: 'var(--text3)', lineHeight: 1.45, marginBottom: 10 }}>
        Auswertung aus dem Recovery-Data-Layer (Issue 53). Fenster ca. <strong>{eff}</strong> Tage · Charts{' '}
        <strong>{cDays}</strong> Tage · Vital-Matrix <strong>{vDays}</strong> Tage.
      </p>

      <KpiTilesOverview tiles={kpiTiles} heading="Kennzahlen" />

      {insights.length > 0 ? (
        <div style={{ marginBottom: 14 }}>
          <div style={{ fontSize: 12, fontWeight: 600, color: 'var(--text3)', marginBottom: 8 }}>Einschätzungen</div>
          <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
            {insights.map((ins) => (
              <div
                key={ins.key}
                style={{
                  borderRadius: 8,
                  padding: '10px 12px',
                  border: '1px solid var(--border)',
                  borderLeft: `4px solid ${getStatusColor(['good', 'warn', 'bad'].includes(ins.tone) ? ins.tone : 'warn')}`,
                  background: 'var(--surface2)',
                }}
              >
                <div style={{ fontSize: 12, fontWeight: 600, marginBottom: 4 }}>{ins.title}</div>
                <div style={{ fontSize: 12, color: 'var(--text2)', lineHeight: 1.45 }}>{ins.body}</div>
              </div>
            ))}
          </div>
        </div>
      ) : null}

      <div style={{ fontSize: 12, fontWeight: 600, color: 'var(--text3)', marginBottom: 8, marginTop: 4 }}>Diagramme</div>

      <ChartCard title="📊 Recovery Score">{renderRecoveryScore()}</ChartCard>
      <ChartCard title="📊 HRV & Ruhepuls">{renderHrvRhr()}</ChartCard>
      <ChartCard title="📈 Vitalwerte — Verlauf (je Kennzahl)">{renderVitalsHistory()}</ChartCard>
      <ChartCard title="📊 Schlaf: Dauer & Qualität">{renderSleepQuality()}</ChartCard>
      <ChartCard title="📊 Schlafschuld">{renderSleepDebt()}</ChartCard>
      <ChartCard title="📋 Vitalwerte — aktuelle Einordnung">{renderVitalSigns()}</ChartCard>
    </div>
  )
}
