import React, { useEffect, useRef, useState, useCallback } from 'react'
import { useSelector } from 'react-redux'
// import { App } from 'antd'
import type { RootState } from '../../store/store'

interface ScreenReaderProps {
  deviceId: string
  maxHeight?: number
}

interface UIElement {
  id: string
  type: string
  text?: string
  description?: string
  bounds: {
    left: number
    top: number
    right: number
    bottom: number
  }
  clickable: boolean
  scrollable: boolean
  focusable: boolean
  enabled: boolean
  visible: boolean
  children?: UIElement[]
  className?: string
  resourceId?: string
  packageName?: string
}

interface UIHierarchy {
  root: UIElement
  timestamp: number
  screenWidth: number
  screenHeight: number
  totalElements: number
  clickableElements: number
}

/**
 * 屏幕阅读器组件 - 在设备屏幕上叠加显示UI元素边界
 */
const ScreenReader: React.FC<ScreenReaderProps> = ({ deviceId, maxHeight }) => {

  // const { message } = App.useApp()
  const { webSocket } = useSelector((state: RootState) => state.connection)
  const { connectedDevices } = useSelector((state: RootState) => state.devices)
  
  // 获取当前设备的屏幕阅读器配置
  const device = connectedDevices.find(d => d.id === deviceId)
  const screenReader = device?.screenReader || {
    enabled: false,
    autoRefresh: true,
    refreshInterval: 1,
    showElementBounds: true,
    highlightClickable: true,
    showVirtualKeyboard: false,
    showText: true
  }

  // 顶部工具栏操作
  // const handleToggleScreenReader = useCallback(() => {
  //   if (!deviceId) return
  //   if (device?.screenReader?.enabled) {
  //     try {
  //       // The original code had enable/disable logic here, but the imports were removed.
  //       // Assuming the intent was to remove the toolbar and its logic.
  //       // For now, we'll just show a message if screen reader is disabled.
  //       message.info('屏幕阅读器已禁用')
  //     } catch {
  //       // ignore
  //     }
  //   } else {
  //     try {
  //       // The original code had enable/disable logic here, but the imports were removed.
  //       // Assuming the intent was to remove the toolbar and its logic.
  //       // For now, we'll just show a message if screen reader is disabled.
  //       message.info('屏幕阅读器已启用')
  //       if (webSocket) {
  //         webSocket.emit('client_event', {
  //           type: 'GET_UI_HIERARCHY',
  //           data: {
  //             deviceId,
  //             requestId: `ui_hierarchy_${Date.now()}`,
  //             includeInvisible: true,
  //             includeNonInteractive: true,
  //             maxDepth: 25,
  //             enhanced: true,
  //             includeDeviceInfo: true
  //           }
  //         })
  //       }
  //     } catch {
  //       // ignore
  //     }
  //   }
  // }, [device?.screenReader?.enabled, deviceId, webSocket, message])

  // const handleExtractConfirmCoords = useCallback(() => {
  //   if (!webSocket || !deviceId) {
  //     message.error('WebSocket未连接')
  //     return
  //   }
  //   webSocket.emit('client_event', {
  //     type: 'START_EXTRACT_CONFIRM_COORDS',
  //     data: { deviceId }
  //   })
  //   message.info('已开始提取确认坐标，按提示点击目标位置')
  // }, [webSocket, deviceId, message])

  // const handleInputConfirmCoords = useCallback(() => {
  //   if (!webSocket || !deviceId) {
  //     message.error('WebSocket未连接')
  //     return
  //   }
  //   const xStr = window.prompt('请输入确认坐标 X：')
  //   const yStr = window.prompt('请输入确认坐标 Y：')
  //   if (!xStr || !yStr) return
  //   const x = parseFloat(xStr)
  //   const y = parseFloat(yStr)
  //   if (Number.isNaN(x) || Number.isNaN(y)) {
  //     message.error('坐标格式不正确')
  //     return
  //   }
  //   webSocket.emit('client_event', {
  //     type: 'SAVE_CONFIRM_COORDS',
  //     data: { deviceId, coords: { x, y } }
  //   })
  //   message.success(`已提交坐标: (${x}, ${y})`)
  // }, [webSocket, deviceId, message])
  const [uiHierarchy, setUiHierarchy] = useState<UIHierarchy | null>(null)
  const [, setLoading] = useState(false)
  const [selectedElement, setSelectedElement] = useState<UIElement | null>(null)
  const [autoRefresh] = useState(true) // 自动刷新开关
  const autoRefreshIntervalRef = useRef<number | null>(null)
  const canvasRef = useRef<HTMLCanvasElement>(null)
  
  // Drag state management
  const [isDragging, setIsDragging] = useState(false)
  const [dragStart, setDragStart] = useState<{x: number, y: number} | null>(null)
  
  // Long press handling
  const [isLongPressTriggered, setIsLongPressTriggered] = useState(false)
  const longPressTimerRef = useRef<number | null>(null)
  
  // Confirm coords extraction state
  const [isExtractingConfirmCoords, setIsExtractingConfirmCoords] = useState(false)
  // const [extractedCoords, setExtractedCoords] = useState<{ x: number; y: number } | null>(null)
  
  // Virtual keyboard state
  const [virtualKeyboard, setVirtualKeyboard] = useState<{
    visible: boolean
    keys: Array<{
      id: string
      text: string
      x: number
      y: number
      width: number
      height: number
    }>
  }>({
    visible: false,
    keys: []
  })

  // Enhanced analysis result state
  // const [enhancedAnalysisResult, setEnhancedAnalysisResult] = useState<any>(null)
  // const [deviceCharacteristics, setDeviceCharacteristics] = useState<any>(null)

  // Generate virtual keyboard layout based on screen reader display size
  const generateVirtualKeyboard = useCallback((screenWidth: number, screenHeight: number) => {
    // 键盘高度：屏幕高度的25%（确保4行按键都能显示）
    const keyboardHeight = screenHeight * 0.25
    const keyboardY = screenHeight - keyboardHeight // 贴到最底部
    
    // 键盘宽度：占满整个屏幕宽度（无左右间距）
    const keyboardWidth = screenWidth
    const keyboardX = 0 // 从屏幕左边缘开始
    
    // 按键尺寸计算：确保4行按键都能在键盘高度内显示
    const keyHeight = keyboardHeight / 4 // 4行按键
    const keyWidth = keyboardWidth / 3   // 3列按键
    
    const keys = []
    
    // 第一行：1, 2, 3
    for (let i = 0; i < 3; i++) {
      keys.push({
        id: `key_${i + 1}`,
        text: `${i + 1}`,
        x: keyboardX + i * keyWidth,
        y: keyboardY,
        width: keyWidth,
        height: keyHeight
      })
    }
    
    // 第二行：4, 5, 6
    for (let i = 0; i < 3; i++) {
      keys.push({
        id: `key_${i + 4}`,
        text: `${i + 4}`,
        x: keyboardX + i * keyWidth,
        y: keyboardY + keyHeight,
        width: keyWidth,
        height: keyHeight
      })
    }
    
    // 第三行：7, 8, 9
    for (let i = 0; i < 3; i++) {
      keys.push({
        id: `key_${i + 7}`,
        text: `${i + 7}`,
        x: keyboardX + i * keyWidth,
        y: keyboardY + 2 * keyHeight,
        width: keyWidth,
        height: keyHeight
      })
    }
    
    // 第四行：0, 删除键
    keys.push({
      id: 'key_0',
      text: '0',
      x: keyboardX + keyWidth,
      y: keyboardY + 3 * keyHeight,
      width: keyWidth,
      height: keyHeight
    })
    
    keys.push({
      id: 'key_delete',
      text: '⌫',
      x: keyboardX + 2 * keyWidth,
      y: keyboardY + 3 * keyHeight,
      width: keyWidth,
      height: keyHeight
    })
    
    console.log('[VirtualKeyboard] Layout calculated:', {
      screenSize: { width: screenWidth, height: screenHeight },
      keyboardSize: { width: keyboardWidth, height: keyboardHeight },
      keySize: { width: keyWidth, height: keyHeight },
      keyboardPosition: { x: keyboardX, y: keyboardY },
      keyboardBottom: keyboardY + keyboardHeight,
      screenBottom: screenHeight,
      totalKeys: keys.length,
      lastRowY: keyboardY + 3 * keyHeight,
      lastRowBottom: keyboardY + 4 * keyHeight
    })
    
    return {
      visible: true,
      keys
    }
  }, [])

  // Enhanced UI hierarchy request - all enhanced features enabled by default
  const requestUIHierarchy = useCallback((enhanced: boolean = true, includeDeviceInfo: boolean = true) => {
    if (!webSocket || !deviceId) return
    
    setLoading(true)
    
    // Enable enhanced UI analysis and device info by default
    webSocket.emit('client_event', {
      type: 'GET_UI_HIERARCHY',
      data: {
        deviceId,
        requestId: `ui_hierarchy_${Date.now()}`,
        includeInvisible: true,        // Enhanced: include invisible elements
        includeNonInteractive: true,   // Enhanced: include non-interactive elements
        includeTextElements: true,     // 包含文本元素
        includeImageElements: true,    // 包含图像元素
        includeContainers: true,       // 包含容器元素
        maxDepth: 25,                  // Enhanced: use larger scan depth
        minSize: 1,                    // 最小元素尺寸
        enhanced: enhanced,            // Enable enhanced features by default
        includeDeviceInfo: includeDeviceInfo  // Include device info by default
      }
    })
    
    //console.log('[ScreenReader] Requesting enhanced UI analysis, deviceId:', deviceId, 'enhanced:', enhanced, 'includeDeviceInfo:', includeDeviceInfo)
  }, [webSocket, deviceId])

  // 设备特征信息现在集成在UI层次结构请求中，无需单独请求

  // 启动定时刷新
  const startAutoRefresh = useCallback(() => {
    if (autoRefreshIntervalRef.current) {
      clearInterval(autoRefreshIntervalRef.current)
    }
    
    if (autoRefresh && screenReader.enabled) {
      // 立即请求一次
      requestUIHierarchy()
      
      // 设置定时器，使用配置的刷新间隔
      autoRefreshIntervalRef.current = setInterval(() => {
        requestUIHierarchy()
      }, screenReader.refreshInterval * 1000)
    }
  }, [autoRefresh, screenReader.enabled, requestUIHierarchy, screenReader.refreshInterval])

  // 停止定时刷新
  const stopAutoRefresh = useCallback(() => {
    if (autoRefreshIntervalRef.current) {
      clearInterval(autoRefreshIntervalRef.current)
      autoRefreshIntervalRef.current = null
    }
  }, [])

  // 监听UI层次结构响应和设备特征响应
  useEffect(() => {
    if (!webSocket || !deviceId) return

    const handleUIHierarchyResponse = (data: any) => {
      //console.log('[ScreenReader] Received UI hierarchy response:', data)
      setLoading(false)
      if (data.success && data.deviceId === deviceId) {
        setUiHierarchy(data.hierarchy)
        // Clear selected element when UI hierarchy updates to avoid stale info
        setSelectedElement(null)
        
        // Process enhanced analysis result
        if (data.enhanced) {
          /*console.log('[ScreenReader] Received enhanced UI analysis result:', {
            enhanced: data.enhanced,
            keyboardElements: data.hierarchy?.keyboardElements?.length || 0,
            digitButtons: data.hierarchy?.digitButtons?.length || 0,
            keyboardConfidence: data.hierarchy?.keyboardConfidence || 0,
            inputMethodWindows: data.hierarchy?.inputMethodWindows?.length || 0
          })*/
          
          // Save enhanced analysis result
          // setEnhancedAnalysisResult({
          //   keyboardElements: data.hierarchy?.keyboardElements || [],
          //   digitButtons: data.hierarchy?.digitButtons || [],
          //   keyboardConfidence: data.hierarchy?.keyboardConfidence || 0,
          //   inputMethodWindows: data.hierarchy?.inputMethodWindows || [],
          //   timestamp: Date.now()
          // })
          
          // 显示键盘检测结果
          if (data.hierarchy?.keyboardConfidence > 0.5) {
            console.log('[ScreenReader] High confidence virtual keyboard detected, confidence:', data.hierarchy.keyboardConfidence)
          } else {
            console.log('[ScreenReader] Low virtual keyboard detection confidence:', data.hierarchy.keyboardConfidence)
          }
        }
        
        // Process device characteristics
        if (data.deviceCharacteristics) {
          /*console.log('[ScreenReader] Received device characteristics:', {
            romType: data.deviceCharacteristics.romFeatures?.romType,
            inputMethodType: data.deviceCharacteristics.inputMethodInfo?.inputMethodType,
            primaryStrategy: data.deviceCharacteristics.keyboardDetectionStrategy?.primaryStrategy,
            deviceSpecificTips: data.deviceCharacteristics.keyboardDetectionStrategy?.deviceSpecificTips
          })*/
          
          // Save device characteristics
          // setDeviceCharacteristics({
          //   ...data.deviceCharacteristics,
          //   timestamp: Date.now()
          // })
        }
        
        /*console.log('[ScreenReader] UI hierarchy data set:', {
          totalElements: data.hierarchy?.totalElements,
          clickableElements: data.hierarchy?.clickableElements,
          screenSize: `${data.hierarchy?.screenWidth}x${data.hierarchy?.screenHeight}`,
          rootElement: data.hierarchy?.root,
          rootChildren: data.hierarchy?.root?.children?.length || 0
        })*/ 
        
        // 递归统计元素类型
        const elementTypes: { [key: string]: number } = {}
        const countElements = (element: any) => {
          if (element.type) {
            elementTypes[element.type] = (elementTypes[element.type] || 0) + 1
          }
          if (element.children) {
            element.children.forEach(countElements)
          }
        }
        if (data.hierarchy?.root) {
          countElements(data.hierarchy.root)
          //console.log('[ScreenReader] UI element type stats:', elementTypes)
        }
      } else {
        console.error('[ScreenReader] Failed to get UI hierarchy:', data.error || data.message)
      }
    }

    // 设备特征信息现在集成在UI层次结构响应中，无需单独处理

    // Listen for confirm coords extraction event
    const handleStartExtractConfirmCoords = (data: any) => {
      if (data.deviceId === deviceId) {
        console.log('[ScreenReader] Start extracting confirm coords mode:', deviceId)
        setIsExtractingConfirmCoords(true)
      }
    }

    webSocket.on('ui_hierarchy_response', handleUIHierarchyResponse)
    webSocket.on('start_extract_confirm_coords', handleStartExtractConfirmCoords)

    return () => {
      webSocket.off('ui_hierarchy_response', handleUIHierarchyResponse)
      webSocket.off('start_extract_confirm_coords', handleStartExtractConfirmCoords)
    }
  }, [webSocket, deviceId])

  // Listen for virtual keyboard visibility changes
  useEffect(() => {
    if (screenReader.showVirtualKeyboard && uiHierarchy) {
      const keyboard = generateVirtualKeyboard(uiHierarchy.screenWidth, uiHierarchy.screenHeight)
      setVirtualKeyboard(keyboard)
      console.log('[VirtualKeyboard] Virtual keys generated:', keyboard.keys.length, 'keys')
    } else {
      setVirtualKeyboard({ visible: false, keys: [] })
      console.log('[VirtualKeyboard] Virtual keys hidden')
    }
  }, [screenReader.showVirtualKeyboard, uiHierarchy, generateVirtualKeyboard])

  // 初始加载
  useEffect(() => {
    if (screenReader.enabled && webSocket && deviceId) {
      //console.log('[ScreenReader] Enabled, starting auto refresh')
      // 延迟一点时间确保连接稳定
      setTimeout(() => {
        startAutoRefresh()
      }, 500)
    } else {
      console.log('[ScreenReader] Not enabled or connection missing, stopping auto refresh')
      stopAutoRefresh()
    }
    
    // 清理函数
    return () => {
      stopAutoRefresh()
    }
  }, [screenReader.enabled, startAutoRefresh, stopAutoRefresh, webSocket, deviceId])

  // 在画布上绘制UI元素边界
  const drawElementBounds = useCallback(() => {
    if (!canvasRef.current || !uiHierarchy) {
      console.log('[ScreenReader] Canvas or UI hierarchy missing', { canvas: !!canvasRef.current, uiHierarchy: !!uiHierarchy })
      return
    }

    const canvas = canvasRef.current
    const ctx = canvas.getContext('2d')
    if (!ctx) return

    // 获取容器的实际显示尺寸
    const container = canvas.parentElement
    if (!container) return
    
    // const containerRect = container.getBoundingClientRect() // 暂时未使用
    const dpr = window.devicePixelRatio || 1
    
    // Fix: use container clientWidth and clientHeight, excluding borders and scrollbars
    const displayWidth = container.clientWidth
    const displayHeight = container.clientHeight
    
    canvas.width = displayWidth * dpr
    canvas.height = displayHeight * dpr
    canvas.style.width = displayWidth + 'px'
    canvas.style.height = displayHeight + 'px'
    
    // 缩放绘图上下文以匹配设备像素比
    ctx.scale(dpr, dpr)
    
    // 启用高质量渲染
    ctx.imageSmoothingEnabled = true
    ctx.imageSmoothingQuality = 'high'

    /*console.log('[ScreenReader] Start drawing UI bounds', { 
      screenSize: `${uiHierarchy.screenWidth}x${uiHierarchy.screenHeight}`,
      canvasSize: `${canvas.width}x${canvas.height}`,
      displaySize: `${displayWidth}x${displayHeight}`,
      dpr: dpr,
      totalElements: uiHierarchy.totalElements 
    })*/

    // 清除画布并设置白色背景
    ctx.fillStyle = '#ffffff'
    ctx.fillRect(0, 0, displayWidth, displayHeight)

    // 计算缩放比例 - 保持宽高比，合适填充容器
    const scaleX = displayWidth / uiHierarchy.screenWidth
    const scaleY = displayHeight / uiHierarchy.screenHeight
    
    // 使用较小的缩放比例保持宽高比，避免过大显示
    const scale = Math.min(scaleX, scaleY)
    
    // Calculate actual display area and center offset
    // const actualDisplayWidth = uiHierarchy.screenWidth * scale // 暂时未使用
    // const actualDisplayHeight = uiHierarchy.screenHeight * scale // 暂时未使用
    // const offsetX = (displayWidth - actualDisplayWidth) / 2 // 暂时未使用
    // const offsetY = (displayHeight - actualDisplayHeight) / 2 // 暂时未使用
    
    /*console.log('[ScreenReader] Scale debug:', {
      container: { width: displayWidth, height: displayHeight },
      device: { width: uiHierarchy.screenWidth, height: uiHierarchy.screenHeight },
      scaleX, scaleY, 
      selectedScale: scale,
      actualDisplay: { width: actualDisplayWidth, height: actualDisplayHeight },
      offset: { x: offsetX, y: offsetY }
    })*/
    
    // 保存上下文，不预先缩放，在绘制时直接计算坐标
    ctx.save()

    let elementCount = 0

    const drawElement = (element: UIElement, depth: number = 0) => {
      const { bounds } = element
      // Key fix: use unified scale without offset, fill container from top-left
      const x = bounds.left * scale
      const y = bounds.top * scale
      const width = (bounds.right - bounds.left) * scale
      const height = (bounds.bottom - bounds.top) * scale

      elementCount++

      // 调试信息：记录元素详情，特别关注按钮元素和数字键盘区域
      const isInKeypadArea = bounds.top > uiHierarchy.screenHeight * 0.3 && bounds.top < uiHierarchy.screenHeight * 0.9
      const hasDigitText = element.text && /[0-9]/.test(element.text)
      const isZeroButton = element.text === '0' || (element.description && element.description.includes('0')) || (element.resourceId && element.resourceId.toLowerCase().includes('zero'))
      
      // Search for "0" button - expanded search range
      const zeroRelated = 
        element.text === '0' ||
        element.text?.includes('0') ||
        element.description === '0' ||
        element.description?.includes('0') ||
        element.resourceId?.includes('0') ||
        element.resourceId?.toLowerCase().includes('zero') ||
        element.resourceId?.toLowerCase().includes('digit_0') ||
        element.resourceId?.toLowerCase().includes('button_0') ||
        element.type.toLowerCase().includes('0')
      
      if (zeroRelated) {
        /*console.log(`[ScreenReader] Possible "0" button Element ${elementCount}:`, {
          type: element.type,
          text: element.text,
          description: element.description,
          resourceId: element.resourceId,
          bounds: element.bounds,
          actualSize: { width: bounds.right - bounds.left, height: bounds.bottom - bounds.top },
          visible: element.visible,
          clickable: element.clickable,
          enabled: element.enabled,
          children: element.children?.length || 0,
          scaledSize: { width, height },
          flags: {
            isInKeypadArea,
            hasDigitText,
            isZeroButton,
            zeroRelated
          }
        })*/
      }
      
      if (depth === 0 || elementCount <= 50 || element.clickable || element.type.toLowerCase().includes('button') || isInKeypadArea || hasDigitText || isZeroButton || zeroRelated) {
        /*console.log(`[ScreenReader] Element ${elementCount}:`, {
          type: element.type,
          text: element.text,
          description: element.description,
          resourceId: element.resourceId,
          bounds: element.bounds,
          visible: element.visible,
          clickable: element.clickable,
          children: element.children?.length || 0,
          scaledSize: { width, height },
          flags: {
            isInKeypadArea,
            hasDigitText,
            isZeroButton,
            zeroRelated
          }
        })*/
      }

      // 只跳过完全无效的元素
      if (width <= 0 || height <= 0) return

      // 绘制所有元素的边框 - 简化逻辑
      ctx.lineWidth = 1
      ctx.setLineDash([])
      
      // 根据元素属性设置边框颜色
      if (element.clickable) {
        ctx.strokeStyle = '#1890ff'  // 可点击元素用蓝色
      } else if (!element.visible) {
        ctx.strokeStyle = '#ff4d4f'  // 不可见元素用红色
        ctx.setLineDash([2, 2])      // 虚线
      } else {
        ctx.strokeStyle = '#666666'  // 普通元素用灰色
      }
      
      ctx.strokeRect(x, y, width, height)

      // 绘制所有元素的文字标签 - 跳过FrameLayout和ViewGroup类型的元素
      if (width > 2 && height > 2) {
        // 检查是否为FrameLayout或ViewGroup，如果是则跳过文字绘制
        const typeParts = element.type.split('.')
        const elementTypeName = typeParts[typeParts.length - 1] || 'Element'
        
        // 跳过基本的布局容器类型，保留其他元素的文字显示
        if (elementTypeName === 'FrameLayout' ||elementTypeName === 'ImageView' || elementTypeName === 'ListView' || elementTypeName === 'ViewGroup' || elementTypeName === 'LinearLayout' || elementTypeName === 'RelativeLayout' || elementTypeName === 'ScreenView' || elementTypeName === 'View' || elementTypeName === 'ViewAnimator'|| elementTypeName === 'RecyclerView' || elementTypeName === 'ScrollView') {
          // 基本布局容器不显示文字，只显示边框
        } else {
          let displayText = ''
          
          // 获取显示文本
          if (element.text && element.text.trim()) {
            displayText = element.text.trim()
          } else if (element.description && element.description.trim()) {
            displayText = element.description.trim()
          } else if (element.resourceId) {
            // 显示resourceId的最后一部分
            const parts = element.resourceId.split('/')
            displayText = parts[parts.length - 1] || element.resourceId
          } else {
            // 显示元素类型的简化名称
            displayText = elementTypeName
          }

          // 确保有显示内容
          if (!displayText) {
            displayText = 'UI'
          }

          // Optimize font size calculation - increase for readability
          const fontSize = Math.max(8, Math.min(width * 0.15, height * 0.35, 24))
          
          // 设置文字样式
          ctx.font = `bold ${fontSize}px -apple-system, BlinkMacSystemFont, 'Segoe UI', 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', sans-serif`
          ctx.textAlign = 'center'
          ctx.textBaseline = 'middle'
          
          // Optimize: multiline text drawing
          drawMultilineText(ctx, displayText, x + width / 2, y + height / 2, width - 4, height - 4, fontSize)
        }
      }

      // 高亮选中元素
      if (selectedElement && selectedElement.id === element.id) {
        ctx.strokeStyle = '#ff4d4f'
        ctx.lineWidth = 2
        ctx.setLineDash([])
        ctx.strokeRect(x - 1, y - 1, width + 2, height + 2)
        
        // 添加半透明背景
        ctx.fillStyle = 'rgba(255, 77, 79, 0.1)'
        ctx.fillRect(x, y, width, height)
      }

      // 递归绘制子元素
      if (element.children && element.children.length > 0) {
        element.children.forEach(child => drawElement(child, depth + 1))
      }
    }

    // Multiline text drawing function
    function drawMultilineText(
      ctx: CanvasRenderingContext2D, 
      text: string, 
      x: number, 
      y: number, 
      maxWidth: number, 
      maxHeight: number, 
      fontSize: number
    ) {
      if (!text || maxWidth <= 0 || maxHeight <= 0) return
      
      // 计算行高
      const lineHeight = fontSize * 1.2
      const maxLines = Math.floor(maxHeight / lineHeight)
      
      if (maxLines < 1) return
      
      // 分割文本为单词（支持中英文）
      const words = text.match(/[\u4e00-\u9fa5]|[a-zA-Z0-9]+|[^\u4e00-\u9fa5a-zA-Z0-9\s]+/g) || [text]
      
      const lines: string[] = []
      let currentLine = ''
      
      for (const word of words) {
        const testLine = currentLine + word
        const metrics = ctx.measureText(testLine)
        
        if (metrics.width > maxWidth && currentLine) {
          // 当前行太长，换行
          lines.push(currentLine)
          currentLine = word
          
          // 检查是否超过最大行数
          if (lines.length >= maxLines) {
            break
          }
        } else {
          currentLine = testLine
        }
      }
      
      // 添加最后一行
      if (currentLine && lines.length < maxLines) {
        lines.push(currentLine)
      }
      
      // 如果文本被截断，在最后一行添加省略号
      if (lines.length === maxLines && words.length > lines.join('').length) {
        const lastLine = lines[lines.length - 1]
        // const ellipsisWidth = ctx.measureText('…').width // 暂时未使用
        
        // 缩短最后一行以容纳省略号
        let truncatedLine = lastLine
        while (truncatedLine.length > 0 && ctx.measureText(truncatedLine + '…').width > maxWidth) {
          truncatedLine = truncatedLine.slice(0, -1)
        }
        lines[lines.length - 1] = truncatedLine + '…'
      }
      
      // 计算起始Y坐标以垂直居中
      const totalHeight = lines.length * lineHeight
      const startY = y - totalHeight / 2 + lineHeight / 2
      
      // 绘制每一行
      lines.forEach((line, index) => {
        const lineY = startY + index * lineHeight
        
        // Fix ghost text: remove shadow, only draw clear main text
        ctx.fillStyle = '#ff1744'
        ctx.fillText(line, x, lineY)
      })
    }

    // 辅助函数：绘制圆角矩形（暂时未使用）
    // function roundRect(ctx: CanvasRenderingContext2D, x: number, y: number, width: number, height: number, radius: number) {
    //   ctx.beginPath()
    //   ctx.moveTo(x + radius, y)
    //   ctx.lineTo(x + width - radius, y)
    //   ctx.quadraticCurveTo(x + width, y, x + width, y + radius)
    //   ctx.lineTo(x + width, y + height - radius)
    //   ctx.quadraticCurveTo(x + width, y + height, x + width - radius, y + height)
    //   ctx.lineTo(x + radius, y + height)
    //   ctx.quadraticCurveTo(x, y + height, x, y + height - radius)
    //   ctx.lineTo(x, y + radius)
    //   ctx.quadraticCurveTo(x, y, x + radius, y)
    //   ctx.closePath()
    // }

    // 辅助函数：根据应用名称获取图标颜色（暂时未使用）
    // function getIconColor(appName: string): string {
    //   const colors = [
    //     '#f44336', '#e91e63', '#9c27b0', '#673ab7', '#3f51b5',
    //     '#2196f3', '#03a9f4', '#00bcd4', '#009688', '#4caf50',
    //     '#8bc34a', '#cddc39', '#ffeb3b', '#ffc107', '#ff9800',
    //     '#ff5722', '#795548', '#9e9e9e', '#607d8b'
    //   ]
    //   
    //   // 根据应用名称生成一致的颜色
    //   let hash = 0
    //   for (let i = 0; i < appName.length; i++) {
    //     hash = appName.charCodeAt(i) + ((hash << 5) - hash)
    //   }
    //   return colors[Math.abs(hash) % colors.length]
    // }

    // Draw virtual keyboard (click-through version)
    function drawVirtualKeyboard(ctx: CanvasRenderingContext2D, scale: number) {
      if (!virtualKeyboard.visible || virtualKeyboard.keys.length === 0) return
      
      console.log('[VirtualKeyboard] Drawing virtual keys:', virtualKeyboard.keys.length, 'keys')
      
      virtualKeyboard.keys.forEach(key => {
        // 计算按键在画布上的位置
        const x = key.x * scale
        const y = key.y * scale
        const width = key.width * scale
        const height = key.height * scale
        
        // Do not draw background, only draw border and text for click-through
        // 绘制按键边框（虚线样式，更明显）
        ctx.strokeStyle = '#1890ff'
        ctx.lineWidth = 3
        ctx.setLineDash([8, 4]) // 虚线样式
        ctx.strokeRect(x, y, width, height)
        ctx.setLineDash([]) // 重置为实线
        
        // 绘制按键文字（带背景的文字，确保可见性）
        const fontSize = Math.max(12, Math.min(width * 0.25, height * 0.35, 18))
        ctx.font = `bold ${fontSize}px -apple-system, BlinkMacSystemFont, sans-serif`
        ctx.textAlign = 'center'
        ctx.textBaseline = 'middle'
        
        // 为文字添加半透明背景，确保在复杂背景下可见
        const textX = x + width / 2
        const textY = y + height / 2
        const textMetrics = ctx.measureText(key.text)
        const textWidth = textMetrics.width
        const textHeight = fontSize * 1.2
        
        // 绘制文字背景
        ctx.fillStyle = 'rgba(255, 255, 255, 0.8)'
        ctx.fillRect(
          textX - textWidth / 2 - 4, 
          textY - textHeight / 2 - 2, 
          textWidth + 8, 
          textHeight + 4
        )
        
        // 绘制文字
        ctx.fillStyle = '#1890ff'
        ctx.fillText(key.text, textX, textY)
        
        // 如果是删除键，添加特殊边框样式
        if (key.id === 'key_delete') {
          ctx.strokeStyle = '#ff4d4f'
          ctx.lineWidth = 2
          ctx.setLineDash([4, 2])
          ctx.strokeRect(x + 2, y + 2, width - 4, height - 4)
          ctx.setLineDash([])
        }
      })
    }

    // 辅助函数：根据应用名称获取图标符号（暂时未使用）
    // function getIconSymbol(appName: string): string {
    //   const name = appName.toLowerCase()
    //   
    //   // 常见应用的图标符号
    //   const iconMap: { [key: string]: string } = {
    //     'youtube': '>',
    //     'settings': 'S',
    //     'photos': 'P',
    //     'gmail': 'M',
    //     'camera': 'C',
    //     'chrome': 'W',
    //     'calendar': 'D',
    //     'contacts': 'U',
    //     'phone': 'T',
    //     'messages': 'X',
    //     'maps': 'N',
    //     'drive': 'V',
    //     'files': 'F',
    //     'clock': 'K',
    //     'google': 'G',
    //     'android': 'A'
    //   }
    //   
    //   // 查找匹配的图标
    //   for (const [key, symbol] of Object.entries(iconMap)) {
    //     if (name.includes(key)) {
    //       return symbol
    //     }
    //   }
    //   
    //   // 默认使用首字母
    //   return appName.charAt(0).toUpperCase()
    // }

    // 辅助函数：判断是否为应用图标容器（暂时未使用）
    // function isAppIconContainer(element: UIElement): boolean {
    //   return !!(element.children && element.children.some(child => 
    //     child.type === 'ImageView' || (child.children && child.children.some(grandChild => grandChild.type === 'ImageView'))
    //   ))
    // }

    drawElement(uiHierarchy.root)
    
    // Draw virtual keyboard
    if (virtualKeyboard.visible && virtualKeyboard.keys.length > 0) {
      drawVirtualKeyboard(ctx, scale)
    }
    
    // 恢复上下文
    ctx.restore()
    
    /*console.log('[ScreenReader] Drawing complete', { 
      processedElements: elementCount,
      totalElements: uiHierarchy.totalElements,
      clickableElements: uiHierarchy.clickableElements,
      screenSize: `${uiHierarchy.screenWidth}x${uiHierarchy.screenHeight}`,
      canvasSize: `${displayWidth}x${displayHeight}`,
      scale: scale,
      rootElement: uiHierarchy.root 
    })*/

    // 如果没有绘制任何内容，显示调试信息
    if (elementCount === 0) {
      ctx.fillStyle = '#666666'
      ctx.font = '16px -apple-system, BlinkMacSystemFont, sans-serif'
      ctx.textAlign = 'center'
      ctx.textBaseline = 'middle'
      ctx.fillText('[No UI Data]', displayWidth / 2, displayHeight / 2)
      ctx.font = '14px -apple-system, BlinkMacSystemFont, sans-serif'
      ctx.fillText('点击右上角刷新按钮获取UI结构', displayWidth / 2, displayHeight / 2 + 30)
    }
  }, [uiHierarchy, selectedElement, screenReader.highlightClickable, virtualKeyboard])

  // 监听容器尺寸变化并重新绘制
  useEffect(() => {
    if (!canvasRef.current) return

    const canvas = canvasRef.current
    const container = canvas.parentElement
    if (!container) return
    
    const resizeObserver = new ResizeObserver(() => {
      // 容器尺寸变化时只需要重新绘制，画布内在尺寸保持为设备尺寸
      if (uiHierarchy) {
        drawElementBounds()
      }
    })

    resizeObserver.observe(container)

    return () => resizeObserver.disconnect()
  }, [drawElementBounds, uiHierarchy])

  // 绘制UI边界
  useEffect(() => {
      drawElementBounds()
  }, [drawElementBounds])

  // Fix coordinate conversion function (fully match drawing logic)
  const convertCanvasToDeviceCoords = useCallback((canvasX: number, canvasY: number, forceDebug: boolean = false) => {
    if (!canvasRef.current || !uiHierarchy) return null

    const canvas = canvasRef.current
    const container = canvas.parentElement
    if (!container) return null
    
    const containerRect = container.getBoundingClientRect()
    const deviceWidth = uiHierarchy.screenWidth
    const deviceHeight = uiHierarchy.screenHeight
    
    // Key fix: coordinate calculation fully matching drawing logic
    // 绘制时使用的是容器的显示尺寸，不是canvas的物理尺寸
    const displayWidth = containerRect.width
    const displayHeight = containerRect.height
    
    // 计算缩放比例 - 与绘制时完全一致
    const scaleX = displayWidth / deviceWidth
    const scaleY = displayHeight / deviceHeight
    const scale = Math.min(scaleX, scaleY)
    
    // Direct coordinate conversion, fully matching drawing logic
    // 绘制时：x = bounds.left * scale, y = bounds.top * scale
    // 转换时：deviceX = canvasX / scale, deviceY = canvasY / scale
    const deviceX = canvasX / scale
    const deviceY = canvasY / scale
    
    // 确保坐标在设备范围内，移除-1限制以支持完整范围
    const clampedX = Math.max(0, Math.min(deviceWidth, deviceX))
    const clampedY = Math.max(0, Math.min(deviceHeight, deviceY))
    
    // In debug mode or when coords are adjusted, show debug info
    if (forceDebug || Math.abs(deviceX - clampedX) > 1 || Math.abs(deviceY - clampedY) > 1) {
      console.log('[ScreenReader] Coordinate conversion:', {
        canvas: { x: canvasX, y: canvasY },
        container: { width: displayWidth, height: displayHeight },
        device: { width: deviceWidth, height: deviceHeight },
        scale,
        converted: { x: deviceX, y: deviceY },
        final: { x: clampedX, y: clampedY }
      })
    }
    
    return { x: clampedX, y: clampedY }
  }, [uiHierarchy])

  // Show touch indicator
  const showTouchIndicator = (x: number, y: number) => {
    const indicator = document.createElement('div')
    indicator.style.position = 'absolute'
    indicator.style.left = `${x - 10}px`
    indicator.style.top = `${y - 10}px`
    indicator.style.width = '20px'
    indicator.style.height = '20px'
    indicator.style.borderRadius = '50%'
    indicator.style.backgroundColor = 'rgba(24, 144, 255, 0.6)'
    indicator.style.border = '2px solid #1890ff'
    indicator.style.pointerEvents = 'none'
    indicator.style.zIndex = '1000'

    const container = canvasRef.current?.parentElement
    if (container) {
      container.style.position = 'relative'
      container.appendChild(indicator)

      setTimeout(() => {
        if (container.contains(indicator)) {
          container.removeChild(indicator)
        }
      }, 500)
    }
  }

  // Show swipe indicator
  const showSwipeIndicator = (startX: number, startY: number, endX: number, endY: number) => {
    const container = canvasRef.current?.parentElement
    if (!container) return

    // 创建滑动轨迹线
    const line = document.createElement('div')
    const length = Math.sqrt(Math.pow(endX - startX, 2) + Math.pow(endY - startY, 2))
    const angle = Math.atan2(endY - startY, endX - startX) * 180 / Math.PI

    line.style.position = 'absolute'
    line.style.left = `${startX}px`
    line.style.top = `${startY}px`
    line.style.width = `${length}px`
    line.style.height = '2px'
    line.style.backgroundColor = '#ff4d4f'
    line.style.transformOrigin = '0 50%'
    line.style.transform = `rotate(${angle}deg)`
    line.style.pointerEvents = 'none'
    line.style.zIndex = '1000'

    // 创建箭头
    const arrow = document.createElement('div')
    arrow.style.position = 'absolute'
    arrow.style.left = `${endX - 5}px`
    arrow.style.top = `${endY - 5}px`
    arrow.style.width = '10px'
    arrow.style.height = '10px'
    arrow.style.backgroundColor = '#ff4d4f'
    arrow.style.transform = 'rotate(45deg)'
    arrow.style.pointerEvents = 'none'
    arrow.style.zIndex = '1000'

    container.style.position = 'relative'
    container.appendChild(line)
    container.appendChild(arrow)

    setTimeout(() => {
      if (container.contains(line)) container.removeChild(line)
      if (container.contains(arrow)) container.removeChild(arrow)
    }, 800)
  }

  const showLongPressIndicator = (x: number, y: number) => {
    const indicator = document.createElement('div')
    indicator.style.position = 'absolute'
    indicator.style.left = `${x - 15}px`
    indicator.style.top = `${y - 15}px`
    indicator.style.width = '30px'
    indicator.style.height = '30px'
    indicator.style.borderRadius = '50%'
    indicator.style.backgroundColor = 'rgba(255, 77, 79, 0.6)'
    indicator.style.border = '3px solid #ff4d4f'
    indicator.style.pointerEvents = 'none'
    indicator.style.zIndex = '1000'
    indicator.style.animation = 'pulse 1s infinite'

    const container = canvasRef.current?.parentElement
    if (container) {
      container.style.position = 'relative'
      container.appendChild(indicator)

      setTimeout(() => {
        if (container.contains(indicator)) {
          container.removeChild(indicator)
        }
      }, 1000)
    }
  }

  // Find element at click position
  const findElementAtPoint = useCallback((deviceX: number, deviceY: number): UIElement | null => {
    if (!uiHierarchy) return null

    const findElement = (element: UIElement): UIElement | null => {
      const { bounds } = element
      if (deviceX >= bounds.left && deviceX <= bounds.right &&
          deviceY >= bounds.top && deviceY <= bounds.bottom) {
        
        // 先检查子元素
        if (element.children) {
          for (const child of element.children) {
            const found = findElement(child)
            if (found) return found
          }
        }
        
        // 如果没有子元素匹配，返回当前元素
        return element
      }
      return null
    }

    return findElement(uiHierarchy.root)
  }, [uiHierarchy])

  // Find virtual key at click position
  const findVirtualKeyAtPoint = useCallback((deviceX: number, deviceY: number) => {
    if (!virtualKeyboard.visible || virtualKeyboard.keys.length === 0) return null
    
    return virtualKeyboard.keys.find(key => 
      deviceX >= key.x && deviceX <= key.x + key.width &&
      deviceY >= key.y && deviceY <= key.y + key.height
    )
  }, [virtualKeyboard])

  // Perform click action
  const performClick = useCallback((canvasX: number, canvasY: number) => {
    if (!webSocket || !deviceId) return

    // In extract mode, enable debug info
    const deviceCoords = convertCanvasToDeviceCoords(canvasX, canvasY, isExtractingConfirmCoords)
    if (!deviceCoords) {
      console.warn('[ScreenReader] Click outside device screen area')
      return
    }

    console.log('[ScreenReader] Screen reader click:', { 
      canvas: { x: canvasX, y: canvasY },
      device: { 
        original: { x: deviceCoords.x, y: deviceCoords.y },
        rounded: { x: Math.round(deviceCoords.x), y: Math.round(deviceCoords.y) }
      },
      screenSize: uiHierarchy ? { width: uiHierarchy.screenWidth, height: uiHierarchy.screenHeight } : null,
      extractingMode: isExtractingConfirmCoords
    })

    // If in confirm coords extraction mode
    if (isExtractingConfirmCoords) {
      // Fix: use same coordinate precision as normal click
      const coords = { x: deviceCoords.x, y: deviceCoords.y }
      // setExtractedCoords(coords)
      
      // 保存到服务器
      webSocket.emit('client_event', {
        type: 'SAVE_CONFIRM_COORDS',
        data: { deviceId, coords },
        timestamp: Date.now()
      })
      
      // 显示特殊指示器
      showTouchIndicator(canvasX, canvasY)
      
      console.log('[ScreenReader] Confirm coords extracted:', coords)
      
      // 自动退出提取模式
      setTimeout(() => {
        setIsExtractingConfirmCoords(false)
      }, 1000)
      
      return // 提取模式下不执行实际点击
    }

    // Check if virtual key was clicked (priority detection)
    const clickedVirtualKey = findVirtualKeyAtPoint(deviceCoords.x, deviceCoords.y)
    if (clickedVirtualKey) {
      console.log('[VirtualKeyboard] Clicked virtual key:', clickedVirtualKey.text)
      
      // 发送按键事件到设备
      if (clickedVirtualKey.id === 'key_delete') {
        // 删除键
        webSocket.emit('control_message', {
          type: 'KEY_EVENT',
          deviceId,
          data: { keyCode: 67 }, // KEYCODE_DEL
          timestamp: Date.now()
        })
      } else {
        // 数字键
        const digit = parseInt(clickedVirtualKey.text)
        if (!isNaN(digit)) {
          webSocket.emit('control_message', {
            type: 'KEY_EVENT',
            deviceId,
            data: { keyCode: 7 + digit }, // KEYCODE_0 = 7, KEYCODE_1 = 8, etc.
            timestamp: Date.now()
          })
        }
      }
      
      // Continue sending click event to device (don't return, let click event continue)
      console.log('[VirtualKeyboard] Virtual key click, also sending click event to device')
    }
    
    // If virtual keyboard visible but click is not on a key, check if in keyboard area
    if (virtualKeyboard.visible && virtualKeyboard.keys.length > 0) {
      // 检查点击位置是否在键盘的总体区域内（包括按键间隙）
      const keyboardArea = {
        left: Math.min(...virtualKeyboard.keys.map(k => k.x)),
        right: Math.max(...virtualKeyboard.keys.map(k => k.x + k.width)),
        top: Math.min(...virtualKeyboard.keys.map(k => k.y)),
        bottom: Math.max(...virtualKeyboard.keys.map(k => k.y + k.height))
      }
      
      const isInKeyboardArea = deviceCoords.x >= keyboardArea.left && 
                              deviceCoords.x <= keyboardArea.right &&
                              deviceCoords.y >= keyboardArea.top && 
                              deviceCoords.y <= keyboardArea.bottom
      
      // 如果在键盘区域内但不在具体按键上，则穿透到下方元素
      if (isInKeyboardArea) {
        console.log('[VirtualKeyboard] Click on keyboard gap, passing through to element below')
        // 继续执行下方的正常点击逻辑
      }
    }

    // 正常点击模式：发送点击事件到设备
    webSocket.emit('control_message', {
      type: 'CLICK',
      deviceId,
      data: { x: deviceCoords.x, y: deviceCoords.y },
      timestamp: Date.now()
    })

    // 显示触摸指示器
    showTouchIndicator(canvasX, canvasY)

    // Optimize: update selected element for info display, avoid duplicate selection
    const clickedElement = findElementAtPoint(deviceCoords.x, deviceCoords.y)
    if (clickedElement) {
      // 只有当选中的元素发生变化时才更新
      if (!selectedElement || selectedElement.id !== clickedElement.id) {
        setSelectedElement(clickedElement)
        console.log('[ScreenReader] Selected new element:', clickedElement.text || clickedElement.type)
      }
    } else {
      // Clear selected element when clicking blank area
      if (selectedElement) {
        setSelectedElement(null)
        console.log('[ScreenReader] Clicked blank area, cleared selection')
      }
    }
  }, [webSocket, deviceId, convertCanvasToDeviceCoords, findElementAtPoint, findVirtualKeyAtPoint, isExtractingConfirmCoords, selectedElement])

  // Handle long press action
  const performLongPress = useCallback((canvasX: number, canvasY: number) => {
    if (!webSocket || !deviceId) return

    // In extract mode, enable debug info
    const deviceCoords = convertCanvasToDeviceCoords(canvasX, canvasY, isExtractingConfirmCoords)
    if (!deviceCoords) {
      console.warn('[ScreenReader] Long press outside device screen area')
      return
    }

    console.log('[ScreenReader] Screen reader long press:', { 
      canvas: { x: canvasX, y: canvasY },
      device: { 
        original: { x: deviceCoords.x, y: deviceCoords.y },
        rounded: { x: Math.round(deviceCoords.x), y: Math.round(deviceCoords.y) }
      },
      screenSize: uiHierarchy ? { width: uiHierarchy.screenWidth, height: uiHierarchy.screenHeight } : null,
      extractingMode: isExtractingConfirmCoords
    })

    // If in confirm coords extraction mode, long press also counts as extraction
    if (isExtractingConfirmCoords) {
      const coords = { x: deviceCoords.x, y: deviceCoords.y }
      // setExtractedCoords(coords)
      
      // 保存到服务器
      webSocket.emit('client_event', {
        type: 'SAVE_CONFIRM_COORDS',
        data: { deviceId, coords },
        timestamp: Date.now()
      })
      
      // 显示特殊指示器
      showLongPressIndicator(canvasX, canvasY)
      
      console.log('[ScreenReader] Long press extracted confirm coords:', coords)
      
      // 自动退出提取模式
      setTimeout(() => {
        setIsExtractingConfirmCoords(false)
      }, 1000)
      
      return // 提取模式下不执行实际长按
    }

    // Check if virtual key was long pressed (priority detection)
    const longPressedVirtualKey = findVirtualKeyAtPoint(deviceCoords.x, deviceCoords.y)
    if (longPressedVirtualKey) {
      console.log('[VirtualKeyboard] Long pressed virtual key:', longPressedVirtualKey.text)
      
      // 虚拟按键长按处理（可以用于特殊功能，比如连续输入）
      if (longPressedVirtualKey.id === 'key_delete') {
        // 长按删除键可以清空输入
        webSocket.emit('control_message', {
          type: 'KEY_EVENT',
          deviceId,
          data: { keyCode: 67 }, // KEYCODE_DEL
          timestamp: Date.now()
        })
      }
      
      // Continue sending long press event to device (don't return, let long press event continue)
      console.log('[VirtualKeyboard] Virtual key long press, also sending long press event to device')
    }
    
    // If virtual keyboard visible but long press is not on a key, check if in keyboard area
    if (virtualKeyboard.visible && virtualKeyboard.keys.length > 0) {
      // 检查长按位置是否在键盘的总体区域内（包括按键间隙）
      const keyboardArea = {
        left: Math.min(...virtualKeyboard.keys.map(k => k.x)),
        right: Math.max(...virtualKeyboard.keys.map(k => k.x + k.width)),
        top: Math.min(...virtualKeyboard.keys.map(k => k.y)),
        bottom: Math.max(...virtualKeyboard.keys.map(k => k.y + k.height))
      }
      
      const isInKeyboardArea = deviceCoords.x >= keyboardArea.left && 
                              deviceCoords.x <= keyboardArea.right &&
                              deviceCoords.y >= keyboardArea.top && 
                              deviceCoords.y <= keyboardArea.bottom
      
      // 如果在键盘区域内但不在具体按键上，则穿透到下方元素
      if (isInKeyboardArea) {
        console.log('[VirtualKeyboard] Long press on keyboard gap, passing through to element below')
        // 继续执行下方的正常长按逻辑
      }
    }

    // 正常长按模式：发送长按事件到设备
    webSocket.emit('control_message', {
      type: 'LONG_PRESS',
      deviceId,
      data: { x: deviceCoords.x, y: deviceCoords.y },
      timestamp: Date.now()
    })

    // 显示长按指示器
    showLongPressIndicator(canvasX, canvasY)

    // Update selected element for info display
    const clickedElement = findElementAtPoint(deviceCoords.x, deviceCoords.y)
    if (clickedElement) {
      // 只有当选中的元素发生变化时才更新
      if (!selectedElement || selectedElement.id !== clickedElement.id) {
        setSelectedElement(clickedElement)
        console.log('[ScreenReader] Long press selected new element:', clickedElement.text || clickedElement.type)
      }
    } else {
      // Clear selected element when long pressing blank area
      if (selectedElement) {
        setSelectedElement(null)
        console.log('[ScreenReader] Long press blank area, cleared selection')
      }
    }
  }, [webSocket, deviceId, convertCanvasToDeviceCoords, findElementAtPoint, findVirtualKeyAtPoint, isExtractingConfirmCoords, selectedElement, uiHierarchy])

  // Mouse down handler
  const handleMouseDown = useCallback((event: React.MouseEvent) => {
    event.preventDefault()
    setIsDragging(true)
    
    const canvas = canvasRef.current
    if (!canvas) return
    
    const rect = canvas.getBoundingClientRect()
    const startX = event.clientX - rect.left
    const startY = event.clientY - rect.top
    
    setDragStart({ x: startX, y: startY })
    
    // Start long press timer
    setIsLongPressTriggered(false)
    longPressTimerRef.current = window.setTimeout(() => {
      setIsLongPressTriggered(true)
      performLongPress(startX, startY)
    }, 500) // 500ms 后触发长按
  }, [performLongPress])

  // Mouse move handler
  const handleMouseMove = useCallback((event: React.MouseEvent) => {
    if (!isDragging || !dragStart) return
    
    event.preventDefault()
  }, [isDragging, dragStart])

  // Mouse up handler
  const handleMouseUp = useCallback((event: React.MouseEvent) => {
    if (!isDragging || !dragStart) return
    
    event.preventDefault()
    setIsDragging(false)
    
    // Clean up long press timer
    if (longPressTimerRef.current) {
      clearTimeout(longPressTimerRef.current)
      longPressTimerRef.current = null
    }
    
    // If long press already triggered, clean up state, don't execute click or swipe
    if (isLongPressTriggered) {
      setDragStart(null)
      setIsLongPressTriggered(false)
      return
    }
    
    const canvas = canvasRef.current
    if (!canvas || !webSocket || !deviceId) return
    
    const rect = canvas.getBoundingClientRect()
    const endX = event.clientX - rect.left
    const endY = event.clientY - rect.top
    
    // 计算移动距离
    const deltaX = Math.abs(endX - dragStart.x)
    const deltaY = Math.abs(endY - dragStart.y)
    const threshold = 10 // 10像素阈值，避免误触
    
    if (deltaX < threshold && deltaY < threshold) {
      // 小距离移动，当作点击处理
      performClick(endX, endY)
    } else {
      // 大距离移动，当作滑动处理
      const startCoords = convertCanvasToDeviceCoords(dragStart.x, dragStart.y)
      const endCoords = convertCanvasToDeviceCoords(endX, endY)
      
      if (!startCoords || !endCoords) {
        console.warn('[ScreenReader] Swipe coordinate conversion failed, swipe may be outside screen area')
        return
      }

      console.log('[ScreenReader] Screen reader swipe:', { 
        start: { canvas: dragStart, device: startCoords },
        end: { canvas: { x: endX, y: endY }, device: endCoords }
      })

      // 发送滑动事件到设备
      webSocket.emit('control_message', {
        type: 'SWIPE',
        deviceId,
        data: { 
          startX: startCoords.x,
          startY: startCoords.y,
          endX: endCoords.x,
          endY: endCoords.y,
          duration: 300
        },
        timestamp: Date.now()
      })

      // 显示滑动指示器
      showSwipeIndicator(dragStart.x, dragStart.y, endX, endY)
    }
    
    setDragStart(null)
  }, [isDragging, dragStart, webSocket, deviceId, convertCanvasToDeviceCoords, performClick, isLongPressTriggered])
  
  // Mouse leave handler
  const handleMouseLeave = useCallback(() => {
    setIsDragging(false)
    setDragStart(null)
    
    // Clean up long press timer and state
    if (longPressTimerRef.current) {
      clearTimeout(longPressTimerRef.current)
      longPressTimerRef.current = null
    }
    setIsLongPressTriggered(false)
  }, [])

  // Removed handleElementClick to avoid duplicate clicks

  // 当UI层次结构或选中元素变化时重新绘制
  useEffect(() => {
    drawElementBounds()
  }, [drawElementBounds])

  // 如果屏幕阅读器未启用，显示提示信息
  if (!screenReader.enabled) {
    return (
      <div style={{
        display: 'flex',
        alignItems: 'center',
        justifyContent: 'center',
        height: '100%',
        color: '#666',
        flexDirection: 'column',
        gap: '16px',
        padding: '20px',
        textAlign: 'center'
      }}>
        <div style={{ fontSize: '48px' }}>[ ]</div>
        <div style={{ fontSize: '16px', fontWeight: 'bold' }}>
          屏幕阅读器未启用
        </div>
        <div style={{ lineHeight: '1.5' }}>请在控制面板中启用屏幕阅读器</div>
        <div style={{ fontSize: '12px', color: '#999' }}>
          启用后将显示设备的UI结构图
        </div>
      </div>
    )
  }

    return (
    <div style={{ position: 'relative', height: maxHeight ? `${maxHeight}px` : '100%', width: '100%' }}>
      <canvas
        ref={canvasRef}
        onMouseDown={handleMouseDown}
        onMouseUp={handleMouseUp}
        onMouseMove={handleMouseMove}
        onMouseLeave={handleMouseLeave}
        onContextMenu={(e) => e.preventDefault()}
        style={{
          width: '100%',
          height: '100%',
          maxWidth: '100%',
          maxHeight: '100%',
          cursor: 'crosshair',
          display: 'block',
          background: '#ffffff',
          imageRendering: 'auto',
          margin: 0,
          padding: 0
        }}
      />
    </div>
  )
}

export default ScreenReader 