package de.krisenvorrat.app.ui.category

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

internal data class CategoryListUiState(
    val categories: List<CategoryEntity> = emptyList(),
    val isAddDialogVisible: Boolean = false,
    val isEditDialogVisible: Boolean = false,
    val isDeleteDialogVisible: Boolean = false,
    val isReassignDialogVisible: Boolean = false,
    val categoryToDelete: CategoryEntity? = null,
    val categoryToEdit: CategoryEntity? = null,
    val newCategoryName: String = "",
    val editCategoryName: String = "",
    val itemCountForDelete: Int = 0,
    val reassignTargetCategoryId: Int? = null
)

@HiltViewModel
internal class CategoryListViewModel @Inject constructor(
    private val repository: CategoryRepository,
    private val itemRepository: ItemRepository
) : ViewModel() {

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

    init {
        viewModelScope.launch {
            repository.getAll().collect { categories ->
                _uiState.update { it.copy(categories = categories) }
            }
        }
    }

    fun showAddDialog() {
        _uiState.update { it.copy(isAddDialogVisible = true, newCategoryName = "") }
    }

    fun dismissAddDialog() {
        _uiState.update { it.copy(isAddDialogVisible = false, newCategoryName = "") }
    }

    fun updateNewCategoryName(name: String) {
        _uiState.update { it.copy(newCategoryName = name) }
    }

    fun addCategory() {
        val name = _uiState.value.newCategoryName.trim()
        if (name.isBlank()) return
        viewModelScope.launch {
            try {
                repository.insert(CategoryEntity(name = name))
            } catch (_: Exception) {}
        }
        _uiState.update { it.copy(isAddDialogVisible = false, newCategoryName = "") }
    }

    fun showEditDialog(category: CategoryEntity) {
        _uiState.update {
            it.copy(
                isEditDialogVisible = true,
                categoryToEdit = category,
                editCategoryName = category.name
            )
        }
    }

    fun dismissEditDialog() {
        _uiState.update { it.copy(isEditDialogVisible = false, categoryToEdit = null, editCategoryName = "") }
    }

    fun updateEditCategoryName(name: String) {
        _uiState.update { it.copy(editCategoryName = name) }
    }

    fun saveEditCategory() {
        val category = _uiState.value.categoryToEdit ?: return
        val name = _uiState.value.editCategoryName.trim()
        if (name.isBlank()) return
        viewModelScope.launch {
            try {
                repository.update(category.copy(name = name))
            } catch (_: Exception) {}
        }
        _uiState.update { it.copy(isEditDialogVisible = false, categoryToEdit = null, editCategoryName = "") }
    }

    fun showDeleteDialog(category: CategoryEntity) {
        viewModelScope.launch {
            val count = try {
                itemRepository.countByCategoryId(category.id)
            } catch (_: Exception) { 0 }

            if (count > 0) {
                _uiState.update {
                    it.copy(
                        isReassignDialogVisible = true,
                        categoryToDelete = category,
                        itemCountForDelete = count,
                        reassignTargetCategoryId = null
                    )
                }
            } else {
                _uiState.update {
                    it.copy(isDeleteDialogVisible = true, categoryToDelete = category)
                }
            }
        }
    }

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

    fun dismissReassignDialog() {
        _uiState.update {
            it.copy(
                isReassignDialogVisible = false,
                categoryToDelete = null,
                itemCountForDelete = 0,
                reassignTargetCategoryId = null
            )
        }
    }

    fun updateReassignTarget(categoryId: Int) {
        _uiState.update { it.copy(reassignTargetCategoryId = categoryId) }
    }

    fun deleteCategory() {
        val category = _uiState.value.categoryToDelete ?: return
        viewModelScope.launch {
            try {
                repository.delete(category)
            } catch (_: Exception) {}
        }
        _uiState.update { it.copy(isDeleteDialogVisible = false, categoryToDelete = null) }
    }

    fun deleteWithReassignment() {
        val category = _uiState.value.categoryToDelete ?: return
        val targetId = _uiState.value.reassignTargetCategoryId ?: return
        viewModelScope.launch {
            try {
                itemRepository.reassignCategory(fromId = category.id, toId = targetId)
                repository.delete(category)
            } catch (_: Exception) {}
        }
        _uiState.update {
            it.copy(
                isReassignDialogVisible = false,
                categoryToDelete = null,
                itemCountForDelete = 0,
                reassignTargetCategoryId = null
            )
        }
    }
}

