package com.hyperling.expensetracker import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.flatMapLatest import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.flow.update import kotlinx.coroutines.launch class ExpenseViewModel ( private val dao: ExpenseDao, ): ViewModel() { private val _sortType = MutableStateFlow(SortType.NAME) private val _state = MutableStateFlow(ExpenseState()) private val _expenses = _sortType .flatMapLatest { sortType -> when(sortType) { SortType.NAME -> dao.selectExpensesName() SortType.COST -> dao.selectExpensesCost() SortType.RATE -> dao.selectExpensesRate() } }.stateIn(viewModelScope, SharingStarted.WhileSubscribed(), emptyList()) val state = combine(_state, _sortType, _expenses) { state, sortType, expenses -> state.copy( expenses = expenses, sortType = sortType ) }.stateIn(viewModelScope, SharingStarted.WhileSubscribed(5000), ExpenseState()) fun onEvent(event: ExpenseEvent) { when(event) { is ExpenseEvent.DeleteExpense -> { viewModelScope.launch { dao.deleteExpense(event.expense) } } ExpenseEvent.HideDialog -> { _state.update { it.copy( isAddingExpense = false ) } } ExpenseEvent.SaveExpense -> { val name = state.value.name val cost = state.value.cost val rate = state.value.rate if (name.isBlank() || cost.isBlank() //|| rate.isBlank() # TBD, enable this once Rate is working. ) { return } val expense = Expense(name, cost, rate) viewModelScope.launch { dao.upsertExpense(expense) } _state.update { it.copy( isAddingExpense = false, name = "", cost = "", rate = Rate.MONTHLY, ) } } is ExpenseEvent.SetName -> { _state.update { it.copy( name = event.name ) } } is ExpenseEvent.SetCost -> { _state.update { it.copy( cost = event.cost ) } } is ExpenseEvent.SetRate -> { _state.update { it.copy( rate = event.rate ) } } ExpenseEvent.ShowDialog -> { _state.update { it.copy( isAddingExpense = true ) } } is ExpenseEvent.SortExpenses -> { _sortType.value = event.sortType } } } }