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 StarterKit from '@tiptap/starter-kit';
import Link from '@tiptap/extension-link';
import {
  Bold,
  Italic,
  List,
  ListOrdered,
  Quote,
  Redo,
  Undo,
  AlignLeft,
  AlignCenter,
  SquareUser,
  Link as LinkIcon,
  ArrowRightToLine,
} from 'lucide-react';
import { useEffect, useState } from 'react';
import { CustomImage } from '../CustomImageExtension';
import TipTapImageUploadButton from './TipTapWithCaptionButton';
import { IndentedParagraph } from './IndentedParagraph';
import LinkModal from '../LinkModal';


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

export function TipTapEditor({ initialContent, onContentChange, articleId }: TipTapEditorProps) {
  const [selectedImage, setSelectedImage] = useState<string | null>(null);
  const [isLinkModalOpen, setIsLinkModalOpen] = useState(false); // Состояние для модального окна
  const [currentLinkUrl, setCurrentLinkUrl] = useState('');      // Текущий URL для редактирования

  const editor = useEditor({
    extensions: [
      StarterKit.configure({
          blockquote: false,
          paragraph: false,
      }),
      IndentedParagraph,
      Blockquote.configure({
        HTMLAttributes: {
          class: 'border-l-4 border-gray-300 pl-4 italic',
        },
      }),
      TextAlign.configure({
        types: ['heading', 'paragraph'],
      }),
      CustomImage,
      Highlight,
      Link.configure({                      // Добавляем расширение Link
        openOnClick: false,                 // Отключаем автоматическое открытие ссылок при клике (удобно для редактирования)
        HTMLAttributes: {
          class: 'text-blue-500 underline', // Стили для ссылок
          target: '_blank',                 // Открывать в новой вкладке
          rel: 'noopener noreferrer',       // Безопасность
        },
        autolink: true,                     // Включаем автоматическое распознавание ссылок
      }),
    ],
    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 === 'customImage') {
          setSelectedImage(node.attrs.src);
          foundImage = true;
        }
      });

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

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

  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 handleClick = () => {
    const { state, dispatch } = editor.view;
    const tr = state.tr;

    state.doc.forEach((paragraphNode, paragraphOffset) => {
      if (paragraphNode.type.name !== 'paragraph') return;

      let paragraphText = '';
      const textPositions: { start: number; end: number }[] = [];

      paragraphNode.content.forEach((textNode, textOffset) => {
        if (textNode.isText) {
          const nodeText = textNode.text || '';
          const start = paragraphOffset + 1 + textOffset;
          textPositions.push({
            start,
            end: start + nodeText.length,
          });
          paragraphText += nodeText;
        }
      });

      if (!paragraphText) return;

      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;
      }

      if (lastIndex < paragraphText.length) {
        sentences.push({
          text: paragraphText.slice(lastIndex),
          start: lastIndex,
          end: paragraphText.length,
        });
      }

      sentences.forEach((sentence) => {
        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;

        let isFirstWord = true;

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

          if (/^[A-ZА-ЯЁ]/u.test(currentWord)) {
            if (isFirstWord) {
              isFirstWord = false;
              continue;
            }

            let afterQuote = false;

            if (i > 0) {
              const prevWord = words[i - 1].word;
              if (/[""«»''`*]$/.test(prevWord)) {
                afterQuote = true;
              } else {
                const betweenWords = sentence.text.substring(
                    words[i - 1].end - sentence.start,
                    word.start - sentence.start
                );
                if (/\s[""«»''`]/.test(betweenWords) || /\s\*[«»]\*/.test(betweenWords) || /\s\*/.test(betweenWords)) {
                  afterQuote = true;
                }
              }
            } else {
              const sentencePrefix = sentence.text.substring(0, word.start - sentence.start).trim();
              if (/^[""«»''`]/.test(sentencePrefix) || /^\*[«»]\*/.test(sentencePrefix) || /^\*/.test(sentencePrefix)) {
                afterQuote = true;
              }
            }

            if (!afterQuote) {
              const docPositions = mapWordToDocumentPositions(word, textPositions, paragraphOffset);
              if (docPositions) {
                tr.addMark(docPositions.start, docPositions.end, state.schema.marks.bold.create());
              }
            }
          }
          isFirstWord = false;
        }
      });
    });

    dispatch(tr);
  };

  // Функция для открытия модального окна
  const openLinkModal = () => {
    const previousUrl = editor.getAttributes('link')?.href || '';
    setCurrentLinkUrl(previousUrl);
    setIsLinkModalOpen(true);
  };

  // Функция для применения ссылки
  const handleLinkConfirm = (url: string) => {
    setIsLinkModalOpen(false);
    if (url.trim() === '') {
      editor.chain().focus().unsetLink().run();
      return;
    }

    const validUrl = url.match(/^https?:\/\//) ? url : `https://${url}`;
    editor.chain().focus().setLink({ href: validUrl }).run();
  };

  // Функция для закрытия модального окна
  const handleLinkCancel = () => {
    setIsLinkModalOpen(false);
    // Удаляем ссылку только если мы добавляем новую (currentLinkUrl пустой)
    if (!currentLinkUrl) {
      editor.chain().focus().unsetLink().run();
    }
    // Если currentLinkUrl не пустой (редактируем существующую ссылку), ничего не делаем
  };

  const mapWordToDocumentPositions = (
      word: { start: number; end: number },
      textPositions: { start: number; end: number }[],
      paragraphOffset: number
  ) => {
    let docStart = -1;
    let docEnd = -1;

    for (const pos of textPositions) {
      if (docStart === -1 && word.start < pos.end - paragraphOffset - 1) {
        const relativeStart = Math.max(0, word.start - (pos.start - paragraphOffset - 1));
        docStart = pos.start + relativeStart;
      }

      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;
  };

  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().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={() => editor.chain().focus().setNode('paragraph', { class: 'text-indent' }).run()}
                className={`p-2 rounded border ${
                    editor.isActive('paragraph', { class: 'text-indent' }) ? 'bg-blue-100' : 'hover:bg-gray-100'
                }`}
                title="Отступ"
            >
              <ArrowRightToLine 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={openLinkModal}
                className={`p-1 rounded hover:bg-gray-200 ${editor?.isActive('link') ? 'bg-gray-200' : ''}`}
                title="Добавить или редактировать ссылку"
            >
              <LinkIcon size={18} />
            </button>
            {editor?.isActive('link') && ( // Показываем кнопку удаления ссылки, если выделенный текст — ссылка
                <button
                    type="button"
                    onClick={() => editor.chain().focus().unsetLink().run()}
                    className="p-1 rounded hover:bg-gray-200"
                    title="Удалить ссылку"
                >
                  <LinkIcon size={18} className="text-red-500" />
                </button>
            )}
            <TipTapImageUploadButton
                editor={editor}
                articleId={articleId}
            />
          </div>
        </div>
        <div className="p-4">
          <EditorContent editor={editor} />
        </div>
        {/* Добавляем отображение URL выбранного изображения */}
        {selectedImage && (
            <div className="p-4 border-t bg-gray-50">
              <p className="text-sm text-gray-600">
                Выбранное изображение: <a href={selectedImage} target="_blank" rel="noopener noreferrer" className="text-blue-500">{selectedImage}</a>
              </p>
            </div>
        )}
        <LinkModal
            isOpen={isLinkModalOpen}
            initialUrl={currentLinkUrl}
            onConfirm={handleLinkConfirm}
            onCancel={handleLinkCancel}
        />
      </div>
  );
}