package com.example.godeye.managers

import android.content.Context
import android.util.Log
import com.example.godeye.models.DeviceInfo
import com.example.godeye.utils.Logger
import com.example.godeye.utils.PreferenceManager
import com.example.godeye.utils.getLocalIpAddress
import com.example.godeye.utils.extractServerIP
import io.socket.client.IO
import io.socket.client.Socket
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
import org.json.JSONArray
import org.json.JSONObject
import java.net.URI
import java.text.SimpleDateFormat
import java.util.*

/**
 * Менеджер соединений с интеграцией WebRTC
 * Управляет видеопотоком, статусом трансляции и счетчиком времени записи
 */
class ConnectionManager(
    private val context: Context,
    private val preferenceManager: PreferenceManager
) {
    companion object {
        private const val TAG = "ConnectionManager"
        private const val RECONNECTION_DELAY = 5000L // 5 секунд
        private const val MAX_RECONNECTION_ATTEMPTS = 5
    }

    // НОВОЕ: WebRTC Manager для видео
    lateinit var webRTCManager: WebRTCManager
        private set

    // Статусы соединения (для совместимости с существующим кодом)
    enum class ConnectionState {
        DISCONNECTED,
        CONNECTING,
        CONNECTED,
        ERROR,
        RECONNECTING;

        // Для совместимости со старым кодом добавляем альтернативные названия
        companion object {
            val Connected = CONNECTED
            val Registered = CONNECTED // Mapped to CONNECTED
            val Connecting = CONNECTING
            val Error = ERROR
            val Disconnected = DISCONNECTED
        }
    }

    // События соединения
    sealed class ConnectionEvent {
        object Connected : ConnectionEvent()
        object Disconnected : ConnectionEvent()
        data class Error(val message: String) : ConnectionEvent()
        data class StreamingStarted(val sessionId: String) : ConnectionEvent()
        data class StreamingStopped(val sessionId: String) : ConnectionEvent()
        data class RecordingTimeUpdated(val duration: String) : ConnectionEvent()
        data class StatusUpdated(val status: String) : ConnectionEvent()
    }

    // Статусы трансляции
    enum class StreamingStatus {
        IDLE,           // Неактивен
        CONNECTING,     // Подключение
        STREAMING,      // Идет трансляция
        ERROR,          // Ошибка
        STOPPING        // Остановка
    }

    private var socket: Socket? = null
    private val scope = CoroutineScope(Dispatchers.IO + SupervisorJob())
    private var reconnectionJob: Job? = null
    private var reconnectionAttempts = 0

    // Состояние соединения (для совместимости)
    private val _connectionState = MutableStateFlow(ConnectionState.DISCONNECTED)
    val connectionState: Flow<ConnectionState> = _connectionState

    // Информация об устройстве (для совместимости)
    private val _deviceInfo = MutableStateFlow(createDeviceInfo())
    val deviceInfo: Flow<DeviceInfo> = _deviceInfo

    private val _events = MutableStateFlow<ConnectionEvent?>(null)
    val events: Flow<ConnectionEvent?> = _events

    private val _streamingStatus = MutableStateFlow(StreamingStatus.IDLE)
    val streamingStatus: Flow<StreamingStatus> = _streamingStatus

    private val _recordingDuration = MutableStateFlow("00:00:00")
    val recordingDuration: Flow<String> = _recordingDuration

    private val _isRecording = MutableStateFlow(false)
    val isRecording: Flow<Boolean> = _isRecording

    // Система событий для совместимости с AutoApprovalManager
    private val eventListeners = mutableMapOf<String, MutableList<(Array<Any>) -> Unit>>()

    // Корутины для таймера
    private var recordingJob: Job? = null
    private var startTime: Long = 0
    private var keepAliveJob: Job? = null

    // Текущая сессия
    private var currentSessionId: String? = null
    private var currentOperatorId: String? = null

    init {
        initializeManagers()
    }

    /**
     * Создание информации об устройстве
     */
    private fun createDeviceInfo(): DeviceInfo {
        return DeviceInfo(
            deviceId = preferenceManager.migrateToUUID(),
            deviceName = android.os.Build.MODEL,
            androidVersion = android.os.Build.VERSION.RELEASE,
            appVersion = "1.0.0"
        )
    }

    /**
     * НОВОЕ: Получение реального IP-адреса устройства
     */
    private fun getDeviceLocalIP(): String {
        return context.getLocalIpAddress()
    }

    /**
     * НОВОЕ: Получение IP сервера из настроек
     */
    private fun getServerIP(): String {
        val serverUrl = preferenceManager.getServerUrl() ?: return "192.168.219.1"
        return extractServerIP(serverUrl)
    }

    /**
     * Инициализация менеджеров
     */
    private fun initializeManagers() {
        try {
            Logger.step("CONNECTION_INIT", "Initializing connection managers")

            // Инициализация WebRTC
            webRTCManager = WebRTCManager(context).apply {
                // Установка колбэков для сигналинга
                onOfferCreated = { sessionId, offer ->
                    sendWebRTCOffer(sessionId, offer)
                }
                
                onAnswerCreated = { sessionId, answer ->
                    sendWebRTCAnswer(sessionId, answer)
                }
                
                onIceCandidateCreated = { sessionId, candidate ->
                    sendICECandidate(sessionId, candidate)
                }
            }

            // НЕ инициализируем WebSocketManager - используем только Socket.IO
            // webSocketManager = WebSocketManager().apply { ... }

            // Подписка на события WebRTC
            scope.launch {
                webRTCManager.events.collect { event ->
                    when (event) {
                        is WebRTCManager.WebRTCEvent.Connected -> {
                            _streamingStatus.value = StreamingStatus.STREAMING
                            updateStatus("Трансляция активна")
                        }
                        is WebRTCManager.WebRTCEvent.Disconnected -> {
                            _streamingStatus.value = StreamingStatus.IDLE
                            updateStatus("Трансляция остановлена")
                            stopRecordingTimer()
                        }
                        is WebRTCManager.WebRTCEvent.Error -> {
                            _streamingStatus.value = StreamingStatus.ERROR
                            updateStatus("Ошибка: ${event.message}")
                            _events.value = ConnectionEvent.Error(event.message)
                        }
                        is WebRTCManager.WebRTCEvent.CameraStarted -> {
                            startRecordingTimer()
                            updateStatus("Запись началась")
                            _events.value = ConnectionEvent.StreamingStarted(event.sessionId)
                        }
                        is WebRTCManager.WebRTCEvent.CameraStopped -> {
                            stopRecordingTimer()
                            updateStatus("Запись остановлена")
                            _events.value = ConnectionEvent.StreamingStopped(event.sessionId)
                        }
                        is WebRTCManager.WebRTCEvent.StatisticsUpdated -> {
                            // Обновление статистики видео
                            Logger.step("CONNECTION_STATS_UPDATE", "Video statistics updated: ${event.statistics}")
                        }
                        null -> {}
                    }
                }
            }

            Logger.step("CONNECTION_INIT_SUCCESS", "Connection managers initialized successfully")

        } catch (e: Exception) {
            Logger.error("CONNECTION_INIT_ERROR", "Failed to initialize connection managers", e)
            _events.value = ConnectionEvent.Error("Ошибка инициализации: ${e.message}")
        }
    }

    /**
     * Подключение к серверу (для совместимости с существующим кодом)
     */
    fun connect(serverUrl: String? = null) {
        try {
            Logger.step("CONNECTION_CONNECT", "Connecting to server")
            _connectionState.value = ConnectionState.CONNECTING
            updateStatus("Подключение к серверу...")

            val url = serverUrl ?: preferenceManager.getServerUrl()

            if (url.isNullOrEmpty()) {
                throw Exception("Server URL not configured")
            }

            // Используем только Socket.IO соединение (WebSocket вызывает конфликты)
            connectSocketIO(url)

        } catch (e: Exception) {
            Logger.error("CONNECTION_CONNECT_ERROR", "Failed to connect to server", e)
            _connectionState.value = ConnectionState.ERROR
            updateStatus("Ошибка подключения")
            _events.value = ConnectionEvent.Error("Ошибка подключения: ${e.message}")
        }
    }

    /**
     * Подключение через Socket.IO (для совместимости)
     */
    private fun connectSocketIO(serverUrl: String) {
        try {
            val options = IO.Options().apply {
                timeout = 10000
                reconnection = true
                reconnectionAttempts = MAX_RECONNECTION_ATTEMPTS
                reconnectionDelay = RECONNECTION_DELAY
            }

            socket = IO.socket(URI.create(serverUrl), options)

            socket?.apply {
                on(Socket.EVENT_CONNECT) {
                    scope.launch(Dispatchers.Main) {
                        _connectionState.value = ConnectionState.CONNECTED
                        _events.value = ConnectionEvent.Connected
                        reconnectionAttempts = 0
                        updateStatus("Подключено через Socket.IO")

                        // Регистрируем устройство на сервере
                        registerDevice()
                    }
                }

                on(Socket.EVENT_DISCONNECT) {
                    scope.launch(Dispatchers.Main) {
                        _connectionState.value = ConnectionState.DISCONNECTED
                        _events.value = ConnectionEvent.Disconnected
                        updateStatus("Отключено от сервера")
                    }
                }

                // ИСПРАВЛЕНИЕ: Добавляем правильный обработчик событий от Node.js сервера
                on("camera:request") { args ->
                    handleCameraRequest(args)
                }

                on("webrtc:answer") { args ->
                    handleWebRTCAnswerFromSocket(args)
                }

                on("webrtc:ice-candidate") { args ->
                    handleICECandidate(args)
                }

                // Добавляем обработчики для всех возможных вариантов событий от сервера
                on("camera-request") { args ->
                    handleCameraRequest(args)
                }

                on("camera_request") { args ->
                    handleCameraRequest(args)
                }

                // Добавляем обработчики для подтверждения регистрации
                on("device-registered") { args ->
                    handleDeviceRegistered(args)
                }

                on("register-success") { args ->
                    handleDeviceRegistered(args)
                }

                on("registration-success") { args ->
                    handleDeviceRegistered(args)
                }

                // Обработчик ошибок регистрации
                on("register-error") { args ->
                    handleRegistrationError(args)
                }

                on("registration-error") { args ->
                    handleRegistrationError(args)
                }

                connect()
            }

        } catch (e: Exception) {
            Logger.error("SOCKET_IO_ERROR", "Socket.IO connection failed", e)
        }
    }

    /**
     * Отправка WebRTC Offer (требуется для AutoApprovalManager)
     */
    fun sendWebRTCOffer(sessionId: String, offer: String) {
        try {
            val message = JSONObject().apply {
                put("sessionId", sessionId)
                put("offer", JSONObject().apply {
                    put("type", "offer")
                    put("sdp", offer)
                })
                put("timestamp", System.currentTimeMillis())
            }

            socket?.emit("webrtc:offer", message)

            Logger.step("CONNECTION_OFFER_SENT", "WebRTC offer sent for session: $sessionId")

        } catch (e: Exception) {
            Logger.error("CONNECTION_OFFER_ERROR", "Failed to send WebRTC offer", e)
        }
    }

    /**
     * Отправка WebRTC Answer
     */
    fun sendWebRTCAnswer(sessionId: String, answer: String) {
        try {
            val message = JSONObject().apply {
                put("sessionId", sessionId)
                put("answer", JSONObject().apply {
                    put("type", "answer")
                    put("sdp", answer)
                })
                put("timestamp", System.currentTimeMillis())
            }

            socket?.emit("webrtc:answer", message)

            Logger.step("CONNECTION_ANSWER_SENT", "WebRTC answer sent for session: $sessionId")

        } catch (e: Exception) {
            Logger.error("CONNECTION_ANSWER_ERROR", "Failed to send WebRTC answer", e)
        }
    }

    /**
     * Отправка ICE кандидата (требуется для AutoApprovalManager)
     */
    fun sendICECandidate(sessionId: String, candidate: String) {
        try {
            // Парсим JSON строку кандидата
            val candidateJson = JSONObject(candidate)

            val message = JSONObject().apply {
                put("sessionId", sessionId)
                put("candidate", candidateJson)
                put("timestamp", System.currentTimeMillis())
            }

            socket?.emit("webrtc:ice-candidate", message)

            Logger.step("CONNECTION_ICE_SENT", "ICE candidate sent for session: $sessionId")

        } catch (e: Exception) {
            Logger.error("CONNECTION_ICE_ERROR", "Failed to send ICE candidate", e)
        }
    }

    /**
     * ИСПРАВЛЕНИЕ: Улучшенная отправка ответа на запрос камеры с правильным форматом
     */
    fun sendCameraResponse(sessionId: String, accepted: Boolean, reason: String = "", operatorId: String = "") {
        try {
            Logger.step("CONNECTION_CAMERA_RESPONSE", "Sending camera response: accepted=$accepted for session: $sessionId")

            // ИСПРАВЛЕНИЕ: Отправляем camera:response в правильном формате для Node.js сервера
            val responseData = JSONObject().apply {
                put("sessionId", sessionId)
                put("accepted", accepted)
                put("timestamp", System.currentTimeMillis())

                // Добавляем дополнительную информацию
                if (operatorId.isNotEmpty()) {
                    put("operatorId", operatorId)
                }

                if (!accepted && reason.isNotEmpty()) {
                    put("reason", reason)
                }

                // НОВОЕ: Добавляем информацию об устройстве для трекинга
                put("deviceId", _deviceInfo.value.deviceId)
                put("deviceName", _deviceInfo.value.deviceName)

                // НОВОЕ: Добавляем информацию о доступных камерах
                // val cameraTypes = camera2Manager?.getAvailableCameraTypes() ?: emptyList()
                put("availableCameras", JSONArray(listOf("back", "front")))
            }

            // Отправляем с правильным именем события
            socket?.emit("camera:response", responseData)

            // НОВОЕ: Также отправляем с альтернативными именами для совместимости
            socket?.emit("camera-response", responseData)
            socket?.emit("camera_response", responseData)

            Logger.step("CONNECTION_CAMERA_RESPONSE_SENT", "✅ Camera response sent successfully: accepted=$accepted for session: $sessionId")

            // НОВОЕ: Если запрос принят, начинаем трансляцию
            if (accepted) {
                currentSessionId = sessionId
                currentOperatorId = operatorId

                // Запускаем трансляцию с задержкой для обеспечения обработки ответа
                scope.launch {
                    kotlinx.coroutines.delay(500) // Небольшая задержка
                    startStreaming(sessionId, operatorId)
                }
            }

        } catch (e: Exception) {
            Logger.error("CONNECTION_CAMERA_RESPONSE_ERROR", "Failed to send camera response", e)
        }
    }

    /**
     * НОВОЕ: Запуск трансляции после принятия запроса камеры
     */
    private fun startStreaming(sessionId: String, operatorId: String) {
        try {
            Logger.step("CONNECTION_START_STREAMING", "Starting streaming for session: $sessionId, operator: $operatorId")

            _streamingStatus.value = StreamingStatus.CONNECTING
            updateStatus("Запуск трансляции...")

            // Запускаем WebRTC трансляцию
            webRTCManager.startStreaming(sessionId, operatorId, "back") // По умолчанию задняя камера

            Logger.step("CONNECTION_STREAMING_STARTED", "✅ Streaming started for session: $sessionId")

        } catch (e: Exception) {
            Logger.error("CONNECTION_START_STREAMING_ERROR", "Failed to start streaming", e)
            _streamingStatus.value = StreamingStatus.ERROR
            updateStatus("Ошибка запуска трансляции")
            _events.value = ConnectionEvent.Error("Ошибка запуска трансляции: ${e.message}")
        }
    }

    /**
     * Добавление слушателя событий Socket.IO (требуется для AutoApprovalManager)
     */
    fun addEventListener(event: String, callback: (Array<Any>) -> Unit) {
        socket?.on(event) { args ->
            try {
                callback(args)
            } catch (e: Exception) {
                Logger.error("SOCKET_EVENT_ERROR", "Error in event listener for $event", e)
            }
        }
    }

    /**
     * Обработка запроса камеры
     */
    private fun handleCameraRequest(args: Array<Any>) {
        try {
            Log.d("ConnectionManager", "=== CAMERA REQUEST RECEIVED ===")
            Log.d("ConnectionManager", "Args count: ${args.size}")

            if (args.isNotEmpty()) {
                val data = args[0] as? JSONObject
                data?.let {
                    Log.d("ConnectionManager", "Camera request data: $it")
                    Logger.step("CONNECTION_CAMERA_REQUEST", "Received camera request: ${it}")

                    // Эмитируем событие для AutoApprovalManager с правильным именем
                    scope.launch(Dispatchers.Main) {
                        _events.value = ConnectionEvent.StatusUpdated("Получен запрос доступа к камере")

                        // ВАЖНО: Уведомляем все зарегистрированные слушатели
                        Log.d("ConnectionManager", "Notifying listeners for camera:request event")
                        notifyEventListeners("camera:request", arrayOf(it))

                        // Также уведомляем слушателя с альтернативными именами
                        notifyEventListeners("camera-request", arrayOf(it))
                        notifyEventListeners("camera_request", arrayOf(it))
                    }
                } ?: run {
                    Log.e("ConnectionManager", "Camera request data is null")
                }
            } else {
                Log.e("ConnectionManager", "Camera request args are empty")
            }
            Log.d("ConnectionManager", "=== CAMERA REQUEST PROCESSED ===")
        } catch (e: Exception) {
            Log.e("ConnectionManager", "CAMERA REQUEST ERROR: ", e)
            Logger.error("CONNECTION_HANDLE_CAMERA_REQUEST_ERROR", "Failed to handle camera request", e)
        }
    }

    /**
     * Обработка WebRTC Answer (приватный метод для Socket.IO)
     */
    private fun handleWebRTCAnswerFromSocket(args: Array<Any>) {
        try {
            if (args.isNotEmpty()) {
                val data = args[0] as JSONObject
                val sessionId = data.optString("sessionId")

                // Получаем answer как объект, а не строку
                val answerObj = data.optJSONObject("answer")
                if (answerObj != null) {
                    val answerSdp = answerObj.optString("sdp")
                    if (sessionId.isNotEmpty() && answerSdp.isNotEmpty()) {
                        Logger.step("CONNECTION_ANSWER_RECEIVED", "WebRTC answer received for session: $sessionId")
                        webRTCManager.handleAnswer(sessionId, answerSdp)
                    }
                } else {
                    // Fallback для старого формата (если answer приходит как строка)
                    val answer = data.optString("answer")
                    if (sessionId.isNotEmpty() && answer.isNotEmpty()) {
                        Logger.step("CONNECTION_ANSWER_RECEIVED_LEGACY", "WebRTC answer received (legacy format) for session: $sessionId")
                        webRTCManager.handleAnswer(sessionId, answer)
                    }
                }
            }
        } catch (e: Exception) {
            Logger.error("CONNECTION_HANDLE_ANSWER_ERROR", "Failed to handle WebRTC answer", e)
        }
    }

    /**
     * Обработка ICE кандидата
     */
    private fun handleICECandidate(args: Array<Any>) {
        try {
            if (args.isNotEmpty()) {
                val data = args[0] as JSONObject
                val sessionId = data.optString("sessionId")

                // Получаем candidate как объект, а не строку
                val candidateObj = data.optJSONObject("candidate")
                if (candidateObj != null) {
                    val candidateStr = candidateObj.toString()
                    if (sessionId.isNotEmpty()) {
                        Logger.step("CONNECTION_ICE_RECEIVED", "ICE candidate received for session: $sessionId")
                        webRTCManager.handleIceCandidate(sessionId, candidateStr)
                    }
                } else {
                    // Fallback для старого формата (если candidate приходит как строка)
                    val candidate = data.optString("candidate")
                    if (sessionId.isNotEmpty() && candidate.isNotEmpty()) {
                        Logger.step("CONNECTION_ICE_RECEIVED_LEGACY", "ICE candidate received (legacy format) for session: $sessionId")
                        webRTCManager.handleIceCandidate(sessionId, candidate)
                    }
                }
            }
        } catch (e: Exception) {
            Logger.error("CONNECTION_HANDLE_ICE_ERROR", "Failed to handle ICE candidate", e)
        }
    }

    /**
     * Подключение к серверу (новая версия с WebSocket)
     */
    fun connectToServer(serverUrl: String) {
        connect(serverUrl)
    }

    /**
     * Отключение от сервера
     */
    fun disconnect() {
        try {
            Logger.step("CONNECTION_DISCONNECT", "Disconnecting from server")
            
            stopKeepAlive()
            stopAllStreaming()
            socket?.disconnect()
            // webSocketManager?.disconnect()

            _connectionState.value = ConnectionState.DISCONNECTED
            _streamingStatus.value = StreamingStatus.IDLE
            updateStatus("Отключено")
            
        } catch (e: Exception) {
            Logger.error("CONNECTION_DISCONNECT_ERROR", "Failed to disconnect", e)
        }
    }

    /**
     * Очистка ресурсов (требуется для ConnectionService)
     */
    fun cleanup() {
        disconnect()
        dispose()
    }

    /**
     * Начало видеопотока для оператора
     */
    fun startVideoStream(sessionId: String, operatorId: String, cameraType: String = "back") {
        try {
            Logger.step("CONNECTION_START_STREAM", "Starting video stream - Session: $sessionId, Operator: $operatorId")
            
            currentSessionId = sessionId
            currentOperatorId = operatorId
            
            _streamingStatus.value = StreamingStatus.CONNECTING
            updateStatus("Начало трансляции...")
            
            webRTCManager.startStreaming(sessionId, operatorId, cameraType)

        } catch (e: Exception) {
            Logger.error("CONNECTION_START_STREAM_ERROR", "Failed to start video stream", e)
            _streamingStatus.value = StreamingStatus.ERROR
            updateStatus("Ошибка запуска трансляции")
            _events.value = ConnectionEvent.Error("Ошибка запуска видеопотока: ${e.message}")
        }
    }

    /**
     * Остановка видеопотока для сессии
     */
    fun stopVideoStream(sessionId: String) {
        try {
            Logger.step("CONNECTION_STOP_STREAM", "Stopping video stream for session: $sessionId")
            
            _streamingStatus.value = StreamingStatus.STOPPING
            updateStatus("Остановка трансляции...")
            
            webRTCManager.stopStreaming(sessionId)

            if (currentSessionId == sessionId) {
                currentSessionId = null
                currentOperatorId = null
            }
            
        } catch (e: Exception) {
            Logger.error("CONNECTION_STOP_STREAM_ERROR", "Failed to stop video stream", e)
            _events.value = ConnectionEvent.Error("Ошибка остановки видеопотока: ${e.message}")
        }
    }

    /**
     * Остановка всех видеопотоков
     */
    fun stopAllStreaming() {
        try {
            Logger.step("CONNECTION_STOP_ALL", "Stopping all streaming")
            
            _streamingStatus.value = StreamingStatus.STOPPING
            updateStatus("Остановка всех трансляций...")
            
            webRTCManager.stopAllStreaming()
            stopRecordingTimer()
            
            currentSessionId = null
            currentOperatorId = null
            
        } catch (e: Exception) {
            Logger.error("CONNECTION_STOP_ALL_ERROR", "Failed to stop all streaming", e)
        }
    }

    /**
     * Переключение камеры
     */
    fun switchCamera() {
        try {
            Logger.step("CONNECTION_SWITCH_CAMERA", "Switching camera")
            webRTCManager.switchCamera()
            updateStatus("Камера переключена")
            
        } catch (e: Exception) {
            Logger.error("CONNECTION_SWITCH_CAMERA_ERROR", "Failed to switch camera", e)
            _events.value = ConnectionEvent.Error("Ошибка переключения камеры: ${e.message}")
        }
    }

    /**
     * Отправка сигналингового сообщения
     */
    private fun sendSignalingMessage(sessionId: String, type: String, data: String) {
        try {
            val message = JSONObject().apply {
                put("type", type)
                put("sessionId", sessionId)
                put("data", data)
                put("timestamp", System.currentTimeMillis())
            }
            
            socket?.emit("signaling", message)
            // webSocketManager?.sendMessage(message.toString())
            Logger.step("CONNECTION_SIGNAL_SENT", "Signaling message sent: $type for session: $sessionId")
            
        } catch (e: Exception) {
            Logger.error("CONNECTION_SIGNAL_ERROR", "Failed to send signaling message", e)
        }
    }

    /**
     * Обработка входящих сигналинговых сообщений
     */
    private fun handleSignalingMessage(message: String) {
        try {
            val json = JSONObject(message)
            val type = json.getString("type")
            val sessionId = json.getString("sessionId")
            val data = json.getString("data")
            
            Logger.step("CONNECTION_SIGNAL_RECEIVED", "Signaling message received: $type for session: $sessionId")
            
            when (type) {
                "answer" -> {
                    webRTCManager.handleAnswer(sessionId, data)
                }
                "ice-candidate" -> {
                    webRTCManager.handleIceCandidate(sessionId, data)
                }
                "start-stream" -> {
                    val operatorId = json.optString("operatorId", "unknown")
                    val cameraType = json.optString("cameraType", "back")
                    startVideoStream(sessionId, operatorId, cameraType)
                }
                "stop-stream" -> {
                    stopVideoStream(sessionId)
                }
            }
            
        } catch (e: Exception) {
            Logger.error("CONNECTION_HANDLE_SIGNAL_ERROR", "Failed to handle signaling message", e)
        }
    }

    /**
     * Запуск таймера записи
     */
    private fun startRecordingTimer() {
        stopRecordingTimer() // Останавливаем предыдущий таймер, если он был
        
        startTime = System.currentTimeMillis()
        _isRecording.value = true
        
        recordingJob = scope.launch {
            while (isActive) {
                val elapsed = System.currentTimeMillis() - startTime
                val duration = formatDuration(elapsed)
                
                _recordingDuration.value = duration
                _events.value = ConnectionEvent.RecordingTimeUpdated(duration)
                
                delay(1000) // Обновляем каждую секунду
            }
        }
        
        Logger.step("CONNECTION_TIMER_START", "Recording timer started")
    }

    /**
     * Остановка таймера записи
     */
    private fun stopRecordingTimer() {
        recordingJob?.cancel()
        recordingJob = null
        _isRecording.value = false
        
        if (startTime > 0) {
            val totalDuration = formatDuration(System.currentTimeMillis() - startTime)
            Logger.step("CONNECTION_TIMER_STOP", "Recording timer stopped. Total duration: $totalDuration")
        }
    }

    /**
     * Форматирование длительности в формат HH:MM:SS
     */
    private fun formatDuration(milliseconds: Long): String {
        val seconds = milliseconds / 1000
        val hours = seconds / 3600
        val minutes = (seconds % 3600) / 60
        val secs = seconds % 60
        
        return String.format("%02d:%02d:%02d", hours, minutes, secs)
    }

    /**
     * Обновление статуса
     */
    private fun updateStatus(status: String) {
        Logger.step("CONNECTION_STATUS", status)
        _events.value = ConnectionEvent.StatusUpdated(status)
    }

    /**
     * Получение текущего статуса трансляции
     */
    fun getCurrentStreamingStatus(): StreamingStatus {
        return _streamingStatus.value
    }

    /**
     * Получение текущей длительности записи
     */
    fun getCurrentRecordingDuration(): String {
        return _recordingDuration.value
    }

    /**
     * Проверка, идет ли запись
     */
    fun isCurrentlyRecording(): Boolean {
        return _isRecording.value
    }

    /**
     * Получение информации о текущей сессии
     */
    fun getCurrentSessionInfo(): Pair<String?, String?> {
        return Pair(currentSessionId, currentOperatorId)
    }

    /**
     * Завершение сессии
     */
    fun endSession() {
        try {
            Logger.step("CONNECTION_END_SESSION", "Ending current session")
            
            stopAllStreaming()
            webRTCManager.endSession()

            currentSessionId = null
            currentOperatorId = null
            
            _streamingStatus.value = StreamingStatus.IDLE
            updateStatus("Сессия завершена")
            
        } catch (e: Exception) {
            Logger.error("CONNECTION_END_SESSION_ERROR", "Failed to end session", e)
        }
    }

    /**
     * Освобождение ресурсов
     */
    fun dispose() {
        try {
            Logger.step("CONNECTION_DISPOSE", "Disposing connection manager")
            
            stopRecordingTimer()
            scope.cancel()
            
            socket?.disconnect()
            webRTCManager.dispose()
            // webSocketManager?.dispose()

            Logger.step("CONNECTION_DISPOSED", "Connection manager disposed")
            
        } catch (e: Exception) {
            Logger.error("CONNECTION_DISPOSE_ERROR", "Failed to dispose connection manager", e)
        }
    }

    /**
     * Уведомление слушателей событий (для AutoApprovalManager)
     */
    private fun notifyEventListeners(event: String, args: Array<Any>) {
        Logger.step("CONNECTION_NOTIFY_LISTENERS", "Notifying ${eventListeners[event]?.size ?: 0} listeners for event: $event")
        eventListeners[event]?.forEach { listener ->
            try {
                Logger.step("CONNECTION_CALL_LISTENER", "Calling listener for event: $event with ${args.size} arguments")
                listener(args)
            } catch (e: Exception) {
                Logger.error("EVENT_LISTENER_ERROR", "Error in event listener for $event", e)
            }
        }
    }

    /**
     * Регистрация слушателя событий (для AutoApprovalManager)
     */
    fun registerEventListener(event: String, listener: (Array<Any>) -> Unit) {
        if (eventListeners[event] == null) {
            eventListeners[event] = mutableListOf()
        }
        eventListeners[event]?.add(listener)
        Logger.step("CONNECTION_REGISTER_LISTENER", "Registered listener for event: $event. Total listeners: ${eventListeners[event]?.size}")
    }

    /**
     * Удаление слушателя событий (для AutoApprovalManager)
     */
    fun unregisterEventListener(event: String, listener: (Array<Any>) -> Unit) {
        eventListeners[event]?.remove(listener)
    }

    /**
     * Регистрация устройства на сервере
     */
    private fun registerDevice() {
        try {
            Logger.step("CONNECTION_REGISTER_DEVICE", "Registering device on server")

            val deviceInfo = _deviceInfo.value

            // Подробное логирование информации об устройстве
            Log.d("ConnectionManager", "=== DEVICE REGISTRATION DEBUG ===")
            Log.d("ConnectionManager", "Device ID: ${deviceInfo.deviceId}")
            Log.d("ConnectionManager", "Device Name: ${deviceInfo.deviceName}")
            Log.d("ConnectionManager", "Android Version: ${deviceInfo.androidVersion}")
            Log.d("ConnectionManager", "App Version: ${deviceInfo.appVersion}")
            Log.d("ConnectionManager", "Socket connected: ${socket?.connected()}")

            if (deviceInfo.deviceId.isEmpty()) {
                Log.e("ConnectionManager", "ERROR: Device ID is empty! Cannot register device.")
                updateStatus("Ошибка: пустой ID устройства")
                return
            }

            // Отправляем регистрацию устройства
            val registrationData = JSONObject().apply {
                put("deviceId", deviceInfo.deviceId)
                put("deviceName", deviceInfo.deviceName)
                put("deviceType", "android")
                put("androidVersion", deviceInfo.androidVersion)
                put("appVersion", deviceInfo.appVersion)
                put("status", "online")
                put("capabilities", JSONObject().apply {
                    put("camera", true)
                    put("microphone", true)
                    put("webrtc", true)
                })
                put("timestamp", System.currentTimeMillis())
            }

            Log.d("ConnectionManager", "Registration data: $registrationData")

            // ВАЖНО: Отправляем основное событие, которое ожидает сервер
            Log.d("ConnectionManager", "Sending register:android event (MAIN EVENT)...")
            socket?.emit("register:android", registrationData)

            // Отправляем различные варианты событий для совместимости с разными серверами
            Log.d("ConnectionManager", "Sending device-register event...")
            socket?.emit("device-register", registrationData)

            Log.d("ConnectionManager", "Sending register-device event...")
            socket?.emit("register-device", registrationData)

            Log.d("ConnectionManager", "Sending device:register event...")
            socket?.emit("device:register", registrationData)

            Log.d("ConnectionManager", "Sending register event...")
            socket?.emit("register", registrationData)

            // Также отправляем старый формат для обратной совместимости
            Log.d("ConnectionManager", "Sending device-info event...")
            socket?.emit("device-info", registrationData)

            // Дополнительные события для совместимости с GodEye Signal Center
            Log.d("ConnectionManager", "Sending devices:register event...")
            socket?.emit("devices:register", registrationData)

            Log.d("ConnectionManager", "Sending device_register event...")
            socket?.emit("device_register", registrationData)

            Logger.step("CONNECTION_DEVICE_REGISTERED", "Device registration sent: ${deviceInfo.deviceId}")
            updateStatus("Устройство зарегистрировано")

            Log.d("ConnectionManager", "=== REGISTRATION COMPLETE ===")

            // Запускаем keepalive после успешной регистрации
            startKeepAlive()

        } catch (e: Exception) {
            Log.e("ConnectionManager", "REGISTRATION ERROR: ", e)
            Logger.error("CONNECTION_REGISTER_DEVICE_ERROR", "Failed to register device", e)
            updateStatus("Ошибка регистрации устройства: ${e.message}")
        }
    }

    /**
     * Обработка подтверждения регистрации устройства
     */
    private fun handleDeviceRegistered(args: Array<Any>) {
        try {
            Log.d("ConnectionManager", "=== DEVICE REGISTERED EVENT ===")
            Log.d("ConnectionManager", "Received device-registered event with ${args.size} arguments")

            if (args.isNotEmpty()) {
                val data = args[0] as? JSONObject
                data?.let {
                    Log.d("ConnectionManager", "Registration confirmation data: $it")
                    Logger.step("CONNECTION_DEVICE_REGISTERED", "Device registered: ${it}")

                    // Обновляем статус устройства
                    val deviceId = it.optString("deviceId")
                    if (deviceId.isNotEmpty() && deviceId == preferenceManager.getDeviceId()) {
                        Log.d("ConnectionManager", "✅ Device ID matches! Registration confirmed.")
                        updateStatus("✅ Устройство успешно зарегистрировано на сервере")
                    } else {
                        Log.w("ConnectionManager", "⚠️ Device ID mismatch or empty: received=$deviceId, expected=${preferenceManager.getDeviceId()}")
                        updateStatus("⚠️ Регистрация: несовпадение ID устройства")
                    }

                    // Эмитируем событие для совместимости
                    _events.value = ConnectionEvent.Connected
                } ?: run {
                    Log.w("ConnectionManager", "Registration event data is null")
                }
            } else {
                Log.w("ConnectionManager", "Registration event received but no arguments provided")
            }
            Log.d("ConnectionManager", "=== DEVICE REGISTERED COMPLETE ===")
        } catch (e: Exception) {
            Log.e("ConnectionManager", "DEVICE REGISTERED ERROR: ", e)
            Logger.error("CONNECTION_HANDLE_DEVICE_REGISTERED_ERROR", "Failed to handle device registered", e)
        }
    }

    /**
     * Обработка ошибок регистрации устройства
     */
    private fun handleRegistrationError(args: Array<Any>) {
        try {
            Log.d("ConnectionManager", "=== REGISTRATION ERROR EVENT ===")
            Log.d("ConnectionManager", "Received registration error with ${args.size} arguments")

            if (args.isNotEmpty()) {
                val data = args[0] as? JSONObject
                data?.let {
                    Log.e("ConnectionManager", "Registration error data: $it")
                    Logger.error("CONNECTION_REGISTRATION_ERROR", "Device registration error: ${it}")

                    // Обновляем статус с ошибкой
                    val errorMessage = it.optString("message", "Неизвестная ошибка регистрации")
                    val errorCode = it.optString("code", "unknown")
                    Log.e("ConnectionManager", "❌ Registration failed: $errorMessage (code: $errorCode)")
                    updateStatus("❌ Ошибка регистрации: $errorMessage")

                    // Попробуем зарегистрироваться снова через 5 секунд
                    scope.launch {
                        delay(5000)
                        Log.d("ConnectionManager", "Retrying device registration...")
                        registerDevice()
                    }
                } ?: run {
                    Log.w("ConnectionManager", "Registration error data is null")
                }
            } else {
                Log.w("ConnectionManager", "Registration error event received but no arguments provided")
            }
            Log.d("ConnectionManager", "=== REGISTRATION ERROR COMPLETE ===")
        } catch (e: Exception) {
            Log.e("ConnectionManager", "REGISTRATION ERROR HANDLER ERROR: ", e)
            Logger.error("CONNECTION_HANDLE_REGISTRATION_ERROR_ERROR", "Failed to handle registration error", e)
        }
    }

    /**
     * Запуск периодической отправки keepalive сообщений
     */
    private fun startKeepAlive() {
        stopKeepAlive() // Останавливаем предыдущий keepalive, если он был

        keepAliveJob = scope.launch {
            while (isActive) {
                try {
                    // Отправляем keepalive каждые 30 секунд
                    delay(30000)

                    val keepAliveData = JSONObject().apply {
                        put("deviceId", _deviceInfo.value.deviceId)
                        put("status", "online")
                        put("timestamp", System.currentTimeMillis())
                    }

                    // Отправляем различные варианты keepalive для совместимости
                    socket?.emit("device-keepalive", keepAliveData)
                    socket?.emit("keepalive", keepAliveData)
                    socket?.emit("ping", keepAliveData)

                    Logger.step("CONNECTION_KEEPALIVE", "Keepalive sent")

                } catch (e: Exception) {
                    Logger.error("CONNECTION_KEEPALIVE_ERROR", "Failed to send keepalive", e)
                }
            }
        }

        Logger.step("CONNECTION_KEEPALIVE_START", "Keepalive started")
    }

    /**
     * Остановка keepalive
     */
    private fun stopKeepAlive() {
        keepAliveJob?.cancel()
        keepAliveJob = null
        Logger.step("CONNECTION_KEEPALIVE_STOP", "Keepalive stopped")
    }

    /**
     * Тестовая функция для проверки автоподтверждения с UUID
     * Имитирует получение запроса камеры от сервера с настоящими UUID
     */
    fun testAutoApproval() {
        try {
            Logger.step("CONNECTION_TEST_AUTO_APPROVAL", "Testing auto approval functionality with UUID")

            // Создаем фиктивный запрос камеры с настоящими UUID
            val testRequest = JSONObject().apply {
                put("sessionId", java.util.UUID.randomUUID().toString())
                put("operatorId", java.util.UUID.randomUUID().toString())
                put("cameraType", "back")
                put("timestamp", System.currentTimeMillis())
            }

            Logger.step("CONNECTION_TEST_REQUEST", "Simulating camera request with UUID: $testRequest")

            // Отправляем событие в AutoApprovalManager
            scope.launch(Dispatchers.Main) {
                notifyEventListeners("camera:request", arrayOf(testRequest))
                updateStatus("Тестовый запрос камеры с UUID отправлен")
            }

        } catch (e: Exception) {
            Logger.error("CONNECTION_TEST_ERROR", "Failed to test auto approval with UUID", e)
        }
    }

    /**
     * Обработка WebRTC Answer от AutoApprovalManager
     */
    fun handleWebRTCAnswer(sessionId: String, answer: String) {
        try {
            Logger.step("CONNECTION_HANDLE_WEBRTC_ANSWER", "Handling WebRTC answer for session: $sessionId")
            webRTCManager.handleAnswer(sessionId, answer)
        } catch (e: Exception) {
            Logger.error("CONNECTION_HANDLE_WEBRTC_ANSWER_ERROR", "Failed to handle WebRTC answer", e)
        }
    }

    /**
     * Обработка ICE кандидата от AutoApprovalManager
     */
    fun handleWebRTCIceCandidate(sessionId: String, candidate: String) {
        try {
            Logger.step("CONNECTION_HANDLE_ICE_CANDIDATE", "Handling ICE candidate for session: $sessionId")
            webRTCManager.handleIceCandidate(sessionId, candidate)
        } catch (e: Exception) {
            Logger.error("CONNECTION_HANDLE_ICE_CANDIDATE_ERROR", "Failed to handle ICE candidate", e)
        }
    }

    /**
     * Диагностическая функция для проверки регистрации устройства
     */
    fun diagnoseRegistration() {
        try {
            Log.d("ConnectionManager", "=== REGISTRATION DIAGNOSIS ===")

            val deviceInfo = _deviceInfo.value
            val serverUrl = preferenceManager.getServerUrl()
            val allSettings = preferenceManager.getAllSettings()

            Log.d("ConnectionManager", "Server URL: $serverUrl")
            Log.d("ConnectionManager", "Socket connected: ${socket?.connected()}")
            Log.d("ConnectionManager", "Socket ID: ${socket?.id()}")
            Log.d("ConnectionManager", "Connection state: ${_connectionState.value}")
            Log.d("ConnectionManager", "All settings: $allSettings")

            // Принудительно пытаемся зарегистрироваться снова
            if (socket?.connected() == true) {
                Log.d("ConnectionManager", "Socket is connected. Forcing device registration...")
                registerDevice()
            } else {
                Log.e("ConnectionManager", "Socket is NOT connected! Cannot register device.")
                updateStatus("❌ Нет соединения с сервером для регистрации")
            }

            Log.d("ConnectionManager", "=== DIAGNOSIS COMPLETE ===")

        } catch (e: Exception) {
            Log.e("ConnectionManager", "DIAGNOSIS ERROR: ", e)
        }
    }

    /**
     * Принудительная повторная регистрация
     */
    fun forceRegistration() {
        scope.launch {
            try {
                Log.d("ConnectionManager", "Forcing device registration...")
                updateStatus("🔄 Принудительная регистрация устройства...")

                if (socket?.connected() == true) {
                    registerDevice()
                } else {
                    Log.e("ConnectionManager", "Cannot force registration: socket not connected")
                    updateStatus("❌ Нет соединения для регистрации")
                }
            } catch (e: Exception) {
                Log.e("ConnectionManager", "FORCE REGISTRATION ERROR: ", e)
                updateStatus("❌ Ошибка принудительной регистрации")
            }
        }
    }
}
