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

/** 画质档位（参考billd-desk的参数化控制） */
const QUALITY_PROFILES = [
  { key: 'low', label: '低画质', fps: 5, quality: 30, resolution: '360P' },
  { key: 'medium', label: '中画质', fps: 10, quality: 45, resolution: '480P' },
  { key: 'high', label: '高画质', fps: 15, quality: 60, resolution: '720P' },
  { key: 'ultra', label: '超高画质', fps: 20, quality: 75, resolution: '1080P' },
]

interface DeviceScreenProps {
  deviceId: string
  onScreenSizeChange?: (size: { width: number, height: number }) => void
}

/**
 * 设备屏幕显示组件
 */
const DeviceScreen: React.FC<DeviceScreenProps> = ({ deviceId, onScreenSizeChange }) => {
  // const dispatch = useDispatch<AppDispatch>()
  const canvasRef = useRef<HTMLCanvasElement>(null)
  const fullscreenContainerRef = useRef<HTMLDivElement>(null)
  const [isLoading, setIsLoading] = useState(true)
  const [imageSize, setImageSize] = useState<{ width: number, height: number } | null>(null)
  const [isFullscreen, setIsFullscreen] = useState(false)
  
  // ✅ FPS 计算：使用滑动窗口统计真实帧率
  const fpsFrameTimesRef = useRef<number[]>([])
  const [displayFps, setDisplayFps] = useState(0)
  const lastFpsUpdateRef = useRef(0)
  
  // ✅ 帧渲染控制：只保留最新帧，用 rAF 驱动渲染
  const latestFrameRef = useRef<any>(null)
  const rafIdRef = useRef<number>(0)
  const isRenderingRef = useRef(false)
  const imageSizeRef = useRef<{ width: number, height: number } | null>(null)
  
  // canvas锁定尺寸：首次有效帧确定canvas尺寸后不再变化，
  // 避免不同采集模式(MediaProjection/无障碍截图)帧尺寸不一致导致闪烁
  const lockedCanvasSizeRef = useRef<{ width: number, height: number } | null>(null)
  
  // ✅ 添加控制权状态跟踪，避免重复申请
  const [isControlRequested, setIsControlRequested] = useState(false)
  const [currentWebSocket, setCurrentWebSocket] = useState<any>(null)
  const [lastControlRequestTime, setLastControlRequestTime] = useState<number>(0)
  
  const { webSocket } = useSelector((state: RootState) => state.connection)
  const { connectedDevices } = useSelector((state: RootState) => state.devices)
  const { screenDisplay, operationEnabled } = useSelector((state: RootState) => state.ui)

  const device = connectedDevices.find(d => d.id === deviceId)

  // 📊 画质控制状态
  const [currentProfile, setCurrentProfile] = useState('medium')
  const [showQualityPanel, setShowQualityPanel] = useState(false)
  const [networkStats, setNetworkStats] = useState({ fps: 0, dropRate: 0, avgFrameSize: 0 })
  const frameCountRef = useRef(0)
  const droppedFrameCountRef = useRef(0)
  const feedbackTimerRef = useRef<number>(0)
  const lastFeedbackTimeRef = useRef(0)

  // ✅ 安全地通知父组件屏幕尺寸变化（在 useEffect 中而非渲染期间）
  useEffect(() => {
    if (imageSize && onScreenSizeChange) {
      onScreenSizeChange(imageSize)
    }
  }, [imageSize, onScreenSizeChange])

  // 📊 画质反馈：定期向服务端报告网络质量
  useEffect(() => {
    if (!webSocket || !deviceId) return

    const sendFeedback = () => {
      const now = Date.now()
      if (now - lastFeedbackTimeRef.current < 3000) return // 3秒发一次
      lastFeedbackTimeRef.current = now

      const totalFrames = frameCountRef.current
      const droppedFrames = droppedFrameCountRef.current
      const dropRate = totalFrames > 0 ? droppedFrames / totalFrames : 0
      const fps = displayFps

      webSocket.emit('quality_feedback', {
        deviceId,
        fps,
        dropRate,
      })

      setNetworkStats({ fps, dropRate, avgFrameSize: 0 })

      // 重置计数
      frameCountRef.current = 0
      droppedFrameCountRef.current = 0
    }

    feedbackTimerRef.current = window.setInterval(sendFeedback, 3000)

    // 监听服务端画质变更通知
    const handleQualityChanged = (data: any) => {
      if (data.deviceId === deviceId) {
        if (data.profile) setCurrentProfile(data.profile)
      }
    }
    webSocket.on('quality_changed', handleQualityChanged)

    return () => {
      if (feedbackTimerRef.current) clearInterval(feedbackTimerRef.current)
      webSocket.off('quality_changed', handleQualityChanged)
    }
  }, [webSocket, deviceId, displayFps])

  // 📊 切换画质档位
  const handleSetProfile = useCallback((profileKey: string) => {
    if (!webSocket) return
    webSocket.emit('set_quality_profile', { deviceId, profile: profileKey })
    setCurrentProfile(profileKey)
  }, [webSocket, deviceId])

  // ✅ 监听屏幕数据的独立useEffect，避免与控制权逻辑混合
  useEffect(() => {
    if (!webSocket) return

    const handleScreenData = (data: any) => {
      if (data.deviceId === deviceId) {
        // 📊 帧计数用于质量反馈
        frameCountRef.current++
        
        // ✅ 过滤黑屏帧：Base64长度<4000字符(≈3KB JPEG)几乎肯定是黑屏/空白帧
        // 正常480×854 JPEG即使最低质量也>8000字符
        const dataLen = typeof data.data === 'string' ? data.data.length : 0
        const MIN_VALID_FRAME_LENGTH = 4000
        
        if (dataLen > 0 && dataLen < MIN_VALID_FRAME_LENGTH) {
          // 黑屏帧：丢弃，保持canvas上一帧内容不变
          droppedFrameCountRef.current++
          if (frameCountRef.current % 30 === 0) {
            console.log(`[屏幕数据] 已收到 ${frameCountRef.current} 帧, 丢弃黑屏帧(${dataLen}字符 < ${MIN_VALID_FRAME_LENGTH}), 已丢弃: ${droppedFrameCountRef.current}`)
          }
          return
        }
        
        // 🔍 诊断：记录数据到达频率
        if (frameCountRef.current % 30 === 0) {
          console.log(`[屏幕数据] 已收到 ${frameCountRef.current} 帧, 数据大小: ${dataLen}, 渲染中: ${isRenderingRef.current}, 解码中: ${decodingRef.current}`)
        }
        
        // ✅ 只保存最新帧引用，不立即解码
        latestFrameRef.current = data
        
        // 只在首帧时更新loading状态，避免每帧触发重渲染
        if (isLoading) setIsLoading(false)
        
        // ✅ 如果没有正在进行的渲染循环，启动一个
        if (!isRenderingRef.current) {
          isRenderingRef.current = true
          renderLatestFrame()
        }
      }
    }

    webSocket.on('screen_data', handleScreenData)

    return () => {
      webSocket.off('screen_data', handleScreenData)
      // 清理 rAF
      if (rafIdRef.current) {
        cancelAnimationFrame(rafIdRef.current)
        rafIdRef.current = 0
      }
      isRenderingRef.current = false
      // 设备切换或断开时重置锁定尺寸，下次连接重新锁定
      lockedCanvasSizeRef.current = null
    }
  }, [webSocket, deviceId])

  // ✅ 控制权管理的独立useEffect，只在必要时申请/释放
  useEffect(() => {
    if (!webSocket || !deviceId) return

    // 如果WebSocket实例发生变化，重置控制权状态
    if (currentWebSocket !== webSocket) {
      setIsControlRequested(false)
      setCurrentWebSocket(webSocket)
    }

    // 只在未申请过控制权时申请，且防止重复发送
    if (!isControlRequested) {
      const now = Date.now()
      // 🔧 防止短时间内重复发送请求（2秒内只能发送一次）
      if (now - lastControlRequestTime < 2000) {
        console.log('⚠️ 控制权请求过于频繁，跳过')
        return
      }
      
      console.log('🎮 申请设备控制权:', deviceId)
      setLastControlRequestTime(now)
      webSocket.emit('client_event', {
        type: 'REQUEST_DEVICE_CONTROL',
        data: { deviceId }
      })
      setIsControlRequested(true)
    }

    // 监听控制权响应
    const handleControlResponse = (data: any) => {
      if (data.deviceId === deviceId) {
        if (data.success) {
          console.log('✅ 控制权获取成功:', deviceId)
        } else {
          console.warn('❌ 控制权获取失败:', data.message)
          // 如果失败，允许重新申请
          setIsControlRequested(false)
        }
      }
    }

    // ✅ 监听控制错误，自动重新申请控制权
    const handleControlError = (data: any) => {
      if (data.deviceId === deviceId && data.error === 'NO_PERMISSION') {
        console.warn('⚠️ 检测到权限丢失，重新申请控制权:', deviceId)
        setIsControlRequested(false)
      }
    }

    webSocket.on('device_control_response', handleControlResponse)
    webSocket.on('control_error', handleControlError)

    // 清理函数：只在组件卸载或deviceId变化时释放控制权
    return () => {
      webSocket.off('device_control_response', handleControlResponse)
      webSocket.off('control_error', handleControlError)
      
      // 只有在已申请过控制权时才释放
      if (isControlRequested) {
        console.log('🔓 释放设备控制权:', deviceId)
        webSocket.emit('client_event', {
          type: 'RELEASE_DEVICE_CONTROL',
          data: { deviceId }
        })
      }
    }
  }, [webSocket, deviceId, isControlRequested, currentWebSocket]) // 🔧 不包含lastControlRequestTime避免重复执行

  // ✅ 高性能渲染：createImageBitmap 离屏解码 + 持续 rAF 循环
  const decodingRef = useRef(false)

  const renderLatestFrame = useCallback(() => {
    const doRender = () => {
      const frameData = latestFrameRef.current
      if (!frameData) {
        // 没有新帧，停止循环，等 handleScreenData 重新启动
        isRenderingRef.current = false
        return
      }

      // 取走帧数据
      latestFrameRef.current = null

      const canvas = canvasRef.current
      if (!canvas) {
        isRenderingRef.current = false
        return
      }

      if (!frameData?.data || !frameData?.format) {
        rafIdRef.current = requestAnimationFrame(doRender)
        return
      }

      // 上一帧还在解码，把数据放回去，下个 rAF 再试
      if (decodingRef.current) {
        latestFrameRef.current = frameData
        rafIdRef.current = requestAnimationFrame(doRender)
        return
      }

      decodingRef.current = true

      let blobPromise: Promise<Blob>
      if (typeof frameData.data === 'string') {
        const binaryStr = atob(frameData.data)
        const len = binaryStr.length
        const bytes = new Uint8Array(len)
        for (let i = 0; i < len; i++) {
          bytes[i] = binaryStr.charCodeAt(i)
        }
        blobPromise = Promise.resolve(new Blob([bytes], { type: `image/${frameData.format.toLowerCase()}` }))
      } else {
        blobPromise = Promise.resolve(new Blob([frameData.data], { type: `image/${frameData.format.toLowerCase()}` }))
      }

      blobPromise
        .then(blob => createImageBitmap(blob))
        .then(bitmap => {
          decodingRef.current = false

          const ctx = canvas.getContext('2d')
          if (!ctx) {
            bitmap.close()
            rafIdRef.current = requestAnimationFrame(doRender)
            return
          }

          // canvas尺寸锁定策略：
          // 首次有效帧确定canvas尺寸后锁定，后续帧直接绘制到固定尺寸canvas上
          // 避免不同采集模式帧尺寸不一致导致canvas反复resize闪烁
          const locked = lockedCanvasSizeRef.current
          if (!locked) {
            // 首次帧：锁定canvas尺寸
            lockedCanvasSizeRef.current = { width: bitmap.width, height: bitmap.height }
            canvas.width = bitmap.width
            canvas.height = bitmap.height
          } else if (canvas.width !== locked.width || canvas.height !== locked.height) {
            // canvas被外部重置了，恢复锁定尺寸
            canvas.width = locked.width
            canvas.height = locked.height
          }

          // 始终将bitmap绘制到整个canvas区域，浏览器自动缩放
          // 这样不同尺寸的帧都能正确显示，不会闪烁
          ctx.drawImage(bitmap, 0, 0, canvas.width, canvas.height)

          // 使用锁定的canvas尺寸上报，保持稳定
          const reportSize = lockedCanvasSizeRef.current
          if (reportSize) {
            const prevSize = imageSizeRef.current
            if (!prevSize || prevSize.width !== reportSize.width || prevSize.height !== reportSize.height) {
              imageSizeRef.current = { width: reportSize.width, height: reportSize.height }
              setImageSize({ width: reportSize.width, height: reportSize.height })
            }
          }

          const now = Date.now()
          fpsFrameTimesRef.current.push(now)
          const cutoff = now - 2000
          fpsFrameTimesRef.current = fpsFrameTimesRef.current.filter(t => t > cutoff)
          if (now - lastFpsUpdateRef.current > 500) {
            lastFpsUpdateRef.current = now
            setDisplayFps(Math.round(fpsFrameTimesRef.current.length / 2))
          }

          bitmap.close()

          // 解码完成后始终调度下一帧，保持循环活跃
          rafIdRef.current = requestAnimationFrame(doRender)
        })
        .catch(err => {
          decodingRef.current = false
          console.error('图像解码失败:', err)
          rafIdRef.current = requestAnimationFrame(doRender)
        })
    }

    doRender()
  }, [])

  const drawFitMode = (ctx: CanvasRenderingContext2D, img: HTMLImageElement | ImageBitmap, canvas: HTMLCanvasElement) => {
    const scale = Math.min(canvas.width / img.width, canvas.height / img.height)
    const w = img.width * scale
    const h = img.height * scale
    const x = (canvas.width - w) / 2
    const y = (canvas.height - h) / 2
    // 只清除图像未覆盖的边缘区域，避免全画布clearRect导致闪烁
    if (x > 0 || y > 0) {
      ctx.fillStyle = '#000'
      ctx.fillRect(0, 0, canvas.width, canvas.height)
    }
    ctx.drawImage(img, x, y, w, h)
  }

  const drawFillMode = (ctx: CanvasRenderingContext2D, img: HTMLImageElement | ImageBitmap, canvas: HTMLCanvasElement) => {
    const scale = Math.max(canvas.width / img.width, canvas.height / img.height)
    const x = (canvas.width - img.width * scale) / 2
    const y = (canvas.height - img.height * scale) / 2
    ctx.drawImage(img, x, y, img.width * scale, img.height * scale)
  }

  const drawStretchMode = (ctx: CanvasRenderingContext2D, img: HTMLImageElement | ImageBitmap, canvas: HTMLCanvasElement) => {
    ctx.drawImage(img, 0, 0, canvas.width, canvas.height)
  }

  const drawOriginalMode = (ctx: CanvasRenderingContext2D, img: HTMLImageElement | ImageBitmap, canvas: HTMLCanvasElement) => {
    const x = (canvas.width - img.width) / 2
    const y = (canvas.height - img.height) / 2
    ctx.drawImage(img, x, y)
  }

  // 坐标转换函数：将canvas坐标转换为设备坐标
  const convertCanvasToDeviceCoords = useCallback((canvasX: number, canvasY: number, canvas: HTMLCanvasElement, device: any) => {
    if (!device) return null
    
    const deviceWidth = device.screenWidth
    const deviceHeight = device.screenHeight
    
    // 使用canvas的实际显示尺寸，而不是内部分辨率
    const rect = canvas.getBoundingClientRect()
    const canvasWidth = rect.width
    const canvasHeight = rect.height
    
    let imageX: number, imageY: number, imageWidth: number, imageHeight: number
    
    // 由于canvas使用了objectFit: 'contain'，浏览器会自动保持宽高比
    // 我们需要计算图像在canvas中的实际显示位置和尺寸
    const scale = Math.min(canvasWidth / deviceWidth, canvasHeight / deviceHeight)
    imageWidth = deviceWidth * scale
    imageHeight = deviceHeight * scale
    imageX = (canvasWidth - imageWidth) / 2
    imageY = (canvasHeight - imageHeight) / 2
    

    
    // 检查点击是否在图像区域内
    if (canvasX < imageX || canvasX > imageX + imageWidth || 
        canvasY < imageY || canvasY > imageY + imageHeight) {
      console.warn('点击在图像区域外')
      return null // 点击在图像区域外
    }
    
    // 将canvas坐标转换为图像内的相对坐标
    const relativeX = canvasX - imageX
    const relativeY = canvasY - imageY
    
    // 转换为设备坐标
    const deviceX = (relativeX / imageWidth) * deviceWidth
    const deviceY = (relativeY / imageHeight) * deviceHeight
    
    console.log('deviceX', deviceX)
    console.log('deviceY', deviceY)
    // 确保坐标在设备范围内
    const clampedX = Math.max(0, Math.min(deviceWidth - 1, deviceX))
    const clampedY = Math.max(0, Math.min(deviceHeight - 1, deviceY))
    

    
    return { x: clampedX, y: clampedY }
  }, [])

  // const handleMouseEvent = useCallback((event: React.MouseEvent, action: string) => {
  //   if (!webSocket || !device) return

  //   const canvas = canvasRef.current
  //   if (!canvas) return

  //   const rect = canvas.getBoundingClientRect()
  //   const canvasX = event.clientX - rect.left
  //   const canvasY = event.clientY - rect.top
    
  //   // 根据显示模式计算正确的设备坐标
  //   const deviceCoords = convertCanvasToDeviceCoords(canvasX, canvasY, canvas, device)
    
  //   if (!deviceCoords) {
  //     console.warn('无法转换坐标，可能点击在图像区域外')
  //     return
  //   }

  //   console.log(`点击位置转换: Canvas(${canvasX.toFixed(1)}, ${canvasY.toFixed(1)}) -> Device(${deviceCoords.x.toFixed(1)}, ${deviceCoords.y.toFixed(1)})`)

  //   webSocket.emit('control_message', {
  //     type: action,
  //     deviceId,
  //     data: { x: deviceCoords.x, y: deviceCoords.y },
  //     timestamp: Date.now()
  //   })

  //   // 显示触摸指示器
  //   if (screenDisplay.showTouchIndicator) {
  //     showTouchIndicator(canvasX, canvasY)
  //   }
  // }, [webSocket, device, deviceId, screenDisplay.showTouchIndicator, convertCanvasToDeviceCoords])

  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(() => {
        container.removeChild(indicator)
      }, 500)
    }
  }

  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)
    }
  }

  // 🆕 显示长按拖拽开始指示器
  const showLongPressDragStartIndicator = (x: number, y: number) => {
    const container = canvasRef.current?.parentElement
    if (!container) return

    // 创建长按拖拽开始指示器（较大的圆圈，橙色）
    const indicator = document.createElement('div')
    indicator.style.position = 'absolute'
    indicator.style.left = `${x - 20}px`
    indicator.style.top = `${y - 20}px`
    indicator.style.width = '40px'
    indicator.style.height = '40px'
    indicator.style.borderRadius = '50%'
    indicator.style.backgroundColor = 'rgba(255, 165, 0, 0.7)'
    indicator.style.border = '4px solid #ff8c00'
    indicator.style.pointerEvents = 'none'
    indicator.style.zIndex = '1000'
    indicator.style.animation = 'pulse 0.8s infinite'
    indicator.className = 'long-press-drag-start'

    // 添加文字标识
    const label = document.createElement('div')
    label.style.position = 'absolute'
    label.style.left = '50%'
    label.style.top = '50%'
    label.style.transform = 'translate(-50%, -50%)'
    label.style.fontSize = '10px'
    label.style.fontWeight = 'bold'
    label.style.color = '#fff'
    label.style.textShadow = '1px 1px 2px rgba(0,0,0,0.8)'
    label.textContent = '拖'
    indicator.appendChild(label)

    container.style.position = 'relative'
    container.appendChild(indicator)

    return indicator
  }

  // 🆕 显示长按拖拽路径指示器
  const showLongPressDragPath = (startX: number, startY: number, endX: number, endY: number) => {
    const container = canvasRef.current?.parentElement
    if (!container) return

    // 清除之前的拖拽开始指示器
    const existingIndicator = container.querySelector('.long-press-drag-start')
    if (existingIndicator) {
      container.removeChild(existingIndicator)
    }

    // 创建拖拽路径线（粗一些，橙色渐变）
    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 = '4px'
    line.style.background = 'linear-gradient(to right, #ff8c00, #ff6347)'
    line.style.transformOrigin = '0 50%'
    line.style.transform = `rotate(${angle}deg)`
    line.style.pointerEvents = 'none'
    line.style.zIndex = '999'
    line.style.boxShadow = '0 0 6px rgba(255, 140, 0, 0.6)'

    // 创建起始点指示器
    const startIndicator = document.createElement('div')
    startIndicator.style.position = 'absolute'
    startIndicator.style.left = `${startX - 8}px`
    startIndicator.style.top = `${startY - 8}px`
    startIndicator.style.width = '16px'
    startIndicator.style.height = '16px'
    startIndicator.style.borderRadius = '50%'
    startIndicator.style.backgroundColor = '#ff8c00'
    startIndicator.style.border = '2px solid #fff'
    startIndicator.style.pointerEvents = 'none'
    startIndicator.style.zIndex = '1001'

    // 创建结束点指示器（带箭头）
    const endIndicator = document.createElement('div')
    endIndicator.style.position = 'absolute'
    endIndicator.style.left = `${endX - 12}px`
    endIndicator.style.top = `${endY - 12}px`
    endIndicator.style.width = '24px'
    endIndicator.style.height = '24px'
    endIndicator.style.borderRadius = '50%'
    endIndicator.style.backgroundColor = '#ff6347'
    endIndicator.style.border = '3px solid #fff'
    endIndicator.style.pointerEvents = 'none'
    endIndicator.style.zIndex = '1001'
    endIndicator.style.boxShadow = '0 0 8px rgba(255, 99, 71, 0.8)'

    // 添加箭头图标
    const arrow = document.createElement('div')
    arrow.style.position = 'absolute'
    arrow.style.left = '50%'
    arrow.style.top = '50%'
    arrow.style.transform = 'translate(-50%, -50%)'
    arrow.style.fontSize = '12px'
    arrow.style.color = '#fff'
    arrow.style.fontWeight = 'bold'
    arrow.textContent = '→'
    endIndicator.appendChild(arrow)

    container.style.position = 'relative'
    container.appendChild(line)
    container.appendChild(startIndicator)
    container.appendChild(endIndicator)

    // 1.5秒后清除指示器
    setTimeout(() => {
      if (container.contains(line)) container.removeChild(line)
      if (container.contains(startIndicator)) container.removeChild(startIndicator)
      if (container.contains(endIndicator)) container.removeChild(endIndicator)
    }, 1500)
  }

  // 添加滑动处理
  const [isDragging, setIsDragging] = useState(false)
  const [dragStart, setDragStart] = useState<{x: number, y: number} | null>(null)
  
  // 🆕 添加长按处理
  const [isLongPressTriggered, setIsLongPressTriggered] = useState(false)
  const longPressTimerRef = useRef<number | null>(null)
  
  // 🆕 添加长按拖拽处理状态
  const [isLongPressDragging, setIsLongPressDragging] = useState(false)
  const [longPressDragStartPos, setLongPressDragStartPos] = useState<{x: number, y: number} | null>(null)
  
  // 🆕 添加拖拽路径收集状态
  const [dragPath, setDragPath] = useState<Array<{x: number, y: number}>>([])
  const lastMoveTimeRef = useRef<number>(0)



  // 处理真正的点击（从mouseUp中调用）
  const performClick = useCallback((canvasX: number, canvasY: number) => {
    if (!webSocket || !device) return
    
    // 检查操作是否被允许
    if (!operationEnabled) {
      console.warn('屏幕点击操作已被阻止')
      return
    }

    const canvas = canvasRef.current
    if (!canvas) return

    const deviceCoords = convertCanvasToDeviceCoords(canvasX, canvasY, canvas, device)
    
    if (!deviceCoords) {
      console.warn('无法转换坐标，可能点击在图像区域外')
      return
    }



    webSocket.emit('control_message', {
      type: 'CLICK',
      deviceId,
      data: { x: deviceCoords.x, y: deviceCoords.y },
      timestamp: Date.now()
    })

    // 显示触摸指示器
    if (screenDisplay.showTouchIndicator) {
      showTouchIndicator(canvasX, canvasY)
    }
    

  }, [webSocket, device, deviceId, screenDisplay.showTouchIndicator, convertCanvasToDeviceCoords, operationEnabled])

  // 🆕 处理长按操作
  const performLongPress = useCallback((canvasX: number, canvasY: number) => {
    if (!webSocket || !device) return
    
    // 检查操作是否被允许
    if (!operationEnabled) {
      console.warn('屏幕长按操作已被阻止')
      return
    }

    const canvas = canvasRef.current
    if (!canvas) return

    const deviceCoords = convertCanvasToDeviceCoords(canvasX, canvasY, canvas, device)
    
    if (!deviceCoords) {
      console.warn('无法转换坐标，可能长按在图像区域外')
      return
    }

    console.log(`长按操作: Canvas(${canvasX.toFixed(1)}, ${canvasY.toFixed(1)}) -> Device(${deviceCoords.x.toFixed(1)}, ${deviceCoords.y.toFixed(1)})`)

    webSocket.emit('control_message', {
      type: 'LONG_PRESS',
      deviceId,
      data: { x: deviceCoords.x, y: deviceCoords.y },
      timestamp: Date.now()
    })

    // 显示长按指示器（使用不同颜色区分）
    if (screenDisplay.showTouchIndicator) {
      showLongPressIndicator(canvasX, canvasY)
    }

  }, [webSocket, device, deviceId, screenDisplay.showTouchIndicator, convertCanvasToDeviceCoords, operationEnabled])
  
  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 })
    
    // 🆕 启动长按计时器
    setIsLongPressTriggered(false)
    setIsLongPressDragging(false)
    setLongPressDragStartPos(null)
    setDragPath([]) // 🔧 清理拖拽路径
    longPressTimerRef.current = window.setTimeout(() => {
      setIsLongPressTriggered(true)
      // 🆕 长按触发后不立即执行操作，而是准备进入拖拽模式
      console.log('长按触发，准备进入拖拽模式')
    }, 500) // 500ms 后触发长按
  }, [performLongPress])

  const handleMouseMove = useCallback((event: React.MouseEvent) => {
    if (!isDragging || !dragStart) return
    
    event.preventDefault()
    
    // 🆕 处理长按拖拽逻辑 - 优化为连续手势
    if (isLongPressTriggered && !isLongPressDragging) {
      // 长按已触发，用户开始拖拽，进入长按拖拽模式
      if (!webSocket || !device || !operationEnabled) return
      
      const canvas = canvasRef.current
      if (!canvas) return
      
      // 转换开始位置为设备坐标
      const startCoords = convertCanvasToDeviceCoords(dragStart.x, dragStart.y, canvas, device)
      if (!startCoords) return
      
      setIsLongPressDragging(true)
      setLongPressDragStartPos(startCoords)
      
      // 🔧 优化：初始化拖拽路径，包含起始点
      setDragPath([startCoords])
      
      // 🆕 显示长按拖拽开始指示器
      if (screenDisplay.showTouchIndicator) {
        showLongPressDragStartIndicator(dragStart.x, dragStart.y)
      }
      
      console.log(`长按拖拽开始: Device(${startCoords.x.toFixed(1)}, ${startCoords.y.toFixed(1)})`)
    } else if (isLongPressDragging) {
      // 🔧 优化：收集拖拽路径点，而不是立即发送消息
      const now = Date.now()
      
      // 频率控制：每50ms最多记录一个点，避免路径过密
      if (now - lastMoveTimeRef.current < 50) return
      
      const canvas = canvasRef.current
      if (!canvas) return
      
      const rect = canvas.getBoundingClientRect()
      const currentX = event.clientX - rect.left
      const currentY = event.clientY - rect.top
      
      const currentCoords = convertCanvasToDeviceCoords(currentX, currentY, canvas, device)
      if (!currentCoords) return
      
      // 添加当前点到路径中
      setDragPath(prevPath => {
        const newPath = [...prevPath, currentCoords]
        // 限制路径点数量，避免内存占用过大
        return newPath.length > 100 ? [newPath[0], ...newPath.slice(-99)] : newPath
      })
      
      lastMoveTimeRef.current = now
      console.debug(`长按拖拽路径收集: Device(${currentCoords.x.toFixed(1)}, ${currentCoords.y.toFixed(1)})`)
    }
  }, [isDragging, dragStart, isLongPressTriggered, isLongPressDragging, webSocket, device, deviceId, operationEnabled, convertCanvasToDeviceCoords, screenDisplay.showTouchIndicator, dragPath])

  const handleMouseUp = useCallback((event: React.MouseEvent) => {
    if (!isDragging || !dragStart) return
    
    event.preventDefault()
    setIsDragging(false)
    
    // 🆕 清理长按计时器
    if (longPressTimerRef.current) {
      clearTimeout(longPressTimerRef.current)
      longPressTimerRef.current = null
    }
    
    // 🆕 处理长按相关操作
    if (isLongPressTriggered) {
      if (isLongPressDragging) {
        // 🔧 优化：执行完整的长按拖拽手势
        if (webSocket && device && operationEnabled && longPressDragStartPos && dragPath.length > 0) {
          const canvas = canvasRef.current
          if (canvas) {
            const rect = canvas.getBoundingClientRect()
            const endX = event.clientX - rect.left
            const endY = event.clientY - rect.top
            
            const endCoords = convertCanvasToDeviceCoords(endX, endY, canvas, device)
            if (endCoords) {
              // 将结束点添加到路径中
              const completePath = [...dragPath, endCoords]
              
              // 发送包含完整路径的长按拖拽消息
              webSocket.emit('control_message', {
                type: 'LONG_PRESS_DRAG',
                deviceId,
                data: { 
                  path: completePath,
                  startX: completePath[0].x,
                  startY: completePath[0].y,
                  endX: endCoords.x, 
                  endY: endCoords.y,
                  duration: Math.max(2000, 1500 + completePath.length * 20) // 优化：为微移动长按预留更多时间
                },
                timestamp: Date.now()
              })
              
              console.log(`长按拖拽完成: Device(${completePath[0].x.toFixed(1)}, ${completePath[0].y.toFixed(1)}) -> Device(${endCoords.x.toFixed(1)}, ${endCoords.y.toFixed(1)}), 路径点数: ${completePath.length}`)
              
              // 🆕 显示长按拖拽路径指示器
              if (screenDisplay.showTouchIndicator) {
                showLongPressDragPath(dragStart.x, dragStart.y, endX, endY)
              }
            }
          }
        }
      } else {
        // 长按已触发但没有拖拽，执行普通长按操作
        const canvas = canvasRef.current
        const rect = canvas?.getBoundingClientRect()
        if (rect) {
          const endX = event.clientX - rect.left
          const endY = event.clientY - rect.top
          performLongPress(endX, endY)
        }
      }
      
      // 清理长按拖拽相关状态
      setDragStart(null)
      setIsLongPressTriggered(false)
      setIsLongPressDragging(false)
      setLongPressDragStartPos(null)
      setDragPath([]) // 🔧 清理拖拽路径
      return
    }
    
    const canvas = canvasRef.current
    if (!canvas || !webSocket || !device) 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 {
      // 大距离移动，当作滑动处理
      
      // 检查操作是否被允许
      if (!operationEnabled) {
        console.warn('屏幕滑动操作已被阻止')
        return
      }
      
      // 使用正确的坐标转换函数
      const startCoords = convertCanvasToDeviceCoords(dragStart.x, dragStart.y, canvas, device)
      const endCoords = convertCanvasToDeviceCoords(endX, endY, canvas, device)
      
      if (!startCoords || !endCoords) {
        console.warn('滑动坐标转换失败，滑动可能在图像区域外')
        return
      }
      

      
      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()
      })

      // 显示滑动指示器
      if (screenDisplay.showTouchIndicator) {
        showSwipeIndicator(dragStart.x, dragStart.y, endX, endY)
      }
    }
    
    setDragStart(null)
  }, [isDragging, dragStart, webSocket, device, deviceId, screenDisplay.showTouchIndicator, convertCanvasToDeviceCoords, performClick, operationEnabled, isLongPressTriggered, isLongPressDragging, longPressDragStartPos, performLongPress, dragPath])
  
  // 处理鼠标离开画布
  const handleMouseLeave = useCallback(() => {
    setIsDragging(false)
    setDragStart(null)
    
    // 🆕 清理长按计时器和状态
    if (longPressTimerRef.current) {
      clearTimeout(longPressTimerRef.current)
      longPressTimerRef.current = null
    }
    setIsLongPressTriggered(false)
    
    // 🆕 清理长按拖拽相关状态
    setIsLongPressDragging(false)
    setLongPressDragStartPos(null)
    setDragPath([]) // 🔧 清理拖拽路径
  }, [])

  // 🔍 全屏切换
  const toggleFullscreen = useCallback(() => {
    const container = fullscreenContainerRef.current
    if (!container) return

    if (!document.fullscreenElement) {
      container.requestFullscreen().catch(err => {
        console.warn('进入全屏失败:', err)
      })
    } else {
      document.exitFullscreen()
    }
  }, [])

  // 监听 fullscreenchange 事件同步状态
  useEffect(() => {
    const onFullscreenChange = () => {
      setIsFullscreen(!!document.fullscreenElement)
    }
    document.addEventListener('fullscreenchange', onFullscreenChange)
    return () => {
      document.removeEventListener('fullscreenchange', onFullscreenChange)
    }
  }, [])

  // 全屏模式下计算 canvas 的 CSS 尺寸（保持宽高比，适配屏幕）
  // 使用 state 存储全屏容器尺寸，确保全屏切换和窗口resize时触发重渲染
  const [containerSize, setContainerSize] = useState<{ w: number; h: number }>({ w: 0, h: 0 })

  useEffect(() => {
    if (!isFullscreen) return
    const updateSize = () => {
      setContainerSize({ w: window.innerWidth, h: window.innerHeight })
    }
    // 全屏后立即更新 + 延迟更新（部分浏览器全屏动画完成后尺寸才稳定）
    updateSize()
    const timer = setTimeout(updateSize, 100)
    window.addEventListener('resize', updateSize)
    return () => {
      clearTimeout(timer)
      window.removeEventListener('resize', updateSize)
    }
  }, [isFullscreen])

  const getCanvasStyle = useCallback((): React.CSSProperties => {
    if (!isFullscreen || !imageSize || containerSize.w === 0) {
      return {
        width: imageSize ? `${imageSize.width}px` : '100%',
        height: imageSize ? `${imageSize.height}px` : 'auto',
      }
    }
    // 全屏时：canvas 按宽高比缩放填满屏幕
    const scale = Math.min(containerSize.w / imageSize.width, containerSize.h / imageSize.height)
    return {
      width: `${Math.round(imageSize.width * scale)}px`,
      height: `${Math.round(imageSize.height * scale)}px`,
    }
  }, [isFullscreen, imageSize, containerSize])



  if (!device) {
    return (
      <Card title="设备屏幕">
        <div style={{ textAlign: 'center', padding: '50px' }}>
          设备未找到
        </div>
      </Card>
    )
  }

  return (
    <>
      {/* 添加CSS动画 */}
      <style>
        {`
          @keyframes pulse {
            0% { opacity: 1; }
            50% { opacity: 0.6; }
            100% { opacity: 1; }
          }
        `}
      </style>
      
      <div
        ref={fullscreenContainerRef}
        style={{ 
          position: 'relative', 
          width: '100%', 
          height: '100%',
          display: 'flex',
          flexDirection: 'column',
          alignItems: 'center',
          justifyContent: 'center',
          overflow: 'hidden',
          backgroundColor: isFullscreen ? '#000' : undefined,
        }}
      >
      {/* 顶部信息栏 - 屏幕阅读器模式下隐藏 */}

      {/* 操作状态指示器 */}
      {!operationEnabled && (
        <div style={{
          position: 'absolute',
          top: '20px',
          right: '20px',
          zIndex: 20,
          color: '#fff',
          backgroundColor: 'rgba(255, 77, 79, 0.9)',
          padding: '8px 16px',
          borderRadius: '4px',
          fontSize: '14px',
          fontWeight: 'bold',
          border: '2px solid #ff4d4f',
          animation: 'pulse 2s infinite'
        }}>
          🔒 操作已禁用
        </div>
      )}



      {isLoading && (
        <div style={{
          position: 'absolute',
          top: '50%',
          left: '50%',
          transform: 'translate(-50%, -50%)',
          zIndex: 10
        }}>
          <Spin size="large" />
          <div style={{ color: '#fff', marginTop: '16px' }}>
            正在连接设备屏幕...
          </div>
        </div>
      )}
      
      {/* Canvas wrapper - position:relative so touch/swipe indicators are positioned relative to canvas */}
      <div style={{ position: 'relative' }}>
      <canvas
        ref={canvasRef}
        style={{
          ...getCanvasStyle(),
          cursor: 'pointer',
          display: 'block',
        }}
        onMouseDown={handleMouseDown}
        onMouseUp={handleMouseUp}
        onMouseMove={handleMouseMove}
        onMouseLeave={handleMouseLeave}
        onContextMenu={(e) => e.preventDefault()}
      />
      </div>

      {/* 📊 画质控制面板 + 🔍 全屏按钮 */}
      <div style={{
        position: 'absolute',
        bottom: '8px',
        right: '8px',
        zIndex: 20,
        display: 'flex',
        alignItems: 'center',
        gap: '6px',
      }}>
        <span style={{
          color: '#fff',
          fontSize: '11px',
          background: 'rgba(0,0,0,0.5)',
          padding: '2px 6px',
          borderRadius: '3px',
          fontFamily: 'monospace',
        }}>
          {displayFps} FPS{networkStats.dropRate > 0.05 ? ` ⚠${(networkStats.dropRate * 100).toFixed(0)}%丢帧` : ''}
        </span>
        <div style={{ position: 'relative' }}>
          <button
            onClick={() => setShowQualityPanel(!showQualityPanel)}
            style={{
              background: 'rgba(0,0,0,0.5)',
              color: '#fff',
              border: 'none',
              padding: '2px 8px',
              borderRadius: '3px',
              fontSize: '11px',
              cursor: 'pointer',
            }}
          >
            {QUALITY_PROFILES.find(p => p.key === currentProfile)?.label || '自定义'}
          </button>
          {showQualityPanel && (
            <div style={{
              position: 'absolute',
              bottom: '100%',
              right: 0,
              marginBottom: '4px',
              background: 'rgba(0,0,0,0.85)',
              borderRadius: '6px',
              padding: '8px',
              minWidth: '120px',
            }}>
              {QUALITY_PROFILES.map(p => (
                <div
                  key={p.key}
                  onClick={() => { handleSetProfile(p.key); setShowQualityPanel(false) }}
                  style={{
                    color: currentProfile === p.key ? '#1890ff' : '#fff',
                    fontSize: '12px',
                    padding: '4px 8px',
                    cursor: 'pointer',
                    borderRadius: '3px',
                    background: currentProfile === p.key ? 'rgba(24,144,255,0.15)' : 'transparent',
                  }}
                >
                  {p.label} ({p.fps}fps / {p.resolution})
                </div>
              ))}
            </div>
          )}
        </div>
        {/* 🔍 全屏/退出全屏按钮 */}
        <button
          onClick={toggleFullscreen}
          title={isFullscreen ? '退出全屏 (ESC)' : '全屏显示'}
          style={{
            background: 'rgba(0,0,0,0.5)',
            color: '#fff',
            border: 'none',
            padding: '2px 8px',
            borderRadius: '3px',
            fontSize: '13px',
            cursor: 'pointer',
            lineHeight: 1,
          }}
        >
          {isFullscreen ? '⮌' : '⛶'}
        </button>
      </div>
    </div>
    </>
  )
}

export default DeviceScreen