import React from 'react';
import {mergeAttributes, Node, NodeViewProps } from '@tiptap/core';
import {NodeViewWrapper, ReactNodeViewRenderer} from '@tiptap/react';
import {Trash2, ZoomIn, ZoomOut} from 'lucide-react';
import {Node as ProseMirrorNode, DOMOutputSpec} from 'prosemirror-model';

// Определяем тип для атрибутов узла customImage
interface CustomImageAttributes {
  src: string | undefined;
  alt: string | undefined;
  title: string | undefined;
  scale: number;
  caption: string; // Добавляем атрибут caption
}

const ImageNodeView: React.FC<NodeViewProps> = ({ node, updateAttributes, editor, getPos, selected, deleteNode }) => {
  // Утверждаем, что node имеет нужный тип
  const typedNode = node as ProseMirrorNode & { attrs: CustomImageAttributes };

  // Проверяем, что узел корректен
  if (node.type.name !== 'customImage') {
    console.error('Неподдерживаемый тип узла:', node.type.name);
    return <NodeViewWrapper className="relative flex justify-center my-4">Ошибка: неподдерживаемый тип узла</NodeViewWrapper>;
  }

  // Проверяем, что src существует
  if (!typedNode.attrs.src) {
    console.error('Изображение не загружено, src отсутствует:', typedNode.attrs);
    return <NodeViewWrapper className="relative flex justify-center my-4">Ошибка: изображение не загружено</NodeViewWrapper>;
  }

  // Логируем атрибуты узла при загрузке
  //console.log('Атрибуты узла customImage при загрузке:', typedNode.attrs);

  const handleZoomIn = (e: React.MouseEvent) => {
    e.preventDefault();
    e.stopPropagation();
    try {
      if (!editor || editor.isDestroyed) {
        console.error('Редактор уничтожен или недоступен');
        return;
      }

      const pos = getPos();
      const currentNode = editor.state.doc.nodeAt(pos);
      if (!currentNode || currentNode.type.name !== 'customImage') {
        console.error('Узел больше не существует или изменён:', { pos, currentNode });
        return;
      }

      let currentScale = typedNode.attrs.scale;
      if (currentScale <= 0 || isNaN(currentScale)) {
        console.warn('Некорректное значение scale, устанавливаем значение по умолчанию:', { currentScale });
        currentScale = 1;
        updateAttributes({ scale: 1 });
      }

      const newScale = Math.min(currentScale + 0.1, 2);
      const roundedScale = Number(newScale.toFixed(2));
      updateAttributes({ scale: roundedScale });

      console.log('Масштаб увеличен через updateAttributes:', { currentScale, newScale: roundedScale });
    } catch (error) {
      console.error('Ошибка при увеличении масштаба:', error);
    }
  };

  const handleZoomOut = (e: React.MouseEvent) => {
    e.preventDefault();
    e.stopPropagation();
    try {
      if (!editor || editor.isDestroyed) {
        console.error('Редактор уничтожен или недоступен');
        return;
      }

      const pos = getPos();
      const currentNode = editor.state.doc.nodeAt(pos);
      if (!currentNode || currentNode.type.name !== 'customImage') {
        console.error('Узел больше не существует или изменён:', { pos, currentNode });
        return;
      }

      let currentScale = typedNode.attrs.scale;
      if (currentScale <= 0 || isNaN(currentScale)) {
        console.warn('Некорректное значение scale, устанавливаем значение по умолчанию:', { currentScale });
        currentScale = 1;
        updateAttributes({ scale: 1 });
      }

      const newScale = Math.max(currentScale - 0.1, 0.5);
      const roundedScale = Number(newScale.toFixed(2));
      updateAttributes({ scale: roundedScale });

      console.log('Масштаб уменьшен через updateAttributes:', { currentScale, newScale: roundedScale });
    } catch (error) {
      console.error('Ошибка при уменьшении масштаба:', error);
    }
  };

  const handleDelete = (e: React.MouseEvent) => {
    e.preventDefault();
    e.stopPropagation();
    try {
      deleteNode();
    } catch (error) {
      console.error('Ошибка при удалении изображения:', error);
    }
  };

  const scale = typedNode.attrs.scale || 1;
  const caption = typedNode.attrs.caption || '';
  const isEditable = editor.isEditable; // Проверяем, находится ли редактор в режиме редактирования

  return (
      //<NodeViewWrapper className="relative flex justify-center my-4">
      <NodeViewWrapper className="relative flex flex-col items-center my-4">

        {/* Оборачиваем изображение и панель в контейнер, который масштабируется */}
        <div
            className="relative inline-block"
            style={{
              transform: `scale(${scale})`,
              transformOrigin: 'center',
            }}
        >
        <img
            src={typedNode.attrs.src}
            alt={typedNode.attrs.alt}
            className={`max-w-full transition-transform ${selected && isEditable ? 'ring-2 ring-blue-500' : ''}`}
            data-drag-handle=""
        />
          {selected && isEditable && ( // Показываем панель только в режиме редактирования
            <div
                className="absolute top-2 right-2 flex space-x-2 bg-white bg-opacity-75 p-1 rounded shadow"
                style={{
                  transform: `scale(${1 / scale})`, // Компенсируем масштабирование панели
                  transformOrigin: 'top right', // Устанавливаем точку масштабирования в верхний правый угол
                }}
            >
              <button
                  type="button"
                  onClick={handleZoomIn}
                  className="p-1 rounded hover:bg-gray-200"
                  title={`Zoom in (current scale: ${scale})`}
              >
                <ZoomIn size={16} />
              </button>
              <button
                  type="button"
                  onClick={handleZoomOut}
                  className="p-1 rounded hover:bg-gray-200"
                  title={`Zoom out (current scale: ${scale})`}
              >
                <ZoomOut size={16} />
              </button>
              <button
                  type="button"
                  onClick={handleDelete}
                  className="p-1 rounded hover:bg-red-200 text-red-600"
                  title="Delete image"
              >
                <Trash2 size={16} />
              </button>
              <span className="text-xs text-gray-600 px-2 py-1">
              Масштаб: {scale}
          </span>
            </div>
        )}
        </div>
        {caption && (
          <p className="image-caption mt-2 text-sm text-gray-600 italic text-center">
            {caption}
          </p>
        )}
      </NodeViewWrapper>
  );
};

export const CustomImage = Node.create({
  name: 'customImage',
  group: 'block',
  inline: false,
  selectable: true,
  draggable: true,
  atom: true,

  addAttributes() {
    return {
      src: {
        default: undefined,
      },
      alt: {
        default: undefined,
      },
      title: {
        default: undefined,
      },
      scale: {
        default: 1,
        parseHTML: (element) => {
          const scale = Number(element.getAttribute('scale'));
          return isNaN(scale) || scale <= 0 ? 1 : Math.max(0.5, Math.min(2, Number(scale.toFixed(2))));
        },
        renderHTML: (attributes) => {
          const scale = Number(attributes.scale);
          const renderedScale = isNaN(scale) || scale <= 0 ? 1 : Math.max(0.5, Math.min(2, Number(scale.toFixed(2))));
          return { scale: renderedScale };
        },
      },
      caption: { // Добавляем атрибут caption
        default: '',
        parseHTML: (element) => element.getAttribute('data-caption') || '',
        renderHTML: (attributes) => {
          if (!attributes.caption) {
            return {};
          }
          return {
            'data-caption': attributes.caption,
          };
        },
      },
    };
  },

  parseHTML() {
    return [
      {
        tag: 'div.image-container',
        getAttrs: (element: HTMLElement) => {
          const img = element.querySelector('img');
          const caption = element.querySelector('p.image-caption')?.textContent || '';
          return {
            src: img?.getAttribute('src'),
            alt: img?.getAttribute('alt'),
            title: img?.getAttribute('title'),
            scale: img ? Number(img.getAttribute('scale')) || 1 : 1,
            caption,
          };
        },
      },
      {
        tag: 'img[src]',
        getAttrs: (element) => {
          const scale = element.getAttribute('scale');
          const caption = element.getAttribute('data-caption') || '';
          return {
            src: element.getAttribute('src'),
            alt: element.getAttribute('alt'),
            title: element.getAttribute('title'),
            scale: scale ? Number(scale) : 1,
            caption,
          };
        },
      },
    ];
  },

  renderHTML({ HTMLAttributes }): DOMOutputSpec {
    const { scale, caption, ...rest } = HTMLAttributes;

    const imgElement: DOMOutputSpec = [
      'img',
      mergeAttributes(rest, {
        scale: scale,
        'data-caption': caption,
        style: `transform: scale(${scale})`,
      }),
    ];

    const children: DOMOutputSpec[] = [imgElement];

    if (caption) {
      children.push(['p', { class: 'image-caption mt-2 text-sm text-gray-600 italic text-center' }, caption]);
    }

    return ['div', { class: 'image-container flex flex-col items-center my-4' }, ...children];
  },

  addNodeView() {
    return ReactNodeViewRenderer(ImageNodeView);
  },
});