import { useEffect, useCallback } from 'react';
import type Player from 'video.js/dist/types/player';

interface KeyboardOptions {
  playerRef: React.RefObject<Player | null>;
  onStepForward: () => void;
  onStepBackward: () => void;
  onCaptureFrame: () => void;
  onAddMemo: () => void;
  onToggleHelp?: () => void;
  containerRef: React.RefObject<HTMLDivElement | null>;
}

export function useKeyboard({
  playerRef,
  onStepForward,
  onStepBackward,
  onCaptureFrame,
  onAddMemo,
  onToggleHelp,
  containerRef,
}: KeyboardOptions) {
  const handleKey = useCallback(
    (e: KeyboardEvent) => {
      const target = e.target as HTMLElement;
      // Don't fire when typing in an input
      if (target.tagName === 'INPUT' || target.tagName === 'TEXTAREA' || target.isContentEditable) return;

      const player = playerRef.current;
      if (!player) return;

      const ct = player.currentTime() ?? 0;
      const dur = player.duration() ?? 0;

      switch (e.code) {
        case 'Space':
          e.preventDefault();
          player.paused() ? player.play() : player.pause();
          break;
        case 'ArrowLeft':
          e.preventDefault();
          player.currentTime(Math.max(0, ct - 5));
          break;
        case 'ArrowRight':
          e.preventDefault();
          player.currentTime(Math.min(dur, ct + 5));
          break;
        case 'KeyJ':
          player.currentTime(Math.max(0, ct - 10));
          break;
        case 'KeyL':
          player.currentTime(Math.min(dur, ct + 10));
          break;
        case 'Comma':
          e.preventDefault();
          onStepBackward();
          break;
        case 'Period':
          e.preventDefault();
          onStepForward();
          break;
        case 'BracketLeft':
          player.currentTime(Math.max(0, ct - 30));
          break;
        case 'BracketRight':
          player.currentTime(Math.min(dur, ct + 30));
          break;
        case 'KeyF':
          if (containerRef.current) {
            if (!document.fullscreenElement) {
              containerRef.current.requestFullscreen();
            } else {
              document.exitFullscreen();
            }
          }
          break;
        case 'KeyM':
          if (e.shiftKey) {
            e.preventDefault();
            onAddMemo();
          } else {
            player.muted(!player.muted());
          }
          break;
        case 'Equal':
        case 'NumpadAdd':
          player.playbackRate(Math.min(4, (player.playbackRate() ?? 1) + 0.25));
          break;
        case 'Minus':
        case 'NumpadSubtract':
          player.playbackRate(Math.max(0.25, (player.playbackRate() ?? 1) - 0.25));
          break;
        case 'KeyS':
          if (e.shiftKey) { e.preventDefault(); onCaptureFrame(); }
          break;
        case 'Slash':
          if (e.shiftKey) { e.preventDefault(); onToggleHelp?.(); }
          break;
        default:
          if (e.code >= 'Digit0' && e.code <= 'Digit9') {
            const pct = parseInt(e.code.replace('Digit', ''), 10) / 10;
            player.currentTime(dur * pct);
          }
      }
    },
    [playerRef, onStepForward, onStepBackward, onCaptureFrame, onAddMemo, onToggleHelp, containerRef]
  );

  useEffect(() => {
    window.addEventListener('keydown', handleKey);
    return () => window.removeEventListener('keydown', handleKey);
  }, [handleKey]);
}
