// telemetry.jsx — live ride playback widget for ACE hero
// Animated power/HR/cadence readouts + chart, drives a fake ride playback loop.

const { useState, useEffect, useRef, useMemo } = React;

// ── Generated ride profile ──────────────────────────────────────────────────
// 240 samples = 4 minutes-equivalent fake ride loop.
function generateRide(n = 240, seed = 7) {
  let s = seed;
  const rand = () => { s = (s * 9301 + 49297) % 233280; return s / 233280; };
  const power = [];
  const hr = [];
  const cadence = [];
  const elev = [];
  let elevAcc = 120;
  for (let i = 0; i < n; i++) {
    const t = i / n;
    // Build an interval workout: warmup → 3 hard efforts → recovery
    const phase = t < 0.15 ? "warmup"
                : t < 0.35 ? "effort1"
                : t < 0.45 ? "rest1"
                : t < 0.65 ? "effort2"
                : t < 0.75 ? "rest2"
                : t < 0.92 ? "effort3"
                : "cooldown";
    let basePower;
    if (phase === "warmup") basePower = 160 + t * 200;
    else if (phase === "effort1") basePower = 320;
    else if (phase === "rest1")   basePower = 180;
    else if (phase === "effort2") basePower = 360;
    else if (phase === "rest2")   basePower = 195;
    else if (phase === "effort3") basePower = 395;
    else basePower = 190 - (t - 0.92) * 400;
    const p = Math.max(80, basePower + (rand() - 0.5) * 30);
    power.push(p);
    // HR lags power
    const targetHr = 100 + (p / 400) * 80;
    const lastHr = hr[i - 1] ?? 95;
    hr.push(lastHr + (targetHr - lastHr) * 0.05 + (rand() - 0.5) * 1.2);
    // Cadence dips during high power, bounces back
    cadence.push(85 + Math.sin(i * 0.15) * 6 + (p > 350 ? -8 : 0) + (rand() - 0.5) * 3);
    // Elevation: gentle climb-then-descend
    elevAcc += Math.sin(t * Math.PI * 2.2) * 1.4 + (rand() - 0.5) * 0.3;
    elev.push(elevAcc);
  }
  return { power, hr, cadence, elev };
}

const RIDE = generateRide();

function smoothPath(values, w, h, padY = 6) {
  if (!values.length) return "";
  const min = Math.min(...values);
  const max = Math.max(...values);
  const range = max - min || 1;
  const sx = w / (values.length - 1);
  const pts = values.map((v, i) => [i * sx, padY + (h - padY * 2) * (1 - (v - min) / range)]);
  let d = `M ${pts[0][0].toFixed(2)} ${pts[0][1].toFixed(2)}`;
  for (let i = 1; i < pts.length; i++) {
    const [px, py] = pts[i - 1];
    const [cx, cy] = pts[i];
    const mx = (px + cx) / 2;
    d += ` Q ${px.toFixed(2)} ${py.toFixed(2)} ${mx.toFixed(2)} ${((py + cy) / 2).toFixed(2)}`;
  }
  d += ` L ${pts[pts.length - 1][0].toFixed(2)} ${pts[pts.length - 1][1].toFixed(2)}`;
  return { d, pts, min, max };
}

function HeroTrace() {
  // Wide background SVG trace, very subtle.
  const { d } = useMemo(() => smoothPath(RIDE.elev, 1600, 320, 20), []);
  return (
    <svg className="hero-trace" viewBox="0 0 1600 320" preserveAspectRatio="none" aria-hidden>
      <defs>
        <linearGradient id="trace-fill" x1="0" x2="0" y1="0" y2="1">
          <stop offset="0%" stopColor="var(--accent)" stopOpacity="0.10" />
          <stop offset="100%" stopColor="var(--accent)" stopOpacity="0" />
        </linearGradient>
      </defs>
      <path d={`${d} L 1600 320 L 0 320 Z`} fill="url(#trace-fill)" />
      <path d={d} fill="none" stroke="var(--accent)" strokeWidth="1.2" opacity="0.35" />
    </svg>
  );
}

function Telemetry() {
  const [idx, setIdx] = useState(0);
  const rafRef = useRef(0);
  const lastRef = useRef(performance.now());

  useEffect(() => {
    const tick = (now) => {
      const dt = now - lastRef.current;
      if (dt > 65) { // ~15fps update; chart still smooth
        lastRef.current = now;
        setIdx((i) => (i + 1) % RIDE.power.length);
      }
      rafRef.current = requestAnimationFrame(tick);
    };
    rafRef.current = requestAnimationFrame(tick);
    return () => cancelAnimationFrame(rafRef.current);
  }, []);

  const window = 90;
  const slice = (arr) => {
    const out = [];
    for (let i = idx - window; i <= idx; i++) {
      out.push(arr[(i + arr.length) % arr.length]);
    }
    return out;
  };
  const powerWin = slice(RIDE.power);
  const hrWin = slice(RIDE.hr);
  const elevWin = slice(RIDE.elev);

  const W = 560, H = 180;
  const power = smoothPath(powerWin, W, H, 16);
  const hr = smoothPath(hrWin, W, H, 16);

  const curPower = Math.round(RIDE.power[idx]);
  const curHr = Math.round(RIDE.hr[idx]);
  const curCad = Math.round(RIDE.cadence[idx]);
  const ftp = 285;
  const pctFtp = Math.round((curPower / ftp) * 100);
  const zone =
    pctFtp < 56 ? { n: 1, name: "Recovery", color: "var(--fg-3)" } :
    pctFtp < 76 ? { n: 2, name: "Endurance", color: "var(--cool)" } :
    pctFtp < 91 ? { n: 3, name: "Tempo", color: "var(--warn)" } :
    pctFtp < 106 ? { n: 4, name: "Threshold", color: "var(--accent)" } :
    pctFtp < 121 ? { n: 5, name: "VO₂ Max", color: "var(--accent)" } :
                   { n: 6, name: "Anaerobic", color: "var(--danger)" };

  // Time elapsed display (looped fake ride: 1h 12m total)
  const totalSec = 72 * 60;
  const elapsed = Math.round((idx / RIDE.power.length) * totalSec);
  const mm = String(Math.floor(elapsed / 60)).padStart(2, "0");
  const ss = String(elapsed % 60).padStart(2, "0");

  return (
    <div className="telemetry">
      <div className="tel-head">
        <div className="tel-head-l">
          <span className="tel-live">Live</span>
          <span className="tel-title">Threshold intervals · 3 × 8min</span>
        </div>
        <span className="tel-sub">{`${mm}:${ss} / 01:12:00`}</span>
      </div>

      <div className="tel-stats">
        <div className="tel-stat">
          <div className="tel-stat-lbl">Power</div>
          <div className="tel-stat-val">{curPower}<span className="unit">w</span></div>
          <div className="tel-stat-delta up">{pctFtp}% FTP · Z{zone.n} {zone.name}</div>
        </div>
        <div className="tel-stat">
          <div className="tel-stat-lbl">Heart rate</div>
          <div className="tel-stat-val">{curHr}<span className="unit">bpm</span></div>
          <div className="tel-stat-delta">{Math.round((curHr / 188) * 100)}% max</div>
        </div>
        <div className="tel-stat">
          <div className="tel-stat-lbl">Cadence</div>
          <div className="tel-stat-val">{curCad}<span className="unit">rpm</span></div>
          <div className="tel-stat-delta">target 90–95</div>
        </div>
        <div className="tel-stat">
          <div className="tel-stat-lbl">TSS</div>
          <div className="tel-stat-val">{Math.round(72 + idx * 0.4)}<span className="unit"></span></div>
          <div className="tel-stat-delta up">on pace</div>
        </div>
      </div>

      <div className="tel-chart">
        <div className="tel-chart-head">
          <span className="tel-chart-title">Last 90 seconds</span>
          <span className="tel-chart-legend">
            <span><i style={{ background: "var(--accent)" }}></i>Power</span>
            <span><i style={{ background: "var(--danger)" }}></i>HR</span>
          </span>
        </div>
        <svg viewBox={`0 0 ${W} ${H}`} width="100%" height={H} preserveAspectRatio="none" style={{ display: "block" }}>
          <defs>
            <linearGradient id="pwr-fill" x1="0" x2="0" y1="0" y2="1">
              <stop offset="0%" stopColor="var(--accent)" stopOpacity="0.35" />
              <stop offset="100%" stopColor="var(--accent)" stopOpacity="0" />
            </linearGradient>
          </defs>
          {/* grid */}
          {[0.25, 0.5, 0.75].map((p) => (
            <line key={p} x1="0" x2={W} y1={H * p} y2={H * p} stroke="var(--line)" strokeDasharray="2 4" />
          ))}
          <path d={`${power.d} L ${W} ${H} L 0 ${H} Z`} fill="url(#pwr-fill)" />
          <path d={power.d} fill="none" stroke="var(--accent)" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round" />
          <path d={hr.d} fill="none" stroke="var(--danger)" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" opacity="0.85" />
          {/* current point */}
          {power.pts.length > 0 && (
            <>
              <line
                x1={power.pts[power.pts.length - 1][0]}
                x2={power.pts[power.pts.length - 1][0]}
                y1="0" y2={H}
                stroke="var(--accent)" strokeWidth="1" strokeDasharray="2 3" opacity="0.5"
              />
              <circle
                cx={power.pts[power.pts.length - 1][0]}
                cy={power.pts[power.pts.length - 1][1]}
                r="4" fill="var(--accent)" stroke="var(--bg)" strokeWidth="2"
              />
            </>
          )}
        </svg>
      </div>

      <div className="tel-insight">
        <span className="tel-insight-ico">A</span>
        <div>
          <b>ACE adjustment ·</b> Your last interval was 4w above target with HR drifting +3bpm.
          Reducing interval 3 to 92% FTP to preserve quality. <span style={{ color: "var(--fg-3)" }}>auto-applied</span>
        </div>
      </div>
    </div>
  );
}

Object.assign(window, { Telemetry, HeroTrace });
