"use client";

import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import { useRouter } from "next/navigation";

import {
  filterCommands,
  globalCommands,
  moveHighlight,
  projectCommands,
  type Command,
} from "@/lib/command/palette";

// 从 pathname 抽取当前 projectId（/projects/<id>/...）。
function projectIdFromPath(pathname: string): string | null {
  const m = pathname.match(/^\/projects\/([^/]+)/);
  return m ? m[1] : null;
}

interface CommandPaletteProps {
  pathname: string;
}

// 命令面板（⌘K，UX §7）：键盘触发的快速导航/动作。
// 焦点管理（打开自动聚焦输入框、Esc 关闭、上下选择、回车执行）+ a11y（role=dialog/listbox）。
export function CommandPalette({ pathname }: CommandPaletteProps) {
  const router = useRouter();
  const [open, setOpen] = useState(false);
  const [query, setQuery] = useState("");
  const [highlight, setHighlight] = useState(0);
  const inputRef = useRef<HTMLInputElement>(null);

  const projectId = projectIdFromPath(pathname);
  const commands = useMemo<Command[]>(
    () =>
      projectId
        ? [...projectCommands(projectId), ...globalCommands()]
        : globalCommands(),
    [projectId],
  );
  const results = useMemo(
    () => filterCommands(commands, query),
    [commands, query],
  );

  const close = useCallback((): void => {
    setOpen(false);
    setQuery("");
    setHighlight(0);
  }, []);

  const run = useCallback(
    (cmd: Command | undefined): void => {
      if (!cmd) return;
      close();
      if (cmd.href) router.push(cmd.href);
    },
    [close, router],
  );

  // ⌘K / Ctrl+K 全局开关。
  useEffect(() => {
    const onKey = (e: KeyboardEvent): void => {
      if ((e.metaKey || e.ctrlKey) && e.key.toLowerCase() === "k") {
        e.preventDefault();
        setOpen((prev) => !prev);
      }
    };
    window.addEventListener("keydown", onKey);
    return () => window.removeEventListener("keydown", onKey);
  }, []);

  // 打开时聚焦输入框；切查询重置高亮。
  useEffect(() => {
    if (open) inputRef.current?.focus();
  }, [open]);
  useEffect(() => {
    setHighlight(0);
  }, [query]);

  if (!open) return null;

  const onInputKey = (e: React.KeyboardEvent): void => {
    if (e.key === "Escape") {
      e.preventDefault();
      close();
    } else if (e.key === "ArrowDown") {
      e.preventDefault();
      setHighlight((h) => moveHighlight(h, 1, results.length));
    } else if (e.key === "ArrowUp") {
      e.preventDefault();
      setHighlight((h) => moveHighlight(h, -1, results.length));
    } else if (e.key === "Enter") {
      e.preventDefault();
      run(results[highlight]);
    }
  };

  return (
    <div
      className="fixed inset-0 z-[60] flex items-start justify-center bg-black/30 pt-[15vh] motion-safe:transition-opacity"
      onClick={close}
    >
      <div
        role="dialog"
        aria-modal="true"
        aria-label="命令面板"
        className="w-full max-w-lg overflow-hidden rounded-lg border border-line bg-panel shadow-paper"
        onClick={(e) => e.stopPropagation()}
      >
        <input
          ref={inputRef}
          value={query}
          onChange={(e) => setQuery(e.target.value)}
          onKeyDown={onInputKey}
          placeholder="搜索命令或页面…（写本章 / 审稿 / 生成角色 / 跳转伏笔 / 搜设定）"
          aria-label="命令搜索"
          aria-controls="command-list"
          className="w-full border-b border-line bg-bg px-4 py-3 text-sm text-ink outline-none"
        />
        <ul
          id="command-list"
          role="listbox"
          aria-label="命令列表"
          className="max-h-80 overflow-auto py-1"
        >
          {results.length === 0 ? (
            <li className="px-4 py-3 text-sm text-ink-soft">无匹配命令</li>
          ) : (
            results.map((cmd, i) => (
              <li
                key={cmd.id}
                role="option"
                aria-selected={i === highlight}
                onMouseEnter={() => setHighlight(i)}
                onClick={() => run(cmd)}
                className={`flex cursor-pointer items-center justify-between px-4 py-2 text-sm ${
                  i === highlight
                    ? "bg-[var(--color-cinnabar-wash)] text-cinnabar"
                    : "text-ink"
                }`}
              >
                <span>{cmd.title}</span>
                <span className="text-xs text-ink-soft">{cmd.group}</span>
              </li>
            ))
          )}
        </ul>
      </div>
    </div>
  );
}
