import { Node, mergeAttributes, Command, CommandProps } from '@tiptap/core'
import { ReactNodeViewRenderer } from '@tiptap/react'
import ImageNodeView from './ImageNodeView'

export interface CustomImageOptions {
  HTMLAttributes: Record<string, any>
}

declare module '@tiptap/core' {
  interface Commands<ReturnType> {
    customImage: {
      /**
       * Insert a custom image node with optional initial caption.
       */
      insertCustomImage: (options: {
        src: string
        alt?: string
        scale?: number
        caption?: string
      }) => ReturnType
    }
  }
}

export const CustomImage = Node.create<CustomImageOptions>({
  name: 'customImage',
  group: 'block',
  draggable: true,
  inline: false,
  atom: true,               // we handle our own caption, toolbar, etc.
  addOptions() {
    return {
      HTMLAttributes: {},
    }
  },
  addAttributes() {
    return {
      src: {
        default: '',
      },
      alt: {
        default: null,
      },
      scale: {
        default: 1,
      },
      caption: {
        default: '',
      },
    }
  },
  parseHTML() {
    return [
      {
        tag: 'figure[data-type="customImage"]',
      },
    ]
  },
  renderHTML({ HTMLAttributes }) {
    return [
      'figure',
      mergeAttributes(HTMLAttributes, { 'data-type': 'customImage', class: 'relative' }),
      ['img', { src: HTMLAttributes.src, alt: HTMLAttributes.alt }],
      ['figcaption', { class: 'text-sm text-gray-500 mt-2' }, 0],
    ]
  },
  addCommands() {
    return {
      insertCustomImage:
          (options) =>
              ({ commands }) => {
                return commands.insertContent({
                  type: this.name,
                  attrs: {
                    src: options.src,
                    alt: options.alt,
                    scale: options.scale ?? 1,
                    caption: options.caption ?? '',
                  },
                  content: options.caption
                      ? [{ type: 'text', text: options.caption }]
                      : [],
                })
              },
    }
  },
  addNodeView() {
    return ReactNodeViewRenderer(ImageNodeView)
  },
})