// charts.jsx — bespoke SVG charts for PsyFit. No chart libs.

// Smooth cubic path through points
function smoothPath(pts) {
  if (pts.length < 2) return '';
  let d = `M ${pts[0][0]} ${pts[0][1]}`;
  for (let i = 0; i < pts.length - 1; i++) {
    const [x0, y0] = pts[i];
    const [x1, y1] = pts[i + 1];
    const cx = (x0 + x1) / 2;
    d += ` C ${cx} ${y0}, ${cx} ${y1}, ${x1} ${y1}`;
  }
  return d;
}

// ── Line chart with area fill ────────────────────────────────
function LineChart({ data, labels, accent = '#C8FF2E', height = 160, muted = '#5A5F68', text = '#8A8F98' }) {
  const W = 320, H = height, padX = 14, padT = 22, padB = 22;
  const min = Math.min(...data), max = Math.max(...data);
  const span = max - min || 1;
  const innerW = W - padX * 2, innerH = H - padT - padB;
  const pts = data.map((v, i) => [
    padX + (i / (data.length - 1)) * innerW,
    padT + innerH - ((v - min) / span) * innerH,
  ]);
  const line = smoothPath(pts);
  const area = `${line} L ${pts[pts.length - 1][0]} ${padT + innerH} L ${pts[0][0]} ${padT + innerH} Z`;
  const gid = 'lg' + Math.round(min + max);
  const last = pts[pts.length - 1];
  return (
    <svg viewBox={`0 0 ${W} ${H}`} width="100%" style={{ display: 'block', overflow: 'visible' }}>
      <defs>
        <linearGradient id={gid} x1="0" y1="0" x2="0" y2="1">
          <stop offset="0%" stopColor={accent} stopOpacity="0.32" />
          <stop offset="100%" stopColor={accent} stopOpacity="0" />
        </linearGradient>
      </defs>
      {[0, 0.5, 1].map((g, i) => (
        <line key={i} x1={padX} x2={W - padX} y1={padT + innerH * g} y2={padT + innerH * g}
          stroke={muted} strokeOpacity="0.18" strokeWidth="1" strokeDasharray="2 4" />
      ))}
      <path d={area} fill={`url(#${gid})`} />
      <path d={line} fill="none" stroke={accent} strokeWidth="3" strokeLinecap="round" strokeLinejoin="round" />
      {pts.map(([x, y], i) => i === pts.length - 1 ? (
        <g key={i}>
          <circle cx={x} cy={y} r="6" fill={accent} />
          <circle cx={x} cy={y} r="11" fill={accent} opacity="0.18" />
        </g>
      ) : (
        <circle key={i} cx={x} cy={y} r="2.4" fill={muted} opacity="0.5" />
      ))}
      <text x={last[0]} y={last[1] - 14} textAnchor="end" fontSize="14" fontWeight="700"
        fill={accent} style={{ fontFamily: 'var(--font-display)' }}>{data[data.length - 1]}</text>
      {labels && labels.map((l, i) => (i % 2 === 0 || i === labels.length - 1) && (
        <text key={i} x={pts[i][0]} y={H - 5} textAnchor="middle" fontSize="9" fill={text}
          style={{ fontFamily: 'var(--font-body)', letterSpacing: 0.5 }}>{l}</text>
      ))}
    </svg>
  );
}

// ── Vertical bar chart ───────────────────────────────────────
function BarChart({ data, accent = '#C8FF2E', height = 160, valueFmt = (v) => v, text = '#8A8F98', surface = '#23262C' }) {
  const W = 320, H = height, padX = 10, padT = 20, padB = 22;
  const max = Math.max(...data.map(d => d.value));
  const innerW = W - padX * 2, innerH = H - padT - padB;
  const bw = innerW / data.length;
  const barW = Math.min(bw * 0.56, 26);
  return (
    <svg viewBox={`0 0 ${W} ${H}`} width="100%" style={{ display: 'block' }}>
      {data.map((d, i) => {
        const h = (d.value / max) * innerH;
        const x = padX + i * bw + (bw - barW) / 2;
        const y = padT + innerH - h;
        const isLast = i === data.length - 1;
        return (
          <g key={i}>
            <rect x={x} y={padT} width={barW} height={innerH} rx={barW / 2} fill={surface} opacity="0.5" />
            <rect x={x} y={y} width={barW} height={h} rx={barW / 2} fill={isLast ? accent : surface}
              stroke={isLast ? 'none' : accent} strokeOpacity={isLast ? 0 : 0.4} strokeWidth="1.5" />
            <text x={x + barW / 2} y={H - 6} textAnchor="middle" fontSize="8.5" fill={text}
              style={{ fontFamily: 'var(--font-body)' }}>{d.label.replace('May ', '')}</text>
          </g>
        );
      })}
    </svg>
  );
}

// ── Streak heatmap (weeks × days) ────────────────────────────
function Heatmap({ values, accent = '#C8FF2E', empty = '#23262C' }) {
  const cols = 12, rows = 7, gap = 3, cell = 13;
  const W = cols * (cell + gap), H = rows * (cell + gap);
  const tint = (v) => {
    if (v === 0) return empty;
    const op = v === 1 ? 0.35 : v === 2 ? 0.62 : 1;
    return accent + Math.round(op * 255).toString(16).padStart(2, '0');
  };
  return (
    <svg viewBox={`0 0 ${W} ${H}`} width="100%" style={{ display: 'block' }}>
      {values.map((v, i) => {
        const col = Math.floor(i / rows), row = i % rows;
        return <rect key={i} x={col * (cell + gap)} y={row * (cell + gap)} width={cell} height={cell}
          rx="3.5" fill={tint(v)} />;
      })}
    </svg>
  );
}

// ── Progress ring ────────────────────────────────────────────
function ProgressRing({ pct, accent = '#C8FF2E', size = 120, stroke = 11, track = '#23262C', children }) {
  const r = (size - stroke) / 2;
  const c = 2 * Math.PI * r;
  const off = c * (1 - pct / 100);
  return (
    <div style={{ position: 'relative', width: size, height: size }}>
      <svg width={size} height={size} style={{ display: 'block', transform: 'rotate(-90deg)' }}>
        <circle cx={size / 2} cy={size / 2} r={r} fill="none" stroke={track} strokeWidth={stroke} />
        <circle cx={size / 2} cy={size / 2} r={r} fill="none" stroke={accent} strokeWidth={stroke}
          strokeLinecap="round" strokeDasharray={c} strokeDashoffset={off}
          style={{ transition: 'stroke-dashoffset 0.7s cubic-bezier(.2,.8,.2,1)' }} />
      </svg>
      <div style={{ position: 'absolute', inset: 0, display: 'flex', flexDirection: 'column',
        alignItems: 'center', justifyContent: 'center' }}>{children}</div>
    </div>
  );
}

// ── Mini sparkline (inline in cards) ─────────────────────────
function MiniSpark({ data, accent = '#C8FF2E', w = 64, h = 26 }) {
  const min = Math.min(...data), max = Math.max(...data), span = max - min || 1;
  const pts = data.map((v, i) => [
    (i / (data.length - 1)) * w,
    h - 3 - ((v - min) / span) * (h - 6),
  ]);
  return (
    <svg width={w} height={h} viewBox={`0 0 ${w} ${h}`} style={{ display: 'block' }}>
      <path d={smoothPath(pts)} fill="none" stroke={accent} strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round" />
      <circle cx={pts[pts.length - 1][0]} cy={pts[pts.length - 1][1]} r="2.6" fill={accent} />
    </svg>
  );
}

Object.assign(window, { LineChart, BarChart, Heatmap, ProgressRing, MiniSpark });
