import "./styles.scss";

import { EditorContent, useEditor } from "@tiptap/react";
import StarterKit from "@tiptap/starter-kit";
import Mention from "@tiptap/extension-mention";
import Image from "@tiptap/extension-image";
import Link from "@tiptap/extension-link";
import Strike from "@tiptap/extension-strike";
import Highlight from "@tiptap/extension-highlight";
import React, { useImperativeHandle, forwardRef, useEffect } from "react";
import { Placeholder } from "@tiptap/extension-placeholder";

import suggestion from "./suggestion.js";

export const MentionEditor = forwardRef(
  (
    {
      value,
      onChange,
      onSend,
      disabled = false,
      maxLength = 5000,
      placeholder = "Type message...",
      chatId,
      loadParticipantsAvatar,
      ...restConfig
    },
    ref
  ) => {
    const editor = useEditor({
      ...restConfig,
      extensions: [
        StarterKit,
        Placeholder.configure({
          placeholder: placeholder,
        }),
        Mention.configure({
          HTMLAttributes: {
            class: "mention",
          },
          suggestion: suggestion,
        }),
        Image.configure({
          inline: true,
          allowBase64: true,
        }),
        Link.configure({
          openOnClick: false,
          HTMLAttributes: {
            rel: "noopener noreferrer",
            class: "link",
          },
        }),
        Strike,
        Highlight.configure({
          multicolor: true,
          // defaultColor: "#fef3c7",
          // HTMLAttributes: {
          //   class: "highlight",
          //   style:
          //     "background-color: #fef3c7; border-radius: 4px; padding: 2px 4px;",
          // },
        }),
      ],
      content: value || "",
      editable: !disabled,
      onUpdate: ({ editor }) => {
        const html = editor.getHTML();
        onChange?.(html);
      },
      onCreate: ({ editor }) => {
        // Store the props in editor storage for access in suggestion
        editor.storage.mentionConfig = {
          chatId,
          loadParticipantsAvatar,
        };
      },
      editorProps: {
        handleKeyDown: (view, event) => {
          if (event.key === "Enter" && !event.shiftKey) {
            const { state } = view;
            const { selection } = state;

            // Check if we're in a list
            const isInList =
              editor?.isActive("bulletList") || editor?.isActive("orderedList");

            // Check if mention popup is open (this checks if there's an active mention suggestion)
            const isMentionActive =
              state.doc.resolve(selection.from).parent.type.name ===
                "mention" ||
              (selection.$from.nodeBefore &&
                selection.$from.nodeBefore.type.name === "mention");

            // Check if we're currently typing a mention (text before cursor contains @)
            const textBefore = state.doc.textBetween(
              Math.max(0, selection.from - 20),
              selection.from
            );
            const isTypingMention = /@\w*$/.test(textBefore);

            // Don't send if we're in a list, mention is active, or typing a mention
            if (isInList || isMentionActive || isTypingMention) {
              return false; // Let the default behavior handle it (new line or list item)
            }

            // Otherwise, send the message
            event.preventDefault();
            onSend?.();
            return true;
          }
          return false;
        },
        attributes: {
          class:
            "prose prose-sm sm:prose lg:prose-lg xl:prose-2xl mx-auto focus:outline-none",
          style:
            "max-height: 100px; overflow-y: auto; padding: 8px 12px; min-height: 40px;",
        },
      },
    });

    useEffect(() => {
      if (editor && value !== editor.getHTML()) {
        editor.commands.setContent(value || "");
      }
    }, [value, editor]);

    // Update mention config when props change
    useEffect(() => {
      if (editor) {
        editor.storage.mentionConfig = {
          chatId,
          loadParticipantsAvatar,
        };
      }
    }, [editor, chatId, loadParticipantsAvatar]);

    // Expose editor commands to parent
    useImperativeHandle(ref, () => ({
      // Text formatting
      toggleBold: () => editor?.chain().focus().toggleBold().run(),
      toggleItalic: () => editor?.chain().focus().toggleItalic().run(),
      toggleLink: () => {
        const previousUrl = editor?.getAttributes("link").href;
        const url = window.prompt("URL", previousUrl);
        if (url === null) return;
        if (url === "") {
          editor?.chain().focus().extendMarkRange("link").unsetLink().run();
          return;
        }
        editor
          ?.chain()
          .focus()
          .extendMarkRange("link")
          .setLink({ href: url })
          .run();
      },

      // File handling
      addImage: (url, alt) => {
        if (url) {
          editor
            ?.chain()
            .focus()
            .setImage({ src: url, alt: alt || "" })
            .run();
        }
      },

      // Get content
      getHTML: () => editor?.getHTML() || "",
      getJSON: () => editor?.getJSON(),
      clearContent: () => editor?.commands.clearContent(),

      // Editor state
      isEmpty: () => (editor ? editor.isEmpty : true),

      // Emoji handling
      insertEmoji: (emoji) => {
        editor?.chain().focus().insertContent(emoji).run();
      },

      // Additional formatting
      toggleStrike: () => editor?.chain().focus().toggleStrike().run(),
      toggleHighlight: () => {
        const result = editor?.chain().focus().toggleHighlight().run();
        return result;
      },

      // List formatting
      toggleBulletList: () => editor?.chain().focus().toggleBulletList().run(),
      toggleOrderedList: () =>
        editor?.chain().focus().toggleOrderedList().run(),

      // Heading commands
      toggleH1: () => editor?.chain().focus().toggleHeading({ level: 1 }).run(),
      toggleH2: () => editor?.chain().focus().toggleHeading({ level: 2 }).run(),
      toggleH3: () => editor?.chain().focus().toggleHeading({ level: 3 }).run(),
      toggleH4: () => editor?.chain().focus().toggleHeading({ level: 4 }).run(),
      toggleH5: () => editor?.chain().focus().toggleHeading({ level: 5 }).run(),
      toggleH6: () => editor?.chain().focus().toggleHeading({ level: 6 }).run(),

      // Editor instance
      editor: editor,
    }));

    // Update parent when selection changes
    useEffect(() => {
      if (editor) {
        const updateHandler = () => {
          onChange?.(editor.getHTML());
        };

        editor.on("selectionUpdate", updateHandler);

        // Cleanup listener on unmount
        return () => {
          editor.off("selectionUpdate", updateHandler);
        };
      }
    }, [editor, onChange]);

    if (!editor) {
      return null;
    }

    return (
      <div className="tiptap-editor">
        <EditorContent editor={editor} />
      </div>
    );
  }
);
