import {Clipboard} from "@capacitor/clipboard"
import {Capacitor} from "@capacitor/core"
import {Extension} from "@tiptap/core"
import {Plugin, PluginKey} from "@tiptap/pm/state"

const nativeClipboardAvailable = () =>
  Capacitor.isNativePlatform() && Capacitor.isPluginAvailable("Clipboard")

const hasStandardPastePayload = (event: ClipboardEvent) => {
  const clipboardData = event.clipboardData

  if (!clipboardData) {
    return false
  }

  if (Array.from(clipboardData.items).some(item => item.kind === "file")) {
    return true
  }

  if (clipboardData.types.includes("text/html")) {
    return true
  }

  return clipboardData.getData("text/plain") !== ""
}

const getNativeClipboardImage = async () => {
  try {
    const {type, value} = await Clipboard.read()

    if (!type.startsWith("image/") || value === "") {
      return undefined
    }

    const imageData = value.startsWith("data:") ? value : `data:${type};base64,${value}`
    const blob = await fetch(imageData).then(res => res.blob())

    if (!blob.type.startsWith("image/")) {
      return undefined
    }

    const extension = type.split("/")[1]?.split("+")[0] || "png"

    return new File([blob], `clipboard-image.${extension}`, {type: blob.type || type})
  } catch {
    return undefined
  }
}

export const NativeClipboardPasteExtension = Extension.create({
  name: "nativeClipboardPaste",

  addProseMirrorPlugins() {
    const editor = this.editor

    return [
      new Plugin({
        key: new PluginKey("nativeClipboardPaste"),
        props: {
          handlePaste: (_view, event) => {
            if (!nativeClipboardAvailable() || hasStandardPastePayload(event)) {
              return false
            }

            event.preventDefault()

            void getNativeClipboardImage().then(file => {
              if (!file) {
                return
              }

              editor.commands.addFile(file, editor.state.selection.from + 1)
            })

            return true
          },
        },
      }),
    ]
  },
})
