package com.radiola.ui.stations

import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.radiola.domain.geo.GeoBlock
import com.radiola.domain.model.Station
import com.radiola.domain.model.Track
import com.radiola.domain.repository.FavoritesRepository
import com.radiola.domain.repository.NowPlayingRepository
import com.radiola.domain.repository.RegionRepository
import com.radiola.domain.repository.StationRepository
import com.radiola.domain.usecase.GetStationsUseCase
import com.radiola.domain.usecase.PlayStationUseCase
import com.radiola.domain.usecase.RefreshStationsUseCase
import com.radiola.domain.usecase.ToggleFavoriteUseCase
import com.radiola.service.PlayerController
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.*
import kotlinx.coroutines.launch
import javax.inject.Inject

@HiltViewModel
class StationsViewModel @Inject constructor(
    private val getStationsUseCase: GetStationsUseCase,
    private val refreshStationsUseCase: RefreshStationsUseCase,
    private val playStationUseCase: PlayStationUseCase,
    private val toggleFavoriteUseCase: ToggleFavoriteUseCase,
    private val favoritesRepository: FavoritesRepository,
    private val stationRepository: StationRepository,
    private val nowPlayingRepository: NowPlayingRepository,
    private val regionRepository: RegionRepository,
    private val playerController: PlayerController
) : ViewModel() {

    // Активная (играющая) станция — для подсветки карточки в списке.
    val playingStationId: StateFlow<Int?> = playerController.currentStationId
    val isPlaying: StateFlow<Boolean> = playerController.isPlaying

    private val _searchQuery = MutableStateFlow("")
    val searchQuery: StateFlow<String> = _searchQuery.asStateFlow()

    private val _selectedTag = MutableStateFlow<String?>(null)
    val selectedTag: StateFlow<String?> = _selectedTag.asStateFlow()

    private val _isLoading = MutableStateFlow(false)
    val isLoading: StateFlow<Boolean> = _isLoading.asStateFlow()

    private val _error = MutableStateFlow<String?>(null)
    val error: StateFlow<String?> = _error.asStateFlow()

    val stations: StateFlow<List<Station>> = combine(
        getStationsUseCase(),
        _searchQuery,
        _selectedTag
    ) { allStations, query, tag ->
        allStations
            .filter { station ->
                tag == null ||
                station.genre.equals(tag, ignoreCase = true) ||
                station.tags.any { it.equals(tag, ignoreCase = true) }
            }
            .filter { station ->
                query.isBlank() ||
                station.name.contains(query, ignoreCase = true) ||
                station.genre.contains(query, ignoreCase = true)
            }
    }.stateIn(viewModelScope, SharingStarted.WhileSubscribed(5000), emptyList())

    // Чипы-жанры. Для пользователей из РФ убираем жанры украинских станций
    // (Radio ROKS, Kiss FM) — их чипы не показываем вовсе.
    val tags: StateFlow<List<String>> = combine(
        stationRepository.getTags(),
        stationRepository.getStations(),
        regionRepository.countryCode()
    ) { tags, allStations, country ->
        if (GeoBlock.shouldHideUa(country)) {
            val uaGenres = allStations.filter { GeoBlock.isUaStation(it) }.map { it.genre }.toSet()
            tags.filterNot { it in uaGenres }
        } else {
            tags
        }
    }.stateIn(viewModelScope, SharingStarted.WhileSubscribed(5000), emptyList())

    val favoriteIds: StateFlow<Set<Int>> = favoritesRepository.getFavorites()
        .map { list -> list.map { it.id }.toSet() }
        .stateIn(viewModelScope, SharingStarted.WhileSubscribed(5000), emptySet())

    // Текущие треки по id станции (каталожный == station.id) — без коллизий по имени.
    val nowPlaying: StateFlow<Map<Int, Track>> = nowPlayingRepository.getAllNowPlaying()
        .stateIn(viewModelScope, SharingStarted.WhileSubscribed(5000), emptyMap())

    init {
        // Определяем страну пользователя по IP (для гео-фильтрации станций).
        viewModelScope.launch { regionRepository.refresh() }
        viewModelScope.launch {
            _isLoading.value = true
            refreshStationsUseCase()
                .onFailure { _error.value = it.localizedMessage ?: "Ошибка загрузки" }
            _isLoading.value = false
        }
        // Периодическое обновление now-playing каждые 20 секунд.
        viewModelScope.launch {
            while (true) {
                nowPlayingRepository.refreshNowPlaying()
                delay(20_000)
            }
        }
    }

    fun onSearchQueryChange(query: String) {
        _searchQuery.value = query
    }

    fun onTagSelected(tag: String?) {
        _selectedTag.value = tag
    }

    fun playStation(station: Station) {
        viewModelScope.launch {
            playStationUseCase(station)
        }
    }

    fun toggleFavorite(station: Station) {
        viewModelScope.launch {
            toggleFavoriteUseCase(station)
        }
    }
}
