// 리스트 키보드 네비게이션 runes 컴포저블 — Phase D.4 신규.
// - j / ArrowDown → next, k / ArrowUp → prev
// - Enter → onenter(items[index])
// - Escape → onescape?.()
// - input/textarea/select/contenteditable 포커스 중이면 완전히 비활성
//   → '/' 키 검색 포커스(+layout.svelte)와 충돌 없음
//
// 사용 (documents/+page.svelte):
//   let selectedIndex = $state(0);
//   useListKeyboardNav({
//     get items() { return items; },
//     get index() { return selectedIndex; },
//     setIndex: (i) => { selectedIndex = i; scrollSelectedIntoView(); },
//     onenter: (doc) => selectDoc(doc),
//   });

interface Options {
  readonly items: unknown[];
  readonly index: number;
  setIndex(i: number): void;
  onenter?: (item: unknown) => void;
  onescape?: () => void;
}

function isTypingTarget(el: Element | null): boolean {
  if (!el) return false;
  const tag = el.tagName;
  if (tag === 'INPUT' || tag === 'TEXTAREA' || tag === 'SELECT') return true;
  return (el as HTMLElement).isContentEditable === true;
}

export function useListKeyboardNav(opts: Options): void {
  $effect(() => {
    function handler(e: KeyboardEvent) {
      if (isTypingTarget(document.activeElement)) return;
      const len = opts.items.length;
      if (len === 0) return;

      switch (e.key) {
        case 'j':
        case 'ArrowDown':
          e.preventDefault();
          opts.setIndex(Math.min(opts.index + 1, len - 1));
          break;
        case 'k':
        case 'ArrowUp':
          e.preventDefault();
          opts.setIndex(Math.max(opts.index - 1, 0));
          break;
        case 'Enter':
          e.preventDefault();
          opts.onenter?.(opts.items[opts.index]);
          break;
        case 'Escape':
          opts.onescape?.();
          break;
      }
    }
    window.addEventListener('keydown', handler);
    return () => window.removeEventListener('keydown', handler);
  });
}
