import { useEffect, useRef, useState } from 'react';
import { cn } from '@/lib/utils';

// ShiftRow — the RIT / XIT offset control, shared by the radio consoles.
//
// It began inside the Icom panel and is here because the next console needed
// exactly it. Consoles that each invent their own way of nudging an offset make
// an operator learn the same thing twice, which is the complaint that moved it:
// "none of the consoles look alike".
//
// Three ways to move it, because operators reach for different ones: the ± keys,
// the wheel over the number, and TYPING a value straight in. The last one is
// what a button row cannot do — 'put me 300 Hz down' is one keystroke sequence,
// not thirty clicks.
export function ShiftRow({ label, on, hz, accent, disabled, step = 10, onToggle, onSet }: {
  label: string;
  on: boolean;
  hz: number;
  accent: string;
  disabled?: boolean;
  step?: number;
  onToggle: () => void;
  onSet: (hz: number) => void;
}) {
  const ref = useRef<HTMLDivElement>(null);
  const [editing, setEditing] = useState<string | null>(null);
  const cb = useRef(onSet); cb.current = onSet;
  const cur = useRef({ hz, on, disabled }); cur.current = { hz, on, disabled };

  // Wheel over the row. A native non-passive listener, because React's onWheel
  // is passive and cannot preventDefault — without that the panel scrolls under
  // the pointer while the number changes.
  useEffect(() => {
    const el = ref.current;
    if (!el) return;
    const onWheel = (e: WheelEvent) => {
      const c = cur.current;
      if (c.disabled || !c.on) return;
      e.preventDefault();
      cb.current(c.hz + (e.deltaY < 0 ? step : -step));
    };
    el.addEventListener('wheel', onWheel, { passive: false });
    return () => el.removeEventListener('wheel', onWheel);
  }, [step]);

  const commit = (raw: string) => {
    setEditing(null);
    const v = parseInt(raw.replace(/[^0-9+-]/g, ''), 10);
    if (!Number.isNaN(v)) onSet(v);
  };

  const dead = disabled || !on;
  return (
    <div className="flex items-center gap-2">
      <button type="button" onClick={onToggle} disabled={disabled}
        className={cn('w-14 shrink-0 px-2 py-1 rounded-md text-[11px] font-bold border transition-colors disabled:opacity-30',
          on ? 'bg-success border-success text-success-foreground' : 'bg-card text-muted-foreground border-border hover:bg-muted')}>
        {label}
      </button>
      <div ref={ref} title="Wheel, ± or type"
        className={cn('flex-1 flex items-center justify-between rounded-md border px-1 py-0.5 select-none',
          dead ? 'border-border/60 bg-muted/20 opacity-60' : 'border-border bg-muted/40 cursor-ns-resize')}>
        <button type="button" disabled={dead} onClick={() => onSet(hz - step)}
          className="px-2 text-sm font-bold text-muted-foreground hover:text-foreground disabled:opacity-40">−</button>
        {editing !== null ? (
          <input
            autoFocus
            value={editing}
            onChange={(e) => setEditing(e.target.value)}
            onBlur={(e) => commit(e.target.value)}
            onKeyDown={(e) => {
              if (e.key === 'Enter') commit((e.target as HTMLInputElement).value);
              else if (e.key === 'Escape') setEditing(null);
            }}
            className="w-20 bg-transparent text-center text-sm font-mono font-bold tabular-nums outline-none"
          />
        ) : (
          <button type="button" disabled={dead} onClick={() => setEditing(String(hz))}
            className="text-sm font-mono font-bold tabular-nums disabled:cursor-default"
            style={{ color: on ? accent : undefined }}>
            {hz > 0 ? '+' : hz < 0 ? '−' : ''}{Math.abs(hz)} Hz
          </button>
        )}
        <button type="button" disabled={dead} onClick={() => onSet(hz + step)}
          className="px-2 text-sm font-bold text-muted-foreground hover:text-foreground disabled:opacity-40">+</button>
      </div>
      <button type="button" disabled={dead} onClick={() => onSet(0)}
        className="w-8 shrink-0 py-1 rounded-md text-[11px] font-bold border border-border bg-card text-muted-foreground hover:bg-muted disabled:opacity-30">0</button>
    </div>
  );
}
