package app.closer.ui.auth

import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import app.closer.domain.repository.AuthRepository
import dagger.hilt.android.lifecycle.HiltViewModel
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

data class SignUpUiState(
    val email: String = "",
    val password: String = "",
    val confirmPassword: String = "",
    val isPasswordVisible: Boolean = false,
    val isLoading: Boolean = false,
    val error: String? = null,
    val success: Boolean = false
)

@HiltViewModel
class SignUpViewModel @Inject constructor(
    private val authRepository: AuthRepository
) : ViewModel() {

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

    fun updateEmail(v: String) = _uiState.update { it.copy(email = v, error = null) }
    fun updatePassword(v: String) = _uiState.update { it.copy(password = v, error = null) }
    fun updateConfirmPassword(v: String) = _uiState.update { it.copy(confirmPassword = v, error = null) }
    fun togglePasswordVisibility() = _uiState.update { it.copy(isPasswordVisible = !it.isPasswordVisible) }
    fun dismissError() = _uiState.update { it.copy(error = null) }

    fun signUp() {
        val state = _uiState.value
        when {
            state.email.isBlank() -> { _uiState.update { it.copy(error = "Please enter your email.") }; return }
            state.password.length < 6 -> { _uiState.update { it.copy(error = "Password must be at least 6 characters.") }; return }
            state.password != state.confirmPassword -> { _uiState.update { it.copy(error = "Passwords don't match.") }; return }
        }
        _uiState.update { it.copy(isLoading = true, error = null) }
        viewModelScope.launch {
            authRepository.signUpWithEmail(state.email.trim(), state.password)
                .onSuccess { _uiState.update { it.copy(isLoading = false, success = true) } }
                .onFailure { e ->
                    val msg = friendlyError(e)
                    _uiState.update { it.copy(isLoading = false, error = msg) }
                }
        }
    }

    private fun friendlyError(e: Throwable): String = when {
        e.message?.contains("email address is already") == true -> "An account with this email already exists."
        e.message?.contains("badly formatted") == true -> "Please enter a valid email address."
        else -> e.message ?: "Something went wrong. Please try again."
    }
}
