import React, { useEffect, useRef, useCallback, useState } from 'react'
import { useTabStore } from '../../stores/tabStore'
import { useEditorStore } from '../../stores/editorStore'
import { useSearchStore } from '../../stores/searchStore'
import { findMatches, buildLineStarts, getLineNumber } from '../../lib/searchEngine'
import type { SearchMatch } from '../../types/search'

export function Editor() {
  const textareaRef = useRef<HTMLTextAreaElement>(null)
  const lineNumbersRef = useRef<HTMLDivElement>(null)
  const wrapperRef = useRef<HTMLDivElement>(null)

  const activeTabId = useTabStore(s => s.activeTabId)
  const getActiveTab = useTabStore(s => s.getActiveTab)
  const updateTabContent = useTabStore(s => s.updateTabContent)
  const setModified = useTabStore(s => s.setModified)

  const searchStore = useSearchStore()

  const [lineCount, setLineCount] = useState(1)
  const [cursorPos, setCursorPos] = useState({ line: 1, col: 1 })
  const [fileSize, setFileSize] = useState('')
  const updateTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null)

  // 测量行高
  const lineHeightRef = useRef(20.8)
  useEffect(() => {
    const textarea = textareaRef.current
    if (!textarea) return
    const style = getComputedStyle(textarea)
    const measure = document.createElement('div')
    measure.style.cssText = `position:absolute;visibility:hidden;font-family:${style.fontFamily};font-size:${style.fontSize};line-height:${style.lineHeight};white-space:pre;width:0;`
    measure.textContent = 'X'
    document.body.appendChild(measure)
    const singleHeight = measure.offsetHeight
    measure.textContent = 'X\nX'
    const doubleHeight = measure.offsetHeight
    document.body.removeChild(measure)
    lineHeightRef.current = doubleHeight - singleHeight || 20.8
  }, [])

  // 加载标签内容到编辑器
  useEffect(() => {
    const tab = getActiveTab()
    const textarea = textareaRef.current
    if (!tab || !textarea) return

    textarea.value = tab.content
    updateLineNumbers(tab.content)
    updateFileSizeDisplay(tab.content)
    updateCursorPos()

    requestAnimationFrame(() => {
      textarea.scrollTop = tab.scrollTop
      textarea.scrollLeft = tab.scrollLeft
      textarea.setSelectionRange(tab.selectionStart, tab.selectionEnd)
      if (lineNumbersRef.current) {
        lineNumbersRef.current.scrollTop = tab.scrollTop
      }
    })
  }, [activeTabId, getActiveTab])

  // 保存当前标签状态
  const saveCurrentState = useCallback(() => {
    const tab = getActiveTab()
    const textarea = textareaRef.current
    if (!tab || !textarea) return
    useTabStore.getState().updateTabScroll(tab.id, {
      scrollTop: textarea.scrollTop,
      scrollLeft: textarea.scrollLeft,
      selectionStart: textarea.selectionStart,
      selectionEnd: textarea.selectionEnd,
      previewScrollTop: 0 // will be set by preview
    })
  }, [getActiveTab])

  // 更新行号
  const updateLineNumbers = useCallback((content: string) => {
    const count = (content.match(/\n/g) || []).length + 1
    setLineCount(count)
  }, [])

  // 更新文件大小
  const updateFileSizeDisplay = useCallback((content: string) => {
    const bytes = new Blob([content]).size
    if (bytes < 1024) setFileSize(bytes + ' B')
    else if (bytes < 1024 * 1024) setFileSize((bytes / 1024).toFixed(1) + ' KB')
    else setFileSize((bytes / (1024 * 1024)).toFixed(1) + ' MB')
  }, [])

  // 更新光标位置
  const updateCursorPos = useCallback(() => {
    const textarea = textareaRef.current
    if (!textarea) return
    const text = textarea.value
    const pos = textarea.selectionStart
    const textBefore = text.substring(0, pos)
    const lines = textBefore.split('\n')
    setCursorPos({ line: lines.length, col: lines[lines.length - 1].length + 1 })
  }, [])

  // 输入事件
  const handleInput = useCallback(() => {
    const textarea = textareaRef.current
    const tab = getActiveTab()
    if (!textarea || !tab) return

    const content = textarea.value
    updateTabContent(tab.id, content)
    setModified(tab.id, true)
    updateLineNumbers(content)
    updateFileSizeDisplay(content)

    // 防抖更新
    if (updateTimerRef.current) clearTimeout(updateTimerRef.current)
    updateTimerRef.current = setTimeout(() => {
      // 触发预览更新（通过 store）
    }, 150)
  }, [getActiveTab, updateTabContent, setModified, updateLineNumbers, updateFileSizeDisplay])

  // 滚动同步
  const handleScroll = useCallback(() => {
    const textarea = textareaRef.current
    if (!textarea) return
    if (lineNumbersRef.current) {
      lineNumbersRef.current.scrollTop = textarea.scrollTop
    }
  }, [])

  // Tab 键支持
  const handleKeyDown = useCallback((e: React.KeyboardEvent) => {
    if (e.key === 'Tab') {
      e.preventDefault()
      const textarea = textareaRef.current
      if (!textarea) return
      const start = textarea.selectionStart
      const end = textarea.selectionEnd
      if (start !== end) {
        const lines = textarea.value.substring(start, end).split('\n')
        const indented = lines.map(line => '    ' + line).join('\n')
        document.execCommand('insertText', false, indented)
      } else {
        document.execCommand('insertText', false, '    ')
      }
    }

    // 搜索导航
    if (e.key === 'Enter' && searchStore.isVisible) {
      e.preventDefault()
      if (e.shiftKey) {
        searchStore.findPrev()
      } else {
        searchStore.findNext()
      }
    }
  }, [searchStore])

  // 渲染行号
  const renderLineNumbers = () => {
    const lineHeight = lineHeightRef.current
    const LARGE_THRESHOLD = 2000
    if (lineCount > LARGE_THRESHOLD) {
      // 虚拟化
      const textarea = textareaRef.current
      if (!textarea) return null
      const scrollTop = textarea.scrollTop
      const viewportHeight = textarea.clientHeight
      const buffer = 20
      const startLine = Math.max(0, Math.floor(scrollTop / lineHeight) - buffer)
      const endLine = Math.min(lineCount, Math.ceil((scrollTop + viewportHeight) / lineHeight) + buffer)
      const topPadding = startLine * lineHeight
      const bottomPadding = (lineCount - endLine) * lineHeight
      return (
        <>
          <div style={{ height: topPadding }} />
          {Array.from({ length: endLine - startLine }, (_, i) => (
            <div key={startLine + i} className="line-num" style={{ height: lineHeight }}>
              {startLine + i + 1}
            </div>
          ))}
          <div style={{ height: bottomPadding }} />
        </>
      )
    }
    return Array.from({ length: lineCount }, (_, i) => (
      <div key={i} className="line-num" style={{ height: lineHeight }}>
        {i + 1}
      </div>
    ))
  }

  return (
    <div id="editor-wrapper" ref={wrapperRef}>
      <div id="line-numbers" ref={lineNumbersRef}>
        {renderLineNumbers()}
      </div>
      <textarea
        ref={textareaRef}
        id="editor"
        spellCheck={false}
        placeholder="在此输入 Markdown 内容，或拖拽 .md 文件到窗口打开..."
        onInput={handleInput}
        onScroll={handleScroll}
        onClick={updateCursorPos}
        onKeyUp={updateCursorPos}
        onKeyDown={handleKeyDown}
      />
    </div>
  )
}
