package com.example.godeye.managers

import android.content.Context
import android.provider.Settings
import android.util.Log
import com.example.godeye.models.*
import com.example.godeye.signaling.SignalingClient
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*

/**
 * Менеджер сигналлинга для управления подключениями к операторам
 */
class SignalingManager(
    private val context: Context
) {
    companion object {
        private const val TAG = "SignalingManager"
    }

    private val signalingClient = SignalingClient()
    private var managerScope = CoroutineScope(Dispatchers.Main + SupervisorJob())

    // Состояния
    val signalingState: StateFlow<SignalingState> = signalingClient.signalingState
    val sessionState: StateFlow<SessionState> = signalingClient.sessionState
    val currentCall: StateFlow<IncomingCall?> = signalingClient.currentCall

    // Callbacks для WebRTC интеграции
    private var webRTCManager: Any? = null // Будет связан с WebRTCManager

    /**
     * Запуск сигналлинга
     */
    fun start(serverUrl: String? = null) {
        Log.d(TAG, "Starting signaling manager")

        managerScope.launch {
            try {
                val deviceInfo = createDeviceInfo()
                val url = serverUrl ?: getDefaultServerUrl()

                Log.d(TAG, "Connecting to signaling server: $url")
                signalingClient.connect(url, deviceInfo)

                // Настраиваем обработчики WebRTC сигналлинга
                setupWebRTCHandlers()

            } catch (e: Exception) {
                Log.e(TAG, "Failed to start signaling", e)
            }
        }
    }

    /**
     * Остановка сигналлинга
     */
    fun stop() {
        Log.d(TAG, "Stopping signaling manager")

        signalingClient.disconnect()
        managerScope.cancel()
        managerScope = CoroutineScope(Dispatchers.Main + SupervisorJob())
    }

    /**
     * Принятие входящего вызова
     */
    fun acceptIncomingCall() {
        Log.d(TAG, "Accepting incoming call")
        signalingClient.acceptCall()
    }

    /**
     * Отклонение входящего вызова
     */
    fun rejectIncomingCall() {
        Log.d(TAG, "Rejecting incoming call")
        signalingClient.rejectCall()
    }

    /**
     * Завершение активного вызова
     */
    fun endActiveCall() {
        Log.d(TAG, "Ending active call")
        signalingClient.endCall()
    }

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

    /**
     * Получение уникального ID устройства
     */
    private fun getDeviceId(): String {
        return try {
            Settings.Secure.getString(
                context.contentResolver,
                Settings.Secure.ANDROID_ID
            ) ?: "unknown_device_${System.currentTimeMillis()}"
        } catch (e: Exception) {
            "unknown_device_${System.currentTimeMillis()}"
        }
    }

    /**
     * Получение имени устройства
     */
    private fun getDeviceName(): String {
        return try {
            "${android.os.Build.MANUFACTURER} ${android.os.Build.MODEL}"
        } catch (e: Exception) {
            "Android Device"
        }
    }

    /**
     * Получение URL сервера по умолчанию
     */
    private fun getDefaultServerUrl(): String {
        // ИСПРАВЛЕНИЕ: Обновляем IP по умолчанию на ваш сервер
        return "ws://192.168.219.108:3000"
    }

    /**
     * Настройка обработчиков WebRTC сигналлинга
     */
    private fun setupWebRTCHandlers() {
        signalingClient.setOnOfferReceived { offer ->
            Log.d(TAG, "Received WebRTC offer")
            // TODO: Передать offer в WebRTCManager
            handleWebRTCOffer(offer)
        }

        signalingClient.setOnAnswerReceived { answer ->
            Log.d(TAG, "Received WebRTC answer")
            // TODO: Передать answer в WebRTCManager
            handleWebRTCAnswer(answer)
        }

        signalingClient.setOnIceCandidateReceived { candidate ->
            Log.d(TAG, "Received ICE candidate")
            // TODO: Передать candidate в WebRTCManager
            handleICECandidate(candidate)
        }

        signalingClient.setOnCallEnded {
            Log.d(TAG, "Call ended by operator")
            handleCallEnded()
        }
    }

    /**
     * Обработка WebRTC Offer
     */
    private fun handleWebRTCOffer(offer: RTCSessionDescription) {
        managerScope.launch {
            try {
                // TODO: Интеграция с WebRTCManager
                Log.d(TAG, "Processing WebRTC offer: ${offer.type}")

                // Здесь должна быть логика создания answer и его отправки
                // val answer = webRTCManager.createAnswer(offer)
                // signalingClient.sendAnswer(answer, currentCall.value?.operatorId ?: "")

            } catch (e: Exception) {
                Log.e(TAG, "Error processing WebRTC offer", e)
            }
        }
    }

    /**
     * Обработка WebRTC Answer
     */
    private fun handleWebRTCAnswer(answer: RTCSessionDescription) {
        managerScope.launch {
            try {
                // TODO: Интеграция с WebRTCManager
                Log.d(TAG, "Processing WebRTC answer: ${answer.type}")

                // webRTCManager.setRemoteDescription(answer)

            } catch (e: Exception) {
                Log.e(TAG, "Error processing WebRTC answer", e)
            }
        }
    }

    /**
     * Обработка ICE Candidate
     */
    private fun handleICECandidate(candidate: RTCIceCandidate) {
        managerScope.launch {
            try {
                // TODO: Интеграция с WebRTCManager
                Log.d(TAG, "Processing ICE candidate")

                // webRTCManager.addIceCandidate(candidate)

            } catch (e: Exception) {
                Log.e(TAG, "Error processing ICE candidate", e)
            }
        }
    }

    /**
     * Обработка завершения вызова
     */
    private fun handleCallEnded() {
        managerScope.launch {
            try {
                // TODO: Очистка WebRTC соединения
                Log.d(TAG, "Cleaning up after call end")

                // webRTCManager.cleanup()

            } catch (e: Exception) {
                Log.e(TAG, "Error cleaning up after call end", e)
            }
        }
    }

    /**
     * Отправка WebRTC Offer (для исходящих вызовов)
     */
    fun sendOffer(offer: RTCSessionDescription) {
        val operatorId = currentCall.value?.operatorId ?: return
        signalingClient.sendOffer(offer, operatorId)
    }

    /**
     * Отправка WebRTC Answer
     */
    fun sendAnswer(answer: RTCSessionDescription) {
        val operatorId = currentCall.value?.operatorId ?: return
        signalingClient.sendAnswer(answer, operatorId)
    }

    /**
     * Отправка ICE Candidate
     */
    fun sendIceCandidate(candidate: RTCIceCandidate) {
        val operatorId = currentCall.value?.operatorId ?: return
        signalingClient.sendIceCandidate(candidate, operatorId)
    }

    /**
     * Получение информации о текущем состоянии
     */
    fun getConnectionInfo(): Map<String, Any> {
        return mapOf(
            "signalingState" to signalingState.value.name,
            "sessionState" to sessionState.value.name,
            "hasActiveCall" to (currentCall.value != null),
            "operatorId" to (currentCall.value?.operatorId ?: "none"),
            "deviceId" to getDeviceId()
        )
    }
}
