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>(emptyMap()) val nowPlaying: StateFlow> = _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) } } }