import { Extension } from "@tiptap/core";
import Suggestion from "@tiptap/suggestion";
import { ref, h } from "vue";

export const SlashCommand = Extension.create({
  name: "slash-command",

  addOptions() {
    return {
      suggestion: {
        char: "/",
        startOfLine: true,
        command: ({ editor, range, props }) => {
          // props.type => 'paragraph' | 'heading' | 'todo'
          if (props.type === "paragraph") {
            editor
              .chain()
              .focus()
              .deleteRange(range)
              .insertContent({
                type: "paragraph",
                content: [{ type: "text", text: "" }],
              })
              .run();
          }

          if (props.type === "heading") {
            editor
              .chain()
              .focus()
              .deleteRange(range)
              .setNode("heading", { level: 2 })
              .run();
          }

          if (props.type === "todo") {
            editor
              .chain()
              .focus()
              .deleteRange(range)
              .insertContent({
                type: "paragraph",
                content: [{ type: "text", text: "☑️ Todo " }],
              })
              .run();
          }
        },
        items: ({ query }) => {
          const all = [
            { title: "Text", type: "paragraph" },
            { title: "Heading", type: "heading" },
            { title: "Todo", type: "todo" },
          ];
          return all.filter((item) =>
            item.title.toLowerCase().startsWith(query.toLowerCase())
          );
        },
        render: () => {
          let component;
          let popup;

          return {
            onStart: (props) => {
              component = ref({
                items: props.items,
                command: props.command,
                selected: 0,
              });
              popup = document.createElement("div");
              popup.style.position = "absolute";
              popup.style.background = "white";
              popup.style.border = "1px solid #ddd";
              popup.style.borderRadius = "6px";
              popup.style.padding = "4px 0";
              popup.style.zIndex = 100;
              document.body.appendChild(popup);
              update();
              function update() {
                popup.innerHTML = "";
                component.value.items.forEach((item, i) => {
                  const div = document.createElement("div");
                  div.textContent = item.title;
                  div.style.padding = "4px 12px";
                  div.style.cursor = "pointer";
                  div.style.background =
                    i === component.value.selected ? "#f0f0f0" : "white";
                  div.onclick = () =>
                    component.value.command({
                      editor: props.editor,
                      range: props.range,
                      props: item,
                    });
                  popup.appendChild(div);
                });
              }
              component.value.update = update;
            },
            onUpdate: (props) => {
              component.value.items = props.items;
              component.value.update();
            },
            onKeyDown: (props) => {
              const event = props.event;
              if (event.key === "ArrowDown") {
                component.value.selected =
                  (component.value.selected + 1) % component.value.items.length;
                component.value.update();
                return true;
              }
              if (event.key === "ArrowUp") {
                component.value.selected =
                  (component.value.selected -
                    1 +
                    component.value.items.length) %
                  component.value.items.length;
                component.value.update();
                return true;
              }
              if (event.key === "Enter") {
                component.value.command({
                  editor: props.editor,
                  range: props.range,
                  props: component.value.items[component.value.selected],
                });
                return true;
              }
              return false;
            },
            onExit: () => {
              popup.remove();
            },
          };
        },
      },
    };
  },

  addProseMirrorPlugins() {
    return [Suggestion(this.options.suggestion)];
  },
});
