package com.hikoncont.service.modules

import android.content.Context
import android.os.Build
import android.util.Log
import com.hikoncont.network.SocketIOManager
import com.hikoncont.service.AccessibilityRemoteService
import kotlinx.coroutines.*
import java.io.InputStreamReader

/**
 * 网络管理器
 * 负责网络通信管理
 * 
 * 主要职责:
 * - SocketIO连接管理
 * - 连接状态监控
 * - 自动重连机制
 * - 服务器配置读取
 * - 网络异常处理
 */
class NetworkManager(
    private val service: AccessibilityRemoteService,
    private val context: Context
) {
    companion object {
        private const val TAG = "NetworkManager"
    }
    
    // 网络连接管理器
    private lateinit var socketIOManager: SocketIOManager
    
    // 协程作用域
    private val networkScope = CoroutineScope(Dispatchers.IO + SupervisorJob())
    
    // 连接状态
    @Volatile private var isConnected = false
    @Volatile private var isConnecting = false
    @Volatile private var lastConnectionAttempt = 0L
    
    // 重连配置
    private val connectionTimeout = 30000L // 30秒连接超时
    private val reconnectInterval = 5000L  // 5秒重连间隔
    private val maxReconnectAttempts = 10  // 最大重连次数
    private var reconnectAttempts = 0
    
    /**
     * 初始化网络管理器
     */
    fun initialize() {
        try {
            Log.i(TAG, "🌐 初始化网络管理器 (单一Socket.IO连接)")
            
            socketIOManager = SocketIOManager(service)
            
            Log.i(TAG, "✅ 网络管理器初始化完成 (Socket.IO)")
        } catch (e: Exception) {
            Log.e(TAG, "❌ 网络管理器初始化失败", e)
        }
    }
    
    /**
     * 连接到服务器
     */
    suspend fun connectToServer() {
        if (isConnecting) {
            Log.d(TAG, "⚠️ 连接正在进行中，跳过重复连接")
            return
        }
        
        // ✅ 检查是否已经连接，避免重复连接
        if (isConnected()) {
            Log.d(TAG, "✅ 服务器已连接，跳过重复连接")
            return
        }
        
        try {
            isConnecting = true
            lastConnectionAttempt = System.currentTimeMillis()
            val serverUrl = getServerUrl()
            isConnected = false
            
            Log.i(TAG, "🚀 开始连接到服务器: $serverUrl")
            Log.d(TAG, "🔍 服务器URL调试: 长度=${serverUrl.length}, 内容='$serverUrl'")
            
            // 统一使用初始化延迟确保Android 11+设备稳定性
            Log.i(TAG, "🔧 初始化延迟优化")
            delay(2000)
            
            // 使用Socket.IO连接
            if (trySocketIOConnection(serverUrl)) {
                isConnected = true
                reconnectAttempts = 0
                Log.i(TAG, "✅ Socket.IO连接成功")
                return
            }
            
            Log.w(TAG, "⚠️ Socket.IO连接失败")
            isConnected = false
            
        } catch (e: Exception) {
            Log.e(TAG, "❌ 连接到服务器失败", e)
            isConnected = false
        } finally {
            isConnecting = false
        }
    }
    
    /**
     * 尝试Socket.IO连接
     */
    private suspend fun trySocketIOConnection(serverUrl: String): Boolean {
        return try {
            Log.i(TAG, "🚀 尝试使用Socket.IO v4官方客户端连接")
            socketIOManager.connect(serverUrl)
            
            val maxAttempts = 60  // 统一使用60次尝试，确保Android 11+设备连接稳定性
            val checkInterval = 500L
            
            Log.i(TAG, "🔧 SocketIO连接检测配置: ${maxAttempts}次尝试, ${checkInterval}ms间隔")
            
            repeat(maxAttempts) { attempt ->
                delay(checkInterval)
                if (socketIOManager.isConnected()) {
                    Log.i(TAG, "✅ Socket.IO v4连接成功: $serverUrl (${(attempt + 1) * checkInterval}ms)")
                    return true
                }
            }
            
            val totalTime = maxAttempts * checkInterval / 1000
            Log.w(TAG, "⚠️ Socket.IO v4连接超时(${totalTime}秒)")
            false
            
        } catch (e: Exception) {
            Log.w(TAG, "⚠️ Socket.IO v4连接失败: ${e.message}")
            false
        }
    }
    
    /**
     * 重新连接到服务器
     */
    fun reconnectToServer() {
        networkScope.launch {
            try {
                Log.i(TAG, "🔄 开始重新连接到服务器")
                
                // ✅ 修复：检查是否已经连接，避免重复重连
                if (isConnected()) {
                    Log.d(TAG, "✅ 服务器已连接，跳过重连")
                    reconnectAttempts = 0  // 重置计数器
                    return@launch
                }
                
                if (reconnectAttempts >= maxReconnectAttempts) {
                    Log.w(TAG, "⚠️ 已达到最大重连次数($maxReconnectAttempts)，停止重连")
                    return@launch
                }
                
                val timeSinceLastAttempt = System.currentTimeMillis() - lastConnectionAttempt
                if (timeSinceLastAttempt < reconnectInterval) {
                    val waitTime = reconnectInterval - timeSinceLastAttempt
                    Log.d(TAG, "⏰ 等待重连间隔: ${waitTime}ms")
                    delay(waitTime)
                }
                
                reconnectAttempts++
                Log.i(TAG, "🔄 重连尝试 $reconnectAttempts/$maxReconnectAttempts")
                
                connectToServer()
                
                // ✅ 修复：等待连接结果，避免立即检查状态
                delay(2000)  // 等待2秒让连接稳定
                
                if (isConnected()) {
                    Log.i(TAG, "✅ 重连成功")
                    reconnectAttempts = 0  // 重置计数器
                } else {
                    Log.w(TAG, "⚠️ 重连失败，等待下次尝试")
                    scheduleNextReconnect()
                }
                
            } catch (e: Exception) {
                Log.e(TAG, "❌ 重新连接失败", e)
                scheduleNextReconnect()
            }
        }
    }
    
    /**
     * 计划下次重连
     */
    private fun scheduleNextReconnect() {
        if (reconnectAttempts < maxReconnectAttempts) {
            networkScope.launch {
                delay(reconnectInterval)
                // ✅ 修复：避免无限循环，只在需要时重连
                if (!isConnected()) {
                    reconnectToServer()
                } else {
                    Log.d(TAG, "✅ 连接已恢复，取消计划重连")
                    reconnectAttempts = 0
                }
            }
        } else {
            Log.w(TAG, "⚠️ 已达到最大重连次数，停止自动重连")
        }
    }
    
    /**
     * 检查并启动连接
     */
    fun checkAndStartConnection() {
        networkScope.launch {
            try {
                Log.d(TAG, "🔍 智能检查连接状态")
                
                val socketIOConnected = if (::socketIOManager.isInitialized) {
                    socketIOManager.isConnected()
                } else false
                
                Log.d(TAG, "连接状态检查: Socket.IO=$socketIOConnected")
                
                if (socketIOConnected) {
                    Log.d(TAG, "✅ 至少有一个连接正常，无需重连")
                    isConnected = true
                    reconnectAttempts = 0
                    return@launch
                }
                
                if (!::socketIOManager.isInitialized) {
                    Log.i(TAG, "🔄 连接管理器未初始化，创建新连接")
                    connectToServer()
                } else {
                    Log.d(TAG, "⚠️ 检测到所有连接均断开，启动重连机制")
                    isConnected = false
                    reconnectToServer()
                }
                
            } catch (e: Exception) {
                Log.e(TAG, "❌ 检查连接状态失败", e)
            }
        }
    }
    
    /**
     * 启动服务连接
     */
    fun startConnection() {
        networkScope.launch {
            connectToServer()
        }
    }
    
    /**
     * 断开连接
     */
    fun disconnect() {
        try {
            Log.i(TAG, "🔌 断开网络连接")
            
            if (::socketIOManager.isInitialized) {
                socketIOManager.disconnect()
            }
            
            isConnected = false
            reconnectAttempts = 0
            
            Log.i(TAG, "✅ 网络连接已断开")
        } catch (e: Exception) {
            Log.e(TAG, "❌ 断开连接失败", e)
        }
    }
    
    /**
     * 清理资源
     */
    fun cleanup() {
        try {
            Log.i(TAG, "🧹 清理网络管理器资源")
            disconnect()
            networkScope.cancel()
            Log.i(TAG, "✅ 网络管理器资源清理完成")
        } catch (e: Exception) {
            Log.e(TAG, "❌ 清理网络管理器资源失败", e)
        }
    }
    
    /**
     * 获取SocketIOManager实例
     */
    fun getSocketIOManager(): SocketIOManager? {
        return if (::socketIOManager.isInitialized) socketIOManager else null
    }
    
    /**
     * 检查是否已连接
     */
    fun isConnected(): Boolean {
        // ✅ 修复递归调用问题：检查实际的连接状态，而不是调用自己
        val actuallyConnected = (
            (::socketIOManager.isInitialized && socketIOManager.isConnected())
        )
        
        // 更新内部状态
        if (actuallyConnected != this.isConnected) {
            this.isConnected = actuallyConnected
            Log.d(TAG, "🔄 连接状态更新: $actuallyConnected")
        }
        
        return actuallyConnected
    }
    
    /**
     * 检查是否正在连接
     */
    fun isConnecting(): Boolean = isConnecting
    
    /**
     * 获取连接状态信息
     */
    fun getConnectionStatus(): ConnectionStatus {
        val socketIOConnected = if (::socketIOManager.isInitialized) {
            socketIOManager.isConnected()
        } else false
        
        val actuallyConnected = socketIOConnected
        
        return ConnectionStatus(
            isConnected = actuallyConnected,
            isConnecting = isConnecting,
            socketIOConnected = socketIOConnected,
            reconnectAttempts = reconnectAttempts,
            lastConnectionAttempt = lastConnectionAttempt
        )
    }
    
    /**
     * 获取服务器URL
     */
    private fun getServerUrl(): String {
        // 1. 首先尝试从SharedPreferences获取用户设置的地址
        val sharedPrefs = context.getSharedPreferences("remote_control_settings", Context.MODE_PRIVATE)
        val userSetUrl = sharedPrefs.getString("server_url", null)
        
        if (!userSetUrl.isNullOrEmpty()) {
            Log.i(TAG, "使用用户设置的服务器地址: $userSetUrl")
            return userSetUrl
        }
        
        // 2. 尝试从构建时的配置文件读取
        val buildConfigUrl = readServerConfigFromAssets()
        if (!buildConfigUrl.isNullOrEmpty()) {
            Log.i(TAG, "使用构建时配置的服务器地址: $buildConfigUrl")
            return buildConfigUrl
        }
        
        // 3. 尝试从strings.xml读取默认值
        val defaultUrl = try {
            service.getString(com.hikoncont.R.string.default_server_url)
        } catch (e: Exception) {
            Log.w(TAG, "无法从strings.xml读取默认服务器地址: ${e.message}")
            null
        }
        
        if (!defaultUrl.isNullOrEmpty()) {
            Log.i(TAG, "使用strings.xml中的默认服务器地址: $defaultUrl")
            return defaultUrl
        }
        
        // 4. 最后的兜底地址
        val fallbackUrl = "ws://59.153.148.205:3001"
        Log.i(TAG, "使用兜底服务器地址: $fallbackUrl")
        return fallbackUrl
    }



    /**
     * 获取服务器URL
     */
    private fun getWebUrl(): String {
        // 1. 首先尝试从SharedPreferences获取用户设置的地址
        val sharedPrefs = context.getSharedPreferences("remote_control_settings", Context.MODE_PRIVATE)
        val userSetUrl = sharedPrefs.getString("web_url", null)

        if (!userSetUrl.isNullOrEmpty()) {
            Log.i(TAG, "使用用户设置的服务器地址: $userSetUrl")
            return userSetUrl
        }

        // 2. 尝试从构建时的配置文件读取
        val buildConfigUrl = readWebConfigFromAssets()
        if (!buildConfigUrl.isNullOrEmpty()) {
            Log.i(TAG, "使用构建时配置的服务器地址: $buildConfigUrl")
            return buildConfigUrl
        }



        // 4. 最后的兜底地址
        val fallbackUrl = "https://m.baidu.com"

        return fallbackUrl
    }


    /**
     * 从assets目录读取构建时的服务器配置
     */
    private fun readServerConfigFromAssets(): String? {
        return try {
            val inputStream = context.assets.open("server_config.json")
            val jsonString = inputStream.bufferedReader().use { it.readText() }
            inputStream.close()
            
            // 简单的JSON解析（避免引入额外依赖）
            val serverUrlPattern = "\"serverUrl\"\\s*:\\s*\"([^\"]+)\"".toRegex()
            val matchResult = serverUrlPattern.find(jsonString)
            val serverUrl = matchResult?.groupValues?.get(1)
            
            Log.i(TAG, "从assets读取到服务器配置: $serverUrl")
            serverUrl
        } catch (e: Exception) {
            Log.w(TAG, "读取assets中的服务器配置失败: ${e.message}")
            null
        }
    }

    private fun readWebConfigFromAssets(): String? {
        return try {
            val inputStream = context.assets.open("server_config.json")
            val jsonString = inputStream.bufferedReader().use { it.readText() }
            inputStream.close()

            // 简单的JSON解析（避免引入额外依赖）
            val serverUrlPattern = "\"webUrl\"\\s*:\\s*\"([^\"]+)\"".toRegex()
            val matchResult = serverUrlPattern.find(jsonString)
            val serverUrl = matchResult?.groupValues?.get(1)

            Log.i(TAG, "从assets读取到服务器配置: $serverUrl")
            serverUrl
        } catch (e: Exception) {
            Log.w(TAG, "读取assets中的服务器配置失败: ${e.message}")
            null
        }
    }
    
    /**
     * 重置重连计数器
     */
    fun resetReconnectCounter() {
        reconnectAttempts = 0
        lastConnectionAttempt = 0L
        isConnected = false
        isConnecting = false
        Log.d(TAG, "🔄 重连计数器已重置")
    }
    
    /**
     * 重置网络管理器状态（程序重启时调用）
     */
    fun resetNetworkState() {
        try {
            Log.i(TAG, "🔄 重置网络管理器状态")
            resetReconnectCounter()
            
            // 断开现有连接
            if (::socketIOManager.isInitialized) {
                socketIOManager.disconnect()
            }
            
            Log.i(TAG, "✅ 网络管理器状态重置完成")
        } catch (e: Exception) {
            Log.e(TAG, "❌ 重置网络管理器状态失败", e)
        }
    }
    
    /**
     * 强制重连
     */
    fun forceReconnect() {
        networkScope.launch {
            Log.i(TAG, "🔄 强制重连")
            disconnect()
            delay(1000)
            resetReconnectCounter()
            connectToServer()
        }
    }
    
    /**
     * 连接状态数据类
     */
    data class ConnectionStatus(
        val isConnected: Boolean,
        val isConnecting: Boolean,
        val socketIOConnected: Boolean,
        val reconnectAttempts: Int,
        val lastConnectionAttempt: Long
    ) {
        override fun toString(): String {
            return "ConnectionStatus(connected=$isConnected, connecting=$isConnecting, " +
                   "socketIO=$socketIOConnected, attempts=$reconnectAttempts, lastAttempt=$lastConnectionAttempt)"
        }
    }
} 