/**
 * StatusPanel.jsx — Live pipeline status display.
 *
 * Subscribes to /social/orchestrator/state (std_msgs/String, JSON payload):
 *   {
 *     state: "idle"|"listening"|"thinking"|"speaking"|"throttled",
 *     gpu_free_mb: number,
 *     gpu_total_mb: number,
 *     latency: {
 *       wakeword_to_transcript: { mean_ms, p95_ms, n },
 *       transcript_to_llm: { mean_ms, p95_ms, n },
 *       llm_to_tts: { mean_ms, p95_ms, n },
 *       end_to_end: { mean_ms, p95_ms, n }
 *     },
 *     persona_name: string,
 *     active_person: string
 *   }
 */

import { useEffect, useState } from 'react';

const STATE_CONFIG = {
  idle:      { label: 'IDLE',       color: 'text-gray-400',  bg: 'bg-gray-800',   border: 'border-gray-600', pulse: '' },
  listening: { label: 'LISTENING',  color: 'text-blue-300',  bg: 'bg-blue-950',   border: 'border-blue-600', pulse: 'pulse-blue' },
  thinking:  { label: 'THINKING',   color: 'text-amber-300', bg: 'bg-amber-950',  border: 'border-amber-600', pulse: 'pulse-amber' },
  speaking:  { label: 'SPEAKING',   color: 'text-green-300', bg: 'bg-green-950',  border: 'border-green-600', pulse: 'pulse-green' },
  throttled: { label: 'THROTTLED',  color: 'text-red-300',   bg: 'bg-red-950',    border: 'border-red-600',   pulse: 'pulse-amber' },
};

function LatencyRow({ label, stat }) {
  if (!stat || stat.n === 0) return null;
  const warn = stat.mean_ms > 500;
  const crit = stat.mean_ms > 1500;
  const cls = crit ? 'text-red-400' : warn ? 'text-amber-400' : 'text-cyan-400';
  return (
    <div className="flex justify-between items-center py-0.5">
      <span className="text-gray-500 text-xs">{label}</span>
      <div className="text-right">
        <span className={`text-xs font-bold ${cls}`}>{Math.round(stat.mean_ms)}ms</span>
        <span className="text-gray-600 text-xs ml-1">p95:{Math.round(stat.p95_ms)}ms</span>
      </div>
    </div>
  );
}

export function StatusPanel({ subscribe }) {
  const [status, setStatus] = useState(null);
  const [lastUpdate, setLastUpdate] = useState(null);

  useEffect(() => {
    const unsub = subscribe(
      '/social/orchestrator/state',
      'std_msgs/String',
      (msg) => {
        try {
          const data = JSON.parse(msg.data);
          setStatus(data);
          setLastUpdate(Date.now());
        } catch {
          // ignore parse errors
        }
      }
    );
    return unsub;
  }, [subscribe]);

  const state = status?.state ?? 'idle';
  const cfg = STATE_CONFIG[state] ?? STATE_CONFIG.idle;
  const gpuFree = status?.gpu_free_mb ?? 0;
  const gpuTotal = status?.gpu_total_mb ?? 1;
  const gpuUsed = gpuTotal - gpuFree;
  const gpuPct = Math.round((gpuUsed / gpuTotal) * 100);
  const gpuWarn = gpuPct > 80;
  const lat = status?.latency ?? {};

  const stale = lastUpdate && Date.now() - lastUpdate > 5000;

  return (
    <div className="space-y-4">
      {/* Pipeline State */}
      <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">PIPELINE STATE</div>
        <div className="flex items-center gap-4">
          <div
            className={`w-5 h-5 rounded-full shrink-0 ${cfg.bg} border-2 ${cfg.border} ${cfg.pulse}`}
          />
          <div>
            <div className={`text-2xl font-bold tracking-widest ${cfg.color}`}>{cfg.label}</div>
            {status?.persona_name && (
              <div className="text-gray-500 text-xs mt-0.5">
                Persona: <span className="text-cyan-500">{status.persona_name}</span>
              </div>
            )}
            {status?.active_person && (
              <div className="text-gray-500 text-xs">
                Talking to: <span className="text-amber-400">{status.active_person}</span>
              </div>
            )}
          </div>
          {stale && (
            <div className="ml-auto text-red-500 text-xs">STALE</div>
          )}
          {!status && (
            <div className="ml-auto text-gray-600 text-xs">No signal</div>
          )}
        </div>
      </div>

      {/* GPU Memory */}
      <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">GPU MEMORY</div>
        {gpuTotal > 1 ? (
          <>
            <div className="flex justify-between text-xs mb-1.5">
              <span className={gpuWarn ? 'text-red-400' : 'text-gray-400'}>
                {Math.round(gpuUsed)} MB used
              </span>
              <span className="text-gray-500">{Math.round(gpuTotal)} MB total</span>
            </div>
            <div className="w-full h-3 bg-gray-900 rounded overflow-hidden border border-gray-800">
              <div
                className="h-full transition-all duration-500 rounded"
                style={{
                  width: `${gpuPct}%`,
                  background: gpuPct > 90 ? '#ef4444' : gpuPct > 75 ? '#f59e0b' : '#06b6d4',
                }}
              />
            </div>
            <div className={`text-xs mt-1 text-right ${gpuWarn ? 'text-amber-400' : 'text-gray-600'}`}>
              {gpuPct}%
            </div>
          </>
        ) : (
          <div className="text-gray-600 text-xs">No GPU data</div>
        )}
      </div>

      {/* Latency */}
      <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">LATENCY</div>
        {Object.keys(lat).length > 0 ? (
          <div className="divide-y divide-gray-900">
            <LatencyRow label="Wake → Transcript" stat={lat.wakeword_to_transcript} />
            <LatencyRow label="Transcript → LLM"  stat={lat.transcript_to_llm} />
            <LatencyRow label="LLM → TTS"         stat={lat.llm_to_tts} />
            <LatencyRow label="End-to-End"         stat={lat.end_to_end} />
          </div>
        ) : (
          <div className="text-gray-600 text-xs">No latency data yet</div>
        )}
      </div>
    </div>
  );
}
