'use client'

import React, { useCallback, useMemo, useState } from 'react'
import { createEditor, Descendant, Editor, Transforms, BaseEditor, Element, Text } from 'slate'
import { Slate, Editable, withReact, RenderElementProps, RenderLeafProps, ReactEditor } from 'slate-react'
import { withHistory, HistoryEditor } from 'slate-history'
import { useDocumentStore } from '@/stores/document-store'
import { useDesignStore } from '@/stores/design-store'
import { FileText, Bold, Italic, Type, List, ListOrdered } from 'lucide-react'
import { withMentions, getMentionSearch, insertMention } from './mention-plugin'
import MentionSuggestions from './MentionSuggestions'
import MentionElementComponent from './MentionElement'

// Define custom types for Slate
interface CustomElement {
  type?: string
  children: CustomText[]
  nodeId?: string
  nodeType?: string
}

interface CustomText {
  text: string
  bold?: boolean
  italic?: boolean
  underline?: boolean
}

declare module 'slate' {
  interface CustomTypes {
    Editor: BaseEditor & ReactEditor & HistoryEditor
    Element: CustomElement
    Text: CustomText
  }
}

const CustomElement = ({ attributes, children, element }: RenderElementProps) => {
  const customElement = element as CustomElement
  switch (customElement.type) {
    case 'mention':
      return <MentionElementComponent attributes={attributes} children={children} element={element} />
    case 'heading-one':
      return <h1 {...attributes} className="text-2xl font-bold mb-4">{children}</h1>
    case 'heading-two':
      return <h2 {...attributes} className="text-xl font-semibold mb-3">{children}</h2>
    case 'heading-three':
      return <h3 {...attributes} className="text-lg font-medium mb-2">{children}</h3>
    case 'bulleted-list':
      return <ul {...attributes} className="list-disc pl-6 mb-2">{children}</ul>
    case 'numbered-list':
      return <ol {...attributes} className="list-decimal pl-6 mb-2">{children}</ol>
    case 'list-item':
      return <li {...attributes}>{children}</li>
    case 'paragraph':
    default:
      return <p {...attributes} className="mb-2">{children}</p>
  }
}

const CustomLeaf = ({ attributes, children, leaf }: RenderLeafProps) => {
  const customLeaf = leaf as CustomText
  if (customLeaf.bold) {
    children = <strong>{children}</strong>
  }

  if (customLeaf.italic) {
    children = <em>{children}</em>
  }

  if (customLeaf.underline) {
    children = <u>{children}</u>
  }

  return <span {...attributes}>{children}</span>
}

const DocumentEditor: React.FC = () => {
  const { getCurrentDocument, updateCurrentDocumentContent } = useDocumentStore()
  const { currentDesign } = useDesignStore()

  const editor = useMemo(() => withMentions(withHistory(withReact(createEditor()))), [])
  const currentDoc = getCurrentDocument()
  
  const [mentionSearch, setMentionSearch] = useState<{ search: string } | null>(null)
  
  // Reset editor when document changes to prevent invalid path errors
  React.useEffect(() => {
    if (editor) {
      // Clear history and reset editor state when document changes
      editor.history = { undos: [], redos: [] }
      editor.selection = null
    }
  }, [currentDoc.id, editor])

  const renderElement = useCallback((props: RenderElementProps) => <CustomElement {...props} />, [])
  const renderLeaf = useCallback((props: RenderLeafProps) => <CustomLeaf {...props} />, [])

  const handleChange = useCallback((newValue: Descendant[]) => {
    updateCurrentDocumentContent(newValue)

    // Check for mention triggers
    const mentionSearchResult = getMentionSearch(editor)
    setMentionSearch(mentionSearchResult ? { search: mentionSearchResult.search } : null)
  }, [updateCurrentDocumentContent, editor])

  const isMarkActive = (format: string) => {
    const marks = Editor.marks(editor)
    return marks ? (marks as any)[format] === true : false
  }

  const isBlockActive = (format: string) => {
    const { selection } = editor
    if (!selection) return false

    const [match] = Array.from(
      Editor.nodes(editor, {
        at: Editor.unhangRange(editor, selection),
        match: n => !Editor.isEditor(n) && Element.isElement(n) && (n as CustomElement).type === format,
      })
    )

    return !!match
  }

  const toggleMark = (format: string) => {
    const isActive = isMarkActive(format)
    if (isActive) {
      Editor.removeMark(editor, format)
    } else {
      Editor.addMark(editor, format, true)
    }
  }

  const toggleBlock = (format: string) => {
    const isActive = isBlockActive(format)
    const isList = ['numbered-list', 'bulleted-list'].includes(format)

    Transforms.unwrapNodes(editor, {
      match: n =>
        !Editor.isEditor(n) &&
        Element.isElement(n) &&
        ['numbered-list', 'bulleted-list'].includes((n as CustomElement).type as string),
      split: true,
    })

    let newProperties: Partial<CustomElement>
    if (isActive) {
      newProperties = { type: 'paragraph' }
    } else if (isList) {
      newProperties = { type: 'list-item' }
    } else {
      newProperties = { type: format }
    }

    Transforms.setNodes<CustomElement>(editor, newProperties)

    if (!isActive && isList) {
      const block = { type: format, children: [] } as CustomElement
      Transforms.wrapNodes(editor, block)
    }
  }

  const handleMentionSelect = useCallback((suggestion: { id: string; type: string; label: string }) => {
    insertMention(editor, suggestion.id, suggestion.type, suggestion.label)
    setMentionSearch(null)
  }, [editor])

  const handleMentionClose = useCallback(() => setMentionSearch(null), [])

  if (!currentDesign) {
    return (
      <div className="p-4 text-gray-500">
        <FileText className="h-8 w-8 mb-2" />
        No design selected
      </div>
    )
  }

  return (
    <div className="flex flex-col h-full">
      {/* Toolbar */}
      <div className="border-b border-gray-200 p-2 flex gap-1 flex-wrap">
        <button
          className={`p-2 rounded hover:bg-gray-100 ${isMarkActive('bold') ? 'bg-gray-200' : ''}`}
          onMouseDown={(event) => {
            event.preventDefault()
            toggleMark('bold')
          }}
          title="Bold"
        >
          <Bold className="h-4 w-4" />
        </button>
        <button
          className={`p-2 rounded hover:bg-gray-100 ${isMarkActive('italic') ? 'bg-gray-200' : ''}`}
          onMouseDown={(event) => {
            event.preventDefault()
            toggleMark('italic')
          }}
          title="Italic"
        >
          <Italic className="h-4 w-4" />
        </button>
        
        <div className="w-px bg-gray-300 mx-1" />
        
        <button
          className={`p-2 rounded hover:bg-gray-100 ${isBlockActive('heading-one') ? 'bg-gray-200' : ''}`}
          onMouseDown={(event) => {
            event.preventDefault()
            toggleBlock('heading-one')
          }}
          title="Heading 1"
        >
          <span className="text-sm font-bold">H1</span>
        </button>
        <button
          className={`p-2 rounded hover:bg-gray-100 ${isBlockActive('heading-two') ? 'bg-gray-200' : ''}`}
          onMouseDown={(event) => {
            event.preventDefault()
            toggleBlock('heading-two')
          }}
          title="Heading 2"
        >
          <span className="text-sm font-bold">H2</span>
        </button>
        <button
          className={`p-2 rounded hover:bg-gray-100 ${isBlockActive('heading-three') ? 'bg-gray-200' : ''}`}
          onMouseDown={(event) => {
            event.preventDefault()
            toggleBlock('heading-three')
          }}
          title="Heading 3"
        >
          <span className="text-sm font-bold">H3</span>
        </button>
        
        <div className="w-px bg-gray-300 mx-1" />
        
        <button
          className={`p-2 rounded hover:bg-gray-100 ${isBlockActive('bulleted-list') ? 'bg-gray-200' : ''}`}
          onMouseDown={(event) => {
            event.preventDefault()
            toggleBlock('bulleted-list')
          }}
          title="Bulleted List"
        >
          <List className="h-4 w-4" />
        </button>
        <button
          className={`p-2 rounded hover:bg-gray-100 ${isBlockActive('numbered-list') ? 'bg-gray-200' : ''}`}
          onMouseDown={(event) => {
            event.preventDefault()
            toggleBlock('numbered-list')
          }}
          title="Numbered List"
        >
          <ListOrdered className="h-4 w-4" />
        </button>
      </div>

      {/* Editor */}
      <div className="flex-1 p-4 overflow-y-auto">
        <Slate key={currentDoc.id} editor={editor} initialValue={currentDoc.content} onValueChange={handleChange}>
          <Editable
            renderElement={renderElement}
            renderLeaf={renderLeaf}
            placeholder="Start writing your document..."
            className="h-full outline-none"
            spellCheck={false}
            style={{ minHeight: '100%' }}

          />
        </Slate>
      </div>

      {/* Mention Suggestions */}
      {mentionSearch && (
        <MentionSuggestions
          editor={editor}
          search={mentionSearch.search}
          onSelect={handleMentionSelect}
          onClose={handleMentionClose}
        />
      )}
    </div>
  )
}

export default DocumentEditor