"use client";

import { useCallback, useMemo } from "react";
import type { JSX } from "react";
import {
  SuggestionMenuController,
  getDefaultReactSlashMenuItems,
  type DefaultReactSuggestionItem,
} from "@blocknote/react";
import { filterSuggestionItems, type BlockNoteEditor } from "@blocknote/core";
import { useRouter } from "next/navigation";
import {
  FileImage,
  FilePlus2,
  FileVideo,
  ListTree,
  Music,
  Paperclip,
  PilcrowSquare,
  Play,
  Sparkles,
  SquareCheckBig,
} from "lucide-react";
import type { CustomBlockSchema } from "../schema";
import { useImagePicker } from "@/components/media/image-picker-context";
import type { MediaKind, MediaSelection } from "@/types/media";

type Props = {
  editor: BlockNoteEditor<CustomBlockSchema>;
  currentDocumentId: string;
};

const matchKeywords = (query: string, aliases: string[]) => {
  const lower = query.trim().toLowerCase();
  if (!lower) return true;
  return aliases.some((alias) => alias.toLowerCase().includes(lower));
};

const GROUP_TRANSLATIONS: Record<string, string> = {
  "Headings": "标题",
  "Subheadings": "副标题",
  "Basic blocks": "基础块",
  "Advanced": "高级",
  "Media": "媒体",
  "Others": "其他",
};

const DEFAULT_ITEM_TRANSLATIONS: Record<
  string,
  { title?: string; subtext?: string; group?: string; aliases?: string[] }
> = {
  "Paragraph": { title: "正文", group: "基础块", aliases: ["zw", "paragraph", "body"] },
  "Heading 1": { title: "主标题", group: "标题", aliases: ["biaoti", "bt1"] },
  "Heading 2": { title: "大标题", group: "标题", aliases: ["biaoti", "bt2"] },
  "Heading 3": { title: "中标题", group: "标题", aliases: ["biaoti", "bt3"] },
  "Heading 4": { title: "小标题", group: "标题", aliases: ["biaoti", "bt4"] },
  "Heading 5": { title: "极小标题", group: "标题", aliases: ["biaoti", "bt5"] },
  "Heading 6": { title: "最小标题", group: "标题", aliases: ["biaoti", "bt6"] },
  "Toggle Heading 1": { title: "可折叠主标题", group: "标题", aliases: ["toggle", "zd1"] },
  "Toggle Heading 2": { title: "可折叠大标题", group: "标题", aliases: ["toggle", "zd2"] },
  "Toggle Heading 3": { title: "可折叠中标题", group: "标题", aliases: ["toggle", "zd3"] },
  "Quote": { title: "引用", group: "基础块", aliases: ["quote", "引用"] },
  "Toggle List": { title: "折叠列表", group: "基础块", aliases: ["toggle list", "zd"] },
  "Numbered List": { title: "数字列表", group: "基础块", aliases: ["ordered", "ol"] },
  "Bullet List": { title: "符号列表", group: "基础块", aliases: ["ul", "list"] },
  "Check List": { title: "任务列表", group: "基础块", aliases: ["todo", "checkbox"] },
  "Code Block": { title: "代码块", group: "基础块", aliases: ["code", "pre"] },
  "Table": { title: "表格", group: "高级", aliases: ["table", "biaoge"] },
  "Image": { title: "插入图片", group: "媒体", subtext: "上传或引用图片资源", aliases: ["tupian", "image", "tp"] },
  "Video": { title: "插入视频", group: "媒体", subtext: "上传或引用视频", aliases: ["shipin", "video", "sp"] },
  "Audio": { title: "插入音频", group: "媒体", subtext: "上传或引用音频", aliases: ["yinpin", "audio", "yp"] },
  "File": { title: "插入文件", group: "媒体", subtext: "上传附件并生成卡片", aliases: ["wenjian", "file", "wj"] },
  "Emoji": { title: "插入表情", group: "其他", aliases: ["emoji", "biaoqing"] },
  "Divider": { title: "分割线", group: "基础块", aliases: ["divider", "hr"] },
  "Page Break": { title: "分页符", group: "基础块", aliases: ["page", "break"] },
};

const MEDIA_ICONS: Record<MediaKind, JSX.Element> = {
  image: <FileImage className="h-4 w-4 text-[#2563eb]" />,
  video: <FileVideo className="h-4 w-4 text-[#f97316]" />,
  audio: <Music className="h-4 w-4 text-[#10b981]" />,
  file: <Paperclip className="h-4 w-4 text-[#0f172a]" />,
};

const HEADING_PRESETS = [
  {
    level: 1,
    title: "主标题",
    subtext: "适合页面名称/顶层章节",
    aliases: ["biaoti1", "h1", "level1"],
  },
  {
    level: 2,
    title: "大标题",
    subtext: "用于章节逻辑层",
    aliases: ["biaoti2", "h2", "level2"],
  },
  {
    level: 3,
    title: "中标题",
    subtext: "用于小节和段落",
    aliases: ["biaoti3", "h3", "level3"],
  },
  {
    level: 4,
    title: "小标题",
    subtext: "更细的结构说明",
    aliases: ["biaoti4", "h4", "level4"],
  },
  {
    level: 5,
    title: "极小标题",
    subtext: "适合脚注/补充说明",
    aliases: ["biaoti5", "h5", "level5"],
  },
];

const isHeadingDefaultItem = (item: DefaultReactSuggestionItem) => {
  const maybeKey = (item as { key?: string }).key ?? "";
  if (maybeKey && (maybeKey === "heading" || maybeKey.startsWith("heading_") || maybeKey.startsWith("toggle_heading"))) {
    return true;
  }
  const title = item.title ?? "";
  return title.includes("标题");
};

export const CustomSlashMenu = ({ editor, currentDocumentId }: Props) => {
  const defaultItems = useMemo(() => getDefaultReactSlashMenuItems(editor), [editor]);
  const router = useRouter();
  const { openPicker } = useImagePicker();

  const getItems = useCallback(
    async (query: string) => {
      const cursor = editor.getTextCursorPosition();
      const referenceBlock = cursor?.block ?? editor.topLevelBlocks[0];

      const createPageItem: DefaultReactSuggestionItem = {
        title: "嵌入页面",
        group: "嵌入",
        aliases: ["page", "ym", "子页面", "嵌入页面块"],
        icon: <FilePlus2 className="h-4 w-4 text-[#2563eb]" />,
        onItemClick: async () => {
          const response = await fetch("/api/documents/create-child", {
            method: "POST",
            headers: { "Content-Type": "application/json" },
            body: JSON.stringify({
              parentId: currentDocumentId,
              title: cursor?.block?.content?.[0]?.text ?? "未命名页面",
              blocks: cursor ? [cursor.block] : [],
            }),
          });

          if (!response.ok) return;
          const { pageId, title } = await response.json();
          editor.insertBlocks(
            [
              {
                type: "pageReference",
                props: { pageId, title },
              },
            ],
            referenceBlock,
            "after",
          );
          router.refresh();
        },
      };

      const headingItems: DefaultReactSuggestionItem[] = HEADING_PRESETS.map((preset) => ({
        title: preset.title,
        group: "标题",
        subtext: preset.subtext,
        aliases: preset.aliases,
        icon: <PilcrowSquare className="h-4 w-4 text-[#0f172a]" />,
        onItemClick: () => {
          editor.insertBlocks(
            [
              {
                type: "heading",
                props: { level: preset.level },
              },
            ],
            referenceBlock,
            "after",
          );
        },
      }));

      const foldHeading: DefaultReactSuggestionItem = {
        title: "折叠标题",
        group: "标题",
        aliases: ["toggle", "zd", "fold"],
        icon: <ListTree className="h-4 w-4 text-[#0f172a]" />,
        onItemClick: () => {
          editor.insertBlocks(
            [
              {
                type: "heading",
                props: { level: 2, isToggleable: true },
              },
            ],
            referenceBlock,
            "after",
          );
        },
      };

      const advancedTodo: DefaultReactSuggestionItem = {
        title: "高级待办",
        group: "待办",
        subtext: "四态状态 · Alt 直接取消",
        aliases: ["gjdblb", "todopro", "gaoji", "todo+"],
        icon: <SquareCheckBig className="h-4 w-4 text-[#2563eb]" />,
        onItemClick: () => {
          editor.insertBlocks(
            [
              {
                type: "advancedTodo",
                props: { status: "todo" },
              },
            ],
            referenceBlock,
            "after",
          );
        },
      };

      const progressMeter: DefaultReactSuggestionItem = {
        title: "进度条",
        group: "进度",
        subtext: "自动读取下方待办完成度",
        aliases: ["jdt", "progress", "jindu"],
        icon: <Sparkles className="h-4 w-4 text-[#f59e0b]" />,
        onItemClick: () => {
          editor.insertBlocks(
            [
              {
                type: "progressMeter",
                props: { percent: 0, auto: true },
              },
            ],
            referenceBlock,
            "after",
          );
        },
      };

      const foldAdvancedTodo: DefaultReactSuggestionItem = {
        title: "折叠高级待办",
        group: "待办",
        aliases: ["zdgjdb", "foldtodo"],
        icon: <Play className="h-4 w-4 text-[#9f1239]" />,
        onItemClick: () => {
          editor.insertBlocks(
            [
              {
                type: "advancedTodo",
                props: { status: "todo" },
              },
            ],
            referenceBlock,
            "after",
          );
        },
      };

      const customItems = [
        ...headingItems,
        foldHeading,
        createPageItem,
        advancedTodo,
        foldAdvancedTodo,
        progressMeter,
      ].filter((item) => matchKeywords(query, item.aliases ?? []));

      const insertMediaSelection = (selection: MediaSelection) => {
        editor.insertBlocks(
          [
            {
              type: "media",
              props: {
                fileUrl: selection.fileUrl,
                thumbnailUrl: selection.thumbnailUrl ?? selection.fileUrl,
                assetId: selection.assetId,
                assetType: selection.assetType ?? "image",
                fileName: selection.fileName ?? "",
                fileSize: selection.fileSize ?? null,
                mimeType: selection.mimeType ?? "",
                ocrStatus: "idle",
              },
            },
          ],
          referenceBlock,
          "after",
        );
      };

      const handleMediaPick = (mediaType: MediaKind) => {
        openPicker({
          mediaType,
          onSelect: (selection) => {
            insertMediaSelection({
              ...selection,
              assetType: selection.assetType ?? mediaType,
            });
          },
        });
      };

      const localizedDefaults = defaultItems.map((item) => {
        const translation = DEFAULT_ITEM_TRANSLATIONS[item.title];
        const next: DefaultReactSuggestionItem = { ...item };
        if (translation?.title) next.title = translation.title;
        if (translation?.subtext) next.subtext = translation.subtext;
        if (translation?.aliases) next.aliases = translation.aliases;
        if (translation?.group) {
          next.group = translation.group;
        } else if (item.group && GROUP_TRANSLATIONS[item.group]) {
          next.group = GROUP_TRANSLATIONS[item.group];
        }

        if (["Image", "Video", "Audio", "File"].includes(item.title)) {
          const mediaType = item.title.toLowerCase() as MediaKind;
          next.icon = MEDIA_ICONS[mediaType];
          next.group = translation?.group ?? "媒体";
          next.subtext = translation?.subtext ?? next.subtext;
          next.aliases = translation?.aliases ?? next.aliases;
          next.onItemClick = () => handleMediaPick(mediaType);
        }
        return next;
      });

      const sanitizedDefaults = localizedDefaults.filter(
        (item) => !isHeadingDefaultItem(item) && item.title !== "表格",
      );
      const merged = [...customItems, ...sanitizedDefaults];
      return filterSuggestionItems(merged, query);
    },
    [currentDocumentId, defaultItems, editor, openPicker, router],
  );

  return <SuggestionMenuController triggerCharacter="/" getItems={getItems} />;
}
