package com.pixelized.desktop.lwa.ui.screen.admin.map.list

import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.pixelized.desktop.lwa.repository.map.MapRepository
import com.pixelized.desktop.lwa.ui.composable.error.ErrorSnackUio
import com.pixelized.desktop.lwa.ui.composable.textfield.createLwaTextField
import com.pixelized.desktop.lwa.ui.composable.textfield.createLwaTextFieldFlow
import com.pixelized.desktop.lwa.utils.extention.unAccent
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.SharedFlow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.runBlocking
import lwacharactersheet.composeapp.generated.resources.Res
import lwacharactersheet.composeapp.generated.resources.game_master__character__filter
import org.jetbrains.compose.resources.getString

class GMMapViewModel(
    private val mapRepository: MapRepository,
    itemFactory: GMMapFactory,
) : ViewModel() {

    private val _error = MutableSharedFlow<ErrorSnackUio>()
    val error: SharedFlow<ErrorSnackUio> get() = _error

    private val _filter = createLwaTextFieldFlow(
        label = runBlocking { getString(Res.string.game_master__character__filter) },
    )
    val filter = _filter.createLwaTextField()

    val items: StateFlow<List<GMMapItemUio>> = combine(
        mapRepository.mapsFlow(),
        filter.valueFlow.map { it.unAccent() },
    ) { items, unAccentFilter ->
        itemFactory.convertToGMMapUio(
            items = itemFactory.filterItem(
                items = items.values,
                unAccentFilter = unAccentFilter,
            ),
        )
    }.stateIn(
        scope = viewModelScope,
        started = SharingStarted.Lazily,
        initialValue = emptyList(),
    )

    suspend fun deleteMap(mapId: String) {
        try {
            mapRepository.deleteMap(mapId = mapId)
        } catch (exception: Exception) {
            val message = ErrorSnackUio.from(exception = exception)
            _error.emit(message)
        }
    }
}