// ---- Cycle Dashboard Page ----
// Dedicated cycle tracking view: current phase hero, Sims focus, predictions,
// symptom history, 35-day phase map, and phase × training retrospective.

// CYCLE_META is exported by 16-calendar.jsx as window.CYCLE_META (Babel-standalone
// scripts don't share top-level scope) — bare references below resolve via window.
const CYCLE_PHASE_LABELS = {
  menstrual:        'cycleMenstrual',
  follicular:       'cycleFollicular',
  ovulation:        'cycleOvulation',
  early_mid_luteal: 'cycleLuteal',
  late_luteal:      'cycleLateLuteal',
};

const PHASE_ORDER = ['menstrual', 'follicular', 'ovulation', 'early_mid_luteal', 'late_luteal'];

// SYMPTOM_ICONS is defined and exported by 16-calendar.jsx as window.SYMPTOM_ICONS
const SYMPTOM_ICONS = window.SYMPTOM_ICONS || {};

function PhasePill({ phase, t }) {
  const meta = CYCLE_META[phase] || {};
  return (
    <span style={{
      display: 'inline-flex', alignItems: 'center', gap: 6,
      padding: '4px 12px', borderRadius: 20, fontSize: 13, fontWeight: 600,
      background: meta.tint || 'var(--surface-2)',
      border: `1px solid ${meta.dot || 'var(--border)'}`,
      color: meta.dot || 'var(--text-primary)',
    }}>
      <span style={{ width: 8, height: 8, borderRadius: '50%', background: meta.dot, display: 'inline-block' }} />
      {t(CYCLE_PHASE_LABELS[phase] || phase)}
    </span>
  );
}

function PhaseBar({ cycleLength, periodLength, currentDayOfCycle, t }) {
  const ovulationDay = Math.max(periodLength + 2, cycleLength - 14);
  const phases = [
    { key: 'menstrual',        start: 1,              end: periodLength },
    { key: 'follicular',       start: periodLength + 1, end: ovulationDay - 2 },
    { key: 'ovulation',        start: ovulationDay - 1, end: ovulationDay + 1 },
    { key: 'early_mid_luteal', start: ovulationDay + 2, end: cycleLength - 4 },
    { key: 'late_luteal',      start: cycleLength - 3,  end: cycleLength },
  ];
  const markerPct = ((currentDayOfCycle - 1) / cycleLength) * 100;

  return (
    <div style={{ position: 'relative', marginTop: 16, marginBottom: 8 }}>
      <div style={{ display: 'flex', borderRadius: 8, overflow: 'hidden', height: 16 }}>
        {phases.map(p => {
          const meta = CYCLE_META[p.key] || {};
          const width = ((p.end - p.start + 1) / cycleLength) * 100;
          return (
            <div key={p.key} style={{
              width: `${width}%`,
              background: meta.tint || 'var(--surface-2)',
              borderRight: '1px solid var(--border)',
            }} title={t(CYCLE_PHASE_LABELS[p.key])} />
          );
        })}
      </div>
      {/* "You are here" marker */}
      <div style={{
        position: 'absolute', top: -4, left: `${markerPct}%`,
        transform: 'translateX(-50%)',
        width: 4, height: 24, borderRadius: 2,
        background: 'var(--text-primary)',
        boxShadow: '0 0 6px rgba(255,255,255,0.5)',
      }} />
      <div style={{ display: 'flex', justifyContent: 'space-between', marginTop: 4 }}>
        <span style={{ fontSize: 10, color: 'var(--text-muted)' }}>Day 1</span>
        <span style={{ fontSize: 10, color: 'var(--text-muted)' }}>Day {cycleLength}</span>
      </div>
    </div>
  );
}

function PredictionRow({ label, date, note, t }) {
  return (
    <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', padding: '8px 0', borderBottom: '1px solid var(--border)' }}>
      <span style={{ fontSize: 13, color: 'var(--text-secondary)' }}>{label}</span>
      <div style={{ textAlign: 'right' }}>
        <span style={{ fontSize: 14, fontFamily: 'JetBrains Mono', color: 'var(--text-primary)' }}>{date}</span>
        {note && <span style={{ fontSize: 11, color: 'var(--text-muted)', marginLeft: 6 }}>({note})</span>}
      </div>
    </div>
  );
}

// Phase name mapping for API calls
const PHASE_API_KEYS = {
  menstrual: 'menstrual',
  follicular: 'follicular',
  ovulatory: 'ovulatory',
  luteal: 'luteal',
};

function RecipeNutrientBadge({ label, value, unit, color }) {
  if (value == null) return null;
  return (
    <span style={{
      fontSize: 11, padding: '2px 6px', borderRadius: 4,
      background: color + '22', color: color, fontFamily: 'JetBrains Mono',
    }}>
      {Math.round(value * 10) / 10}{unit} {label}
    </span>
  );
}

function RecipeCard({ recipe, t }) {
  const totalMin = (recipe.prep_time_min || 0) + (recipe.cook_time_min || 0);
  return (
    <a
      href={recipe.url}
      target="_blank"
      rel="noopener noreferrer"
      style={{ textDecoration: 'none', color: 'inherit' }}
    >
      <div className="card" style={{
        padding: 0, overflow: 'hidden', cursor: 'pointer',
        transition: 'border-color 0.15s', borderColor: 'var(--border)',
        display: 'flex', flexDirection: 'column', height: '100%',
      }}
        onMouseEnter={e => e.currentTarget.style.borderColor = 'var(--accent-blue)'}
        onMouseLeave={e => e.currentTarget.style.borderColor = 'var(--border)'}
      >
        {recipe.image_url && (
          <div style={{ width: '100%', height: 140, overflow: 'hidden', flexShrink: 0 }}>
            <img
              src={recipe.image_url}
              alt={recipe.name}
              style={{ width: '100%', height: '100%', objectFit: 'cover' }}
              loading="lazy"
            />
          </div>
        )}
        <div style={{ padding: '10px 12px', flex: 1, display: 'flex', flexDirection: 'column', gap: 6 }}>
          <div style={{ fontSize: 13, fontWeight: 600, color: 'var(--text-primary)', lineHeight: 1.3 }}>
            {recipe.name}
          </div>
          {recipe.category && (
            <div style={{ fontSize: 11, color: 'var(--text-muted)' }}>{recipe.category}</div>
          )}
          <div style={{ display: 'flex', flexWrap: 'wrap', gap: 4, marginTop: 'auto', paddingTop: 4 }}>
            {recipe.calories != null && (
              <RecipeNutrientBadge label="kcal" value={recipe.calories} unit="" color="var(--accent-blue)" />
            )}
            {recipe.protein_g != null && (
              <RecipeNutrientBadge label="prot" value={recipe.protein_g} unit="g" color="var(--accent-green)" />
            )}
            {recipe.iron_mg != null && recipe.iron_mg > 1 && (
              <RecipeNutrientBadge label="iron" value={recipe.iron_mg} unit="mg" color="#e07b54" />
            )}
            {recipe.omega3_g != null && recipe.omega3_g > 0.1 && (
              <RecipeNutrientBadge label="ω-3" value={recipe.omega3_g} unit="g" color="var(--accent-purple)" />
            )}
            {totalMin > 0 && (
              <span style={{ fontSize: 11, color: 'var(--text-muted)', marginLeft: 'auto' }}>
                {totalMin} min
              </span>
            )}
          </div>
        </div>
      </div>
    </a>
  );
}

function RecipeSection({ phase, t }) {
  const [recipes, setRecipes] = React.useState([]);
  const [loading, setLoading] = React.useState(true);
  const [query, setQuery] = React.useState('');
  const [searching, setSearching] = React.useState(false);

  React.useEffect(() => {
    const apiPhase = PHASE_API_KEYS[phase] || 'follicular';
    api.get(`/api/recipes?phase=${apiPhase}&limit=6`)
      .then(data => setRecipes(data.recipes || []))
      .catch(() => setRecipes([]))
      .finally(() => setLoading(false));
  }, [phase]);

  const handleSearch = async (e) => {
    e.preventDefault();
    if (!query.trim()) return;
    setSearching(true);
    const apiPhase = PHASE_API_KEYS[phase] || 'follicular';
    try {
      const data = await api.get(`/api/recipes?q=${encodeURIComponent(query)}&phase=${apiPhase}&limit=9`);
      setRecipes(data.recipes || []);
    } catch {}
    setSearching(false);
  };

  const clearSearch = () => {
    setQuery('');
    setLoading(true);
    const apiPhase = PHASE_API_KEYS[phase] || 'follicular';
    api.get(`/api/recipes?phase=${apiPhase}&limit=6`)
      .then(data => setRecipes(data.recipes || []))
      .catch(() => setRecipes([]))
      .finally(() => setLoading(false));
  };

  return (
    <div className="card" style={{ padding: '16px 20px', marginBottom: 12 }}>
      <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 12, gap: 12 }}>
        <div>
          <h3 style={{ margin: 0, fontSize: 15 }}>🥗 {t('recipeIdeas')}</h3>
          <p style={{ margin: '2px 0 0', fontSize: 12, color: 'var(--text-muted)' }}>{t('recipePhaseLabel')}</p>
        </div>
        <form onSubmit={handleSearch} style={{ display: 'flex', gap: 6 }}>
          <input
            value={query}
            onChange={e => setQuery(e.target.value)}
            placeholder={t('recipeSearch')}
            style={{
              padding: '5px 10px', fontSize: 12, borderRadius: 6, border: '1px solid var(--border)',
              background: 'var(--bg-secondary)', color: 'var(--text-primary)', width: 160,
            }}
          />
          <button className="btn btn-sm" type="submit" disabled={searching || !query.trim()}>
            {searching ? <span className="spinner" style={{ width: 10, height: 10 }} /> : '🔍'}
          </button>
          {query && (
            <button className="btn btn-sm" type="button" onClick={clearSearch}>✕</button>
          )}
        </form>
      </div>

      {loading ? (
        <div style={{ display: 'flex', alignItems: 'center', gap: 8, color: 'var(--text-muted)', padding: '12px 0' }}>
          <div className="spinner" /> {t('recipesLoading')}
        </div>
      ) : recipes.length === 0 ? (
        <p style={{ color: 'var(--text-muted)', fontSize: 13 }}>{t('recipesNone')}</p>
      ) : (
        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fill, minmax(180px, 1fr))', gap: 10 }}>
          {recipes.map(r => <RecipeCard key={r.id} recipe={r} t={t} />)}
        </div>
      )}

      <p style={{ fontSize: 11, color: 'var(--text-muted)', marginTop: 10, marginBottom: 0 }}>
        Recipes from <a href="https://www.pickuplimes.com" target="_blank" rel="noopener noreferrer" style={{ color: 'var(--accent-blue)' }}>Pick Up Limes</a> — whole food, plant-based.
      </p>
    </div>
  );
}

function SymptomInsightsCard({ symptoms, phaseCalendar, t }) {
  if (!symptoms || symptoms.length === 0) return null;

  // Build date → phase lookup
  const phaseByDate = {};
  (phaseCalendar || []).forEach(e => { phaseByDate[e.date] = e.phase; });

  // Aggregate
  const totalCounts = {};
  const phaseCounts = {}; // { phase: { symptom: count } }
  const energyByDate = {};

  for (const log of symptoms) {
    if (log.energy != null) energyByDate[log.date] = log.energy;
    const phase = phaseByDate[log.date];
    for (const s of (log.symptoms || [])) {
      totalCounts[s] = (totalCounts[s] || 0) + 1;
      if (phase) {
        if (!phaseCounts[phase]) phaseCounts[phase] = {};
        phaseCounts[phase][s] = (phaseCounts[phase][s] || 0) + 1;
      }
    }
  }

  const topSymptoms = Object.entries(totalCounts).sort((a, b) => b[1] - a[1]).slice(0, 6);
  const hasInsights = topSymptoms.length > 0 || Object.keys(energyByDate).length > 3;
  if (!hasInsights) return null;

  // 30-day energy bars (oldest → newest)
  const today = new Date();
  const energyBars = [];
  for (let i = 29; i >= 0; i--) {
    const d = new Date(today.getTime() - i * 86400000);
    const key = `${d.getFullYear()}-${String(d.getMonth()+1).padStart(2,'0')}-${String(d.getDate()).padStart(2,'0')}`;
    energyBars.push({ date: key, energy: energyByDate[key] ?? null });
  }
  const avg = (() => {
    const vals = energyBars.map(b => b.energy).filter(v => v != null);
    return vals.length ? (vals.reduce((a, b) => a + b, 0) / vals.length).toFixed(1) : null;
  })();

  // Phase × top symptom
  const PHASE_ORDER = ['menstrual', 'follicular', 'ovulation', 'early_mid_luteal', 'late_luteal'];
  const phaseTopSymptom = {};
  for (const [phase, counts] of Object.entries(phaseCounts)) {
    const top = Object.entries(counts).sort((a, b) => b[1] - a[1])[0];
    if (top && top[1] >= 2) phaseTopSymptom[phase] = top;
  }
  const hasPhaseData = Object.keys(phaseTopSymptom).length > 0;

  return (
    <div className="card" style={{ marginBottom: 16, borderColor: 'rgba(139,92,246,0.25)' }}>
      <div className="card-header">
        <div className="card-title" style={{ color: 'var(--accent-purple)' }}>📊 Symptom Patterns</div>
      </div>

      {/* Energy sparkline */}
      {energyBars.some(b => b.energy != null) && (
        <div style={{ marginBottom: 18 }}>
          <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline', marginBottom: 6 }}>
            <span style={{ fontSize: 12, color: 'var(--text-muted)', fontWeight: 600 }}>⚡ Energy — 30 days</span>
            {avg && <span style={{ fontSize: 11, fontFamily: 'JetBrains Mono', color: 'var(--text-secondary)' }}>avg {avg}/5</span>}
          </div>
          <div style={{ display: 'flex', alignItems: 'flex-end', gap: 2, height: 36 }}>
            {energyBars.map((b, i) => {
              const h = b.energy != null ? (b.energy / 5) * 36 : 4;
              const color = b.energy == null ? 'var(--border)' : b.energy >= 4 ? 'var(--accent-green)' : b.energy <= 2 ? '#ef4444' : '#fbbf24';
              return (
                <div key={i} title={b.energy != null ? `${b.date}: ${b.energy}/5` : b.date} style={{
                  flex: 1, height: `${h}px`, borderRadius: 2,
                  background: color, opacity: b.energy == null ? 0.3 : 0.85,
                  minWidth: 4,
                }} />
              );
            })}
          </div>
          <div style={{ display: 'flex', justifyContent: 'space-between', marginTop: 3 }}>
            <span style={{ fontSize: 9, color: 'var(--text-muted)' }}>30d ago</span>
            <span style={{ fontSize: 9, color: 'var(--text-muted)' }}>Today</span>
          </div>
        </div>
      )}

      {/* Top symptoms */}
      {topSymptoms.length > 0 && (
        <div style={{ marginBottom: hasPhaseData ? 18 : 0 }}>
          <div style={{ fontSize: 12, color: 'var(--text-muted)', fontWeight: 600, marginBottom: 8 }}>Most frequent symptoms</div>
          <div style={{ display: 'flex', flexWrap: 'wrap', gap: 6 }}>
            {topSymptoms.map(([s, count]) => (
              <span key={s} style={{
                display: 'flex', alignItems: 'center', gap: 5,
                fontSize: 12, padding: '4px 10px', borderRadius: 12,
                background: 'var(--bg-card-hover)', border: '1px solid var(--border-light)',
                color: 'var(--text-primary)',
              }}>
                <span>{SYMPTOM_ICONS[s] || '•'}</span>
                <span>{s.replace(/_/g, ' ')}</span>
                <span style={{ fontFamily: 'JetBrains Mono', fontSize: 11, color: 'var(--accent-purple)', fontWeight: 700 }}>{count}×</span>
              </span>
            ))}
          </div>
        </div>
      )}

      {/* Phase × symptom patterns */}
      {hasPhaseData && (
        <div>
          <div style={{ fontSize: 12, color: 'var(--text-muted)', fontWeight: 600, marginBottom: 8 }}>Symptoms by phase</div>
          <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
            {PHASE_ORDER.filter(p => phaseTopSymptom[p]).map(phase => {
              const [sym, count] = phaseTopSymptom[phase];
              const m = CYCLE_META[phase] || {};
              return (
                <div key={phase} style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
                  <div style={{ display: 'flex', alignItems: 'center', gap: 6, minWidth: 110 }}>
                    <span style={{ width: 8, height: 8, borderRadius: '50%', background: m.dot, flexShrink: 0 }} />
                    <span style={{ fontSize: 12, color: 'var(--text-secondary)' }}>{t(CYCLE_PHASE_LABELS[phase] || phase)}</span>
                  </div>
                  <div style={{ display: 'flex', alignItems: 'center', gap: 6 }}>
                    <span style={{ fontSize: 12, padding: '3px 9px', borderRadius: 10, background: m.tint || 'var(--surface-2)', border: `1px solid ${m.dot || 'var(--border)'}`, color: 'var(--text-primary)' }}>
                      {SYMPTOM_ICONS[sym] || '•'} {sym.replace(/_/g, ' ')}
                    </span>
                    <span style={{ fontSize: 11, color: 'var(--text-muted)', fontFamily: 'JetBrains Mono' }}>{count}×</span>
                  </div>
                </div>
              );
            })}
          </div>
        </div>
      )}
    </div>
  );
}

window.RecipeCard = RecipeCard;

window.CyclePage = function CyclePage({ config, t }) {
  const [data, setData] = React.useState(null);
  const [loading, setLoading] = React.useState(true);

  React.useEffect(() => {
    api.get('/api/cycle/dashboard')
      .then(setData)
      .catch(() => setData({ enabled: false }))
      .finally(() => setLoading(false));
  }, []);

  if (loading) {
    return (
      <div>
        <div className="page-header"><h2>{t('cyclePage')}</h2></div>
        <div style={{ display: 'flex', alignItems: 'center', gap: 10, color: 'var(--text-muted)', padding: 24 }}>
          <div className="spinner" /> Loading…
        </div>
      </div>
    );
  }

  if (!data || !data.enabled) {
    return (
      <div>
        <div className="page-header"><h2>🌸 {t('cyclePage')}</h2></div>
        <div className="card" style={{ padding: 24 }}>
          <p style={{ color: 'var(--text-secondary)', marginBottom: 8 }}>{t('cycleNotEnabled')}</p>
          <p style={{ fontSize: 13, color: 'var(--text-muted)' }}>{t('cycleEnablePrompt')}</p>
        </div>
      </div>
    );
  }

  const { today, predictions, phaseCalendar, symptoms, phaseTraining, cycleLength, periodLength } = data;
  const meta = CYCLE_META[today?.phase] || {};
  const focusKey = meta.focusKey;

  // Group symptom logs for display (last 14 days)
  const recentSymptoms = symptoms ? symptoms.slice(0, 14) : [];

  // Build phase run-length encoding for 35-day summary strip
  const phaseRuns = [];
  for (const entry of (phaseCalendar || [])) {
    const last = phaseRuns[phaseRuns.length - 1];
    if (last && last.phase === entry.phase) {
      last.end = entry.date;
      last.count++;
    } else {
      phaseRuns.push({ phase: entry.phase, start: entry.date, end: entry.date, count: 1 });
    }
  }

  return (
    <div>
      <div className="page-header">
        <h2>🌸 {t('cyclePage')}</h2>
      </div>

      {/* Hero: current phase */}
      <div className="card" style={{ marginBottom: 16, borderColor: meta.dot || 'var(--border)', background: meta.tint ? `${meta.tint}` : undefined }}>
        <div className="card-header">
          <div className="card-title">{t('cycleCurrentPhase')}</div>
          <PhasePill phase={today?.phase} t={t} />
        </div>
        <div style={{ padding: '4px 0 8px' }}>
          <div style={{ fontSize: 13, color: 'var(--text-muted)', marginBottom: 2 }}>
            {t('cycleDayOf').replace('{day}', today?.dayOfCycle ?? '–').replace('{total}', cycleLength)}
          </div>
          <PhaseBar
            cycleLength={cycleLength}
            periodLength={periodLength}
            currentDayOfCycle={today?.dayOfCycle || 1}
            t={t}
          />
        </div>
      </div>

      {/* Sims focus card */}
      {focusKey && (
        <div className="card" style={{ marginBottom: 16, borderColor: 'rgba(139,92,246,0.2)' }}>
          <div className="card-header">
            <div className="card-title">🧬 {t('cycleTrainingFocus')}</div>
          </div>
          <p style={{ fontSize: 13, color: 'var(--text-secondary)', lineHeight: 1.6, padding: '4px 0' }}>
            {t(focusKey)}
          </p>
        </div>
      )}

      {/* Predictions */}
      {predictions && (
        <div className="card" style={{ marginBottom: 16 }}>
          <div className="card-header">
            <div className="card-title">📅 {t('cyclePredictions')}</div>
            <span className="card-badge" style={{ fontSize: 11 }}>{t('cycleEstimated')}</span>
          </div>
          <div style={{ padding: '4px 0' }}>
            <PredictionRow label={t('cycleNextPeriod')} date={predictions.nextPeriod} t={t} />
            <PredictionRow label={t('cycleNextOvulation')} date={predictions.nextOvulation} t={t} />
            <PredictionRow label={t('cycleFertileWindow')} date={`${predictions.fertileWindowStart} – ${predictions.fertileWindowEnd}`} t={t} />
          </div>
        </div>
      )}

      {/* 35-day phase summary strip */}
      {phaseCalendar && phaseCalendar.length > 0 && (
        <div className="card" style={{ marginBottom: 16 }}>
          <div className="card-header">
            <div className="card-title">🗓️ {t('cyclePhaseSummary')}</div>
          </div>
          <div style={{ display: 'flex', gap: 2, flexWrap: 'wrap', padding: '6px 0' }}>
            {phaseCalendar.map(entry => {
              const m = CYCLE_META[entry.phase] || {};
              return (
                <div key={entry.date} title={`${entry.date}: ${entry.phase}`} style={{
                  width: 14, height: 14, borderRadius: 3,
                  background: m.dot || 'var(--surface-2)',
                  opacity: 0.8,
                }} />
              );
            })}
          </div>
          <div style={{ display: 'flex', flexWrap: 'wrap', gap: 10, marginTop: 8 }}>
            {Object.entries(CYCLE_META).map(([key, m]) => (
              <div key={key} style={{ display: 'flex', alignItems: 'center', gap: 4, fontSize: 11, color: 'var(--text-muted)' }}>
                <div style={{ width: 10, height: 10, borderRadius: 2, background: m.dot }} />
                {t(CYCLE_PHASE_LABELS[key])}
              </div>
            ))}
          </div>
        </div>
      )}

      {/* Symptom history */}
      <div className="card" style={{ marginBottom: 16 }}>
        <div className="card-header">
          <div className="card-title">🩺 {t('cycleSymptomHistory')}</div>
        </div>
        {recentSymptoms.length === 0 ? (
          <p style={{ fontSize: 13, color: 'var(--text-muted)', padding: '8px 0' }}>{t('cycleNoSymptoms')}</p>
        ) : (
          <div style={{ display: 'flex', flexDirection: 'column', gap: 10, padding: '4px 0' }}>
            {recentSymptoms.map(log => (
              <div key={log.id || log.date} style={{ display: 'flex', gap: 12, alignItems: 'flex-start' }}>
                <span style={{ fontSize: 11, fontFamily: 'JetBrains Mono', color: 'var(--text-muted)', minWidth: 84, paddingTop: 3 }}>
                  {log.date}
                </span>
                <div style={{ display: 'flex', flexWrap: 'wrap', gap: 6 }}>
                  {log.energy != null && (
                    <span style={{
                      fontSize: 12, padding: '3px 10px', borderRadius: 12,
                      background: log.energy >= 4 ? 'var(--accent-green-dim)' : log.energy <= 2 ? 'rgba(239,68,68,0.15)' : 'rgba(245,158,11,0.15)',
                      color: log.energy >= 4 ? 'var(--accent-green)' : log.energy <= 2 ? '#f87171' : '#fbbf24',
                      border: '1px solid currentColor', opacity: 0.9,
                      fontWeight: 600,
                    }}>
                      ⚡ {log.energy}/5
                    </span>
                  )}
                  {(log.symptoms || []).map(s => (
                    <span key={s} style={{
                      fontSize: 12, padding: '3px 10px', borderRadius: 12,
                      background: 'var(--bg-card-hover)',
                      color: 'var(--text-primary)',
                      border: '1px solid var(--border-light)',
                    }}>
                      {SYMPTOM_ICONS[s] || '•'} {s.replace(/_/g, ' ')}
                    </span>
                  ))}
                </div>
              </div>
            ))}
          </div>
        )}
      </div>

      {/* Symptom pattern insights */}
      <SymptomInsightsCard symptoms={symptoms} phaseCalendar={phaseCalendar} t={t} />

      {/* Phase × training retrospective */}
      <div className="card" style={{ marginBottom: 16 }}>
        <div className="card-header">
          <div className="card-title">🏃 {t('cyclePhaseTraining')}</div>
        </div>
        {!phaseTraining ? (
          <p style={{ fontSize: 13, color: 'var(--text-muted)', padding: '8px 0' }}>{t('cyclePhaseTrainingNone')}</p>
        ) : Object.keys(phaseTraining).length === 0 ? (
          <p style={{ fontSize: 13, color: 'var(--text-muted)', padding: '8px 0' }}>No activities in the last 35 days.</p>
        ) : (
          <div style={{ display: 'flex', flexDirection: 'column', gap: 10, padding: '4px 0' }}>
            {PHASE_ORDER.filter(p => phaseTraining[p]).map(phaseKey => {
              const bucket = phaseTraining[phaseKey];
              const m = CYCLE_META[phaseKey] || {};
              return (
                <div key={phaseKey} style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
                  <div style={{ width: 8, height: 8, borderRadius: '50%', background: m.dot, flexShrink: 0 }} />
                  <span style={{ fontSize: 13, color: 'var(--text-secondary)', minWidth: 120 }}>
                    {t(CYCLE_PHASE_LABELS[phaseKey])}
                  </span>
                  <span style={{ fontSize: 13, fontFamily: 'JetBrains Mono', color: 'var(--text-primary)' }}>
                    {bucket.count} session{bucket.count !== 1 ? 's' : ''} · {Math.round(bucket.movingTimeMin / 60)}h
                  </span>
                </div>
              );
            })}
          </div>
        )}
      </div>

      {/* Recipe recommendations for current phase */}
      <RecipeSection phase={today?.phase || 'follicular'} t={t} />

      {/* Disclaimer */}
      <p style={{ fontSize: 11, color: 'var(--text-muted)', textAlign: 'center', padding: '8px 0 16px' }}>
        {t('cycleDisclaimer')}
      </p>
    </div>
  );
};
