import { Editor, Range, Transforms, Element, Point, Text } from 'slate'
import { ReactEditor } from 'slate-react'


export interface MentionElement {
  type: 'mention'
  nodeId: string
  nodeType: string
  children: { text: string }[]
}

// Helper to check if a node is a mention
export const isMentionElement = (element: any): element is MentionElement => {
  return element.type === 'mention'
}

// Find mentions in text
export const withMentions = (editor: Editor) => {
  const { isInline, isVoid, markableVoid } = editor

  editor.isInline = element => {
    return element.type === 'mention' ? true : isInline(element)
  }

  editor.isVoid = element => {
    return element.type === 'mention' ? true : isVoid(element)
  }

  editor.markableVoid = element => {
    return element.type === 'mention' || markableVoid(element)
  }

  return editor
}

// Get current mention search
export const getMentionSearch = (editor: Editor): { range: Range; search: string } | null => {
  const { selection } = editor

  if (!selection || !Range.isCollapsed(selection)) {
    return null
  }

  const [start] = Range.edges(selection)
  
  // Get text before cursor (up to 20 characters to find @)
  const beforeRange = {
    anchor: Editor.before(editor, start, { distance: 20, unit: 'character' }) || Editor.start(editor, []),
    focus: start,
  }
  
  const beforeText = Editor.string(editor, beforeRange)
  
  // Look for @ followed by word characters at the end of the text
  const match = beforeText.match(/@(\w*)$/)
  
  if (match) {
    const matchStart = beforeText.lastIndexOf(match[0])
    const matchRange = {
      anchor: Editor.before(editor, start, { distance: beforeText.length - matchStart, unit: 'character' }) || start,
      focus: start,
    }
    
    return {
      range: matchRange,
      search: match[1] || ''
    }
  }

  return null
}

// Insert mention
export const insertMention = (editor: Editor, nodeId: string, nodeType: string, nodeName: string) => {
  const mention: MentionElement = {
    type: 'mention',
    nodeId,
    nodeType,
    children: [{ text: '' }]
  }

  const mentionSearch = getMentionSearch(editor)
  if (mentionSearch) {
    // Replace the @ and search text with the mention
    Transforms.select(editor, mentionSearch.range)
    Transforms.insertNodes(editor, mention)
    Transforms.insertText(editor, ` ${nodeName} `)
    Transforms.move(editor)
  }
}