package com.omixlab.lckcontrol.p2p

import android.util.Log
import com.omixlab.lckcontrol.p2p.channels.ControlChannelHandler
import com.omixlab.lckcontrol.p2p.channels.FileChannelHandler
import com.omixlab.lckcontrol.p2p.discovery.NsdAdvertiser
import com.omixlab.lckcontrol.p2p.discovery.P2pPreferences
import com.omixlab.lckcontrol.p2p.webrtc.LanSignalingServer
import com.omixlab.lckcontrol.p2p.webrtc.RemoteSignalingClient
import com.omixlab.lckcontrol.p2p.webrtc.WebRtcPeerManager
import kotlinx.coroutines.CoroutineScope
import javax.inject.Inject
import javax.inject.Singleton

/**
 * Orchestrates the complete P2P lifecycle:
 * 1. NSD discovery/advertising
 * 2. LAN signaling server (HTTP on port 8765)
 * 3. Remote signaling (WebSocket to backend)
 * 4. WebRTC peer connection
 * 5. Control + file data channels
 */
@Singleton
class PeerSessionManager @Inject constructor(
    private val nsdAdvertiser: NsdAdvertiser,
    private val lanSignalingServer: LanSignalingServer,
    private val remoteSignalingClient: RemoteSignalingClient,
    private val webRtcPeerManager: WebRtcPeerManager,
    private val controlHandler: ControlChannelHandler,
    private val fileHandler: FileChannelHandler,
    private val p2pPreferences: P2pPreferences,
) {
    companion object {
        private const val TAG = "PeerSessionManager"
    }

    fun start(userId: String, scope: CoroutineScope) {
        Log.d(TAG, "Starting P2P session for user $userId")

        // Initialize WebRTC
        webRtcPeerManager.initialize()

        // Wire up control and file handlers
        webRtcPeerManager.onControlMessage = { json ->
            controlHandler.handleMessage(json)
        }
        webRtcPeerManager.onFileData = { data ->
            fileHandler.handleData(data)
        }

        // Start NSD advertising
        nsdAdvertiser.startAdvertising(userId)

        // Start LAN signaling server
        lanSignalingServer.onOfferReceived = { sdp, candidates, nonce ->
            Log.d(TAG, "Received LAN offer, creating answer")
            webRtcPeerManager.handleOffer(sdp, candidates)
        }
        lanSignalingServer.start(scope)

        // Connect to backend signaling
        remoteSignalingClient.onOfferReceived = { from, sdp ->
            Log.d(TAG, "Received remote offer from $from")
            // Handle remote offer (create answer and send back)
            val candidates = emptyList<com.omixlab.lckcontrol.p2p.webrtc.IceCandidateDto>()
            val response = webRtcPeerManager.handleOffer(sdp, candidates)
            response?.let {
                remoteSignalingClient.sendAnswer(from, it.sdp)
            }
        }
        remoteSignalingClient.connect()
    }

    fun stop() {
        Log.d(TAG, "Stopping P2P session")
        nsdAdvertiser.stopAdvertising()
        lanSignalingServer.stop()
        remoteSignalingClient.disconnect()
        webRtcPeerManager.disconnect()
    }

    fun release() {
        stop()
        webRtcPeerManager.release()
    }
}
