package com.taskttl.data.viewmodel import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.taskttl.data.local.model.Category import com.taskttl.data.local.model.CategoryType import com.taskttl.data.local.model.Countdown import com.taskttl.data.repository.CategoryRepository import com.taskttl.data.repository.CountdownRepository import com.taskttl.data.state.CountdownEffect import com.taskttl.data.state.CountdownIntent import com.taskttl.data.state.CountdownState import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.SharedFlow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.asSharedFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.launch /** * 倒计时视图模型 * @author admin * @date 2025/10/04 * @constructor 创建[CountdownViewModel] * @param [countdownRepository] 倒计时存储库 */ class CountdownViewModel( private val countdownRepository: CountdownRepository, private val categoryRepository: CategoryRepository ) : ViewModel() { private val _state = MutableStateFlow(CountdownState()) val state: StateFlow = _state.asStateFlow() private val _effects = MutableSharedFlow() val effects: SharedFlow = _effects.asSharedFlow() init { handleIntent(CountdownIntent.LoadCountdowns) } fun handleIntent(intent: CountdownIntent) { when (intent) { is CountdownIntent.LoadCountdowns -> loadCountdowns() is CountdownIntent.GetCountdownById -> getCountdownById(intent.countdownId) is CountdownIntent.AddCountdown -> addCountdown(intent.countdown) is CountdownIntent.UpdateCountdown -> updateCountdown(intent.countdown) is CountdownIntent.DeleteCountdown -> deleteCountdown(intent.countdownId) is CountdownIntent.FilterByCategory -> filterByCategory(intent.category) is CountdownIntent.ClearError -> clearError() } } private fun loadCountdowns() { viewModelScope.launch { _state.value = _state.value.copy(isLoading = true, error = null) try { launch { categoryRepository.getCategoriesByType(CategoryType.COUNTDOWN) .collect { categories -> _state.value = _state.value.copy(categories = categories) } } launch { countdownRepository.getAllCountdowns().collect { countdowns -> _state.value = _state.value.copy( countdowns = countdowns, filteredCountdowns = filterCountdowns(countdowns), isLoading = false ) } } } catch (e: Exception) { _state.value = _state.value.copy(isLoading = false, error = e.message ?: "加载倒数日失败") } } } private fun getCountdownById(countdownId: String) { viewModelScope.launch { try { val countdown = countdownRepository.getCountdownById(countdownId) _state.value = _state.value.copy(editingCountdown = countdown) } catch (e: Exception) { _state.value = _state.value.copy(error = e.message ?: "查询倒数日失败") } } } private fun addCountdown(countdown: Countdown) { viewModelScope.launch { try { countdownRepository.insertCountdown(countdown) _effects.emit(CountdownEffect.ShowMessage("倒数日添加成功")) _effects.emit(CountdownEffect.NavigateBack) } catch (e: Exception) { _state.value = _state.value.copy(error = e.message ?: "添加倒数日失败") } } } private fun updateCountdown(countdown: Countdown) { viewModelScope.launch { try { countdownRepository.updateCountdown(countdown) _effects.emit(CountdownEffect.ShowMessage("倒数日更新成功")) } catch (e: Exception) { _state.value = _state.value.copy(error = e.message ?: "更新倒数日失败") } } } private fun deleteCountdown(countdownId: String) { viewModelScope.launch { try { countdownRepository.deleteCountdown(countdownId) _effects.emit(CountdownEffect.ShowMessage("倒数日删除成功")) } catch (e: Exception) { _state.value = _state.value.copy(error = e.message ?: "删除倒数日失败") } } } private fun filterByCategory(category: Category?) { _state.value = _state.value.copy( selectedCategory = category, filteredCountdowns = filterCountdowns(_state.value.countdowns) ) } private fun clearError() { _state.value = _state.value.copy(error = null) } private fun filterCountdowns(countdowns: List): List { val currentState = _state.value return countdowns.filter { countdown -> currentState.selectedCategory?.let { countdown.category == it } ?: true } } }