import { Extension } from "@tiptap/core";
import { PluginKey } from "@tiptap/pm/state";
import Suggestion from "@tiptap/suggestion";
import { createSuggestionRenderer } from "./suggestionRenderer";
import type { SuggestionItem } from "@/components/SuggestionDropdown.vue";
import type { Editor } from "@tiptap/vue-3";

const slashCommandsKey = new PluginKey("slashCommands");

interface SlashCommand {
  label: string;
  value: string;
  keywords: string[];
}

const COMMANDS: SlashCommand[] = [
  { label: "Heading 1",      value: "h1",    keywords: ["heading", "h1", "title"] },
  { label: "Heading 2",      value: "h2",    keywords: ["heading", "h2", "subtitle"] },
  { label: "Heading 3",      value: "h3",    keywords: ["heading", "h3"] },
  { label: "Bullet List",    value: "ul",    keywords: ["bullet", "list", "ul", "unordered"] },
  { label: "Numbered List",  value: "ol",    keywords: ["numbered", "ordered", "ol", "number"] },
  { label: "Task List",      value: "task",  keywords: ["task", "todo", "checkbox", "check"] },
  { label: "Code Block",     value: "code",  keywords: ["code", "block", "pre", "codeblock"] },
  { label: "Blockquote",     value: "quote", keywords: ["quote", "blockquote"] },
];

function applyCommand(editor: Editor, value: string) {
  const chain = editor.chain().focus();
  switch (value) {
    case "h1":   chain.toggleHeading({ level: 1 }).run(); break;
    case "h2":   chain.toggleHeading({ level: 2 }).run(); break;
    case "h3":   chain.toggleHeading({ level: 3 }).run(); break;
    case "ul":   chain.toggleBulletList().run(); break;
    case "ol":   chain.toggleOrderedList().run(); break;
    case "task": chain.toggleTaskList().run(); break;
    case "code": chain.toggleCodeBlock().run(); break;
    case "quote": chain.toggleBlockquote().run(); break;
  }
}

export const SlashCommands = Extension.create({
  name: "slashCommands",

  addProseMirrorPlugins() {
    return [
      Suggestion<SuggestionItem>({
        editor: this.editor,
        pluginKey: slashCommandsKey,
        char: "/",
        allowSpaces: false,
        items: ({ query }): SuggestionItem[] => {
          const q = query.toLowerCase();
          return COMMANDS
            .filter((cmd) =>
              !q ||
              cmd.label.toLowerCase().includes(q) ||
              cmd.keywords.some((k) => k.includes(q))
            )
            .map((cmd) => ({ label: cmd.label, value: cmd.value }));
        },
        command: ({ editor, range, props: item }) => {
          editor.chain().focus().deleteRange(range).run();
          applyCommand(editor as Editor, item.value);
        },
        render: createSuggestionRenderer,
      }),
    ];
  },
});
