import type { EditorView } from "prosemirror-view"
import { contentToDoc, docToContent } from "@/lib/content-model"
import { classifyBlock } from "@/lib/markdown-rules/block-classifier"
import { schema } from "@/lib/schema"

export type PasteSplitHandler = (before: string, after: string) => void

export function createPasteHandler(onSplit: PasteSplitHandler) {
  return function handlePaste(
    view: EditorView,
    event: ClipboardEvent,
  ): boolean {
    const text = event.clipboardData?.getData("text/plain")
    if (!text) return false

    const lines = text.split("\n")
    if (lines.length <= 1) return false

    const classifications = lines.map((line) => classifyBlock(line))
    const firstType = classifications[0]?.kind

    const isContinuationBlock = (kind: string) =>
      kind === "blockquote" &&
      (firstType === "callout" || firstType === "blockquote")

    const hasMixedTypes = classifications
      .slice(1)
      .some(
        (c) =>
          c.kind !== "paragraph" &&
          !isContinuationBlock(c.kind) &&
          c.kind !== firstType,
      )
    if (!hasMixedTypes) return false

    event.preventDefault()

    const { $from } = view.state.selection
    const beforeDoc = view.state.doc.slice(0, $from.pos)
    const afterDoc = view.state.doc.slice(
      $from.pos,
      view.state.doc.content.size,
    )
    const beforeText = docToContent(
      schema.nodes.doc.create(null, beforeDoc.content),
    )
    const afterText = docToContent(
      schema.nodes.doc.create(null, afterDoc.content),
    )
    const firstGroupLines: string[] = [lines[0]!]

    const restLines: string[] = []

    let foundBreak = false
    for (let i = 1; i < lines.length; i++) {
      const kind = classifications[i]?.kind
      const line = lines[i]!
      if (!foundBreak && (kind === firstType || kind === "paragraph")) {
        firstGroupLines.push(line)
      } else {
        foundBreak = true
        restLines.push(line)
      }
    }

    const groupContent = firstGroupLines.join("\n")
    const newBefore = beforeText
      ? `${beforeText}\n${groupContent}`
      : groupContent
    const afterSuffix = afterText
      ? `${restLines.join("\n")}\n${afterText}`
      : restLines.join("\n")

    const newDoc = contentToDoc(newBefore)
    const tr = view.state.tr.replaceWith(
      0,
      view.state.doc.content.size,
      newDoc.content,
    )
    view.dispatch(tr)

    if (afterSuffix) {
      onSplit(newBefore, afterSuffix)
    }

    return true
  }
}
