package app.closer.ui.dates

import android.util.Log
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import app.closer.domain.model.DatePlanPreference
import app.closer.domain.repository.DatePlanRepository
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 DateBuilderViewModel @Inject constructor(
    private val repository: DatePlanRepository
) : ViewModel() {

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

    fun updateDate(date: Long) {
        _uiState.update { it.copy(scheduledDate = date) }
    }

    fun updateTime(time: String) {
        _uiState.update { it.copy(scheduledTime = time) }
    }

    fun updateBudget(budget: Int) {
        _uiState.update { it.copy(budget = budget) }
    }

    fun updateDuration(duration: String) {
        _uiState.update { it.copy(duration = duration) }
    }

    fun setDateIdeaId(dateIdeaId: String) {
        _uiState.update { it.copy(dateIdeaId = dateIdeaId) }
    }

    fun savePreference() {
        val state = _uiState.value
        if (state.dateIdeaId.isEmpty()) return

        val preference = DatePlanPreference(
            dateIdeaId = state.dateIdeaId,
            preferredDate = state.scheduledDate,
            preferredTime = state.scheduledTime.take(MAX_TIME_LENGTH),
            budget = state.budget,
            duration = state.duration.take(MAX_DURATION_LENGTH)
        )

        viewModelScope.launch {
            _uiState.update { it.copy(isSaving = true, error = null) }
            runCatching { repository.savePreference(preference) }
                .onSuccess { _uiState.update { it.copy(isSaving = false, saved = true) } }
                .onFailure { e ->
                    Log.w(TAG, "Could not save date preference", e)
                    _uiState.update {
                        it.copy(isSaving = false, error = "Couldn't save. Check your connection and try again.")
                    }
                }
        }
    }

    fun consumeSaved() = _uiState.update { it.copy(saved = false) }
    fun consumeError() = _uiState.update { it.copy(error = null) }

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

    private companion object {
        const val TAG = "DateBuilderViewModel"
        const val MAX_TIME_LENGTH = 20
        const val MAX_DURATION_LENGTH = 50
    }
}

data class DateBuilderUiState(
    val dateIdeaId: String = "",
    val scheduledDate: Long = 0L,
    val scheduledTime: String = "",
    val budget: Int = 0,
    val duration: String = "",
    val isSaving: Boolean = false,
    val saved: Boolean = false,
    val error: String? = null
)
