/**
 * Image Node Extension
 * 图片节点
 */

import type { NodeSpec, Schema, SlashMenuItem } from '../../core/types';
import { NodeExtension } from '../../core/Extension';
import { Plugin, PluginKey } from 'prosemirror-state';
import { ImageIcon } from 'lucide-react';

export interface ImageOptions {
  /** 图片上传处理函数 */
  onUpload?: (file: File) => Promise<string>;
  /** 允许的图片类型 */
  allowedTypes?: string[];
  /** 最大文件大小（字节） */
  maxSize?: number;
}

export const imagePluginKey = new PluginKey('image');

export class Image extends NodeExtension<ImageOptions> {
  get name(): string {
    return 'image';
  }

  get schema(): NodeSpec {
    return {
      attrs: {
        src: { default: '' },
        alt: { default: '' },
        title: { default: null },
        width: { default: null },
        height: { default: null },
        align: { default: 'center' },
      },
      group: 'block',
      draggable: true,
      parseDOM: [
        {
          tag: 'img[src]',
          getAttrs(dom: HTMLElement) {
            return {
              src: dom.getAttribute('src'),
              alt: dom.getAttribute('alt'),
              title: dom.getAttribute('title'),
              width: dom.getAttribute('width'),
              height: dom.getAttribute('height'),
            };
          },
        },
        {
          tag: 'figure.editor-image',
          getAttrs(dom: HTMLElement) {
            const img = dom.querySelector('img');
            if (!img) return false;
            return {
              src: img.getAttribute('src'),
              alt: img.getAttribute('alt'),
              title: img.getAttribute('title'),
              width: img.getAttribute('width'),
              height: img.getAttribute('height'),
            };
          },
        },
      ],
      toDOM(node) {
        const { src, alt, title, width, height, align } = node.attrs;
        return [
          'figure',
          {
            class: `editor-image editor-image--${align}`,
          },
          [
            'img',
            {
              src,
              alt: alt || '',
              title: title || undefined,
              width: width || undefined,
              height: height || undefined,
            },
          ],
        ];
      },
    };
  }

  plugins(schema: Schema): Plugin[] {
    const options = this.options;
    const imageType = schema.nodes.image;

    return [
      new Plugin({
        key: imagePluginKey,
        props: {
          handleDOMEvents: {
            // 处理粘贴图片
            paste(view, event) {
              const items = event.clipboardData?.items;
              if (!items) return false;

              for (let i = 0; i < items.length; i++) {
                const item = items[i];
                if (item.type.startsWith('image/')) {
                  event.preventDefault();
                  const file = item.getAsFile();
                  if (file) {
                    handleImageUpload(view, file, imageType, options);
                  }
                  return true;
                }
              }
              return false;
            },
            // 处理拖拽图片
            drop(view, event) {
              const files = event.dataTransfer?.files;
              if (!files || files.length === 0) return false;

              const imageFiles = Array.from(files).filter((f) =>
                f.type.startsWith('image/')
              );
              if (imageFiles.length === 0) return false;

              event.preventDefault();
              const pos = view.posAtCoords({
                left: event.clientX,
                top: event.clientY,
              });

              imageFiles.forEach((file) => {
                handleImageUpload(view, file, imageType, options, pos?.pos);
              });
              return true;
            },
          },
        },
      }),
    ];
  }

  slashMenuItems(schema: Schema): SlashMenuItem[] {
    return [
      {
        name: 'image',
        title: '图片',
        description: '插入图片',
        icon: ImageIcon,
        keywords: ['image', 'img', 'picture', '图片', '图像'],
        group: 'media',
        priority: 10,
        command: (state, dispatch) => {
          // 触发文件选择
          const input = document.createElement('input');
          input.type = 'file';
          input.accept = 'image/*';
          input.onchange = () => {
            const file = input.files?.[0];
            if (file && dispatch) {
              // 这里需要通过 view 来处理上传
              // 由于 command 没有 view 参数，我们先插入一个占位符
              const { from } = state.selection;
              const imageNode = schema.nodes.image.create({
                src: URL.createObjectURL(file),
                alt: file.name,
              });
              const tr = state.tr.replaceSelectionWith(imageNode);
              dispatch(tr);
            }
          };
          input.click();
          return true;
        },
      },
    ];
  }
}

/**
 * 处理图片上传
 */
async function handleImageUpload(
  view: any,
  file: File,
  imageType: any,
  options: ImageOptions,
  pos?: number
) {
  const { onUpload, allowedTypes, maxSize } = options;

  // 检查文件类型
  if (allowedTypes && !allowedTypes.includes(file.type)) {
    console.warn('不支持的图片类型:', file.type);
    return;
  }

  // 检查文件大小
  if (maxSize && file.size > maxSize) {
    console.warn('图片文件过大:', file.size);
    return;
  }

  // 创建临时预览
  const tempUrl = URL.createObjectURL(file);
  const insertPos = pos ?? view.state.selection.from;

  // 插入带有临时 URL 的图片
  const tempNode = imageType.create({
    src: tempUrl,
    alt: file.name,
  });

  let tr = view.state.tr.insert(insertPos, tempNode);
  view.dispatch(tr);

  // 如果有上传函数，执行上传并替换 URL
  if (onUpload) {
    try {
      const uploadedUrl = await onUpload(file);

      // 找到刚插入的图片并更新 URL
      view.state.doc.descendants((node: any, nodePos: number) => {
        if (node.type === imageType && node.attrs.src === tempUrl) {
          tr = view.state.tr.setNodeMarkup(nodePos, null, {
            ...node.attrs,
            src: uploadedUrl,
          });
          view.dispatch(tr);
          return false;
        }
        return true;
      });

      // 释放临时 URL
      URL.revokeObjectURL(tempUrl);
    } catch (error) {
      console.error('图片上传失败:', error);
      // 可以选择删除临时图片或保留
    }
  }
}

export default Image;
