package app.closer.ui.dates

import android.util.Log
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import app.closer.domain.model.BucketListItem
import app.closer.domain.repository.BucketListRepository
import com.google.firebase.auth.FirebaseAuth
import dagger.hilt.android.lifecycle.HiltViewModel
import javax.inject.Inject
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch

@HiltViewModel
class BucketListViewModel @Inject constructor(
    private val repository: BucketListRepository
) : ViewModel() {

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

    fun setCoupleId(coupleId: String) {
        _uiState.update { it.copy(coupleId = coupleId) }
        loadItems()
    }

    fun loadItems() {
        val coupleId = _uiState.value.coupleId
        if (coupleId.isEmpty()) return

        viewModelScope.launch {
            runCatching { repository.getItems(coupleId) }
                .onSuccess { items -> _uiState.update { it.copy(items = items) } }
                .onFailure { Log.w(TAG, "Could not load bucket list items", it) }
        }
    }

    fun addItem(
        title: String,
        description: String,
        category: String
    ) {
        val coupleId = _uiState.value.coupleId
        if (coupleId.isEmpty()) return

        val newItem = BucketListItem(
            coupleId = coupleId,
            title = title.take(MAX_TITLE_LENGTH),
            description = description.take(MAX_DESCRIPTION_LENGTH),
            category = category,
            addedBy = FirebaseAuth.getInstance().currentUser?.uid ?: "",
            addedAt = System.currentTimeMillis()
        )

        viewModelScope.launch {
            runCatching { repository.addItem(newItem) }
                .onSuccess { itemId ->
                    val updatedItems = _uiState.value.items + newItem.copy(id = itemId)
                    _uiState.update { it.copy(items = updatedItems) }
                }
                .onFailure { Log.w(TAG, "Could not add bucket list item", it) }
        }
    }

    fun toggleComplete(itemId: String) {
        val item = _uiState.value.items.find { it.id == itemId } ?: return
        val coupleId = _uiState.value.coupleId
        if (coupleId.isEmpty()) return

        viewModelScope.launch {
            runCatching {
                if (item.isCompleted) {
                    repository.updateItem(item.copy(isCompleted = false, completedBy = null, completedAt = null))
                    _uiState.update {
                        it.copy(
                            items = it.items.map { if (it.id == itemId) it.copy(isCompleted = false) else it }
                        )
                    }
                } else {
                    repository.completeItem(coupleId, itemId, FirebaseAuth.getInstance().currentUser?.uid ?: "")
                    _uiState.update {
                        it.copy(
                            items = it.items.map {
                                if (it.id == itemId) it.copy(isCompleted = true, completedAt = System.currentTimeMillis())
                                else it
                            }
                        )
                    }
                }
            }.onFailure { Log.w(TAG, "Could not toggle bucket list item", it) }
        }
    }

    fun deleteItem(itemId: String) {
        val coupleId = _uiState.value.coupleId
        if (coupleId.isEmpty()) return

        viewModelScope.launch {
            runCatching { repository.deleteItem(coupleId, itemId) }
                .onSuccess {
                    _uiState.update {
                        it.copy(items = it.items.filter { it.id != itemId })
                    }
                }
                .onFailure { Log.w(TAG, "Could not delete bucket list item", it) }
        }
    }

    fun setCategoryFilter(category: String?) {
        _uiState.update { it.copy(categoryFilter = category) }
    }

    fun clear() {
        _uiState.update { BucketListUiState() }
    }

    private companion object {
        const val TAG = "BucketListViewModel"
        const val MAX_TITLE_LENGTH = 100
        const val MAX_DESCRIPTION_LENGTH = 500
    }
}

data class BucketListUiState(
    val coupleId: String = "",
    val items: List<BucketListItem> = emptyList(),
    val categoryFilter: String? = null
) {
    val filteredItems: List<BucketListItem>
        get() = if (categoryFilter == null) items else items.filter { it.category == categoryFilter }

    val allCategories: List<String>
        get() = items.map { it.category }.distinct()
}
