package com.radiola.data.remote

import com.radiola.domain.model.Track
import io.socket.client.IO
import io.socket.client.Socket
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.jsonObject
import kotlinx.serialization.json.jsonPrimitive
import javax.inject.Inject
import javax.inject.Singleton

@Singleton
class NowPlayingSocketClient @Inject constructor(
    private val json: Json
) {
    private val _nowPlaying = MutableStateFlow<Map<Int, Track>>(emptyMap())
    val nowPlaying: StateFlow<Map<Int, Track>> = _nowPlaying

    private var socket: Socket? = null

    fun connect() {
        if (socket != null) return
        try {
            val opts = IO.Options().apply {
                transports = arrayOf("websocket")
            }
            socket = IO.socket("http://121.127.37.212:3000/now-playing", opts)
            socket?.on("now-playing") { args ->
                if (args.isNotEmpty()) {
                    val data = args[0] as? String ?: return@on
                    handleNowPlayingEvent(data)
                }
            }
            socket?.on(Socket.EVENT_CONNECT) {
                android.util.Log.d("NowPlayingSocket", "Connected")
            }
            socket?.on(Socket.EVENT_DISCONNECT) {
                android.util.Log.d("NowPlayingSocket", "Disconnected")
            }
            socket?.on(Socket.EVENT_CONNECT_ERROR) { args ->
                android.util.Log.e("NowPlayingSocket", "Connect error: ${args.joinToString()}")
            }
            socket?.connect()
        } catch (e: Exception) {
            android.util.Log.e("NowPlayingSocket", "Failed to connect", e)
        }
    }

    fun disconnect() {
        socket?.disconnect()
        socket = null
    }

    private fun handleNowPlayingEvent(data: String) {
        try {
            val obj = json.parseToJsonElement(data).jsonObject
            val stationId = obj["stationId"]?.jsonPrimitive?.content?.toIntOrNull() ?: return
            val song = obj["song"]?.jsonPrimitive?.content ?: return
            val artist = obj["artist"]?.jsonPrimitive?.content ?: return
            val coverUrl = obj["coverUrl"]?.jsonPrimitive?.content

            val track = Track(
                artist = artist,
                song = song,
                coverUrl = coverUrl,
                stationName = ""
            )

            _nowPlaying.value = _nowPlaying.value.toMutableMap().apply {
                put(stationId, track)
            }
        } catch (e: Exception) {
            android.util.Log.e("NowPlayingSocket", "Failed to parse event", e)
        }
    }
}
