/**
 * DEVKIT — HTML overlay panel with diagnostics.
 *
 * Tabs:
 *  - Inputs: live grip/trigger/pose values for both controllers (real or fake)
 *  - Logs:   captures last 100 console.log/warn/error entries with filter
 *
 * Always visible when ?devkit=1, top-right corner.
 */
import { useEffect, useRef, useState } from 'react';
import { fakeInput, isFakeActive } from './fakeInputStore';

interface LogEntry {
  ts: number;
  level: 'log' | 'warn' | 'error';
  msg: string;
}

const logBuffer: LogEntry[] = [];
let installed = false;

function installLogger() {
  if (installed) return;
  installed = true;
  (['log', 'warn', 'error'] as const).forEach((level) => {
    const orig = console[level].bind(console);
    console[level] = (...args: unknown[]) => {
      try {
        const msg = args.map((a) => {
          if (typeof a === 'string') return a;
          try { return JSON.stringify(a); } catch { return String(a); }
        }).join(' ');
        logBuffer.push({ ts: Date.now(), level, msg });
        if (logBuffer.length > 200) logBuffer.shift();
      } catch { /* noop */ }
      orig(...args);
    };
  });
}

type Tab = 'inputs' | 'logs';

interface DevPanelProps {
  simXR: boolean;
  onToggleSimXR: () => void;
}

export function DevPanel({ simXR, onToggleSimXR }: DevPanelProps) {
  const [tab, setTab] = useState<Tab>('inputs');
  const [collapsed, setCollapsed] = useState(false);
  const [, tick] = useState(0);
  const [logFilter, setLogFilter] = useState('');
  const rafRef = useRef<number | null>(null);

  useEffect(() => { installLogger(); }, []);

  useEffect(() => {
    let last = 0;
    const loop = (t: number) => {
      if (t - last > 150) { tick((n) => n + 1); last = t; }
      rafRef.current = requestAnimationFrame(loop);
    };
    rafRef.current = requestAnimationFrame(loop);
    return () => { if (rafRef.current) cancelAnimationFrame(rafRef.current); };
  }, []);

  if (collapsed) {
    return (
      <button
        onClick={() => setCollapsed(false)}
        className="fixed top-20 right-2 z-50 rounded bg-black/85 px-2 py-1 font-mono text-[10px] text-green-400 border border-green-500/40 hover:bg-black"
      >
        🧪 DevKit
      </button>
    );
  }

  return (
    <div className="fixed top-20 right-2 z-50 w-72 rounded-lg border border-green-500/40 bg-black/90 font-mono text-[10px] text-green-300 shadow-2xl backdrop-blur">
      {/* Header */}
      <div className="flex items-center justify-between border-b border-green-500/30 px-2 py-1.5">
        <span className="font-bold text-green-400">🧪 DEVKIT</span>
        <div className="flex items-center gap-1">
          <button
            onClick={onToggleSimXR}
            className={`rounded px-1.5 py-0.5 text-[9px] ${simXR ? 'bg-green-500 text-black' : 'border border-green-500/40 text-green-300 hover:bg-green-500/20'}`}
          >
            {simXR ? 'SIM ON' : 'Simular XR'}
          </button>
          <button onClick={() => setCollapsed(true)} className="px-1 hover:text-white">✕</button>
        </div>
      </div>

      {/* Tabs */}
      <div className="flex border-b border-green-500/20">
        {(['inputs', 'logs'] as Tab[]).map((t) => (
          <button
            key={t}
            onClick={() => setTab(t)}
            className={`flex-1 px-2 py-1 text-[10px] uppercase ${tab === t ? 'bg-green-500/20 text-green-200' : 'text-green-500/70 hover:text-green-300'}`}
          >
            {t}
          </button>
        ))}
      </div>

      {/* Content */}
      <div className="max-h-[55vh] overflow-y-auto p-2">
        {tab === 'inputs' && (
          <div className="space-y-2">
            <div className="text-green-500/70">
              fake: {isFakeActive() ? 'ATIVO' : 'inativo'}
            </div>
            {(['left', 'right'] as const).map((h) => {
              const s = fakeInput[h];
              const grabbing = s.gripValue > 0.7;
              const p = [s.gripWorld.elements[12], s.gripWorld.elements[13], s.gripWorld.elements[14]];
              return (
                <div key={h} className="rounded border border-green-500/20 p-1.5">
                  <div className={`font-bold ${grabbing ? 'text-yellow-300' : 'text-green-300'}`}>
                    {h.toUpperCase()} {grabbing && '✊ GRAB'}
                  </div>
                  <div>grip: {s.gripValue.toFixed(2)}  trg: {s.triggerValue.toFixed(2)}</div>
                  <div>pose: {p.map((v) => v.toFixed(2)).join(', ')}</div>
                </div>
              );
            })}
            <div className="border-t border-green-500/20 pt-2 text-green-500/70">
              <div className="font-bold text-green-400 mb-1">Atalhos teclado</div>
              <div>Q/W = grip L/R · A/S = trigger L/R</div>
              <div>1/2 = ativar mão · setas = mover</div>
              <div>Shift+↑/↓ = Z (frente/trás) · R = reset</div>
            </div>
          </div>
        )}
        {tab === 'logs' && (
          <div className="space-y-1">
            <input
              value={logFilter}
              onChange={(e) => setLogFilter(e.target.value)}
              placeholder="filtro… (ex: [XR])"
              className="w-full rounded border border-green-500/30 bg-black/60 px-1 py-0.5 text-green-300"
            />
            <div className="space-y-0.5">
              {logBuffer
                .filter((l) => !logFilter || l.msg.toLowerCase().includes(logFilter.toLowerCase()))
                .slice(-80)
                .reverse()
                .map((l, i) => (
                  <div
                    key={i}
                    className={`break-all leading-tight ${
                      l.level === 'error' ? 'text-red-400' : l.level === 'warn' ? 'text-yellow-300' : 'text-green-300/90'
                    }`}
                  >
                    {l.msg}
                  </div>
                ))}
              {logBuffer.length === 0 && <div className="text-green-500/50 italic">sem logs ainda…</div>}
            </div>
          </div>
        )}
      </div>
    </div>
  );
}
