package de.krisenvorrat.app.ui.inventory

import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import dagger.hilt.android.lifecycle.HiltViewModel
import de.krisenvorrat.app.domain.model.SettingsKey.StringKey
import de.krisenvorrat.app.domain.repository.ImportExportRepository
import de.krisenvorrat.app.domain.repository.SettingsRepository
import de.krisenvorrat.app.domain.repository.SyncService
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

@HiltViewModel
internal class InventoryPickerViewModel @Inject constructor(
    private val syncService: SyncService,
    private val settingsRepository: SettingsRepository,
    private val importExportRepository: ImportExportRepository
) : ViewModel() {

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

    init {
        loadActiveInventoryName()
    }

    private fun loadActiveInventoryName() {
        viewModelScope.launch {
            val name = settingsRepository.getString(StringKey.ActiveInventoryName)
            _uiState.update { it.copy(activeInventoryName = name) }
        }
    }

    fun loadInventories() {
        viewModelScope.launch {
            _uiState.update { it.copy(isLoading = true, error = null) }
            syncService.listInventories().fold(
                onSuccess = { inventories ->
                    _uiState.update { it.copy(inventories = inventories, isLoading = false) }
                },
                onFailure = { e ->
                    _uiState.update {
                        it.copy(isLoading = false, error = e.message ?: "Inventare konnten nicht geladen werden")
                    }
                }
            )
        }
    }

    fun showCreateDialog() {
        _uiState.update { it.copy(isCreateDialogVisible = true, newInventoryName = "") }
    }

    fun dismissCreateDialog() {
        _uiState.update { it.copy(isCreateDialogVisible = false, newInventoryName = "") }
    }

    fun onNewInventoryNameChanged(name: String) {
        _uiState.update { it.copy(newInventoryName = name) }
    }

    fun createInventory() {
        val name = _uiState.value.newInventoryName.trim()
        if (name.isBlank()) return
        viewModelScope.launch {
            _uiState.update { it.copy(isCreating = true, error = null) }
            syncService.createInventory(name).fold(
                onSuccess = { info ->
                    settingsRepository.setString(StringKey.ActiveInventoryId, info.id)
                    settingsRepository.setString(StringKey.ActiveInventoryName, info.name)
                    _uiState.update {
                        it.copy(
                            isCreating = false,
                            isCreateDialogVisible = false,
                            newInventoryName = "",
                            activeInventoryName = info.name
                        )
                    }
                    resyncFromServer()
                    loadInventories()
                },
                onFailure = { e ->
                    _uiState.update {
                        it.copy(isCreating = false, error = e.message ?: "Inventar konnte nicht erstellt werden")
                    }
                }
            )
        }
    }

    fun switchInventory(inventoryId: String) {
        val currentId = _uiState.value.inventories.find { it.isActive }?.id
        if (inventoryId == currentId) return
        viewModelScope.launch {
            _uiState.update { it.copy(isSwitching = true, error = null) }
            syncService.switchInventory(inventoryId).fold(
                onSuccess = { info ->
                    settingsRepository.setString(StringKey.ActiveInventoryId, info.id)
                    settingsRepository.setString(StringKey.ActiveInventoryName, info.name)
                    _uiState.update {
                        it.copy(isSwitching = false, activeInventoryName = info.name)
                    }
                    resyncFromServer()
                    loadInventories()
                },
                onFailure = { e ->
                    _uiState.update {
                        it.copy(isSwitching = false, error = e.message ?: "Inventar konnte nicht gewechselt werden")
                    }
                }
            )
        }
    }

    fun dismissError() {
        _uiState.update { it.copy(error = null) }
    }

    private suspend fun resyncFromServer() {
        settingsRepository.setString(StringKey.SyncLastTimestamp, "")
        syncService.downloadInventory().fold(
            onSuccess = { inventoryDto ->
                importExportRepository.importFromInventoryDto(inventoryDto)
            },
            onFailure = { /* Sync-Fehler werden nicht blockierend behandelt */ }
        )
    }
}
