package com.diegocayo.organizame.presentation.features.welcome.firstStep

import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.diegocayo.organizame.R
import com.diegocayo.organizame.domain.model.User
import com.diegocayo.organizame.domain.usecase.SaveUserUseCase
import com.diegocayo.organizame.domain.usecase.SetLoginStatusUseCase
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.catch
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import java.util.Calendar
import javax.inject.Inject

@HiltViewModel
class FirstStepViewModel @Inject constructor(
    private val saveUserUseCase: SaveUserUseCase,
    private val setLoginStatusUseCase: SetLoginStatusUseCase
) : ViewModel() {

    var step by mutableIntStateOf(0)
        private set

    var name by mutableStateOf("")
    var surname by mutableStateOf("")
    var birthdateDay by mutableStateOf("")
    var birthdateMonth by mutableStateOf("")
    var birthdateYear by mutableStateOf("")

    var nameError by mutableStateOf<String?>(null)
        private set
    var surnameError by mutableStateOf<String?>(null)
        private set
    var birthdateError by mutableStateOf<Int?>(null)
        private set

    private val currentDate = Calendar.getInstance()
    val maxYear = currentDate.get(Calendar.YEAR)
    val maxMonth = currentDate.get(Calendar.MONTH) + 1
    val maxDay = currentDate.get(Calendar.DAY_OF_MONTH)

    fun validateName(name: String) {
        this.name = name
        nameError = when {
            name.isBlank() -> "El nombre es obligatorio"
            else -> null
        }
    }

    fun validateSurname(surname: String) {
        this.surname = surname
        surnameError = when {
            surname.isBlank() -> "El apellido es obligatorio"
            else -> null
        }
    }

    fun validateBirthdate() {
        try {
            val day = birthdateDay.toIntOrNull() ?: 0
            val month = birthdateMonth.toIntOrNull() ?: 0
            val year = birthdateYear.toIntOrNull() ?: 0

            birthdateError = when {
                birthdateDay.isBlank() || birthdateMonth.isBlank() || birthdateYear.isBlank() ->
                    R.string.info_all_fields_mandatory

                year > maxYear -> R.string.info_year_can_not_later_current_year
                year == maxYear && month > maxMonth -> R.string.info_date_later
                year == maxYear && month == maxMonth && day > maxDay -> R.string.info_date_later
                !isValidDate(day, month, year) -> R.string.info_invalid_date
                else -> null
            }


        } catch (e: Exception) {

        }
    }

    private fun isValidDate(day: Int, month: Int, year: Int): Boolean {
        return try {
            val calendar = Calendar.getInstance()
            calendar.isLenient = false
            calendar.set(Calendar.YEAR, year)
            calendar.set(Calendar.MONTH, month - 1)
            calendar.set(Calendar.DAY_OF_MONTH, day)
            calendar.time
            true
        } catch (e: Exception) {
            false
        }
    }

    fun canProceedToNextStep(): Boolean {
        return when (step) {
            0 -> name.isNotBlank() && nameError == null
            1 -> surname.isNotBlank() && surnameError == null
            2 -> birthdateDay.isNotBlank() && birthdateMonth.isNotBlank() &&
                    birthdateYear.isNotBlank() && birthdateError == null

            else -> false
        }
    }

    fun nextStep() {
        if (step < 2 && canProceedToNextStep()) {
            step++
        }
    }

    fun previousStep() {
        if (step > 0) {
            step--
        }
    }

    fun saveUserAndLogin(onSuccess: () -> Unit) {
        if (!canProceedToNextStep()) return

        val birthdate = "$birthdateDay/$birthdateMonth/$birthdateYear"
        val user = User(
            name = name,
            surname = surname,
            birthdate = birthdate
        )

        saveUser(user, onSuccess)
    }

    private fun saveUser(user: User, onSuccess: () -> Unit) {
        saveUserUseCase.prepare(user)
            .onEach {
                setLoginStatus(true) {
                    onSuccess()
                }
            }
            .catch { exception ->
            }
            .launchIn(viewModelScope)
    }

    private fun setLoginStatus(isLoggedIn: Boolean, onSuccess: () -> Unit) {
        setLoginStatusUseCase.prepare(isLoggedIn)
            .onEach {
                onSuccess()
            }
            .catch { exception ->
            }
            .launchIn(viewModelScope)
    }
}