package com.radiola.data.repository

import com.radiola.data.remote.CoverEnrichmentManager
import com.radiola.data.remote.NowPlayingSocketClient
import com.radiola.data.remote.RadiolaApi
import com.radiola.domain.model.Track
import com.radiola.domain.repository.NowPlayingRepository
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.combine
import javax.inject.Inject

class NowPlayingRepositoryImpl @Inject constructor(
    private val radiolaApi: RadiolaApi,
    private val socketClient: NowPlayingSocketClient,
    private val coverEnrichment: CoverEnrichmentManager
) : NowPlayingRepository {

    private val _nowPlaying = MutableStateFlow<Map<Int, Track>>(emptyMap())

    init {
        socketClient.connect()
    }

    // Сокет (реалтайм, приоритет) + REST-поллинг с нашего бэкенда.
    // Оба источника ключуются по числовому id станции каталога (== station.id),
    // поэтому матчатся однозначно — без коллизий по одинаковым названиям станций.
    // REST поллится регулярно и всегда свежий; socket-значения НАКАПЛИВАЮТСЯ и
    // НЕ обновляются, если сокет отвалился — поэтому REST в приоритете, иначе
    // залипшее socket-значение навсегда затеняет свежий трек (обложка/название
    // переставали обновляться).
    override fun getNowPlaying(stationId: Int): Flow<Track?> {
        return combine(socketClient.nowPlaying, _nowPlaying) { socketMap, restMap ->
            restMap[stationId] ?: socketMap[stationId]
        }
    }

    override fun getAllNowPlaying(): Flow<Map<Int, Track>> =
        combine(socketClient.nowPlaying, _nowPlaying) { socketMap, restMap ->
            socketMap + restMap
        }

    override suspend fun refreshNowPlaying(): Result<Unit> {
        return try {
            val list = radiolaApi.getNowPlaying()
            _nowPlaying.value = list.associate { dto ->
                dto.stationId to Track(
                    artist = dto.artist,
                    song = dto.song,
                    coverUrl = dto.coverUrl,
                    stationName = dto.name
                )
            }
            // Треки без обложки — обогащаем через iTunes с устройства (наш IP забанен).
            coverEnrichment.enqueue(_nowPlaying.value.values)
            Result.success(Unit)
        } catch (e: Exception) {
            Result.failure(e)
        }
    }

    override fun enrichCoverNow(track: Track) = coverEnrichment.enqueuePriority(track)
}
