import { useEffect } from "react";

/** Tag names whose descendants can receive free-form text input. */
const INPUT_TAGS = new Set(["INPUT", "TEXTAREA", "SELECT"]);

/**
 * Returns true when the keyboard event originated inside a free-form
 * text field, in which case we should NOT consume j/k/escape/`?` —
 * the user is typing, not navigating the drawer.
 *
 * - `INPUT` / `TEXTAREA` / `SELECT` are the obvious cases.
 * - `contenteditable` elements (e.g. rich text editors) are the
 *   non-obvious one: `target.isContentEditable` is the standard check.
 */
function isEditableTarget(target: EventTarget | null): boolean {
  if (!(target instanceof HTMLElement)) return false;
  if (INPUT_TAGS.has(target.tagName)) return true;
  return target.isContentEditable;
}

/**
 * Wires the spec-driven drawer keyboard shortcuts to the drawer's
 * callbacks. When `enabled` is true, listens for `keydown` on `window`
 * and dispatches:
 *
 *   j / ArrowDown  →  onNext
 *   k / ArrowUp    →  onPrev
 *   Escape         →  onClose
 *   ?              →  onToggleHelp
 *
 * Keys are ignored when an `<input>`, `<textarea>`, `<select>`, or
 * `contenteditable` element has focus — typing "j" into a search box
 * must not navigate claims. `preventDefault` is called for each matched
 * key to suppress the browser's default (arrow keys scrolling the page,
 * Escape closing modals/pausing video, etc.).
 *
 * The effect tears down on unmount or when `enabled` flips to false, and
 * re-subscribes whenever any callback identity changes (so consumers
 * don't have to memoize their handlers to keep the listener stable).
 */
export function useDrawerKeyboard(opts: {
  enabled: boolean;
  onNext: () => void;
  onPrev: () => void;
  onClose: () => void;
  onToggleHelp: () => void;
}): void {
  const { enabled, onNext, onPrev, onClose, onToggleHelp } = opts;

  useEffect(() => {
    if (!enabled) return;

    const handler = (e: KeyboardEvent) => {
      if (isEditableTarget(e.target)) return;

      switch (e.key) {
        case "j":
        case "ArrowDown":
          e.preventDefault();
          onNext();
          break;
        case "k":
        case "ArrowUp":
          e.preventDefault();
          onPrev();
          break;
        case "Escape":
          e.preventDefault();
          onClose();
          break;
        case "?":
          e.preventDefault();
          onToggleHelp();
          break;
      }
    };

    window.addEventListener("keydown", handler);
    return () => window.removeEventListener("keydown", handler);
  }, [enabled, onNext, onPrev, onClose, onToggleHelp]);
}
