import React, { useEffect, useRef } from 'react'
import { cn } from '@/utils/cn'
import type { TextElement } from './domino'
import { useDominoStore } from './domino-hooks'

interface TextRenderProps {
  element: TextElement
}

export function TextRender({ element }: TextRenderProps) {
  const updateElement = useDominoStore(state => state.updateElement)
  const setFocusedElementId = useDominoStore(state => state.setFocusedElementId)
  const isFocused = useDominoStore(
    state => state.focusedElementId === element.id,
  )
  const isSelected = useDominoStore(state =>
    state.selectedIds.includes(element.id),
  )
  const isEditing = isFocused && !isSelected

  const textRef = useRef<HTMLDivElement>(null)
  const prevFocused = useRef(false)

  // Focus and Cursor Positioning
  useEffect(() => {
    if (isFocused && !prevFocused.current && textRef.current) {
      const el = textRef.current
      if (document.activeElement !== el) {
        el.focus({ preventScroll: true })
      }
      // Only move cursor to end once on initial focus
      el.innerText = element.content
      const range = document.createRange()
      const sel = window.getSelection()
      if (sel) {
        range.selectNodeContents(el)
        range.collapse(false)
        sel.removeAllRanges()
        sel.addRange(range)
      }
    }
    prevFocused.current = isFocused
  }, [isFocused, element.content])

  // Height Synchronization
  useEffect(() => {
    if (textRef.current) {
      const observer = new ResizeObserver(entries => {
        const entry = entries[0]
        if (entry) {
          const newHeight = entry.contentRect.height
          // Update store height if strictly different
          if (Math.abs(newHeight - (element.height || 0)) > 0.5) {
            updateElement(element.id, { height: newHeight })
          }
        }
      })
      observer.observe(textRef.current)
      return () => observer.disconnect()
    }
  }, [element.id, element.height, updateElement])

  return (
    <div
      ref={textRef}
      contentEditable={isFocused}
      suppressContentEditableWarning
      className={cn(
        'w-full h-auto outline-none break-words cursor-text select-text p-0 m-0',
        !isFocused && 'pointer-events-none',
        isEditing &&
          'text-is-editing bg-transparent border-none shadow-none ring-0',
      )}
      draggable={!isEditing}
      style={{
        fontSize: element.fontSize,
        fontWeight: element.fontWeight,
        color: element.color,
        fontFamily: element.fontFamily,
        lineHeight: 1.2,
        textAlign: element.textAlign,
        fontStyle: element.fontStyle,
        minHeight: '1em',
        minWidth: '20px',
        padding: 0,
        margin: 0,
        cursor: isFocused ? 'text' : 'default',
        whiteSpace: element.width ? 'pre-wrap' : 'nowrap', // auto 宽度时不换行
        paddingRight: isFocused ? '32px' : 0, // 预留光标位置
      }}
      onInput={e => {
        const content = e.currentTarget.innerText
        const height = e.currentTarget.offsetHeight
        updateElement(element.id, { content, height })
      }}
      onPaste={e => {
        e.preventDefault()
        const text = e.clipboardData.getData('text/plain')
        document.execCommand('insertText', false, text)
      }}
      onBlur={() => {
        setFocusedElementId(null)
      }}
    >
      {!isFocused && element.content}
    </div>
  )
}
