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 = playerController.currentStationId val isPlaying: StateFlow = playerController.isPlaying private val _searchQuery = MutableStateFlow("") val searchQuery: StateFlow = _searchQuery.asStateFlow() private val _selectedTag = MutableStateFlow(null) val selectedTag: StateFlow = _selectedTag.asStateFlow() private val _isLoading = MutableStateFlow(false) val isLoading: StateFlow = _isLoading.asStateFlow() private val _error = MutableStateFlow(null) val error: StateFlow = _error.asStateFlow() val stations: StateFlow> = 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> = 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> = favoritesRepository.getFavorites() .map { list -> list.map { it.id }.toSet() } .stateIn(viewModelScope, SharingStarted.WhileSubscribed(5000), emptySet()) // Текущие треки по id станции (каталожный == station.id) — без коллизий по имени. val nowPlaying: StateFlow> = 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) } } }