package de.krisenvorrat.app.ui.dashboard

import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import dagger.hilt.android.lifecycle.HiltViewModel
import de.krisenvorrat.app.domain.model.parseAgeGroupsFromJson
import de.krisenvorrat.app.domain.model.SettingsKey.StringKey
import de.krisenvorrat.app.domain.model.totalDailyKcal
import de.krisenvorrat.app.domain.repository.ItemRepository
import de.krisenvorrat.app.domain.repository.SettingsRepository
import de.krisenvorrat.app.domain.usecase.CalculateCategorySummaryUseCase
import de.krisenvorrat.app.domain.usecase.CalculateSupplyRangeUseCase
import de.krisenvorrat.app.domain.usecase.CalculateTotalValueUseCase
import de.krisenvorrat.app.domain.usecase.GetExpiryWarningsUseCase
import de.krisenvorrat.app.domain.repository.CategoryRepository
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import javax.inject.Inject

@HiltViewModel
internal class DashboardViewModel @Inject constructor(
    private val itemRepository: ItemRepository,
    private val categoryRepository: CategoryRepository,
    private val settingsRepository: SettingsRepository,
    private val calculateCategorySummary: CalculateCategorySummaryUseCase,
    private val calculateTotalValue: CalculateTotalValueUseCase,
    private val calculateSupplyRange: CalculateSupplyRangeUseCase,
    private val getExpiryWarnings: GetExpiryWarningsUseCase
) : ViewModel() {

    private val _uiState = MutableStateFlow(DashboardUiState())
    val uiState: StateFlow<DashboardUiState> = _uiState.asStateFlow()

    init {
        viewModelScope.launch {
            combine(
                itemRepository.getAll(),
                categoryRepository.getAll(),
                settingsRepository.observeString(StringKey.AgeGroups)
            ) { items, categories, ageGroupsJson ->
                val ageGroups = parseAgeGroupsFromJson(ageGroupsJson)
                val totalDailyKcal = ageGroups.totalDailyKcal().let {
                    if (it <= 0) CalculateSupplyRangeUseCase.DEFAULT_TOTAL_DAILY_KCAL else it
                }

                DashboardUiState(
                    categorySummaries = calculateCategorySummary(items, categories),
                    totalValue = calculateTotalValue(items),
                    supplyRangeDays = calculateSupplyRange(items, totalDailyKcal),
                    expiryWarnings = getExpiryWarnings(items),
                    isLoading = false
                )
            }.collect { state ->
                _uiState.update { state }
            }
        }
    }
}
