/**
 * TempGauge.jsx — CPU and GPU temperature circular gauge
 *
 * Features:
 *   - Subscribes to /saltybot/thermal_status for CPU and GPU temperatures
 *   - Circular gauge visualization with color zones
 *   - Temperature zones: green <60°C, yellow 60-75°C, red >75°C
 *   - Real-time temperature display with needle pointer
 *   - Fan speed percentage indicator
 *   - Peak temperature tracking
 *   - Thermal alert indicators
 */

import { useEffect, useRef, useState } from 'react';

const MIN_TEMP = 0;
const MAX_TEMP = 100;
const GAUGE_START_ANGLE = Math.PI * 0.7; // 126°
const GAUGE_END_ANGLE = Math.PI * 2.3; // 414° (180° + 234°)
const GAUGE_RANGE = GAUGE_END_ANGLE - GAUGE_START_ANGLE;

const TEMP_ZONES = {
  good: { max: 60, color: '#10b981', label: 'Good' }, // green
  caution: { max: 75, color: '#f59e0b', label: 'Caution' }, // yellow
  critical: { max: Infinity, color: '#ef4444', label: 'Critical' }, // red
};

function CircularGauge({ temp, maxTemp, label, color }) {
  const canvasRef = useRef(null);

  useEffect(() => {
    const canvas = canvasRef.current;
    if (!canvas) return;

    const ctx = canvas.getContext('2d');
    const width = canvas.width;
    const height = canvas.height;
    const centerX = width / 2;
    const centerY = height * 0.65;
    const radius = width * 0.35;

    // Clear canvas
    ctx.fillStyle = '#1f2937';
    ctx.fillRect(0, 0, width, height);

    // Draw gauge background arcs (color zones)
    const zoneValues = [60, 75, 100];
    const zoneColors = ['#10b981', '#f59e0b', '#ef4444'];

    for (let i = 0; i < zoneValues.length; i++) {
      const startVal = i === 0 ? 0 : zoneValues[i - 1];
      const endVal = zoneValues[i];
      const normalizedStart = startVal / MAX_TEMP;
      const normalizedEnd = endVal / MAX_TEMP;

      const startAngle = GAUGE_START_ANGLE + GAUGE_RANGE * normalizedStart;
      const endAngle = GAUGE_START_ANGLE + GAUGE_RANGE * normalizedEnd;

      ctx.strokeStyle = zoneColors[i];
      ctx.lineWidth = 12;
      ctx.lineCap = 'round';
      ctx.beginPath();
      ctx.arc(centerX, centerY, radius, startAngle, endAngle);
      ctx.stroke();
    }

    // Draw outer ring
    ctx.strokeStyle = '#374151';
    ctx.lineWidth = 2;
    ctx.beginPath();
    ctx.arc(centerX, centerY, radius, GAUGE_START_ANGLE, GAUGE_END_ANGLE);
    ctx.stroke();

    // Draw tick marks and labels
    ctx.fillStyle = '#9ca3af';
    ctx.strokeStyle = '#9ca3af';
    ctx.lineWidth = 1;
    ctx.font = 'bold 10px monospace';
    ctx.textAlign = 'center';
    ctx.textBaseline = 'middle';

    for (let i = 0; i <= 10; i++) {
      const value = (i / 10) * MAX_TEMP;
      const angle = GAUGE_START_ANGLE + (i / 10) * GAUGE_RANGE;
      const tickLen = i % 5 === 0 ? 8 : 4;

      const x1 = centerX + Math.cos(angle) * radius;
      const y1 = centerY + Math.sin(angle) * radius;
      const x2 = centerX + Math.cos(angle) * (radius + tickLen);
      const y2 = centerY + Math.sin(angle) * (radius + tickLen);

      ctx.beginPath();
      ctx.moveTo(x1, y1);
      ctx.lineTo(x2, y2);
      ctx.stroke();

      if (i % 2 === 0) {
        const labelX = centerX + Math.cos(angle) * (radius + 18);
        const labelY = centerY + Math.sin(angle) * (radius + 18);
        ctx.fillText(`${Math.round(value)}°`, labelX, labelY);
      }
    }

    // Draw needle
    const normalizedTemp = Math.max(0, Math.min(1, temp / MAX_TEMP));
    const needleAngle = GAUGE_START_ANGLE + normalizedTemp * GAUGE_RANGE;

    // Needle base circle
    ctx.fillStyle = '#1f2937';
    ctx.strokeStyle = '#9ca3af';
    ctx.lineWidth = 2;
    ctx.beginPath();
    ctx.arc(centerX, centerY, 8, 0, Math.PI * 2);
    ctx.fill();
    ctx.stroke();

    // Needle line
    ctx.strokeStyle = color || '#06b6d4';
    ctx.lineWidth = 3;
    ctx.lineCap = 'round';
    ctx.beginPath();
    ctx.moveTo(centerX, centerY);
    const needleLen = radius * 0.85;
    ctx.lineTo(
      centerX + Math.cos(needleAngle) * needleLen,
      centerY + Math.sin(needleAngle) * needleLen
    );
    ctx.stroke();

    // Needle tip circle
    ctx.fillStyle = color || '#06b6d4';
    ctx.beginPath();
    ctx.arc(
      centerX + Math.cos(needleAngle) * needleLen,
      centerY + Math.sin(needleAngle) * needleLen,
      4,
      0,
      Math.PI * 2
    );
    ctx.fill();

    // Draw temperature display
    ctx.fillStyle = color || '#06b6d4';
    ctx.font = 'bold 32px monospace';
    ctx.textAlign = 'center';
    ctx.textBaseline = 'top';
    ctx.fillText(`${Math.round(temp)}°`, centerX, centerY - 20);

    ctx.fillStyle = '#9ca3af';
    ctx.font = 'bold 12px monospace';
    ctx.fillText(label, centerX, centerY + 25);
  }, [temp, label, color]);

  return <canvas ref={canvasRef} width={200} height={180} className="inline-block" />;
}

function TemperatureRow({ label, temp, fanSpeed, maxTemp = MAX_TEMP }) {
  // Determine color zone
  let zoneColor = '#10b981'; // green
  let zoneLabel = 'Good';
  if (temp >= 60 && temp < 75) {
    zoneColor = '#f59e0b'; // yellow
    zoneLabel = 'Caution';
  } else if (temp >= 75) {
    zoneColor = '#ef4444'; // red
    zoneLabel = 'Critical';
  }

  return (
    <div className="flex flex-col items-center gap-3 p-4 bg-gray-900 rounded border border-gray-800">
      <CircularGauge temp={temp} maxTemp={maxTemp} label={label} color={zoneColor} />

      <div className="w-full space-y-2">
        <div className="flex justify-between items-center text-xs">
          <span className="text-gray-600">STATUS</span>
          <span className={`font-bold ${zoneColor === '#10b981' ? 'text-green-400' : zoneColor === '#f59e0b' ? 'text-yellow-400' : 'text-red-400'}`}>
            {zoneLabel}
          </span>
        </div>

        {fanSpeed !== undefined && (
          <div className="flex justify-between items-center text-xs">
            <span className="text-gray-600">FAN SPEED</span>
            <span className="text-cyan-300 font-mono">{Math.round(fanSpeed)}%</span>
          </div>
        )}

        <div className="flex justify-between items-center text-xs">
          <span className="text-gray-600">MAX REACHED</span>
          <span className="text-amber-300 font-mono">{Math.round(maxTemp)}°</span>
        </div>
      </div>
    </div>
  );
}

export function TempGauge({ subscribe }) {
  const [cpuTemp, setCpuTemp] = useState(0);
  const [gpuTemp, setGpuTemp] = useState(0);
  const [cpuFanSpeed, setCpuFanSpeed] = useState(0);
  const [gpuFanSpeed, setGpuFanSpeed] = useState(0);
  const [cpuMaxTemp, setCpuMaxTemp] = useState(0);
  const [gpuMaxTemp, setGpuMaxTemp] = useState(0);
  const maxTempRef = useRef({ cpu: 0, gpu: 0 });

  // Subscribe to thermal status
  useEffect(() => {
    const unsubscribe = subscribe(
      '/saltybot/thermal_status',
      'saltybot_msgs/ThermalStatus',
      (msg) => {
        try {
          const cpu = msg.cpu_temp || 0;
          const gpu = msg.gpu_temp || 0;
          const cpuFan = msg.cpu_fan_speed || 0;
          const gpuFan = msg.gpu_fan_speed || 0;

          setCpuTemp(cpu);
          setGpuTemp(gpu);
          setCpuFanSpeed(cpuFan);
          setGpuFanSpeed(gpuFan);

          // Track max temperatures
          if (cpu > maxTempRef.current.cpu) {
            maxTempRef.current.cpu = cpu;
            setCpuMaxTemp(cpu);
          }
          if (gpu > maxTempRef.current.gpu) {
            maxTempRef.current.gpu = gpu;
            setGpuMaxTemp(gpu);
          }
        } catch (e) {
          console.error('Error parsing thermal status:', e);
        }
      }
    );

    return unsubscribe;
  }, [subscribe]);

  const overallCritical = cpuTemp >= 75 || gpuTemp >= 75;
  const overallCaution = cpuTemp >= 60 || gpuTemp >= 60;

  return (
    <div className="flex flex-col h-full space-y-3">
      {/* Summary Header */}
      <div className="bg-gray-950 rounded-lg border border-cyan-950 p-3 space-y-2">
        <div className="flex justify-between items-center">
          <div className="text-cyan-700 text-xs font-bold tracking-widest">
            THERMAL STATUS
          </div>
          <div className={`text-xs font-bold px-2 py-1 rounded ${
            overallCritical ? 'bg-red-950 text-red-400 border border-red-800' :
            overallCaution ? 'bg-yellow-950 text-yellow-400 border border-yellow-800' :
            'bg-green-950 text-green-400 border border-green-800'
          }`}>
            {overallCritical ? 'CRITICAL' : overallCaution ? 'CAUTION' : 'NORMAL'}
          </div>
        </div>

        {/* Quick stats */}
        <div className="grid grid-cols-2 gap-2 text-xs">
          <div className="bg-gray-900 rounded p-2">
            <div className="text-gray-600">CPU</div>
            <div className="text-lg font-mono text-cyan-300">{Math.round(cpuTemp)}°C</div>
          </div>
          <div className="bg-gray-900 rounded p-2">
            <div className="text-gray-600">GPU</div>
            <div className="text-lg font-mono text-cyan-300">{Math.round(gpuTemp)}°C</div>
          </div>
        </div>
      </div>

      {/* Gauge Cards */}
      <div className="flex-1 grid grid-cols-2 gap-3 overflow-y-auto">
        <TemperatureRow
          label="CPU"
          temp={cpuTemp}
          fanSpeed={cpuFanSpeed}
          maxTemp={cpuMaxTemp}
        />
        <TemperatureRow
          label="GPU"
          temp={gpuTemp}
          fanSpeed={gpuFanSpeed}
          maxTemp={gpuMaxTemp}
        />
      </div>

      {/* Temperature zones legend */}
      <div className="bg-gray-950 rounded border border-gray-800 p-2 space-y-2">
        <div className="text-xs text-gray-600 font-bold tracking-widest">TEMPERATURE ZONES</div>
        <div className="grid grid-cols-3 gap-2 text-xs">
          <div className="flex items-center gap-2">
            <div className="w-3 h-3 rounded-full bg-green-500" />
            <span className="text-gray-400">&lt;60°C</span>
          </div>
          <div className="flex items-center gap-2">
            <div className="w-3 h-3 rounded-full bg-yellow-500" />
            <span className="text-gray-400">60-75°C</span>
          </div>
          <div className="flex items-center gap-2">
            <div className="w-3 h-3 rounded-full bg-red-500" />
            <span className="text-gray-400">&gt;75°C</span>
          </div>
        </div>
      </div>

      {/* Topic info */}
      <div className="bg-gray-950 rounded border border-gray-800 p-2 text-xs text-gray-600 space-y-1">
        <div className="flex justify-between">
          <span>Topic:</span>
          <span className="text-gray-500">/saltybot/thermal_status</span>
        </div>
        <div className="flex justify-between">
          <span>Type:</span>
          <span className="text-gray-500">saltybot_msgs/ThermalStatus</span>
        </div>
      </div>
    </div>
  );
}
