/**
 * MotorPanel.jsx — Motor telemetry display.
 *
 * Balance bot:  /saltybot/balance_state (std_msgs/String JSON)
 *   motor_cmd [-1000..1000], bridge_speed, bridge_steer
 *
 * Rover mode:   /saltybot/rover_pwm (std_msgs/String JSON)
 *   ch1_us, ch2_us, ch3_us, ch4_us [1000..2000]
 *
 * Temperatures: /diagnostics (diagnostic_msgs/DiagnosticArray)
 *   motor_temp_l_c, motor_temp_r_c
 *
 * Displays PWM-bar for each motor, RPM proxy, temperature.
 */

import { useEffect, useState } from 'react';

const PWM_MIN = 1000;
const PWM_MID = 1500;
const PWM_MAX = 2000;

/** Map [-1..1] normalised value to bar width and color. */
function dutyBar(norm) {
  const pct = Math.abs(norm) * 50;
  const color = norm > 0 ? '#f97316' : '#3b82f6';
  const left  = norm >= 0 ? '50%' : `${50 - pct}%`;
  return { pct, color, left };
}

function MotorGauge({ label, norm, pwmUs, tempC }) {
  const { pct, color, left } = dutyBar(norm);
  const tempWarn = tempC != null && tempC > 70;

  return (
    <div className="bg-gray-950 rounded-lg border border-cyan-950 p-4">
      <div className="flex items-center justify-between mb-2">
        <span className="text-cyan-700 text-xs font-bold tracking-widest">{label}</span>
        {tempC != null && (
          <span className={`text-xs font-bold ${tempWarn ? 'text-red-400' : 'text-gray-400'}`}>
            {tempC.toFixed(0)}°C
          </span>
        )}
      </div>

      {/* PWM value */}
      <div className="text-2xl font-bold text-orange-400 mb-2">
        {pwmUs != null ? `${pwmUs} µs` : `${Math.round(norm * 1000)}`}
      </div>

      {/* Bidirectional duty bar */}
      <div className="relative h-3 bg-gray-900 rounded overflow-hidden border border-gray-800 mb-1">
        <div className="absolute inset-y-0 left-1/2 w-px bg-gray-700" />
        <div
          className="absolute inset-y-0 transition-all duration-100 rounded"
          style={{ left, width: `${pct}%`, background: color }}
        />
      </div>
      <div className="flex justify-between text-xs text-gray-700">
        <span>REV</span>
        <span>{(norm * 100).toFixed(0)}%</span>
        <span>FWD</span>
      </div>
    </div>
  );
}

export function MotorPanel({ subscribe }) {
  const [balState, setBalState] = useState(null);
  const [roverPwm, setRoverPwm] = useState(null);
  const [temps, setTemps]       = useState({ l: null, r: null });

  // Balance state (2-wheel robot)
  useEffect(() => {
    const unsub = subscribe('/saltybot/balance_state', 'std_msgs/String', (msg) => {
      try { setBalState(JSON.parse(msg.data)); }
      catch { /* ignore */ }
    });
    return unsub;
  }, [subscribe]);

  // Rover PWM (4-wheel rover)
  useEffect(() => {
    const unsub = subscribe('/saltybot/rover_pwm', 'std_msgs/String', (msg) => {
      try { setRoverPwm(JSON.parse(msg.data)); }
      catch { /* ignore */ }
    });
    return unsub;
  }, [subscribe]);

  // Motor temperatures from diagnostics
  useEffect(() => {
    const unsub = subscribe('/diagnostics', 'diagnostic_msgs/DiagnosticArray', (msg) => {
      for (const status of msg.status ?? []) {
        const kv = {};
        for (const pair of status.values ?? []) kv[pair.key] = pair.value;
        if (kv.motor_temp_l_c !== undefined || kv.motor_temp_r_c !== undefined) {
          setTemps({
            l: kv.motor_temp_l_c != null ? parseFloat(kv.motor_temp_l_c) : null,
            r: kv.motor_temp_r_c != null ? parseFloat(kv.motor_temp_r_c) : null,
          });
          break;
        }
      }
    });
    return unsub;
  }, [subscribe]);

  // Determine display mode: rover if rover_pwm active, else balance
  const isRover = roverPwm != null;

  let leftNorm = 0, rightNorm = 0;
  let leftPwm = null, rightPwm = null;

  if (isRover) {
    // ch1=left-front, ch2=right-front, ch3=left-rear, ch4=right-rear
    leftPwm  = Math.round((roverPwm.ch1_us + (roverPwm.ch3_us ?? roverPwm.ch1_us)) / 2);
    rightPwm = Math.round((roverPwm.ch2_us + (roverPwm.ch4_us ?? roverPwm.ch2_us)) / 2);
    leftNorm  = (leftPwm  - PWM_MID) / (PWM_MAX - PWM_MID);
    rightNorm = (rightPwm - PWM_MID) / (PWM_MAX - PWM_MID);
  } else if (balState) {
    const cmd = (balState.motor_cmd ?? 0) / 1000;
    const steer = (balState.bridge_steer ?? 0) / 1000;
    leftNorm  = cmd + steer;
    rightNorm = cmd - steer;
  }

  // Clip to ±1
  leftNorm  = Math.max(-1, Math.min(1, leftNorm));
  rightNorm = Math.max(-1, Math.min(1, rightNorm));

  return (
    <div className="space-y-4">
      {/* Mode indicator */}
      <div className="flex items-center gap-2">
        <div className={`px-2 py-0.5 rounded text-xs font-bold border ${
          isRover
            ? 'bg-purple-950 border-purple-700 text-purple-300'
            : 'bg-blue-950 border-blue-700 text-blue-300'
        }`}>
          {isRover ? 'ROVER (4WD)' : 'BALANCE (2WD)'}
        </div>
        {!balState && !roverPwm && (
          <span className="text-gray-600 text-xs">No motor data</span>
        )}
      </div>

      {/* Motor gauges */}
      <div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
        <MotorGauge
          label="LEFT MOTOR"
          norm={leftNorm}
          pwmUs={isRover ? leftPwm : null}
          tempC={temps.l}
        />
        <MotorGauge
          label="RIGHT MOTOR"
          norm={rightNorm}
          pwmUs={isRover ? rightPwm : null}
          tempC={temps.r}
        />
      </div>

      {/* Balance-specific details */}
      {balState && !isRover && (
        <div className="bg-gray-950 rounded-lg border border-cyan-950 p-4">
          <div className="text-cyan-700 text-xs font-bold tracking-widest mb-3">PID DETAILS</div>
          <div className="grid grid-cols-2 sm:grid-cols-4 gap-2 text-xs">
            <div className="bg-gray-900 rounded p-2 text-center">
              <div className="text-gray-600">CMD</div>
              <div className="text-orange-400 font-bold">{balState.motor_cmd}</div>
            </div>
            <div className="bg-gray-900 rounded p-2 text-center">
              <div className="text-gray-600">ERROR</div>
              <div className="text-red-400 font-bold">{balState.pid_error_deg}°</div>
            </div>
            <div className="bg-gray-900 rounded p-2 text-center">
              <div className="text-gray-600">INTEGRAL</div>
              <div className="text-purple-400 font-bold">{balState.integral}</div>
            </div>
            <div className="bg-gray-900 rounded p-2 text-center">
              <div className="text-gray-600">FRAMES</div>
              <div className="text-gray-400 font-bold">{balState.frames}</div>
            </div>
          </div>
        </div>
      )}

      {/* Rover PWM details */}
      {roverPwm && (
        <div className="bg-gray-950 rounded-lg border border-cyan-950 p-4">
          <div className="text-cyan-700 text-xs font-bold tracking-widest mb-3">CHANNEL PWM (µs)</div>
          <div className="grid grid-cols-4 gap-2 text-xs">
            {[1,2,3,4].map(ch => {
              const us = roverPwm[`ch${ch}_us`] ?? PWM_MID;
              const norm = (us - PWM_MID) / (PWM_MAX - PWM_MID);
              return (
                <div key={ch} className="bg-gray-900 rounded p-2 text-center">
                  <div className="text-gray-600">CH{ch}</div>
                  <div className="font-bold" style={{ color: norm > 0.05 ? '#f97316' : norm < -0.05 ? '#3b82f6' : '#6b7280' }}>
                    {us}
                  </div>
                </div>
              );
            })}
          </div>
        </div>
      )}
    </div>
  );
}
