package com.suno.android.ui.screens.home.mediaplayer import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.suno.android.clip.UpdateClipReactionUseCase import com.suno.android.common_core_utils.SunoLogger import com.suno.android.common_core_utils.constants.ReactionType import com.suno.android.common_data.extensions.xIsOwnedBy import com.suno.android.common_data.mappers.clips.LocalClipData import com.suno.android.common_data.mappers.clips.xAsSongListDataOrNull import com.suno.android.common_data.user.UserSessionRepository import com.suno.android.common_networking.remote.session.User import com.suno.android.gating.Feature import com.suno.android.gating.FeatureManager import com.suno.android.media.MediaManager import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.catch import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.update import kotlinx.coroutines.launch import javax.inject.Inject import kotlin.time.Duration @HiltViewModel class HomeBottomMediaPlayerViewModel @Inject constructor( loggerFactory: SunoLogger.Factory, private val userSessionRepository: UserSessionRepository, private val mediaManager: MediaManager, private val featureManager: FeatureManager, private val updateClipReactionUseCase: UpdateClipReactionUseCase, ) : ViewModel() { private val logger = loggerFactory.create(this@HomeBottomMediaPlayerViewModel) private var _currentViewer: User? = null private val _viewState = MutableStateFlow( UiState( isRemixGateEnabled = featureManager.hasFeature(Feature.RemixClip), ), ) val viewState = _viewState.asStateFlow() init { mediaManager.mediaPlayerFlow().onEach { mediaPlayerState -> _viewState.update { oldState -> oldState.copy( startedPlayingMusic = mediaPlayerState.startedPlayingMusic, isPlaying = mediaPlayerState.isPlaying, currentTimestamp = mediaPlayerState.playtimeDuration, nowPlayingClip = mediaPlayerState.nowPlayingClipData(), ) } }.catch { exception -> logger.e(exception) }.launchIn(viewModelScope) userSessionRepository.sessionConfigurationStateFlow() .onEach { sessionConfiguration -> _currentViewer = sessionConfiguration.user }.catch { exception -> logger.e(exception) }.launchIn(viewModelScope) } fun onPlayPauseClicked() { mediaManager.setIsPlaying(mediaManager.isPlaying().not()) } fun onNextClicked() { mediaManager.moveToNextSong() } fun onPrevClicked() { mediaManager.handleGoToPrevious() } fun onReactClicked( reaction: ReactionType, ) { viewState.value.nowPlayingClip?.let { clip -> viewModelScope.launch { updateClipReactionUseCase( clipId = clip.clipId, currentReactionType = clip.reaction, requestedReactionType = reaction, ) } } } fun canRemixCurrentClip(): Boolean = _viewState.value.nowPlayingClip?.canRemix == true || _viewState.value.nowPlayingClip?.xAsSongListDataOrNull()?.xIsOwnedBy(_currentViewer) == true data class UiState( val startedPlayingMusic: Boolean = false, val isPlaying: Boolean = false, val currentTimestamp: Duration? = null, val nowPlayingClip: LocalClipData? = null, val isRemixGateEnabled: Boolean? = false, ) }