import { useEditor, EditorContent } from '@tiptap/react';
import Highlight from '@tiptap/extension-highlight';
import TextAlign from '@tiptap/extension-text-align';
import Blockquote from '@tiptap/extension-blockquote';
import Image from '@tiptap/extension-image';
import StarterKit from '@tiptap/starter-kit';
import {
  Bold,
  Italic,
  List,
  ListOrdered,
  Quote,
  Redo,
  Undo,
  AlignLeft,
  AlignCenter,
  Plus,
  Minus,
  SquareUser,
  ImagePlus
} from 'lucide-react';
import { useEffect, useState } from "react";
import { CustomImage } from "./CustomImageExtension";
import TipTapImageUploadButton from "./TipTapImageUploadButton";


interface TipTapEditorProps {
  initialContent: string;
  onContentChange: (content: string) => void;
  atricleId: string;
}

/*
const ResizableImage = Image.extend({
  addAttributes() {
    return {
      ...this.parent?.(),
      src: { default: null, },
      alt: { default: null, },
      title: { default: null, },
      class: { default: 'max-w-full h-auto', },
      width: {
        default: 'auto',
        parseHTML: (element) => element.getAttribute('width') || 'auto',
        renderHTML: (attributes) => ({
          width: attributes.width,
          class: selectedImage === attributes.src ? 'selected-image' : '',
        }),
      },
      height: {
        default: 'auto',
        parseHTML: (element) => element.getAttribute('height') || 'auto',
        renderHTML: (attributes) => ({
          height: attributes.height,
        }),
      },
    };
  },
});
*/

export function TipTapEditor({ initialContent, onContentChange, atricleId }: TipTapEditorProps) {
  const [selectedImage, setSelectedImage] = useState<string | null>(null);

/*
  const ResizableImage = Image.extend({
    addAttributes() {
      return {
        ...this.parent?.(),
        src: { default: null, },
        alt: { default: null, },
        title: { default: null, },
        class: { default: 'max-w-full h-auto', },
        width: {
          default: 'auto',
          parseHTML: (element) => element.getAttribute('width') || 'auto',
          renderHTML: (attributes) => ({
            width: attributes.width,
            class: selectedImage === attributes.src ? 'selected-image' : '',
          }),
        },
        height: {
          default: 'auto',
          parseHTML: (element) => element.getAttribute('height') || 'auto',
          renderHTML: (attributes) => ({
            height: attributes.height,
          }),
        },
      };
    },
  });
*/

  const editor = useEditor({
    extensions: [
      StarterKit.configure({
        blockquote: false, // Отключаем дефолтный
      }),
      Blockquote.configure({
        HTMLAttributes: {
          class: 'border-l-4 border-gray-300 pl-4 italic',
        },
      }),
      TextAlign.configure({
        types: ['heading', 'paragraph'],
      }),
      CustomImage,
      Highlight,
    ],
    content: initialContent || '',
    editorProps: {
      attributes: {
        class: 'prose prose-lg focus:outline-none min-h-[300px] max-w-none',
      },
    },
    onUpdate: ({ editor }) => {
      const { from, to } = editor.state.selection;
      let foundImage = false;

      editor.state.doc.nodesBetween(from, to, (node) => {
        if (node.type.name === 'image') {
          setSelectedImage(node.attrs.src);
          editor.commands.updateAttributes('image', { class: 'selected-image' });
          foundImage = true;
        }
      });

      if (!foundImage) {
        setSelectedImage(null);
      }

      onContentChange(editor.getHTML());
    },
  });

  // Обновление контента при изменении initialContent
  useEffect(() => {
    if (editor && editor.getHTML() !== initialContent) {
      editor.commands.setContent(initialContent);
    }
  }, [initialContent, editor]);

  useEffect(() => {
    const handleClickOutside = (event: MouseEvent) => {
      if (!editor?.view.dom.contains(event.target as Node)) {
        setSelectedImage(null);
      }
    };

    document.addEventListener('mousedown', handleClickOutside);
    return () => document.removeEventListener('mousedown', handleClickOutside);
  }, [editor]);


  if (!editor) return null;

  const resizeImage = (delta: number) => {
    if (!editor.isActive('image')) return;

    const attrs = editor?.getAttributes('image');
    const newWidth = Math.max((parseInt(attrs?.width, 10) || 100) + delta, 50);

    editor.chain().focus().updateAttributes('image', {width: `${newWidth}px`}).run();
  };

  // Helper function to map paragraph word positions to document positions
  const mapWordToDocumentPositions = (
      word: { start: number, end: number },
      textPositions: { start: number, end: number }[],
      paragraphOffset: number
  ) => {
    let docStart = -1;
    let docEnd = -1;

    // Find which text node(s) contain this word
    for (const pos of textPositions) {
      // Word starts in this text node
      if (docStart === -1 && word.start < pos.end - paragraphOffset - 1) {
        const relativeStart = Math.max(0, word.start - (pos.start - paragraphOffset - 1));
        docStart = pos.start + relativeStart;
      }

      // Word ends in this text node
      if (docStart !== -1 && word.end <= pos.end - paragraphOffset - 1) {
        const relativeEnd = Math.min(pos.end - pos.start, word.end - (pos.start - paragraphOffset - 1));
        docEnd = pos.start + relativeEnd;
        break;
      }
    }

    if (docStart !== -1 && docEnd !== -1) {
      return { start: docStart, end: docEnd };
    }

    return null;
  };

  const handleClick = () => {
    const { state, dispatch } = editor.view;
    const tr = state.tr;

    // Process each paragraph separately to avoid context issues
    state.doc.forEach((paragraphNode, paragraphOffset) => {
      if (paragraphNode.type.name !== 'paragraph') return;

      // Get the full text of this paragraph
      let paragraphText = '';
      const textPositions: { start: number, end: number }[] = [];

      paragraphNode.content.forEach((textNode, textOffset) => {
        if (textNode.isText) {
          const nodeText = textNode.text || ""; // Handle undefined text
          const start = paragraphOffset + 1 + textOffset; // +1 to account for paragraph tag
          textPositions.push({
            start,
            end: start + nodeText.length
          });
          paragraphText += nodeText;
        }
      });

      if (!paragraphText) return;

      // Find all valid sentences in the paragraph
      const sentenceRegex = /[^.!?]+[.!?]+/g;
      const sentences: { text: string, start: number, end: number }[] = [];
      let match;
      let lastIndex = 0;

      while ((match = sentenceRegex.exec(paragraphText)) !== null) {
        sentences.push({
          text: match[0],
          start: match.index,
          end: sentenceRegex.lastIndex
        });
        lastIndex = sentenceRegex.lastIndex;
      }

      // Handle text after the last punctuation if it exists
      if (lastIndex < paragraphText.length) {
        sentences.push({
          text: paragraphText.slice(lastIndex),
          start: lastIndex,
          end: paragraphText.length
        });
      }

      // For each sentence, find capitalized words NOT at the beginning and not after quotes
      sentences.forEach(sentence => {
        // Split into words, keeping track of positions
        const words = [];
        const wordRegex = /\S+/g;
        let wordMatch;

        while ((wordMatch = wordRegex.exec(sentence.text)) !== null) {
          words.push({
            word: wordMatch[0],
            start: sentence.start + wordMatch.index,
            end: sentence.start + wordRegex.lastIndex
          });
        }

        if (words.length === 0) return;

        // Mark the first word as sentence start (shouldn't be bolded if capitalized)
        let isFirstWord = true;

        for (let i = 0; i < words.length; i++) {
          const word = words[i];
          const currentWord = word.word;

          // Check if the word starts with a capital letter
          if (/^[A-ZА-ЯЁ]/u.test(currentWord)) {
            // Skip if it's the first word in the sentence
            if (isFirstWord) {
              isFirstWord = false;
              continue;
            }

            // Check for various quotation patterns
            let afterQuote = false;

            if (i > 0) {
              const prevWord = words[i-1].word;

              // Check if previous word ends with quotation characters
              // Including standard, curly, angular quotes and special formats like *«*
              if (/["""«»''`*]$/.test(prevWord)) {
                afterQuote = true;
              } else {
                // Check for whitespace + quotation mark combination in the text between words
                const betweenWords = sentence.text.substring(
                    words[i-1].end - sentence.start,
                    word.start - sentence.start
                );

                // Check for standard quotes and special patterns like *«*
                if (/\s["""«»''`]/.test(betweenWords) ||
                    /\s\*[«»]\*/.test(betweenWords) ||
                    /\s\*/.test(betweenWords)) {
                  afterQuote = true;
                }
              }
            } else {
              // If it's the first word but after the sentence detection,
              // check if the sentence starts with a quotation mark or special pattern
              const sentencePrefix = sentence.text.substring(0, word.start - sentence.start).trim();
              if (/^["""«»''`]/.test(sentencePrefix) ||
                  /^\*[«»]\*/.test(sentencePrefix) ||
                  /^\*/.test(sentencePrefix)) {
                afterQuote = true;
              }
            }

            // If not after a quote, bold the word
            if (!afterQuote) {
              // Map the word position back to the document
              const docPositions = mapWordToDocumentPositions(word, textPositions, paragraphOffset);
              if (docPositions) {
                tr.addMark(
                    docPositions.start,
                    docPositions.end,
                    state.schema.marks.bold.create()
                );
              }
            }
          }

          // Always mark as no longer first word after processing a word
          isFirstWord = false;
        }
      });
    });

    dispatch(tr);
  };

  return (
    <div className="border rounded-lg overflow-hidden">
      <div className="border-b bg-gray-50 px-4 py-2">
        <div className="flex items-center space-x-4">
          <button
              type="button"
              onClick={() => editor?.chain().focus().toggleBold().run()}
              className={`p-1 rounded hover:bg-gray-200 ${
                  editor?.isActive('bold') ? 'bg-gray-200' : ''
              }`}
              title="Выделение слов жирным шрифтом"
          >
            <Bold size={18} />
          </button>
          <button
              type="button"
              onClick={handleClick}
              className="p-1 rounded hover:bg-gray-200"
              title="Автоматическое выделение жирным имен"
          >
            <SquareUser size={18} />
          </button>
          <button
              type="button"
              onClick={() => editor?.chain().focus().toggleItalic().run()}
              className={`p-1 rounded hover:bg-gray-200 ${
                  editor?.isActive('italic') ? 'bg-gray-200' : ''
              }`}
              title="Выделение слов наклонным шрифтом"
          >
            <Italic size={18} />
          </button>
          <button
              type="button"
              onClick={() => editor?.chain().focus().setParagraph().run()}
              className={`p-1 rounded hover:bg-gray-200 ${editor?.isActive('paragraph') ? 'bg-gray-200' : ''}`}
              title="Выравнивание по левому краю"
          >
            <AlignLeft size={18} />
          </button>
          <button
              type="button"
              onClick={() => editor?.chain().focus().undo().run()}
              disabled={!editor?.can().chain().focus().undo().run()}
              className="p-1 rounded hover:bg-gray-200 disabled:opacity-50"
              title="Отменить действие"
          >
            <Undo size={18} />
          </button>
          <button
              type="button"
              onClick={() => editor?.chain().focus().redo().run()}
              disabled={!editor?.can().chain().focus().redo().run()}
              className="p-1 rounded hover:bg-gray-200 disabled:opacity-50"
              title="Вернуть действие"
          >
            <Redo size={18} />
          </button>
          <button
              type="button"
              onClick={() => editor?.chain().focus().toggleBulletList().run()}
              className={`p-1 rounded hover:bg-gray-200 ${
                  editor?.isActive('bulletList') ? 'bg-gray-200' : ''
              }`}
              title="Создать список"
          >
            <List size={18} />
          </button>
          <button
              type="button"
              onClick={() => editor?.chain().focus().toggleOrderedList().run()}
              className={`p-1 rounded hover:bg-gray-200 ${
                  editor?.isActive('orderedList') ? 'bg-gray-200' : ''
              }`}
              title="Создать упорядоченный список"
          >
            <ListOrdered size={18} />
          </button>
          <button
              type="button"
              onClick={() => {
              editor?.chain().focus().toggleBlockquote().run()}}
              className={`p-1 rounded hover:bg-gray-200 ${
                  editor?.isActive('blockquote') ? 'bg-gray-200' : ''
              }`}
              title="Цитирование (параграф)"
          >
            <Quote size={18} />
          </button>
          <button
              type="button"
              onClick={() => {
              editor?.chain().focus().setTextAlign('center').run()}}
              className={`p-1 rounded hover:bg-gray-200 ${
                  editor?.getAttributes('textAlign')?.textAlign === 'center' ? 'bg-gray-200' : ''
              }`}
              title="Выравнивание по центру"
          >
            <AlignCenter size={18} />
          </button>
          <button
              type="button"
              onClick={() => {
                const url = prompt('Введите URL изображения');
                if (url) {
                  editor?.chain().focus().setImage({ src: url }).run();
                }
              }}
              title="Вставить изображение (старое)"
          >
            <ImagePlus size={18} />
          </button>
          <TipTapImageUploadButton editor={editor} articleId={atricleId} />
          <button
              type="button"
              onClick={() => editor?.chain().focus().setTextAlign('center').run()}
              className={`p-1 rounded hover:bg-gray-200 ${
                  editor?.getAttributes('textAlign')?.textAlign === 'center' ? 'bg-gray-200' : ''
              }`}
          >
            🏛 Центр
          </button>
          <button
              type="button"
              onClick={() => resizeImage(20)} className="p-1 rounded hover:bg-gray-200">
            <Plus size={18} />
          </button>
          <button
              type="button"
              onClick={() => resizeImage(-20)} className="p-1 rounded hover:bg-gray-200">
            <Minus size={18} />
          </button>
        </div>
      </div>
      <div className="p-4">
        <EditorContent editor={editor} />
      </div>
    </div>
  );
}