import { EditorContent, useEditor } from "@tiptap/react"
import { forwardRef, useEffect, useImperativeHandle, useRef, useState } from "react"
import { editorExtensions, editorProps } from "./config"
import { Toolbar } from "./Toolbar"
import "./editor.css"
import "./components/image-upload/image-upload-node.css"

export interface TextEditorProps {
  value?: string
  onChange?: (value: string) => void
  placeholder?: string
  className?: string
  disabled?: boolean
  error?: boolean
  maxHeight?: number | string
}

export interface TextEditorRef {
  focus: () => void
  getHTML: () => string
  getText: () => string
  setContent: (content: string) => void
  clear: () => void
}

export const TextEditor = forwardRef<TextEditorRef, TextEditorProps>(
  (
    { value = "", onChange, placeholder = "", className, disabled, error, maxHeight = 400 },
    ref,
  ) => {
    // Resize functionality
    const [currentHeight, setCurrentHeight] = useState<number>(
      typeof maxHeight === "number" ? maxHeight : 400,
    )
    const containerRef = useRef<HTMLDivElement>(null)
    const isResizingRef = useRef(false)
    const startHeightRef = useRef(0)
    const startYRef = useRef(0)

    // Update height when maxHeight prop changes
    useEffect(() => {
      const newHeight = typeof maxHeight === "number" ? maxHeight : 400
      setCurrentHeight(newHeight)
    }, [maxHeight])

    const editor = useEditor({
      extensions: editorExtensions,
      content: value,
      shouldRerenderOnTransaction: true,
      editorProps: {
        ...editorProps,
        attributes: {
          ...editorProps.attributes,
          class: "tiptap",
          "data-placeholder": placeholder,
        },
      },
      onUpdate: ({ editor }) => {
        const html = editor.getHTML()
        onChange?.(html)
      },
      editable: !disabled,
    })

    useImperativeHandle(ref, () => ({
      focus: () => editor?.commands.focus(),
      getHTML: () => editor?.getHTML() || "",
      getText: () => editor?.getText() || "",
      setContent: (content: string) => editor?.commands.setContent(content),
      clear: () => editor?.commands.clearContent(),
    }))

    const text = editor?.getText() || ""

    const manualWordCount =
      text.trim() === ""
        ? 0
        : text
            .trim()
            .split(/\s+/)
            .filter(word => word.length > 0).length

    const finalWordCount = text.trim() ? manualWordCount : 0

    // Resize handlers
    const handleResizeStart = (e: React.MouseEvent) => {
      e.preventDefault()
      isResizingRef.current = true
      startYRef.current = e.clientY
      startHeightRef.current = currentHeight

      // Add global mouse listeners
      document.addEventListener("mousemove", handleResizeMove)
      document.addEventListener("mouseup", handleResizeEnd)
      document.body.style.cursor = "ns-resize"
      document.body.style.userSelect = "none"
    }

    const handleResizeMove = (e: MouseEvent) => {
      if (!isResizingRef.current) return

      const deltaY = e.clientY - startYRef.current
      const newHeight = Math.max(200, Math.min(800, startHeightRef.current + deltaY))
      setCurrentHeight(newHeight)
    }

    const handleResizeEnd = () => {
      isResizingRef.current = false
      document.removeEventListener("mousemove", handleResizeMove)
      document.removeEventListener("mouseup", handleResizeEnd)
      document.body.style.cursor = ""
      document.body.style.userSelect = ""
    }

    // Convert height to CSS value
    const heightValue = `${currentHeight}px`

    return (
      <div
        className={`w-full border border-gray-300 rounded-lg bg-white overflow-hidden ${
          error ? "border-red-500" : "focus-within:border-blue-500"
        } ${disabled ? "opacity-50 pointer-events-none" : ""} ${className || ""}`}
      >
        <div ref={containerRef} className="flex flex-col h-full" style={{ height: heightValue }}>
          {/* Toolbar */}
          <div className="flex-shrink-0">
            <Toolbar editor={editor} />
          </div>

          {/* Editor Content */}
          <div className="flex-1 overflow-y-auto min-h-0 relative">
            <EditorContent editor={editor} className="max-w-none focus:outline-none" />
          </div>

          {/* Footer */}
          <div className="flex items-center justify-between px-4 py-2 border-t border-gray-200 bg-gray-50 flex-shrink-0">
            <span className="text-xs text-gray-500 font-medium">{finalWordCount} words</span>

            {/* Resize handle */}
            <button
              type="button"
              className="w-3 h-3 opacity-60 cursor-se-resize hover:opacity-80 transition-opacity border-0 p-0 focus:outline-none focus:ring-1 focus:ring-blue-500"
              title="Resize editor"
              onMouseDown={handleResizeStart}
              aria-label="Resize editor"
            >
              <svg
                width="12"
                height="12"
                viewBox="0 0 12 12"
                fill="currentColor"
                className="w-full h-full"
              >
                <title>Resize editor</title>
                <path d="M10 6L6 10L10 10V6Z" />
                <path d="M10 2L2 10H6L10 6V2Z" />
              </svg>
            </button>
          </div>
        </div>
      </div>
    )
  },
)

TextEditor.displayName = "TextEditor"
