// insights.jsx — longitudinal somatic analysis: what the body is learning over time.

// lifetime practice stats: totals, average length, best (longest-ever) streak
function buildStats(sessions) {
  const n = sessions.length;
  const totalMin = sessions.reduce((a, s) => a + (s.duration || 0), 0);
  const avgMin = n ? Math.round(totalMin / n) : 0;
  // best streak across all history (consecutive calendar days with a sit)
  const dayKeys = [...new Set(sessions.map(s => { const d = new Date(s.date); d.setHours(0,0,0,0); return d.getTime(); }))].sort((a, b) => a - b);
  let best = 0, run = 0, prev = null;
  dayKeys.forEach(t => {
    if (prev != null && t - prev === 864e5) run += 1; else run = 1;
    if (run > best) best = run;
    prev = t;
  });
  const totalHours = totalMin / 60;
  return { count: n, totalMin, totalHours, avgMin, bestStreak: best, days: dayKeys.length };
}

// Split sessions into earlier vs recent halves; compare per-REGION intensity rate,
// labelled by that region's dominant sensation. Smoother & more legible than per-pair.
function buildTrends(sessions) {
  const sorted = [...sessions].sort((a, b) => new Date(a.date) - new Date(b.date));
  if (sorted.length < 3) return { enough: false, count: sorted.length };
  const mid = Math.floor(sorted.length / 2);
  const earlier = sorted.slice(0, mid);
  const recent = sorted.slice(mid);

  const agg = (list) => {
    const m = {}; // region -> { sum, sens:{} }
    list.forEach(s => s.markers.forEach(k => {
      const w = (k.intensity || 0) + 1;
      if (!m[k.region]) m[k.region] = { sum: 0, sens: {} };
      m[k.region].sum += w;
      m[k.region].sens[k.sensationId] = (m[k.region].sens[k.sensationId] || 0) + w;
    }));
    return m;
  };
  const eA = agg(earlier), rA = agg(recent);
  const eN = earlier.length || 1, rN = recent.length || 1;
  const regions = new Set([...Object.keys(eA), ...Object.keys(rA)]);
  const changes = [];
  regions.forEach(region => {
    const e = eA[region] || { sum: 0, sens: {} }, r = rA[region] || { sum: 0, sens: {} };
    const eRate = e.sum / eN, rRate = r.sum / rN;
    const delta = rRate - eRate;
    if (Math.abs(delta) < 0.3) return;
    const pct = eRate > 0.2 ? Math.round((delta / eRate) * 100) : 100;
    // dominant sensation: prefer the busier window
    const pool = (r.sum >= e.sum ? r.sens : e.sens);
    const sid = Object.entries(pool).sort((a, b) => b[1] - a[1])[0]?.[0] || 'tension';
    changes.push({ region, sid, eRate, rRate, delta, pct: Math.max(-100, Math.min(400, pct)) });
  });
  changes.sort((a, b) => Math.abs(b.delta) - Math.abs(a.delta));
  const easing = changes.filter(c => c.delta < 0);
  const rising = changes.filter(c => c.delta > 0);

  const easeShare = (list) => {
    let ease = 0, total = 0;
    list.forEach(s => s.markers.forEach(k => { total++; if (k.sensationId === 'ease') ease++; }));
    return total ? ease / total : 0;
  };
  const equanimityDelta = Math.round((easeShare(recent) - easeShare(earlier)) * 100);

  return { enough: true, changes, easing, rising, equanimityDelta,
    earlierCount: earlier.length, recentCount: recent.length };
}

// weekly weighted-noting series for a sparkline (most-recent on the right)
function weeklySeries(sessions, weeks = 8) {
  const now = Date.now();
  const buckets = Array.from({ length: weeks }, () => ({ total: 0, sits: 0 }));
  sessions.forEach(s => {
    const w = Math.floor((now - new Date(s.date).getTime()) / (7 * 864e5));
    if (w >= 0 && w < weeks) {
      buckets[w].sits += 1;
      s.markers.forEach(k => { buckets[w].total += (k.intensity || 0) + 1; });
    }
  });
  return buckets.reverse(); // oldest → newest
}

// minutes practiced per week (for the discipline curve)
function weeklyMinutes(sessions, weeks = 8) {
  const now = Date.now();
  const b = Array.from({ length: weeks }, () => 0);
  sessions.forEach(s => {
    const w = Math.floor((now - new Date(s.date).getTime()) / (7 * 864e5));
    if (w >= 0 && w < weeks) b[w] += (s.duration || 0);
  });
  return b.reverse();
}

function Sparkline({ data, hue, height = 54, fmt }) {
  const C = MT_COLORS;
  const max = Math.max(1, ...data);
  const n = data.length;
  return (
    <div style={{ display: 'flex', alignItems: 'flex-end', gap: 5, height }}>
      {data.map((v, i) => (
        <div key={i} style={{ flex: 1, display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'flex-end', height: '100%' }}>
          <div style={{ width: '100%', maxWidth: 22, height: `${Math.max(3, (v / max) * 100)}%`, borderRadius: 5,
            background: i === n - 1 ? `linear-gradient(180deg, ${hue}, ${hexA(hue, 0.4)})` : hexA(hue, 0.28),
            boxShadow: i === n - 1 ? `0 0 10px ${hexA(hue, 0.5)}` : 'none', transition: 'height .4s ease' }} />
        </div>
      ))}
    </div>
  );
}

function TrendRow({ c, dir }) {
  const C = MT_COLORS;
  const sens = MT_SENS_MAP[c.sid] || {};
  const easing = dir === 'easing';
  const accent = easing ? '#4FE6A0' : '#FF9E6B';
  return (
    <MTPanel style={{ padding: '13px 15px', display: 'flex', alignItems: 'center', gap: 12 }}>
      <div style={{ width: 30, height: 30, borderRadius: 9, display: 'grid', placeItems: 'center', background: hexA(accent, 0.12), color: accent, flexShrink: 0, fontFamily: 'var(--mono)', fontSize: 16 }}>
        {easing ? '↓' : '↑'}
      </div>
      <div style={{ flex: 1, minWidth: 0 }}>
        <div style={{ fontSize: 14.5, color: C.ink }}>
          <span style={{ textTransform: 'capitalize' }}>{sens.label || c.sid}</span> in the {(MT_REGION_LABEL[c.region] || c.region).toLowerCase()}
        </div>
        <div style={{ fontSize: 12, color: C.inkFaint, marginTop: 2 }}>{easing ? 'easing' : 'rising'} · {sens.note || ''}</div>
      </div>
      <span style={{ fontFamily: 'var(--mono)', fontSize: 15, color: accent }}>{c.pct > 0 ? '+' : ''}{c.pct}%</span>
    </MTPanel>
  );
}

// The Trends view inside the Atlas
function TrendsView({ sessions }) {
  const C = MT_COLORS;
  const t = React.useMemo(() => buildTrends(sessions), [sessions]);
  const series = React.useMemo(() => weeklySeries(sessions), [sessions]);
  const mins = React.useMemo(() => weeklyMinutes(sessions), [sessions]);

  if (!t.enough) {
    return (
      <MTPanel style={{ padding: 26, textAlign: 'center' }}>
        <div style={{ color: C.inkDim, font: '300 18px/1.4 var(--serif)', marginBottom: 8 }}>The body reveals its patterns with time.</div>
        <div style={{ fontSize: 13.5, color: C.inkFaint }}>Sit a few more times and Anicca will begin to show what is easing and what is rising — {3 - (t.count || 0) > 0 ? `${3 - (t.count || 0)} more to begin` : 'soon'}.</div>
      </MTPanel>
    );
  }

  const headline = t.easing[0] || t.rising[0];
  const hSens = headline ? (MT_SENS_MAP[headline.sid] || {}) : {};
  const hEasing = headline && headline.delta < 0;

  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 18 }}>
      {/* headline insight */}
      {headline && (
        <div style={{ position: 'relative', borderRadius: 20, overflow: 'hidden', padding: '20px 20px',
          border: `1px solid ${hexA(hEasing ? '#4FE6A0' : '#FF9E6B', 0.4)}`,
          background: `radial-gradient(120% 120% at 0% 0%, ${hexA(hEasing ? '#4FE6A0' : '#FF9E6B', 0.12)}, rgba(7,18,26,0.6))` }}>
          <MTEyebrow color={hEasing ? '#4FE6A0' : '#FF9E6B'}>{hEasing ? 'Something is releasing' : 'Something is asking for attention'}</MTEyebrow>
          <div style={{ font: '300 23px/1.3 var(--serif)', color: C.ink, margin: '10px 0 8px', textWrap: 'pretty' }}>
            {(hSens.label || '').replace(/^./, m => m.toUpperCase())} in the {(MT_REGION_LABEL[headline.region] || '').toLowerCase()} is {hEasing ? 'easing' : 'rising'} — {headline.pct > 0 ? '+' : ''}{headline.pct}% lately.
          </div>
          <div style={{ fontSize: 13.5, color: C.inkDim, lineHeight: 1.5, textWrap: 'pretty' }}>
            {hEasing
              ? 'What you meet with equanimity, loosens. Keep watching it — without pushing.'
              : 'The body is surfacing something. Meet it gently, again and again, and let it be seen.'}
          </div>
        </div>
      )}

      {/* equanimity shift */}
      {t.equanimityDelta !== 0 && (
        <MTPanel style={{ padding: '14px 16px', display: 'flex', alignItems: 'center', gap: 12 }}>
          <div style={{ width: 34, height: 34, borderRadius: 10, display: 'grid', placeItems: 'center', background: 'rgba(124,240,220,0.12)', color: '#7CF0DC', flexShrink: 0 }}>
            <MTIcon name="leaf" size={18} />
          </div>
          <div style={{ flex: 1 }}>
            <div style={{ fontSize: 14.5, color: C.ink }}>Ease &amp; openness {t.equanimityDelta > 0 ? 'is growing' : 'has dipped'}</div>
            <div style={{ fontSize: 12, color: C.inkFaint, marginTop: 2 }}>share of pleasant, flowing sensations</div>
          </div>
          <span style={{ fontFamily: 'var(--mono)', fontSize: 15, color: t.equanimityDelta > 0 ? '#4FE6A0' : '#FF9E6B' }}>{t.equanimityDelta > 0 ? '+' : ''}{t.equanimityDelta}%</span>
        </MTPanel>
      )}

      {/* weekly rhythm */}
      <MTPanel style={{ padding: '16px 18px' }}>
        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline', marginBottom: 14 }}>
          <MTEyebrow>Weekly rhythm</MTEyebrow>
          <span style={{ fontSize: 11, color: C.inkFaint, fontFamily: 'var(--mono)' }}>notings · last 8 wks</span>
        </div>
        <Sparkline data={series.map(b => b.total)} hue={C.teal} />
        <div style={{ display: 'flex', justifyContent: 'space-between', marginTop: 8, fontSize: 10, color: C.inkFaint, fontFamily: 'var(--mono)' }}>
          <span>8 wks ago</span><span>this week</span>
        </div>
      </MTPanel>

      {/* easing */}
      {t.easing.length > 0 && (
        <div>
          <div style={{ margin: '2px 4px 10px' }}><MTEyebrow color="#4FE6A0">Easing — what is loosening</MTEyebrow></div>
          <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
            {t.easing.slice(0, 4).map((c, i) => <TrendRow key={i} c={c} dir="easing" />)}
          </div>
        </div>
      )}

      {/* rising */}
      {t.rising.length > 0 && (
        <div>
          <div style={{ margin: '2px 4px 10px' }}><MTEyebrow color="#FF9E6B">Rising — what is asking to be seen</MTEyebrow></div>
          <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
            {t.rising.slice(0, 4).map((c, i) => <TrendRow key={i} c={c} dir="rising" />)}
          </div>
        </div>
      )}

      <p style={{ fontSize: 12, color: C.inkFaint, textAlign: 'center', lineHeight: 1.6, margin: '4px 12px 0', textWrap: 'pretty' }}>
        Trends compare your recent sittings to earlier ones. They are a mirror, not a verdict — the practice is simply to keep seeing clearly.
      </p>
    </div>
  );
}

Object.assign(window, { buildStats, buildTrends, weeklySeries, weeklyMinutes, Sparkline, TrendsView, TrendRow });
