package de.krisenvorrat.app.ui.location

import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import dagger.hilt.android.lifecycle.HiltViewModel
import de.krisenvorrat.app.data.db.entity.LocationEntity
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.update
import kotlinx.coroutines.launch
import javax.inject.Inject

internal data class LocationListUiState(
    val locations: List<LocationEntity> = emptyList(),
    val isAddDialogVisible: Boolean = false,
    val isEditDialogVisible: Boolean = false,
    val isDeleteDialogVisible: Boolean = false,
    val isReassignDialogVisible: Boolean = false,
    val locationToDelete: LocationEntity? = null,
    val locationToEdit: LocationEntity? = null,
    val newLocationName: String = "",
    val editLocationName: String = "",
    val itemCountForDelete: Int = 0,
    val reassignTargetLocationId: Int? = null
)

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

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

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

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

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

    fun updateNewLocationName(name: String) {
        _uiState.update { it.copy(newLocationName = name) }
    }

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

    fun showEditDialog(location: LocationEntity) {
        _uiState.update {
            it.copy(
                isEditDialogVisible = true,
                locationToEdit = location,
                editLocationName = location.name
            )
        }
    }

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

    fun updateEditLocationName(name: String) {
        _uiState.update { it.copy(editLocationName = name) }
    }

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

    fun showDeleteDialog(location: LocationEntity) {
        viewModelScope.launch {
            val count = try {
                itemRepository.countByLocationId(location.id)
            } catch (_: Exception) { 0 }

            if (count > 0) {
                _uiState.update {
                    it.copy(
                        isReassignDialogVisible = true,
                        locationToDelete = location,
                        itemCountForDelete = count,
                        reassignTargetLocationId = null
                    )
                }
            } else {
                _uiState.update {
                    it.copy(isDeleteDialogVisible = true, locationToDelete = location)
                }
            }
        }
    }

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

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

    fun updateReassignTarget(locationId: Int) {
        _uiState.update { it.copy(reassignTargetLocationId = locationId) }
    }

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

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

