package com.pixelized.rplexicon import android.util.Log import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.setValue import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.pixelized.rplexicon.data.repository.character.ActionRepository import com.pixelized.rplexicon.data.repository.character.AlterationRepository import com.pixelized.rplexicon.data.repository.character.CharacterSheetRepository import com.pixelized.rplexicon.data.repository.character.DescriptionRepository import com.pixelized.rplexicon.data.repository.character.ItemsRepository import com.pixelized.rplexicon.data.repository.character.SkillRepository import com.pixelized.rplexicon.data.repository.character.SpellRepository import com.pixelized.rplexicon.data.repository.firebase.RemoteConfigRepository import com.pixelized.rplexicon.data.repository.lexicon.CategoryOrderRepository import com.pixelized.rplexicon.data.repository.lexicon.LexiconRepository import com.pixelized.rplexicon.data.repository.lexicon.LocationRepository import com.pixelized.rplexicon.data.repository.lexicon.QuestRepository import com.pixelized.rplexicon.ui.composable.error.FetchErrorUio import com.pixelized.rplexicon.ui.composable.error.FetchErrorUio.Structure.Type import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.async import kotlinx.coroutines.awaitAll import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import javax.inject.Inject @HiltViewModel class LauncherViewModel @Inject constructor( categoryRepository: CategoryOrderRepository, lexiconRepository: LexiconRepository, locationRepository: LocationRepository, questRepository: QuestRepository, alterationRepository: AlterationRepository, characterSheetRepository: CharacterSheetRepository, actionRepository: ActionRepository, spellRepository: SpellRepository, skillRepository: SkillRepository, descriptionRepository: DescriptionRepository, itemsRepository: ItemsRepository, removeConRepository: RemoteConfigRepository // Unused but injected to initialize it. ) : ViewModel() { private val _error = MutableStateFlow(null) val error: Flow get() = _error var isLoading by mutableStateOf(true) private set init { viewModelScope.launch(Dispatchers.Default) { val order = async { try { categoryRepository.fetchCategoryOrder() } catch (exception: Exception) { Log.e(TAG, exception.message, exception) _error.emit(FetchErrorUio.Structure(type = Type.CATEGORY_ORDER)) } } val lexicon = async { try { lexiconRepository.fetchLexicon() } catch (exception: Exception) { Log.e(TAG, exception.message, exception) _error.emit(FetchErrorUio.Structure(type = Type.LEXICON)) } } val location = async { try { locationRepository.fetchMap() } catch (exception: Exception) { Log.e(TAG, exception.message, exception) _error.emit(FetchErrorUio.Structure(type = Type.LOCATION)) } } val quest = async { try { questRepository.fetchQuests() } catch (exception: Exception) { Log.e(TAG, exception.message, exception) _error.emit(FetchErrorUio.Structure(type = Type.QUEST)) } } val characterSheet = async { try { characterSheetRepository.fetchCharacterSheet() } catch (exception: Exception) { Log.e(TAG, exception.message, exception) _error.emit(FetchErrorUio.Structure(type = Type.CHARACTER)) } } val description = async { try { descriptionRepository.fetchDescription() } catch (exception: Exception) { Log.e(TAG, exception.message, exception) _error.emit(FetchErrorUio.Structure(type = Type.DESCRIPTION)) } } val inventory = async { try { itemsRepository.fetchItems() } catch (exception: Exception) { Log.e(TAG, exception.message, exception) _error.emit(FetchErrorUio.Structure(type = Type.INVENTORY)) } } awaitAll(characterSheet) val alteration = async { try { alterationRepository.fetchAlterationSheet(sheets = characterSheetRepository.sheets) } catch (exception: Exception) { Log.e(TAG, exception.message, exception) _error.emit(FetchErrorUio.Structure(type = Type.ALTERATION)) } } val action = async { try { actionRepository.fetchActions(characters = characterSheetRepository.data.value) } catch (exception: Exception) { Log.e(TAG, exception.message, exception) _error.emit(FetchErrorUio.Structure(type = Type.ACTION)) } } val skill = async { try { skillRepository.fetchSkills(characters = characterSheetRepository.data.value) } catch (exception: Exception) { Log.e(TAG, exception.message, exception) _error.emit(FetchErrorUio.Structure(type = Type.SKILL)) } } val spell = async { try { spellRepository.fetchSpells() } catch (exception: Exception) { Log.e(TAG, exception.message, exception) _error.emit(FetchErrorUio.Structure(type = Type.SPELL)) } } awaitAll(order, lexicon, location, quest) awaitAll(description, inventory, alteration, action, spell, skill) withContext(Dispatchers.Main) { isLoading = false } } } companion object { private const val TAG = "LauncherViewModel" } }