import React, { useState } from 'react';
import { Text, View } from 'react-native';
import Svg, { Circle, G, Line, Path, Rect, Text as SvgText } from 'react-native-svg';
import { fmtD, fmtDY, hm, kfmt, num } from '../lib/format';
import { C } from '../lib/theme';
import type { Night, Week } from '../lib/types';

const DetailRow = ({ k, v, dot }: { k: string; v: string; dot?: string }) => (
  <View style={{ flexDirection: 'row', justifyContent: 'space-between', marginTop: 2 }}>
    <View style={{ flexDirection: 'row', alignItems: 'center', gap: 5 }}>
      {dot ? <View style={{ width: 7, height: 7, borderRadius: 2, backgroundColor: dot }} /> : null}
      <Text style={{ color: C.muted, fontSize: 11.5 }}>{k}</Text>
    </View>
    <Text style={{ color: C.text, fontSize: 11.5, fontWeight: '500' }}>{v}</Text>
  </View>
);

function DetailCard({ title, rows }: { title: string; rows: [string, string, string?][] }) {
  return (
    <View
      style={{
        backgroundColor: C.surface2, borderWidth: 1, borderColor: C.border,
        borderRadius: 10, padding: 10, marginTop: 10,
      }}>
      <Text style={{ color: C.text, fontSize: 11.5, fontWeight: '600', marginBottom: 3 }}>
        {title}
      </Text>
      {rows.map(([k, v, dot]) => (
        <DetailRow key={k} k={k} v={v} dot={dot} />
      ))}
    </View>
  );
}

/* stacked nightly sleep bars — tap a bar for the night's detail */
export function SleepChart({ nights, width }: { nights: Night[]; width: number }) {
  const [sel, setSel] = useState<number | null>(null);
  const H = 150, padL = 26, padB = 16, W = width;
  const iw = W - padL, n = nights.length, bw = Math.max(3, iw / n - 2);
  const maxH = Math.max(...nights.map((t) => t.total / 3600), 9);
  const yMax = Math.ceil(maxH);
  const y = (v: number) => H - padB - (v / yMax) * (H - padB - 6);

  const grid = [];
  for (let g = 0; g <= yMax; g += 3) grid.push(g);

  const selN = sel != null ? nights[sel] : null;

  return (
    <View>
      <Svg width={W} height={H} viewBox={`0 0 ${W} ${H}`}>
        {grid.map((g) => (
          <G key={g}>
            <Line x1={padL} y1={y(g)} x2={W} y2={y(g)} stroke={C.gridline} strokeWidth={1} />
            <SvgText x={padL - 5} y={y(g) + 3} textAnchor="end" fill={C.muted} fontSize={9.5}>
              {g}h
            </SvgText>
          </G>
        ))}
        {nights.map((t, i) => {
          const x = padL + (i + 0.5) * (iw / n) - bw / 2;
          let acc = 0;
          const segs: [number, string][] = [
            [t.deep, C.s1], [t.rem, C.s2], [t.light, C.s3], [t.awake, C.awake],
          ];
          return (
            <G key={t.date} onPress={() => setSel(i === sel ? null : i)}>
              <Rect x={x - 1} y={6} width={bw + 2} height={H - padB - 6} fill="transparent" />
              {segs.map(([secs, color], j) => {
                const v = secs / 3600;
                if (v <= 0.008) return null;
                const y1 = y(acc + v), y2 = y(acc);
                acc += v;
                return (
                  <Rect key={j} x={x} y={y1} width={bw} height={Math.max(1, y2 - y1 - 1)}
                    rx={1.5} fill={color} opacity={sel == null || sel === i ? 1 : 0.35} />
                );
              })}
            </G>
          );
        })}
        <SvgText x={padL} y={H - 3} fill={C.muted} fontSize={9.5}>
          {fmtD(nights[0].date)}
        </SvgText>
        <SvgText x={W} y={H - 3} textAnchor="end" fill={C.muted} fontSize={9.5}>
          {fmtD(nights[n - 1].date)}
        </SvgText>
      </Svg>
      {selN && (
        <DetailCard
          title={fmtDY(selN.date)}
          rows={[
            ['Asleep', hm(selN.asleep)],
            ...(selN.deep ? ([['Deep', hm(selN.deep), C.s1]] as [string, string, string][]) : []),
            ...(selN.rem ? ([['REM', hm(selN.rem), C.s2]] as [string, string, string][]) : []),
            ...(selN.light ? ([['Light', hm(selN.light), C.s3]] as [string, string, string][]) : []),
            ...(selN.awake ? ([['Awake', hm(selN.awake), C.awake]] as [string, string, string][]) : []),
            ...(selN.hrv ? ([['HRV', `${Math.round(selN.hrv)} ms`]] as [string, string][]) : []),
            ...(selN.hr ? ([['Resting HR', `${Math.round(selN.hr)} bpm`]] as [string, string][]) : []),
            ...(selN.quality != null ? ([['Quality', `${selN.quality}%`]] as [string, string][]) : []),
            ['Source', selN.src],
          ]}
        />
      )}
    </View>
  );
}

/* weekly training volume bars — tap a bar for the week's detail */
export function VolumeChart({ weeks, width }: { weeks: Week[]; width: number }) {
  const [sel, setSel] = useState<number | null>(null);
  const H = 140, padL = 30, padB = 16, W = width;
  const iw = W - padL, n = weeks.length, bw = Math.max(4, iw / n - 3);
  const maxV = Math.max(...weeks.map((w) => w.vol), 1);
  const y = (v: number) => H - padB - (v / maxV) * (H - padB - 8);
  const selW = sel != null ? weeks[sel] : null;

  return (
    <View>
      <Svg width={W} height={H} viewBox={`0 0 ${W} ${H}`}>
        {[0, 0.5, 1].map((f) => (
          <G key={f}>
            <Line x1={padL} y1={y(maxV * f)} x2={W} y2={y(maxV * f)} stroke={C.gridline} strokeWidth={1} />
            <SvgText x={padL - 5} y={y(maxV * f) + 3} textAnchor="end" fill={C.muted} fontSize={9.5}>
              {kfmt(maxV * f)}
            </SvgText>
          </G>
        ))}
        {weeks.map((w, i) => {
          const x = padL + (i + 0.5) * (iw / n) - bw / 2;
          return (
            <G key={w.start} onPress={() => setSel(i === sel ? null : i)}>
              <Rect x={x - 1.5} y={8} width={bw + 3} height={H - padB - 8} fill="transparent" />
              <Rect x={x} y={y(w.vol)} width={bw} height={Math.max(1, H - padB - y(w.vol))}
                rx={2} fill={C.s1} opacity={sel == null || sel === i ? 1 : 0.35} />
            </G>
          );
        })}
        <SvgText x={padL} y={H - 3} fill={C.muted} fontSize={9.5}>
          {fmtD(weeks[0].start)}
        </SvgText>
        <SvgText x={W} y={H - 3} textAnchor="end" fill={C.muted} fontSize={9.5}>
          {fmtD(weeks[n - 1].start)}
        </SvgText>
      </Svg>
      {selW && (
        <DetailCard
          title={`Week of ${fmtDY(selW.start)}`}
          rows={[
            ['Volume', `${num(Math.round(selW.vol))} kg`],
            ['Workouts', String(selW.count)],
            ['Sets', String(selW.sets)],
          ]}
        />
      )}
    </View>
  );
}

/* biomarker sparkline */
export function Sparkline({
  pts, flagged, width,
}: {
  pts: { d: string; v: number }[];
  flagged: boolean;
  width: number;
}) {
  if (pts.length < 2) return null;
  const W = width, H = 30, p = 4;
  const vs = pts.map((q) => q.v);
  const min = Math.min(...vs), max = Math.max(...vs), span = max - min || 1;
  const x = (i: number) => p + (i * (W - 2 * p)) / (pts.length - 1);
  const y = (v: number) => H - p - ((v - min) / span) * (H - 2 * p);
  const d = pts.map((q, i) => (i ? 'L' : 'M') + x(i).toFixed(1) + ' ' + y(q.v).toFixed(1)).join(' ');
  const last = pts[pts.length - 1];
  return (
    <View style={{ marginTop: 6 }}>
      <Svg width={W} height={H} viewBox={`0 0 ${W} ${H}`}>
        <Path d={d} fill="none" stroke={C.s1} strokeWidth={2} strokeLinecap="round" opacity={0.7} />
        <Circle cx={x(pts.length - 1)} cy={y(last.v)} r={3.5}
          fill={flagged ? C.red : C.s1} stroke={C.surface} strokeWidth={1.5} />
      </Svg>
      <View style={{ flexDirection: 'row', justifyContent: 'space-between', marginTop: 4 }}>
        <Text style={{ color: C.dim, fontSize: 10 }}>{fmtD(pts[0].d)}</Text>
        <Text style={{ color: C.dim, fontSize: 10 }}>{fmtD(last.d)}</Text>
      </View>
    </View>
  );
}
