package com.example.godeye.managers

import android.content.Context
import com.example.godeye.utils.Logger
import com.example.godeye.models.VideoStatistics
import com.example.godeye.models.StreamingState
import com.example.godeye.network.SignalingClient
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.*
import org.webrtc.*
import org.webrtc.audio.JavaAudioDeviceModule
import org.json.JSONObject
import java.util.Timer
import java.util.TimerTask

/**
 * Управление WebRTC соединением для передачи видеопотока с интеграцией сигналинга
 */
class WebRTCManager(private val context: Context) {

    companion object {
        private const val TAG = "WebRTCManager"
        private const val STATS_INTERVAL = 1000L // Обновление статистики каждую секунду
    }

    // События WebRTC
    sealed class WebRTCEvent {
        object Connected : WebRTCEvent()
        object Disconnected : WebRTCEvent()
        data class Error(val message: String) : WebRTCEvent()
        data class CameraStarted(val sessionId: String) : WebRTCEvent()
        data class CameraStopped(val sessionId: String) : WebRTCEvent()
        data class StatisticsUpdated(val statistics: VideoStatistics) : WebRTCEvent()
    }

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

    // НОВОЕ: Состояние трансляции и статистика
    private val _streamingState = MutableStateFlow(StreamingState())
    val streamingState: StateFlow<StreamingState> = _streamingState.asStateFlow()

    // НОВОЕ: Таймер для сбора статистики
    private var statisticsTimer: Timer? = null

    // WebRTC компоненты
    private var peerConnectionFactory: PeerConnectionFactory? = null
    private var videoCapturer: CameraVideoCapturer? = null
    private var videoSource: VideoSource? = null
    private var audioSource: AudioSource? = null
    private var localVideoTrack: VideoTrack? = null
    private var localAudioTrack: AudioTrack? = null
    private var eglBase: EglBase? = null

    // НОВОЕ: Локальный видео рендерер для предпросмотра
    private var localVideoRenderer: SurfaceViewRenderer? = null

    // Активные соединения (sessionId -> PeerConnection)
    private val activePeerConnections = mutableMapOf<String, PeerConnection>()

    // Колбэки для отправки сигналов
    var onOfferCreated: ((sessionId: String, offer: String) -> Unit)? = null
    var onAnswerCreated: ((sessionId: String, answer: String) -> Unit)? = null
    var onIceCandidateCreated: ((sessionId: String, candidate: String) -> Unit)? = null

    // Настройки камеры
    private var isFrontCamera = false
    private var isStreamingActive = false

    // Корутины
    private val scope = CoroutineScope(Dispatchers.Main + SupervisorJob())

    // НОВОЕ: Интеграция с сигналингом
    private val signalingClient = SignalingClient()
    private var currentSessionId: String? = null

    init {
        initializeWebRTC()
        setupSignalingCallbacks()
    }

    /**
     * Инициализация WebRTC
     */
    private fun initializeWebRTC() {
        try {
            Logger.step("WEBRTC_INIT", "Initializing WebRTC")

            // ИСПРАВЛЕНИЕ: Упрощаем инициализацию без принудительного H.264
            PeerConnectionFactory.initialize(
                PeerConnectionFactory.InitializationOptions.builder(context)
                    .setFieldTrials("") // Убираем принудительный H.264
                    .setEnableInternalTracer(false)
                    .createInitializationOptions()
            )

            // Создание EglBase для рендеринга
            eglBase = EglBase.create()

            // ИСПРАВЛЕНИЕ: Используем стандартные настройки аудио
            val audioDeviceModule = JavaAudioDeviceModule.builder(context)
                .createAudioDeviceModule()

            // ИСПРАВЛЕНИЕ: Создание стандартных видеокодеков без принудительных настроек
            val videoEncoderFactory = DefaultVideoEncoderFactory(
                eglBase?.eglBaseContext,
                false, // НЕ включаем IntelVp8Encoder
                false  // НЕ включаем H264HighProfile принудительно
            )
            val videoDecoderFactory = DefaultVideoDecoderFactory(eglBase?.eglBaseContext)

            // Создание PeerConnectionFactory
            peerConnectionFactory = PeerConnectionFactory.builder()
                .setAudioDeviceModule(audioDeviceModule)
                .setVideoEncoderFactory(videoEncoderFactory)
                .setVideoDecoderFactory(videoDecoderFactory)
                .createPeerConnectionFactory()

            createMediaSources()

            Logger.step("WEBRTC_INIT_SUCCESS", "WebRTC initialized successfully")

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

    /**
     * Создание оптимизированной фабрики видеокодеров
     */
    private fun createOptimizedVideoEncoderFactory(): VideoEncoderFactory {
        return DefaultVideoEncoderFactory(
            eglBase?.eglBaseContext,
            true, // enableIntelVp8Encoder
            true  // enableH264HighProfile
        )
    }

    /**
     * Создание оптимизированной фабрики видеодекодеров
     */
    private fun createOptimizedVideoDecoderFactory(): VideoDecoderFactory {
        return DefaultVideoDecoderFactory(eglBase?.eglBaseContext)
    }

    /**
     * Создание источников медиа
     */
    private fun createMediaSources() {
        try {
            // Создание видео источника
            videoSource = peerConnectionFactory?.createVideoSource(false)
            Logger.step("WEBRTC_VIDEO_SOURCE", "Video source created: ${videoSource != null}")

            // Создание камеры
            setupCamera()

            // Создание видео трека
            localVideoTrack = peerConnectionFactory?.createVideoTrack("videoTrack", videoSource)
            localVideoTrack?.setEnabled(true) // Явно включаем видеотрек
            Logger.step("WEBRTC_VIDEO_TRACK", "Video track created and enabled: ${localVideoTrack != null}, enabled: ${localVideoTrack?.enabled()}")

            // Создание аудио источника и трека
            val audioConstraints = MediaConstraints()
            audioSource = peerConnectionFactory?.createAudioSource(audioConstraints)
            localAudioTrack = peerConnectionFactory?.createAudioTrack("audioTrack", audioSource)
            localAudioTrack?.setEnabled(true) // Явно включаем аудиотрек
            Logger.step("WEBRTC_AUDIO_TRACK", "Audio track created and enabled: ${localAudioTrack != null}, enabled: ${localAudioTrack?.enabled()}")

            Logger.step("WEBRTC_MEDIA_CREATED", "Media sources created successfully")

        } catch (e: Exception) {
            Logger.error("WEBRTC_MEDIA_ERROR", "Failed to create media sources", e)
            _events.value = WebRTCEvent.Error("Ошибка создания медиа источников: ${e.message}")
        }
    }

    /**
     * Настройка камеры
     */
    private fun setupCamera() {
        try {
            val cameraEnumerator = Camera2Enumerator(context)

            // Поиск подходящей камеры
            val cameraName = findCamera(cameraEnumerator, isFrontCamera)

            if (cameraName != null) {
                videoCapturer = cameraEnumerator.createCapturer(cameraName, null)

                // Создание SurfaceTextureHelper
                val surfaceTextureHelper = SurfaceTextureHelper.create(
                    "CaptureThread", eglBase?.eglBaseContext
                )

                // Инициализация камеры
                videoCapturer?.initialize(surfaceTextureHelper, context, videoSource?.capturerObserver)

                // ИСПРАВЛЕНИЕ: Автоматически запускаем камеру для предпросмотра
                videoCapturer?.startCapture(1280, 720, 30)

                Logger.step("WEBRTC_CAMERA_SETUP", "Camera setup completed and preview started: $cameraName")

            } else {
                throw Exception("No suitable camera found")
            }

        } catch (e: Exception) {
            Logger.error("WEBRTC_CAMERA_ERROR", "Failed to setup camera", e)
            _events.value = WebRTCEvent.Error("Ошибка настройки камеры: ${e.message}")
        }
    }

    /**
     * Поиск камеры
     */
    private fun findCamera(enumerator: CameraEnumerator, useFrontCamera: Boolean): String? {
        val deviceNames = enumerator.deviceNames

        // Сначала ищем нужную камеру
        for (deviceName in deviceNames) {
            if (useFrontCamera && enumerator.isFrontFacing(deviceName)) {
                return deviceName
            } else if (!useFrontCamera && enumerator.isBackFacing(deviceName)) {
                return deviceName
            }
        }

        // Если не нашли, берем первую доступную
        return if (deviceNames.isNotEmpty()) deviceNames[0] else null
    }

    /**
     * Начало трансляции
     */
    fun startStreaming(sessionId: String, operatorId: String, cameraType: String = "back") {
        scope.launch {
            var attempts = 0
            val maxAttempts = 3

            while (attempts < maxAttempts) {
                try {
                    Logger.step("WEBRTC_START_STREAMING", "Starting streaming for session: $sessionId (attempt ${attempts + 1}/$maxAttempts)")

                    // Определяем нужную камеру
                    val needFrontCamera = cameraType == "front"

                    // Если нужно переключить камеру, делаем это
                    if (needFrontCamera != isFrontCamera) {
                        Logger.step("WEBRTC_CAMERA_SWITCH", "Switching camera from ${if (isFrontCamera) "front" else "back"} to ${if (needFrontCamera) "front" else "back"}")

                        // Останавливаем текущую камеру
                        videoCapturer?.stopCapture()
                        delay(500) // Даем время на остановку

                        // Обновляем настройку
                        isFrontCamera = needFrontCamera

                        // Пересоздаем камеру с новым типом
                        setupCamera()
                        delay(1000) // Даем время на инициализацию
                    }

                    // КРИТИЧНО: Запускаем камеру ПЕРЕД созданием видеотрека
                    Logger.step("WEBRTC_CAMERA_START", "Starting camera capture at 1280x720@30fps")
                    videoCapturer?.stopCapture() // Сначала останавливаем если была запущена
                    delay(300)
                    videoCapturer?.startCapture(1280, 720, 30)
                    isStreamingActive = true
                    delay(1500) // УВЕЛИЧИВАЕМ задержку для стабилизации камеры

                    // Пересоздаем видео трек ПОСЛЕ запуска камеры для гарантии получения данных
                    localVideoTrack?.dispose()
                    localVideoTrack = peerConnectionFactory?.createVideoTrack("videoTrack_$sessionId", videoSource)
                    localVideoTrack?.setEnabled(true)
                    Logger.step("WEBRTC_VIDEO_TRACK_RECREATED", "Video track recreated after camera start: enabled=${localVideoTrack?.enabled()}")

                    // НОВОЕ: Переподключаем локальный рендерер к новому видео треку
                    localVideoRenderer?.let { renderer ->
                        localVideoTrack?.addSink(renderer)
                        Logger.step("WEBRTC_RENDERER_RECONNECTED", "Local video renderer reconnected to new video track")
                    }

                    // Создаем peer connection для этой сессии с повышенной надежностью
                    createPeerConnectionWithRetry(sessionId, operatorId)

                    // НОВОЕ: Запуск таймера для сбора статистики
                    startStatisticsTimer(sessionId)

                    _events.value = WebRTCEvent.CameraStarted(sessionId)
                    Logger.step("WEBRTC_STREAMING_STARTED", "✅ Streaming started successfully for session: $sessionId")
                    return@launch // Успешно запустили, выходим из цикла

                } catch (e: Exception) {
                    attempts++
                    Logger.error("WEBRTC_START_ERROR_ATTEMPT_$attempts", "Failed to start streaming (attempt $attempts/$maxAttempts)", e)

                    if (attempts < maxAttempts) {
                        Logger.step("WEBRTC_RETRY", "Retrying in ${attempts * 1000}ms...")
                        delay(attempts * 1000L) // Увеличиваем задержку с каждой попыткой
                    } else {
                        _events.value = WebRTCEvent.Error("Ошибка запуска трансляции после $maxAttempts попыток: ${e.message}")
                        return@launch
                    }
                }
            }
        }
    }

    /**
     * Создание peer connection
     */
    private fun createPeerConnection(sessionId: String, operatorId: String? = null) {
        // ИСПРАВЛЕНИЕ: Настройка ICE серверов для получения IP от сигналинг центра
        val rtcConfig = PeerConnection.RTCConfiguration(
            listOf(
                // Добавляем STUN сервер для получения внешнего IP
                PeerConnection.IceServer.builder("stun:stun.l.google.com:19302").createIceServer(),
                // НОВОЕ: Добавляем получение ICE серверов от сигналинг центра
                PeerConnection.IceServer.builder("stun:${getSignalingServerHost()}:3478").createIceServer()
            )
        ).apply {
            // Настройки для оптимального соединения
            bundlePolicy = PeerConnection.BundlePolicy.MAXBUNDLE
            rtcpMuxPolicy = PeerConnection.RtcpMuxPolicy.REQUIRE
            tcpCandidatePolicy = PeerConnection.TcpCandidatePolicy.DISABLED
            continualGatheringPolicy = PeerConnection.ContinualGatheringPolicy.GATHER_CONTINUALLY
            // НОВОЕ: Включаем агрессивный сбор ICE candidates
        }

        val peerConnection = peerConnectionFactory?.createPeerConnection(rtcConfig, object : PeerConnection.Observer {
            override fun onIceCandidate(candidate: IceCandidate?) {
                candidate?.let {
                    Logger.step("WEBRTC_ICE_CANDIDATE", "ICE candidate generated: ${it.sdp}")

                    // ИСПРАВЛЕНИЕ: Отправляем ICE candidate с правильным форматом
                    val candidateJson = org.json.JSONObject().apply {
                        put("candidate", it.sdp)
                        put("sdpMid", it.sdpMid)
                        put("sdpMLineIndex", it.sdpMLineIndex)
                        // НОВОЕ: Добавляем информацию о источнике IP
                        put("usernameFragment", it.sdp.substringAfter("ufrag ").substringBefore(" "))
                    }

                    onIceCandidateCreated?.invoke(sessionId, candidateJson.toString())
                }
            }

            override fun onIceCandidatesRemoved(candidates: Array<out IceCandidate>?) {
                Logger.step("WEBRTC_ICE_REMOVED", "ICE candidates removed: ${candidates?.size}")
            }

            override fun onIceConnectionChange(newState: PeerConnection.IceConnectionState?) {
                Logger.step("WEBRTC_ICE_STATE", "ICE connection state: $newState")
                when (newState) {
                    PeerConnection.IceConnectionState.CONNECTED -> {
                        _events.value = WebRTCEvent.Connected
                    }
                    PeerConnection.IceConnectionState.DISCONNECTED,
                    PeerConnection.IceConnectionState.FAILED -> {
                        _events.value = WebRTCEvent.Disconnected
                    }
                    else -> {}
                }
            }

            override fun onConnectionChange(newState: PeerConnection.PeerConnectionState?) {
                Logger.step("WEBRTC_CONNECTION_STATE", "Peer connection state: $newState")
            }

            // ...existing observer methods...
            override fun onSignalingChange(p0: PeerConnection.SignalingState?) {}
            override fun onIceGatheringChange(p0: PeerConnection.IceGatheringState?) {}
            override fun onAddStream(p0: MediaStream?) {}
            override fun onRemoveStream(p0: MediaStream?) {}
            override fun onDataChannel(p0: DataChannel?) {}
            override fun onRenegotiationNeeded() {}
            override fun onAddTrack(p0: RtpReceiver?, p1: Array<out MediaStream>?) {}
            override fun onIceConnectionReceivingChange(receiving: Boolean) {
                Logger.step(TAG, "🧊 Получение ICE: $receiving")
            }
        })

        if (peerConnection == null) {
            Logger.error("WEBRTC_PC_CREATE_ERROR", "Failed to create peer connection", null)
            _events.value = WebRTCEvent.Error("Не удалось создать peer connection")
            return
        }

        // ИСПРАВЛЕНИЕ: Добавляем треки ПЕРЕД созданием offer
        localVideoTrack?.let { videoTrack ->
            peerConnection.addTrack(videoTrack, listOf("main_stream"))
            Logger.step("WEBRTC_VIDEO_TRACK_ADDED", "Video track added to peer connection: enabled=${videoTrack.enabled()}")
        }

        localAudioTrack?.let { audioTrack ->
            peerConnection.addTrack(audioTrack, listOf("main_stream"))
            Logger.step("WEBRTC_AUDIO_TRACK_ADDED", "Audio track added to peer connection: enabled=${audioTrack.enabled()}")
        }

        activePeerConnections[sessionId] = peerConnection

        // Создаем offer только если указан operatorId (то есть это запрос от оператора)
        if (operatorId != null) {
            createOffer(sessionId, peerConnection)
        }
    }

    /**
     * НОВОЕ: Получение хоста сигналинг сервера для ICE
     */
    private fun getSignalingServerHost(): String {
        // ИСПРАВЛЕНИЕ: Используем прямой возврат IP вашего сервера
        return "192.168.219.108"
    }

    /**
     * Создание offer
     */
    private fun createOffer(sessionId: String, peerConnection: PeerConnection?) {
        val constraints = MediaConstraints().apply {
            // ИСПРАВЛЕНИЕ: Упрощаем constraints для лучшей совместимости
            mandatory.add(MediaConstraints.KeyValuePair("OfferToReceiveAudio", "false"))
            mandatory.add(MediaConstraints.KeyValuePair("OfferToReceiveVideo", "false"))
            // НОВОЕ: Добавляем constraints для обеспечения передачи видео
            mandatory.add(MediaConstraints.KeyValuePair("IceRestart", "false"))
            mandatory.add(MediaConstraints.KeyValuePair("VoiceActivityDetection", "false"))
        }

        Logger.step("WEBRTC_CREATE_OFFER", "Creating offer with simplified constraints for session: $sessionId")

        // Дополнительная проверка треков перед созданием offer
        val videoTrackState = localVideoTrack?.let { "enabled=${it.enabled()}, state=${it.state()}" } ?: "null"
        val audioTrackState = localAudioTrack?.let { "enabled=${it.enabled()}, state=${it.state()}" } ?: "null"
        Logger.step("WEBRTC_TRACKS_CHECK", "Before offer - Video: $videoTrackState, Audio: $audioTrackState")

        peerConnection?.createOffer(object : SdpObserver {
            override fun onCreateSuccess(description: SessionDescription?) {
                description?.let { sdp ->
                    val originalSdp = sdp.description

                    // Проверяем содержимое SDP
                    val hasVideo = originalSdp.contains("m=video")
                    val hasAudio = originalSdp.contains("m=audio")
                    val hasVP8 = originalSdp.contains("VP8")
                    val hasH264 = originalSdp.contains("H264")

                    Logger.step("WEBRTC_SDP_ANALYSIS", "SDP contains - Video: $hasVideo, Audio: $hasAudio, VP8: $hasVP8, H264: $hasH264")
                    Logger.step("WEBRTC_OFFER_SDP", "Offer SDP created: ${originalSdp.take(300)}...")

                    peerConnection.setLocalDescription(object : SdpObserver {
                        override fun onSetSuccess() {
                            // Отправляем оригинальный offer
                            onOfferCreated?.invoke(sessionId, originalSdp)
                            Logger.step("WEBRTC_OFFER_CREATED", "✅ Offer created and sent for session: $sessionId")
                        }
                        override fun onSetFailure(error: String?) {
                            Logger.error("WEBRTC_SET_LOCAL_ERROR", "Failed to set local description: $error", null)
                            _events.value = WebRTCEvent.Error("Ошибка установки локального описания: $error")
                        }
                        override fun onCreateSuccess(p0: SessionDescription?) {}
                        override fun onCreateFailure(p0: String?) {}
                    }, sdp)
                }
            }

            override fun onCreateFailure(error: String?) {
                Logger.error("WEBRTC_CREATE_OFFER_ERROR", "Failed to create offer: $error", null)
                _events.value = WebRTCEvent.Error("Ошибка создания offer: $error")
            }

            override fun onSetSuccess() {}
            override fun onSetFailure(error: String?) {}
        }, constraints)
    }

    /**
     * Обработка answer
     */
    fun handleAnswer(sessionId: String, answerSdp: String) {
        try {
            val answer = SessionDescription(SessionDescription.Type.ANSWER, answerSdp)
            activePeerConnections[sessionId]?.setRemoteDescription(object : SdpObserver {
                override fun onSetSuccess() {
                    Logger.step("WEBRTC_ANSWER_SET", "Answer set successfully for session: $sessionId")
                }
                override fun onSetFailure(error: String?) {
                    Logger.error("WEBRTC_SET_ANSWER_ERROR", "Failed to set answer: $error", null)
                }
                override fun onCreateSuccess(p0: SessionDescription?) {}
                override fun onCreateFailure(p0: String?) {}
            }, answer)

        } catch (e: Exception) {
            Logger.error("WEBRTC_HANDLE_ANSWER_ERROR", "Failed to handle answer", e)
            _events.value = WebRTCEvent.Error("Ошибка обработки answer: ${e.message}")
        }
    }

    /**
     * Обработка ICE кандидата
     */
    fun handleIceCandidate(sessionId: String, candidateJson: String) {
        try {
            val json = org.json.JSONObject(candidateJson)
            val candidate = IceCandidate(
                json.getString("sdpMid"),
                json.getInt("sdpMLineIndex"),
                json.getString("candidate")
            )

            activePeerConnections[sessionId]?.addIceCandidate(candidate)
            Logger.step("WEBRTC_ICE_ADDED", "ICE candidate added for session: $sessionId")

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

    /**
     * Переключение камеры
     */
    fun switchCamera() {
        try {
            val cameraVideoCapturer = videoCapturer as? CameraVideoCapturer
            cameraVideoCapturer?.switchCamera(object : CameraVideoCapturer.CameraSwitchHandler {
                override fun onCameraSwitchDone(isFrontCamera: Boolean) {
                    this@WebRTCManager.isFrontCamera = isFrontCamera
                    Logger.step("WEBRTC_CAMERA_SWITCHED", "Camera switched to: ${if (isFrontCamera) "front" else "back"}")
                }

                override fun onCameraSwitchError(errorDescription: String?) {
                    Logger.error("WEBRTC_CAMERA_SWITCH_ERROR", "Failed to switch camera: $errorDescription", null)
                    _events.value = WebRTCEvent.Error("Ошибка переключения камеры: $errorDescription")
                }
            })

        } catch (e: Exception) {
            Logger.error("WEBRTC_SWITCH_ERROR", "Failed to switch camera", e)
            _events.value = WebRTCEvent.Error("Ошибка переключения камеры: ${e.message}")
        }
    }

    /**
     * Остановка трансляции для конкретной сессии
     */
    fun stopStreaming(sessionId: String) {
        try {
            Logger.step("WEBRTC_STOP_STREAMING", "Stopping streaming for session: $sessionId")

            activePeerConnections[sessionId]?.close()
            activePeerConnections.remove(sessionId)

            // Если это была последняя сессия, останавливаем камеру
            if (activePeerConnections.isEmpty()) {
                videoCapturer?.stopCapture()
                isStreamingActive = false
            }

            // НОВОЕ: Остановка таймера статистики
            stopStatisticsTimer()

            _events.value = WebRTCEvent.CameraStopped(sessionId)
            Logger.step("WEBRTC_STREAMING_STOPPED", "Streaming stopped for session: $sessionId")

        } catch (e: Exception) {
            Logger.error("WEBRTC_STOP_ERROR", "Failed to stop streaming", e)
        }
    }

    /**
     * Остановка всех трансляций
     */
    fun stopAllStreaming() {
        try {
            Logger.step("WEBRTC_STOP_ALL", "Stopping all streaming")

            activePeerConnections.forEach { (sessionId, peerConnection) ->
                try {
                    peerConnection.close()
                    _events.value = WebRTCEvent.CameraStopped(sessionId)
                } catch (e: Exception) {
                    Logger.error("WEBRTC_STOP_SESSION_ERROR", "Failed to stop session: $sessionId", e)
                }
            }

            activePeerConnections.clear()
            videoCapturer?.stopCapture()
            isStreamingActive = false

            // НОВОЕ: Остановка таймера статистики
            stopStatisticsTimer()

            Logger.step("WEBRTC_ALL_STOPPED", "All streaming stopped")

        } catch (e: Exception) {
            Logger.error("WEBRTC_STOP_ALL_ERROR", "Failed to stop all streaming", e)
        }
    }

    /**
     * Завершение сессии
     */
    fun endSession() {
        stopAllStreaming()
    }

    /**
     * Освобождение ресурсов
     */
    fun dispose() {
        try {
            Logger.step("WEBRTC_DISPOSE", "Disposing WebRTC manager")

            stopAllStreaming()

            videoCapturer?.dispose()
            videoSource?.dispose()
            audioSource?.dispose()
            localVideoTrack?.dispose()
            localAudioTrack?.dispose()
            peerConnectionFactory?.dispose()
            eglBase?.release()

            scope.cancel()

            Logger.step("WEBRTC_DISPOSED", "WebRTC manager disposed")

        } catch (e: Exception) {
            Logger.error("WEBRTC_DISPOSE_ERROR", "Failed to dispose WebRTC manager", e)
        }
    }

    /**
     * НОВОЕ: Запуск таймера для сбора статистики
     */
    private fun startStatisticsTimer(sessionId: String) {
        statisticsTimer?.cancel()

        statisticsTimer = Timer().apply {
            scheduleAtFixedRate(object : TimerTask() {
                override fun run() {
                    // Используем детальную статистику вместо простой
                    collectDetailedStatistics(sessionId)
                }
            }, 0, STATS_INTERVAL)
        }

        // Обновляем состояние трансляции
        _streamingState.value = _streamingState.value.copy(
            isStreaming = true,
            sessionId = sessionId,
            startTime = System.currentTimeMillis(),
            cameraType = if (isFrontCamera) "front" else "back"
        )
    }

    /**
     * НОВОЕ: Сбор реальной статистики WebRTC (упрощенная версия)
     */
    private fun collectWebRTCStatistics(sessionId: String) {
        val peerConnection = activePeerConnections[sessionId] ?: return

        try {
            peerConnection.getStats { reports ->
                // Используем простую заглушку статистики, так как структура RTCStatsReport может различаться
                val currentTime = System.currentTimeMillis()
                val duration = (currentTime - _streamingState.value.startTime) / 1000.0

                // Простая имитация статистики
                val videoStats = VideoStatistics(
                    fps = if (duration > 1) 30 else 0, // Имитируем 30 FPS
                    bitrate = if (duration > 1) 1000000L else 0L, // 1 Mbps
                    bytesSent = (duration * 125000).toLong(), // Примерно 1 Mbps
                    width = 1280,
                    height = 720
                )

                // Обновляем состояние
                _streamingState.value = _streamingState.value.copy(
                    statistics = videoStats
                )

                _events.value = WebRTCEvent.StatisticsUpdated(videoStats)
            }
        } catch (e: Exception) {
            Logger.error("WEBRTC_STATS_ERROR", "Failed to collect statistics", e)
            // В случае ошибки используем базовую статистику
            val videoStats = VideoStatistics(
                fps = 30,
                bitrate = 1000000L,
                bytesSent = 0L,
                width = 1280,
                height = 720
            )

            _streamingState.value = _streamingState.value.copy(
                statistics = videoStats
            )
        }
    }

    /**
     * НОВОЕ: Остановка таймера статистики
     */
    private fun stopStatisticsTimer() {
        statisticsTimer?.cancel()
        statisticsTimer = null

        // Сброс состояния трансляции
        _streamingState.value = StreamingState()
    }

    /**
     * НОВОЕ: Подключение локального видео рендерера для предпросмотра
     */
    fun attachLocalVideoRenderer(renderer: SurfaceViewRenderer) {
        try {
            localVideoRenderer = renderer
            localVideoTrack?.addSink(renderer)
            Logger.step("WEBRTC_RENDERER_ATTACHED", "✅ Local video renderer attached successfully")
        } catch (e: Exception) {
            Logger.error("WEBRTC_RENDERER_ERROR", "Failed to attach local video renderer", e)
        }
    }

    /**
     * НОВОЕ: Отключение локального видео рендерера
     */
    fun detachLocalVideoRenderer() {
        try {
            localVideoRenderer?.let { renderer ->
                localVideoTrack?.removeSink(renderer)
                localVideoRenderer = null
                Logger.step("WEBRTC_RENDERER_DETACHED", "Local video renderer detached")
            }
        } catch (e: Exception) {
            Logger.error("WEBRTC_RENDERER_DETACH_ERROR", "Failed to detach local video renderer", e)
        }
    }

    /**
     * НОВОЕ: Получение EGL контекста для рендерера
     */
    fun getEglBaseContext(): EglBase.Context? {
        return eglBase?.eglBaseContext
    }

    /**
     * НОВОЕ: Подробное логирование WebRTC соединений и передачи данных
     */
    private fun logConnectionDetails(sessionId: String, peerConnection: PeerConnection) {
        try {
            // Логируем конфигурацию ICE серверов
            Logger.step("WEBRTC_ICE_SERVERS", "ICE servers configuration for session: $sessionId")

            // Логируем состояние соединения
            val connectionState = peerConnection.connectionState()
            val iceConnectionState = peerConnection.iceConnectionState()
            val iceGatheringState = peerConnection.iceGatheringState()
            val signalingState = peerConnection.signalingState()

            Logger.step("WEBRTC_CONNECTION_STATE", "Session: $sessionId - Connection: $connectionState, ICE: $iceConnectionState, Gathering: $iceGatheringState, Signaling: $signalingState")

            // Получаем локальное и удаленное описание
            val localDescription = peerConnection.localDescription
            val remoteDescription = peerConnection.remoteDescription

            localDescription?.let { desc ->
                Logger.step("WEBRTC_LOCAL_SDP", "Session: $sessionId - Local SDP type: ${desc.type}")
                Logger.step("WEBRTC_LOCAL_SDP_CONTENT", "Session: $sessionId - Local SDP: ${desc.description.take(500)}...")

                // Анализируем SDP для понимания куда идет трафик
                analyzeSDP(sessionId, desc.description, "LOCAL")
            }

            remoteDescription?.let { desc ->
                Logger.step("WEBRTC_REMOTE_SDP", "Session: $sessionId - Remote SDP type: ${desc.type}")
                Logger.step("WEBRTC_REMOTE_SDP_CONTENT", "Session: $sessionId - Remote SDP: ${desc.description.take(500)}...")

                // Анализируем SDP для понимания куда идет трафик
                analyzeSDP(sessionId, desc.description, "REMOTE")
            }

        } catch (e: Exception) {
            Logger.error("WEBRTC_LOG_ERROR", "Failed to log connection details", e)
        }
    }

    /**
     * НОВОЕ: Анализ SDP для выявления целевых адресов и портов
     */
    private fun analyzeSDP(sessionId: String, sdp: String, type: String) {
        try {
            val lines = sdp.split("\n")

            // Ищем connection data (c=)
            lines.filter { it.startsWith("c=") }.forEach { line ->
                Logger.step("WEBRTC_SDP_CONNECTION", "Session: $sessionId [$type] - Connection data: $line")
            }

            // Ищем media descriptions (m=)
            lines.filter { it.startsWith("m=") }.forEach { line ->
                Logger.step("WEBRTC_SDP_MEDIA", "Session: $sessionId [$type] - Media: $line")
            }

            // Ищем атрибуты кандидатов (a=candidate:)
            lines.filter { it.startsWith("a=candidate:") }.forEach { line ->
                val parts = line.split(" ")
                if (parts.size >= 5) {
                    val ip = parts[4]
                    val port = parts[5]
                    val protocol = parts[2]
                    Logger.step("WEBRTC_SDP_CANDIDATE", "Session: $sessionId [$type] - Candidate: $protocol $ip:$port")
                }
            }

            // Ищем удаленные адреса (a=remote-candidates)
            lines.filter { it.startsWith("a=remote-candidates") }.forEach { line ->
                Logger.step("WEBRTC_SDP_REMOTE_CANDIDATES", "Session: $sessionId [$type] - Remote candidates: $line")
            }

        } catch (e: Exception) {
            Logger.error("WEBRTC_SDP_ANALYSIS_ERROR", "Failed to analyze SDP", e)
        }
    }

    /**
     * НОВОЕ: Детальная статистика соединения с информацией о трафике
     */
    private fun collectDetailedStatistics(sessionId: String) {
        val peerConnection = activePeerConnections[sessionId] ?: return

        try {
            Logger.step("WEBRTC_STATS_COLLECTION", "Collecting detailed statistics for session: $sessionId")

            peerConnection.getStats { stats ->
                var bytesSent = 0L
                var bitrate = 0L
                var width = 0
                var height = 0
                var fps = 0
                var packetsLost = 0
                var jitter = 0.0
                var rtt = 0
                var framerate = 0

                // Анализ отчетов статистики
                for (report in stats.statsMap.values) {
                    when (report.type) {
                        "outbound-rtp" -> {
                            // Обработка исходящего видео потока
                            if (report.members.containsKey("bytesSent")) {
                                bytesSent = report.members["bytesSent"] as? Long ?: 0L
                                width = report.members["frameWidth"] as? Int ?: 0
                                height = report.members["frameHeight"] as? Int ?: 0
                                fps = report.members["framesPerSecond"] as? Int ?: 0
                                framerate = fps
                            }
                        }
                        "codec" -> {
                            // Обработка параметров кодека
                            val mimeType = report.members["mimeType"]?.toString() ?: ""
                            if (mimeType.contains("video")) {
                                bitrate = report.members["bitrate"] as? Long ?: 0L
                                if (bitrate == 0L) {
                                    // Если bitrate не указан явно, рассчитываем по переданным байтам
                                    bitrate = bytesSent * 8 / (STATS_INTERVAL / 1000)
                                }
                            }
                        }
                        "track" -> {
                            // Дополнительные метрики трека
                            if (report.members.containsKey("jitterBufferDelay")) {
                                jitter = report.members["jitter"] as? Double ?: 0.0
                            }
                        }
                    }
                }

                // Создание и обновление объекта статистики
                val videoStats = VideoStatistics(
                    fps = fps.coerceAtLeast(1), // Гарантируем минимум 1 FPS для индикации активности
                    bitrate = bitrate.coerceAtLeast(1000), // Минимум 1 Kbps
                    bytesSent = bytesSent,
                    width = width.coerceAtLeast(640), // Минимальное разрешение
                    height = height.coerceAtLeast(480),
                    packetsLost = packetsLost,
                    jitter = jitter,
                    rtt = rtt.toLong(),
                    framerate = framerate
                )

                // Обновляем состояние трансляции и статистику
                _streamingState.value = _streamingState.value.copy(
                    statistics = videoStats
                )

                // Отправляем событие об обновлении статистики
                _events.value = WebRTCEvent.StatisticsUpdated(videoStats)

                Logger.step("WEBRTC_VIDEO_STATS", "Session: $sessionId - FPS: $fps, Bitrate: $bitrate, Bytes sent: $bytesSent")
            }
        } catch (e: Exception) {
            Logger.error("WEBRTC_STATS_ERROR", "Failed to collect detailed statistics", e)

            // Запасной вариант статистики в случае ошибки
            val videoStats = VideoStatistics(
                fps = 30,
                bitrate = 1000000L,
                bytesSent = _streamingState.value.statistics?.bytesSent ?: 0,
                width = 1280,
                height = 720
            )

            _streamingState.value = _streamingState.value.copy(
                statistics = videoStats
            )

            _events.value = WebRTCEvent.StatisticsUpdated(videoStats)
        }
    }

    /**
     * Настройка обратных вызовов для сигналинг клиента
     */
    private fun setupSignalingCallbacks() {
        // Обработка входящих сообщений от сигналинг сервера
        signalingClient.onMessageReceived = { message ->
            handleSignalingMessage(message)
        }

        // Обработка создания сессии
        signalingClient.onSessionCreated = { sessionId ->
            currentSessionId = sessionId
            Logger.info(TAG, "✅ Сессия создана: $sessionId")

            // Создаем PeerConnection для новой сессии
            createPeerConnection(sessionId)
        }

        // Обработка подключения оператора
        signalingClient.onOperatorJoined = {
            Logger.info(TAG, "👤 Оператор подключился, создание offer...")
            currentSessionId?.let { sessionId ->
                createOffer(sessionId)
            }
        }
    }

    /**
     * Подключение к серверу сигналинга и создание сессии
     */
    fun connectToSignalingServer(serverUrl: String = "ws://192.168.1.100:8765") {
        Logger.step(TAG, "🔗 Подключение к серверу сигналинга: $serverUrl")

        signalingClient.connect(serverUrl)

        // После подключения создаем сессию устройства
        scope.launch {
            // Ждем подключения
            signalingClient.connectionState.collect { state ->
                if (state == SignalingClient.ConnectionState.CONNECTED) {
                    // Создаем сессию с информацией об устройстве
                    val deviceInfo = JSONObject().apply {
                        put("model", android.os.Build.MODEL)
                        put("manufacturer", android.os.Build.MANUFACTURER)
                        put("android_version", android.os.Build.VERSION.RELEASE)
                        put("device_id", android.provider.Settings.Secure.getString(
                            context.contentResolver,
                            android.provider.Settings.Secure.ANDROID_ID
                        ).take(8))
                        put("app_version", "1.0.0")
                    }

                    signalingClient.createSession(deviceInfo)
                }
            }
        }
    }

    /**
     * НОВОЕ: Создание peer connection с повторными попытками для надежности
     */
    private suspend fun createPeerConnectionWithRetry(sessionId: String, operatorId: String? = null) {
        var attempts = 0
        val maxAttempts = 3

        while (attempts < maxAttempts) {
            try {
                attempts++
                Logger.step("WEBRTC_PC_CREATE_RETRY", "Creating peer connection for session: $sessionId (attempt $attempts/$maxAttempts)")

                // ИСПРАВЛЕНИЕ: Настройка ICE серверов для получения IP от сигналинг центра
                val rtcConfig = PeerConnection.RTCConfiguration(
                    listOf(
                        // Добавляем STUN сервер для получения внешнего IP
                        PeerConnection.IceServer.builder("stun:stun.l.google.com:19302").createIceServer(),
                        PeerConnection.IceServer.builder("stun:stun1.l.google.com:19302").createIceServer(),
                        // НОВОЕ: Добавляем получение ICE серверов от сигналинг центра
                        PeerConnection.IceServer.builder("stun:${getSignalingServerHost()}:3478").createIceServer()
                    )
                ).apply {
                    // Настройки для оптимального соединения
                    bundlePolicy = PeerConnection.BundlePolicy.MAXBUNDLE
                    rtcpMuxPolicy = PeerConnection.RtcpMuxPolicy.REQUIRE
                    tcpCandidatePolicy = PeerConnection.TcpCandidatePolicy.DISABLED
                    continualGatheringPolicy = PeerConnection.ContinualGatheringPolicy.GATHER_CONTINUALLY
                    // УВЕЛИЧИВАЕМ таймауты для стабильности
                    iceConnectionReceivingTimeout = 10000
                    iceBackupCandidatePairPingInterval = 2000
                }

                val peerConnection = peerConnectionFactory?.createPeerConnection(rtcConfig, object : PeerConnection.Observer {
                    override fun onIceCandidate(candidate: IceCandidate?) {
                        candidate?.let {
                            Logger.step("WEBRTC_ICE_CANDIDATE", "ICE candidate generated: ${it.sdp}")

                            // ИСПРАВЛЕНИЕ: Отправляем ICE candidate с правильным форматом
                            val candidateJson = org.json.JSONObject().apply {
                                put("candidate", it.sdp)
                                put("sdpMid", it.sdpMid)
                                put("sdpMLineIndex", it.sdpMLineIndex)
                                // НОВОЕ: Добавляем информацию о источнике IP
                                put("usernameFragment", it.sdp.substringAfter("ufrag ").substringBefore(" "))
                            }

                            onIceCandidateCreated?.invoke(sessionId, candidateJson.toString())
                        }
                    }

                    override fun onIceCandidatesRemoved(candidates: Array<out IceCandidate>?) {
                        Logger.step("WEBRTC_ICE_REMOVED", "ICE candidates removed: ${candidates?.size}")
                    }

                    override fun onIceConnectionChange(newState: PeerConnection.IceConnectionState?) {
                        Logger.step("WEBRTC_ICE_STATE", "ICE connection state: $newState for session: $sessionId")
                        when (newState) {
                            PeerConnection.IceConnectionState.CONNECTED -> {
                                Logger.step("WEBRTC_CONNECTION_SUCCESS", "✅ WebRTC connection established for session: $sessionId")
                                _events.value = WebRTCEvent.Connected
                            }
                            PeerConnection.IceConnectionState.DISCONNECTED -> {
                                Logger.step("WEBRTC_CONNECTION_DISCONNECTED", "⚠️ WebRTC connection disconnected for session: $sessionId")
                                _events.value = WebRTCEvent.Disconnected
                            }
                            PeerConnection.IceConnectionState.FAILED -> {
                                Logger.error("WEBRTC_CONNECTION_FAILED", "❌ WebRTC connection failed for session: $sessionId", null)
                                _events.value = WebRTCEvent.Error("WebRTC connection failed")
                            }
                            else -> {}
                        }
                    }

                    override fun onConnectionChange(newState: PeerConnection.PeerConnectionState?) {
                        Logger.step("WEBRTC_CONNECTION_STATE", "Peer connection state: $newState for session: $sessionId")
                    }

                    // ...existing observer methods...
                    override fun onSignalingChange(p0: PeerConnection.SignalingState?) {}
                    override fun onIceGatheringChange(p0: PeerConnection.IceGatheringState?) {}
                    override fun onAddStream(p0: MediaStream?) {}
                    override fun onRemoveStream(p0: MediaStream?) {}
                    override fun onDataChannel(p0: DataChannel?) {}
                    override fun onRenegotiationNeeded() {
                        Logger.step("WEBRTC_RENEGOTIATION", "Renegotiation needed for session: $sessionId")
                    }
                    override fun onAddTrack(p0: RtpReceiver?, p1: Array<out MediaStream>?) {}
                    override fun onIceConnectionReceivingChange(receiving: Boolean) {
                        Logger.step("WEBRTC_ICE_RECEIVING", "ICE receiving change: $receiving for session: $sessionId")
                    }
                })

                if (peerConnection == null) {
                    throw Exception("Failed to create peer connection")
                }

                // ИСПРАВЛЕНИЕ: Проверяем состояние треков перед добавлением
                delay(500) // Даем время на стабилизацию

                // Добавляем треки ПЕРЕД созданием offer
                localVideoTrack?.let { videoTrack ->
                    if (videoTrack.enabled()) {
                        peerConnection.addTrack(videoTrack, listOf("main_stream"))
                        Logger.step("WEBRTC_VIDEO_TRACK_ADDED", "Video track added to peer connection: enabled=${videoTrack.enabled()}")
                    } else {
                        Logger.error("WEBRTC_VIDEO_TRACK_DISABLED", "Video track is disabled, cannot add to peer connection", null)
                        throw Exception("Video track is disabled")
                    }
                }

                localAudioTrack?.let { audioTrack ->
                    if (audioTrack.enabled()) {
                        peerConnection.addTrack(audioTrack, listOf("main_stream"))
                        Logger.step("WEBRTC_AUDIO_TRACK_ADDED", "Audio track added to peer connection: enabled=${audioTrack.enabled()}")
                    } else {
                        Logger.step("WEBRTC_AUDIO_TRACK_DISABLED", "Audio track is disabled, skipping")
                    }
                }

                activePeerConnections[sessionId] = peerConnection

                // Создаем offer только если указан operatorId (то есть это запрос от оператора)
                if (operatorId != null) {
                    delay(500) // Даем время на добавление треков
                    createOfferWithRetry(sessionId, peerConnection)
                }

                Logger.step("WEBRTC_PC_CREATE_SUCCESS", "✅ Peer connection created successfully for session: $sessionId")
                return // Успешно создали, выходим из цикла

            } catch (e: Exception) {
                Logger.error("WEBRTC_PC_CREATE_ERROR_ATTEMPT_$attempts", "Failed to create peer connection (attempt $attempts/$maxAttempts)", e)

                if (attempts < maxAttempts) {
                    Logger.step("WEBRTC_PC_RETRY", "Retrying peer connection creation in ${attempts * 500}ms...")
                    delay(attempts * 500L) // Увеличиваем задержку с каждой попыткой
                } else {
                    Logger.error("WEBRTC_PC_CREATE_FINAL_ERROR", "Failed to create peer connection after $maxAttempts attempts", e)
                    _events.value = WebRTCEvent.Error("Не удалось создать peer connection после $maxAttempts попыток: ${e.message}")
                    throw e
                }
            }
        }
    }

    /**
     * НОВОЕ: Создание offer с повторными попытками
     */
    private suspend fun createOfferWithRetry(sessionId: String, peerConnection: PeerConnection) {
        var attempts = 0
        val maxAttempts = 3

        while (attempts < maxAttempts) {
            try {
                attempts++
                Logger.step("WEBRTC_OFFER_CREATE_RETRY", "Creating offer for session: $sessionId (attempt $attempts/$maxAttempts)")

                val constraints = MediaConstraints().apply {
                    // ИСПРАВЛЕНИЕ: Упрощаем constraints для лучшей совместимости
                    mandatory.add(MediaConstraints.KeyValuePair("OfferToReceiveAudio", "false"))
                    mandatory.add(MediaConstraints.KeyValuePair("OfferToReceiveVideo", "false"))
                    // НОВОЕ: Добавляем constraints для обеспечения передачи видео
                    mandatory.add(MediaConstraints.KeyValuePair("IceRestart", "false"))
                    mandatory.add(MediaConstraints.KeyValuePair("VoiceActivityDetection", "false"))
                }

                // Дополнительная проверка треков перед созданием offer
                val videoTrackState = localVideoTrack?.let { "enabled=${it.enabled()}, state=${it.state()}" } ?: "null"
                val audioTrackState = localAudioTrack?.let { "enabled=${it.enabled()}, state=${it.state()}" } ?: "null"
                Logger.step("WEBRTC_TRACKS_CHECK", "Before offer - Video: $videoTrackState, Audio: $audioTrackState")

                // Используем корутины для async операции
                val offerDeferred = CompletableDeferred<SessionDescription>()

                peerConnection.createOffer(object : SdpObserver {
                    override fun onCreateSuccess(description: SessionDescription?) {
                        description?.let {
                            offerDeferred.complete(it)
                        } ?: run {
                            offerDeferred.completeExceptionally(Exception("Offer description is null"))
                        }
                    }

                    override fun onCreateFailure(error: String?) {
                        offerDeferred.completeExceptionally(Exception("Failed to create offer: $error"))
                    }

                    override fun onSetSuccess() {}
                    override fun onSetFailure(error: String?) {}
                }, constraints)

                // Ждем результат с таймаутом
                val offer = withTimeout(10000L) { // 10 секунд таймаут
                    offerDeferred.await()
                }

                val originalSdp = offer.description

                // Проверяем содержимое SDP
                val hasVideo = originalSdp.contains("m=video")
                val hasAudio = originalSdp.contains("m=audio")
                val hasVP8 = originalSdp.contains("VP8")
                val hasH264 = originalSdp.contains("H264")

                Logger.step("WEBRTC_SDP_ANALYSIS", "SDP contains - Video: $hasVideo, Audio: $hasAudio, VP8: $hasVP8, H264: $hasH264")

                if (!hasVideo) {
                    throw Exception("Generated SDP does not contain video stream")
                }

                // Устанавливаем локальное описание
                val localSetDeferred = CompletableDeferred<Unit>()

                peerConnection.setLocalDescription(object : SdpObserver {
                    override fun onSetSuccess() {
                        localSetDeferred.complete(Unit)
                    }
                    override fun onSetFailure(error: String?) {
                        localSetDeferred.completeExceptionally(Exception("Failed to set local description: $error"))
                    }
                    override fun onCreateSuccess(p0: SessionDescription?) {}
                    override fun onCreateFailure(p0: String?) {}
                }, offer)

                // Ждем установки локального описания
                withTimeout(5000L) {
                    localSetDeferred.await()
                }

                // Отправляем offer
                onOfferCreated?.invoke(sessionId, originalSdp)
                Logger.step("WEBRTC_OFFER_CREATED", "✅ Offer created and sent successfully for session: $sessionId")
                return // Успешно создали offer, выходим из цикла

            } catch (e: Exception) {
                Logger.error("WEBRTC_OFFER_CREATE_ERROR_ATTEMPT_$attempts", "Failed to create offer (attempt $attempts/$maxAttempts)", e)

                if (attempts < maxAttempts) {
                    Logger.step("WEBRTC_OFFER_RETRY", "Retrying offer creation in ${attempts * 1000}ms...")
                    delay(attempts * 1000L)
                } else {
                    Logger.error("WEBRTC_OFFER_CREATE_FINAL_ERROR", "Failed to create offer after $maxAttempts attempts", e)
                    _events.value = WebRTCEvent.Error("Ошибка создания offer после $maxAttempts попыток: ${e.message}")
                    throw e
                }
            }
        }
    }
}
