"use client";

// 글로벌 키보드 단축키 헬프 오버레이.
// `?` (Shift+/) 로 열고 ESC 또는 바깥 클릭 / 닫기 버튼으로 닫음.
// 다른 슬라이스에서 키보드 단축키를 추가해도 발견 가능성을 유지하기 위한 공용 패널.
//
// 등록되는 단축키는 여기 한 곳에서 정의 — 실제 핸들러는 각 컴포넌트가 가지고 있고,
// 이 컴포넌트는 단순 표시 + `?` 토글만 담당. 단일 출처(Single Source of Truth)는 아니지만,
// 이 사이트가 사용하는 단축키 수가 적어 수동 동기화로 충분.

import { useEffect, useRef, useState } from "react";

type Shortcut = {
  keys: string[];        // ['Ctrl', 'K'] 같은 표시용 토큰. 시각적으로 + 로 join.
  label: string;
  scope?: string;        // '전역' / '종목 페이지' 등 — group 헤더 라벨.
};

const SHORTCUTS: Shortcut[] = [
  { scope: "전역", keys: ["/"], label: "종목 검색창 포커스" },
  { scope: "전역", keys: ["Ctrl", "K"], label: "종목 검색창 포커스 (Mac: ⌘K)" },
  { scope: "전역", keys: ["Esc"], label: "팝오버 / 오버레이 닫기" },
  { scope: "전역", keys: ["?"], label: "이 도움말 열기 / 닫기" },
  { scope: "종목 페이지", keys: ["F"], label: "차트 전체화면 토글" },
  { scope: "종목 페이지", keys: ["H"], label: "현재 가격에 수평선 추가" },
  { scope: "종목 페이지", keys: ["Shift", "클릭"], label: "차트 위 클릭 위치에 수평선 추가" },
  { scope: "종목 페이지", keys: ["←", "→"], label: "기간 탭 이전 / 다음" },
  { scope: "종목 페이지", keys: ["S"], label: "관심종목 추가 / 제거" },
  { scope: "검색 팝오버", keys: ["↑", "↓"], label: "결과 이동" },
  { scope: "검색 팝오버", keys: ["Enter"], label: "선택한 종목으로 이동" },
];

function isEditableTarget(t: EventTarget | null): boolean {
  if (!(t instanceof HTMLElement)) return false;
  const tag = t.tagName;
  if (tag === "INPUT" || tag === "TEXTAREA" || tag === "SELECT") return true;
  if (t.isContentEditable) return true;
  return false;
}

export function ShortcutsHelp() {
  const [open, setOpen] = useState(false);
  const closeBtnRef = useRef<HTMLButtonElement | null>(null);

  // `?` 키 = 토글. 입력 중에는 무시 (사용자가 실제 ? 입력하려는 의도).
  // ESC 는 모달 안에서 onKeyDown 으로도 처리하지만, 글로벌 핸들러로도 닫음 — 포커스가
  // 모달 밖에 있어도 닫히도록.
  useEffect(() => {
    if (typeof window === "undefined") return;
    const onKey = (e: KeyboardEvent) => {
      if (e.key === "?" && !isEditableTarget(e.target)) {
        e.preventDefault();
        setOpen((v) => !v);
        return;
      }
      if (e.key === "Escape" && open) {
        setOpen(false);
      }
    };
    window.addEventListener("keydown", onKey);
    return () => window.removeEventListener("keydown", onKey);
  }, [open]);

  // 열릴 때 닫기 버튼에 포커스 — 키보드 사용자가 바로 Tab 흐름을 잡을 수 있게.
  useEffect(() => {
    if (open) closeBtnRef.current?.focus();
  }, [open]);

  // 화면 우하단 floating 버튼 — 모바일/마우스 사용자가 키보드 없이도 발견 가능.
  // 모달이 열려 있으면 같은 버튼이 닫기 역할.
  return (
    <>
      <button
        type="button"
        onClick={() => setOpen((v) => !v)}
        className="fixed bottom-4 right-4 z-30 flex h-8 w-8 items-center justify-center rounded-full border border-zinc-700 bg-zinc-900/80 text-xs text-zinc-300 shadow-lg backdrop-blur transition hover:border-zinc-500 hover:text-zinc-100"
        title="키보드 단축키 (?)"
        aria-label="키보드 단축키 도움말"
        aria-expanded={open}
      >
        ?
      </button>
      {open && (
        <div
          role="dialog"
          aria-modal="true"
          aria-label="키보드 단축키"
          className="fixed inset-0 z-50 flex items-center justify-center bg-black/60 p-4 backdrop-blur-sm"
          onClick={(e) => {
            if (e.target === e.currentTarget) setOpen(false);
          }}
        >
          <div className="w-full max-w-md rounded-lg border border-zinc-700 bg-zinc-950 p-5 shadow-2xl">
            <div className="mb-3 flex items-center justify-between">
              <h2 className="text-sm font-semibold text-zinc-100">키보드 단축키</h2>
              <button
                ref={closeBtnRef}
                type="button"
                onClick={() => setOpen(false)}
                className="rounded-md border border-zinc-700 px-2 py-0.5 text-[11px] text-zinc-400 hover:border-zinc-500 hover:text-zinc-200"
                aria-label="닫기"
              >
                닫기 (Esc)
              </button>
            </div>
            <ShortcutTable />
            <p className="mt-3 text-[10px] text-zinc-500">
              입력 필드에 포커스가 있으면 단축키는 동작하지 않습니다.
            </p>
          </div>
        </div>
      )}
    </>
  );
}

// scope 별로 묶어 한 줄에 [키] — 설명 형태로 표시. 같은 scope 가 연속되면 헤더 생략해서
// 시각적 노이즈 줄임.
function ShortcutTable() {
  let prevScope: string | undefined;
  return (
    <ul className="space-y-1.5">
      {SHORTCUTS.map((s, i) => {
        const showScope = s.scope && s.scope !== prevScope;
        prevScope = s.scope;
        return (
          <li key={i}>
            {showScope && (
              <div className="mb-0.5 mt-2 first:mt-0 text-[10px] uppercase tracking-wide text-zinc-500">
                {s.scope}
              </div>
            )}
            <div className="flex items-center justify-between gap-3 text-[12px]">
              <span className="text-zinc-300">{s.label}</span>
              <span className="flex shrink-0 items-center gap-1">
                {s.keys.map((k, j) => (
                  <span key={j} className="flex items-center gap-1">
                    {j > 0 && <span className="text-[10px] text-zinc-600">+</span>}
                    <kbd className="rounded border border-zinc-700 bg-zinc-900 px-1.5 py-0.5 font-mono text-[10px] text-zinc-200">
                      {k}
                    </kbd>
                  </span>
                ))}
              </span>
            </div>
          </li>
        );
      })}
    </ul>
  );
}
