import { useMemo } from 'react';

import CharacterCount from '@tiptap/extension-character-count';
import History from '@tiptap/extension-history';
import Link from '@tiptap/extension-link';
import Mention from '@tiptap/extension-mention';
import Placeholder from '@tiptap/extension-placeholder';
import Underline from '@tiptap/extension-underline';
import { Plugin, PluginKey } from '@tiptap/pm/state';
import { EditorOptions, Extension, Mark, mergeAttributes } from '@tiptap/react';
import StarterKit from '@tiptap/starter-kit';

import { MAX_POST_BODY_TEXT_LENGTH } from 'src/constants/posts';
import { hasFileToPaste } from 'src/utils/attachments';

import { createMentionOptions } from '../mentions/mentionOptions';
import { getProfileDetailHref } from '../mentions/utils';

// Custom Highlight Mark extension for TipTap v2 to preserve highlighted marks
const Highlight = Mark.create({
  name: 'highlight',
  addOptions() {
    return {
      HTMLAttributes: {
        style: 'background-color: #f9e8b4;',
      },
    };
  },
  parseHTML() {
    return [
      {
        tag: 'mark',
      },
    ];
  },
  renderHTML({ HTMLAttributes }: any) {
    return [
      'mark',
      mergeAttributes(this.options.HTMLAttributes, HTMLAttributes),
      0,
    ];
  },
});

export const EventHandler = Extension.create({
  name: 'eventHandler',
  addOptions() {
    return {
      handlePaste: null,
    };
  },
  addProseMirrorPlugins() {
    const { handlePaste } = this.options;
    return [
      new Plugin({
        key: new PluginKey('eventHandler'),
        props: {
          handlePaste(_, event) {
            if (!hasFileToPaste(event)) return false; // return false to use the default on paste
            return handlePaste(event); // Use the function passed as an option
          },
        },
      }),
    ];
  },
});

type UseExtensionsOptions = {
  placeholder?: string;
  handlePaste?: any;
};

const useExtensions = ({
  placeholder,
  handlePaste,
}: UseExtensionsOptions = {}): EditorOptions['extensions'] => {
  return useMemo(() => {
    return [
      StarterKit.configure({
        horizontalRule: false,
        history: false,
        heading: {
          levels: [1, 2, 3, 4],
        },
      }),
      CharacterCount.configure({
        limit: MAX_POST_BODY_TEXT_LENGTH,
      }),
      Underline,
      Highlight,
      Placeholder.configure({
        placeholder,
      }),
      Link.extend({
        inclusive: false,
      }).configure({
        openOnClick: false,
        autolink: true,
        linkOnPaste: true,
        defaultProtocol: 'https',
      }),
      Mention.configure({
        HTMLAttributes: {
          class: 'mention',
        },
        suggestion: createMentionOptions(),
        renderHTML({ options, node }) {
          return [
            'a',
            mergeAttributes(
              {
                href: getProfileDetailHref(node.attrs.id),
              },
              options.HTMLAttributes,
            ),
            `${options.suggestion.char}${node.attrs.label ?? node.attrs.id}`,
          ];
        },
      }),
      // We use the regular `History` (undo/redo) extension when not using collaborative editing
      History,
      EventHandler.configure({
        handlePaste, // Pass the handlePaste function to the EventHandler
      }),
    ];
  }, [placeholder, handlePaste]);
};

export default useExtensions;
