// gauge.jsx — Motorcycle tachometer-style score gauge

const Gauge = ({ score = 0, label = "Score", subLabel = "", size = 320, accent = "var(--accent)", tickColor = "var(--gauge-tick)", arcBg = "var(--gauge-track)", needleColor = "var(--gauge-needle)", isNight = false }) => {
  // 0 score = -135deg, 100 score = +135deg
  const angle = -135 + (Math.min(100, Math.max(0, score)) / 100) * 270;
  const r = size / 2;
  const cx = r;
  const cy = r;
  const arcR = r - 18;

  // Animated needle
  const [displayAngle, setDisplayAngle] = React.useState(-135);
  React.useEffect(() => {
    const start = performance.now();
    const from = displayAngle;
    const to = angle;
    const dur = 1100;
    let raf;
    const step = (t) => {
      const k = Math.min(1, (t - start) / dur);
      // easeOutBack-ish
      const eased = 1 - Math.pow(1 - k, 3);
      setDisplayAngle(from + (to - from) * eased);
      if (k < 1) raf = requestAnimationFrame(step);
    };
    raf = requestAnimationFrame(step);
    return () => cancelAnimationFrame(raf);
  }, [angle]);

  // Build tick marks every 10 score units
  const ticks = [];
  for (let i = 0; i <= 100; i += 5) {
    const major = i % 20 === 0;
    const a = (-135 + (i / 100) * 270) * (Math.PI / 180);
    const inner = arcR - (major ? 14 : 7);
    const outer = arcR;
    const x1 = cx + Math.cos(a) * inner;
    const y1 = cy + Math.sin(a) * inner;
    const x2 = cx + Math.cos(a) * outer;
    const y2 = cy + Math.sin(a) * outer;
    // Red zone: 0-30 (i.e. left of zero, "danger" — but we map low = bad which is left side)
    const danger = i <= 30;
    const warn = i > 30 && i <= 55;
    ticks.push({ x1, y1, x2, y2, major, danger, warn, num: i, a });
  }
  const numberLabels = [0, 20, 40, 60, 80, 100];

  // Arc path: full sweep -135 to 135
  const arcPath = (startA, endA, R) => {
    const s = startA * (Math.PI / 180);
    const e = endA * (Math.PI / 180);
    const x1 = cx + Math.cos(s) * R;
    const y1 = cy + Math.sin(s) * R;
    const x2 = cx + Math.cos(e) * R;
    const y2 = cy + Math.sin(e) * R;
    const largeArc = Math.abs(endA - startA) > 180 ? 1 : 0;
    return `M ${x1} ${y1} A ${R} ${R} 0 ${largeArc} 1 ${x2} ${y2}`;
  };

  return (
    <div className="gauge" style={{ width: size, height: size, position: "relative" }}>
      <svg width={size} height={size} viewBox={`0 0 ${size} ${size}`} style={{ display: "block" }}>
        <defs>
          <radialGradient id={`gauge-bg-${label}`} cx="50%" cy="50%" r="55%">
            <stop offset="0%" stopColor="var(--gauge-face-c)" stopOpacity="1" />
            <stop offset="100%" stopColor="var(--gauge-face-e)" stopOpacity="1" />
          </radialGradient>
          <filter id={`gauge-glow-${label}`} x="-50%" y="-50%" width="200%" height="200%">
            <feGaussianBlur stdDeviation="3" result="b" />
            <feMerge>
              <feMergeNode in="b" />
              <feMergeNode in="SourceGraphic" />
            </feMerge>
          </filter>
        </defs>

        {/* Face */}
        <circle cx={cx} cy={cy} r={r - 2} fill={`url(#gauge-bg-${label})`} stroke="var(--gauge-rim)" strokeWidth="1.5" />
        <circle cx={cx} cy={cy} r={r - 8} fill="none" stroke="var(--gauge-rim-inner)" strokeWidth="0.5" />

        {/* BG arc */}
        <path d={arcPath(-135, 135, arcR)} stroke={arcBg} strokeWidth="3" fill="none" strokeLinecap="round" opacity="0.5" />

        {/* Filled arc up to score */}
        <path d={arcPath(-135, Math.max(-135, displayAngle), arcR)} stroke={accent} strokeWidth="3" fill="none" strokeLinecap="round" filter={`url(#gauge-glow-${label})`} />

        {/* Tick marks */}
        {ticks.map((t, i) => (
          <line
            key={i}
            x1={t.x1}
            y1={t.y1}
            x2={t.x2}
            y2={t.y2}
            stroke={t.danger ? "var(--gauge-danger)" : t.warn ? "var(--gauge-warn)" : tickColor}
            strokeWidth={t.major ? 2 : 1}
            opacity={t.major ? 1 : 0.5}
          />
        ))}

        {/* Numbers */}
        {numberLabels.map((n) => {
          const a = (-135 + (n / 100) * 270) * (Math.PI / 180);
          const R = arcR - 28;
          const x = cx + Math.cos(a) * R;
          const y = cy + Math.sin(a) * R;
          return (
            <text key={n} x={x} y={y + 4} textAnchor="middle" fill="var(--gauge-num)" fontSize={size > 220 ? 12 : 10} fontFamily="var(--font-mono)" fontWeight="600">
              {n}
            </text>
          );
        })}

        {/* Center labels */}
        <text x={cx} y={cy - 18} textAnchor="middle" fill="var(--gauge-sub)" fontSize="11" fontFamily="var(--font-mono)" letterSpacing="2">
          {label.toUpperCase()}
        </text>

        {/* Score number */}
        <text
          x={cx}
          y={cy + 26}
          textAnchor="middle"
          fill="var(--gauge-score)"
          fontSize={size > 220 ? 64 : 44}
          fontFamily="var(--font-display)"
          fontWeight="700"
          style={{ fontVariantNumeric: "tabular-nums" }}
        >
          {Math.round(score)}
        </text>
        <text x={cx} y={cy + 46} textAnchor="middle" fill="var(--gauge-sub)" fontSize="10" fontFamily="var(--font-mono)" letterSpacing="1.5">
          / 100
        </text>

        {/* Day/Night glyph */}
        <g transform={`translate(${cx}, ${cy + 70})`}>
          {isNight ? (
            <path d="M -8 0 a 8 8 0 1 0 12 -7 a 6 6 0 1 1 -12 7 z" fill="var(--gauge-sub)" opacity="0.6" />
          ) : (
            <g fill="var(--gauge-sub)" opacity="0.6">
              <circle cx="0" cy="0" r="4" />
              {[0, 45, 90, 135, 180, 225, 270, 315].map((d) => {
                const ang = (d * Math.PI) / 180;
                const x1 = Math.cos(ang) * 7;
                const y1 = Math.sin(ang) * 7;
                const x2 = Math.cos(ang) * 10;
                const y2 = Math.sin(ang) * 10;
                return <line key={d} x1={x1} y1={y1} x2={x2} y2={y2} stroke="var(--gauge-sub)" strokeWidth="1.5" />;
              })}
            </g>
          )}
        </g>

        {/* Needle */}
        <g transform={`rotate(${displayAngle} ${cx} ${cy})`}>
          <line x1={cx} y1={cy} x2={cx + arcR - 6} y2={cy} stroke={needleColor} strokeWidth="3" strokeLinecap="round" filter={`url(#gauge-glow-${label})`} />
          <circle cx={cx + arcR - 6} cy={cy} r="3" fill={needleColor} />
        </g>
        <circle cx={cx} cy={cy} r="9" fill="var(--gauge-hub)" stroke={needleColor} strokeWidth="1.5" />
        <circle cx={cx} cy={cy} r="3" fill={needleColor} />

        {/* Sub label e.g. 06:32 → 17:48 */}
        {subLabel && (
          <text x={cx} y={size - 14} textAnchor="middle" fill="var(--gauge-sub)" fontSize="10" fontFamily="var(--font-mono)" letterSpacing="1.5">
            {subLabel}
          </text>
        )}
      </svg>
    </div>
  );
};

window.Gauge = Gauge;
