import { useEffect, useState } from "react";

interface SpeedometerProps {
  speed: string; // e.g., "80 Mbps", "1 Gbps", "1.5 Gbps"
  size?: number;
}

const Speedometer = ({ speed, size = 140 }: SpeedometerProps) => {
  const [animatedValue, setAnimatedValue] = useState(0);

  // Parse speed to get a normalized value (0-1) for indicator position
  // Uses logarithmic curve: fast climb for lower speeds, diminishing impact for higher speeds
  const getSpeedValue = (speedStr: string): number => {
    const lower = speedStr.toLowerCase();
    let mbps: number;

    if (lower.includes("gbps")) {
      mbps = parseFloat(speedStr) * 1000; // Convert Gbps to Mbps
    } else {
      mbps = parseFloat(speedStr);
    }

    // Logarithmic curve: log(1 + x * k) / log(1 + k)
    // Higher k = faster climb for lower speeds, compressed difference at higher speeds
    const maxSpeed = 3500;
    const k = 50; // Higher value for more aggressive lower speed progression
    const normalized = Math.min(mbps / maxSpeed, 1);

    return Math.log(1 + normalized * k) / Math.log(1 + k);
  };

  const targetValue = getSpeedValue(speed);

  // Animate on mount
  useEffect(() => {
    const duration = 1200;
    const startTime = performance.now();

    const animate = (currentTime: number) => {
      const elapsed = currentTime - startTime;
      const progress = Math.min(elapsed / duration, 1);

      // Ease-out cubic for smooth deceleration
      const eased = 1 - Math.pow(1 - progress, 3);
      setAnimatedValue(eased * targetValue);

      if (progress < 1) {
        requestAnimationFrame(animate);
      }
    };

    requestAnimationFrame(animate);
  }, [targetValue]);

  // Parse speed into number and unit
  const speedNumber = parseFloat(speed);
  const speedUnit = speed.toLowerCase().includes("gbps") ? "Gbps" : "Mbps";

  const strokeWidth = 14;
  const radius = (size - strokeWidth) / 2;
  const center = size / 2;

  // Arc path for the gauge
  const polarToCartesian = (cx: number, cy: number, r: number, angleDeg: number) => {
    const rad = ((angleDeg - 90) * Math.PI) / 180;
    return {
      x: cx + r * Math.cos(rad),
      y: cy + r * Math.sin(rad),
    };
  };

  const describeArc = (cx: number, cy: number, r: number, startAngle: number, endAngle: number) => {
    const start = polarToCartesian(cx, cy, r, endAngle);
    const end = polarToCartesian(cx, cy, r, startAngle);
    const largeArcFlag = endAngle - startAngle <= 180 ? "0" : "1";
    return `M ${start.x} ${start.y} A ${r} ${r} 0 ${largeArcFlag} 0 ${end.x} ${end.y}`;
  };

  // Full arc from -135 to 135 (270 degrees)
  const arcPath = describeArc(center, center, radius, -135, 135);

  // Filled arc based on animated value
  const filledAngle = -135 + animatedValue * 270;
  const filledArcPath = describeArc(center, center, radius, -135, filledAngle);

  // Position for the indicator circle
  const indicatorPos = polarToCartesian(center, center, radius, filledAngle);

  const uniqueId = `speedGradient-${speed.replace(/\s/g, '-')}`;

  // Gradient with lighter green tones
  const getGradientColors = () => {
    return { start: "#34d399", mid: "#4ade80", end: "#86efac" };
  };

  const colors = getGradientColors();

  return (
    <div className="relative flex flex-col items-center" style={{ width: size, height: size * 0.7 }}>
      <svg
        viewBox={`0 0 ${size} ${size}`}
        width={size}
        height={size * 0.7}
        className="overflow-visible"
      >
        <defs>
          <linearGradient id={uniqueId} x1="0%" y1="100%" x2="100%" y2="0%">
            <stop offset="0%" stopColor={colors.start} />
            <stop offset="50%" stopColor={colors.mid} />
            <stop offset="100%" stopColor={colors.end} />
          </linearGradient>
          <filter id={`shadow-${uniqueId}`} x="-50%" y="-50%" width="200%" height="200%">
            <feDropShadow dx="0" dy="2" stdDeviation="3" floodOpacity="0.35" />
          </filter>
        </defs>

        {/* Background arc (grey) */}
        <path
          d={arcPath}
          fill="none"
          stroke="hsl(var(--muted))"
          strokeWidth={strokeWidth}
          strokeLinecap="round"
        />

        {/* Colored gradient arc */}
        <path
          d={filledArcPath}
          fill="none"
          stroke={`url(#${uniqueId})`}
          strokeWidth={strokeWidth / 2}
          strokeLinecap="round"
        />

        {/* Indicator circle with shadow */}
        <g filter={`url(#shadow-${uniqueId})`}>
          <circle
            cx={indicatorPos.x}
            cy={indicatorPos.y}
            r={10}
            fill="hsl(var(--muted))"
          />
          <circle
            cx={indicatorPos.x}
            cy={indicatorPos.y}
            r={8}
            fill="white"
          />
        </g>

        {/* Speed number - large */}
        <text
          x={center}
          y={center}
          textAnchor="middle"
          dominantBaseline="middle"
          className="fill-primary font-bold"
          style={{ fontSize: size * 0.35, letterSpacing: "-0.05em" }}
        >
          {speedNumber}
        </text>

        {/* Speed unit - small */}
        <text
          x={center}
          y={center + size * 0.20}
          textAnchor="middle"
          className="fill-muted-foreground font-medium"
          style={{ fontSize: size * 0.12 }}
        >
          {speedUnit}
        </text>
      </svg>
    </div>
  );
};

export default Speedometer;
