package de.krisenvorrat.app.ui.item

import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import dagger.hilt.android.lifecycle.HiltViewModel
import de.krisenvorrat.app.data.db.entity.ItemEntity
import de.krisenvorrat.app.domain.repository.CategoryRepository
import de.krisenvorrat.app.domain.repository.ItemRepository
import de.krisenvorrat.app.domain.repository.LocationRepository
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import javax.inject.Inject

internal enum class ExpiryFilter(val label: String) {
    EXPIRED("Abgelaufen"),
    EXPIRING_SOON("Bald ablaufend"),
    OK("OK")
}

private data class FilterState(
    val searchQuery: String = "",
    val categoryId: Int? = null,
    val locationId: Int? = null,
    val expiryFilter: ExpiryFilter? = null
)

internal data class ItemListUiState(
    val groupedItems: Map<String, List<ItemUiModel>> = emptyMap(),
    val totalItemCount: Int = 0,
    val searchQuery: String = "",
    val selectedCategoryId: Int? = null,
    val selectedLocationId: Int? = null,
    val selectedExpiryFilter: ExpiryFilter? = null,
    val availableCategories: List<Pair<Int, String>> = emptyList(),
    val availableLocations: List<Pair<Int, String>> = emptyList(),
    val isDeleteDialogVisible: Boolean = false,
    val itemToDelete: ItemUiModel? = null
) {
    val isEmpty: Boolean get() = totalItemCount == 0
    val isFiltering: Boolean
        get() = searchQuery.isNotBlank() ||
            selectedCategoryId != null ||
            selectedLocationId != null ||
            selectedExpiryFilter != null
    val hasNoFilterResults: Boolean
        get() = isFiltering && groupedItems.isEmpty() && !isEmpty
}

@HiltViewModel
internal class ItemListViewModel @Inject constructor(
    private val itemRepository: ItemRepository,
    private val categoryRepository: CategoryRepository,
    private val locationRepository: LocationRepository
) : ViewModel() {

    private val _filterState = MutableStateFlow(FilterState())
    private val _uiState = MutableStateFlow(ItemListUiState())
    val uiState: StateFlow<ItemListUiState> = _uiState.asStateFlow()

    init {
        viewModelScope.launch {
            combine(
                itemRepository.getAll(),
                categoryRepository.getAll(),
                locationRepository.getAll(),
                _filterState
            ) { items, categories, locations, filters ->
                val categoryMap = categories.associate { it.id to it.name }
                val locationMap = locations.associate { it.id to it.name }

                val allUiItems = items.map { item ->
                    ItemUiModel(
                        id = item.id,
                        name = item.name,
                        categoryName = categoryMap[item.categoryId] ?: "Unbekannt",
                        quantity = item.quantity,
                        unit = item.unit,
                        locationName = locationMap[item.locationId] ?: "Unbekannt",
                        expiryDate = item.expiryDate,
                        categoryId = item.categoryId,
                        locationId = item.locationId,
                        notes = item.notes
                    )
                }

                val filteredItems = allUiItems
                    .filter { item ->
                        if (filters.searchQuery.isBlank()) true
                        else {
                            val query = filters.searchQuery.lowercase()
                            item.name.lowercase().contains(query) ||
                                item.notes.lowercase().contains(query)
                        }
                    }
                    .filter { item ->
                        filters.categoryId == null || item.categoryId == filters.categoryId
                    }
                    .filter { item ->
                        filters.locationId == null || item.locationId == filters.locationId
                    }
                    .filter { item ->
                        when (filters.expiryFilter) {
                            null -> true
                            ExpiryFilter.EXPIRED -> item.isExpired
                            ExpiryFilter.EXPIRING_SOON -> item.isExpiringSoon
                            ExpiryFilter.OK -> !item.isExpired && !item.isExpiringSoon
                        }
                    }

                val grouped = filteredItems
                    .groupBy { it.categoryName }
                    .toSortedMap()

                ItemListUiState(
                    groupedItems = grouped,
                    totalItemCount = allUiItems.size,
                    searchQuery = filters.searchQuery,
                    selectedCategoryId = filters.categoryId,
                    selectedLocationId = filters.locationId,
                    selectedExpiryFilter = filters.expiryFilter,
                    availableCategories = categories.map { it.id to it.name }
                        .sortedBy { it.second },
                    availableLocations = locations.map { it.id to it.name }
                        .sortedBy { it.second }
                )
            }.collect { newState ->
                _uiState.update { old ->
                    newState.copy(
                        isDeleteDialogVisible = old.isDeleteDialogVisible,
                        itemToDelete = old.itemToDelete
                    )
                }
            }
        }
    }

    fun onSearchQueryChanged(query: String) {
        _filterState.update { it.copy(searchQuery = query) }
    }

    fun onCategoryFilterChanged(categoryId: Int?) {
        _filterState.update { it.copy(categoryId = categoryId) }
    }

    fun onLocationFilterChanged(locationId: Int?) {
        _filterState.update { it.copy(locationId = locationId) }
    }

    fun onExpiryFilterChanged(expiryFilter: ExpiryFilter?) {
        _filterState.update { it.copy(expiryFilter = expiryFilter) }
    }

    fun clearSearch() {
        _filterState.update { it.copy(searchQuery = "") }
    }

    fun showDeleteDialog(item: ItemUiModel) {
        _uiState.update { it.copy(isDeleteDialogVisible = true, itemToDelete = item) }
    }

    fun dismissDeleteDialog() {
        _uiState.update { it.copy(isDeleteDialogVisible = false, itemToDelete = null) }
    }

    fun deleteItem() {
        val item = _uiState.value.itemToDelete ?: return
        viewModelScope.launch {
            try {
                itemRepository.delete(
                    ItemEntity(
                        id = item.id,
                        name = item.name,
                        categoryId = item.categoryId,
                        quantity = item.quantity,
                        unit = item.unit,
                        unitPrice = 0.0,
                        kcalPerKg = null,
                        expiryDate = item.expiryDate,
                        locationId = 0,
                        notes = "",
                        lastUpdated = 0L
                    )
                )
            } catch (_: Exception) {
                // Room-Fehler werden still behandelt
            }
        }
        _uiState.update { it.copy(isDeleteDialogVisible = false, itemToDelete = null) }
    }
}
