package id.iiyh.inatrading.feature.auth.presentation

import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import dagger.hilt.android.lifecycle.HiltViewModel
import id.iiyh.inatrading.feature.auth.domain.repository.AuthRepository
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 RegisterFormError(
    val name: String? = null,
    val email: String? = null,
    val phone: String? = null,
    val password: String? = null,
    val confirmPassword: String? = null,
)

data class RegisterUiState(
    val name: String = "",
    val email: String = "",
    val phone: String = "",
    val password: String = "",
    val confirmPassword: String = "",
    val isPasswordVisible: Boolean = false,
    val isConfirmPasswordVisible: Boolean = false,
    val isLoading: Boolean = false,
    val errors: RegisterFormError = RegisterFormError(),
    val apiError: String? = null,
    val isSuccess: Boolean = false,
)

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

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

    fun onNameChange(value: String) =
        _uiState.update { it.copy(name = value, errors = it.errors.copy(name = null), apiError = null) }

    fun onEmailChange(value: String) =
        _uiState.update { it.copy(email = value, errors = it.errors.copy(email = null), apiError = null) }

    fun onPhoneChange(value: String) =
        _uiState.update { it.copy(phone = value, errors = it.errors.copy(phone = null), apiError = null) }

    fun onPasswordChange(value: String) {
        _uiState.update {
            it.copy(
                password = value,
                apiError  = null,
                errors    = it.errors.copy(
                    password        = null,
                    confirmPassword = if (it.confirmPassword.isNotEmpty() && value != it.confirmPassword)
                        "mismatch" else null,
                )
            )
        }
    }

    fun onConfirmPasswordChange(value: String) {
        _uiState.update {
            it.copy(
                confirmPassword = value,
                errors = it.errors.copy(
                    confirmPassword = if (value.isNotEmpty() && value != it.password) "mismatch" else null
                )
            )
        }
    }

    fun togglePasswordVisibility() =
        _uiState.update { it.copy(isPasswordVisible = !it.isPasswordVisible) }

    fun toggleConfirmPasswordVisibility() =
        _uiState.update { it.copy(isConfirmPasswordVisible = !it.isConfirmPasswordVisible) }

    fun register() {
        if (!validate()) return

        viewModelScope.launch {
            _uiState.update { it.copy(isLoading = true, apiError = null) }
            val s = _uiState.value
            authRepository.register(
                name     = s.name,
                email    = s.email,
                mobile   = s.phone,
                password = s.password,
            ).onSuccess {
                _uiState.update { it.copy(isLoading = false, isSuccess = true) }
            }.onFailure { e ->
                _uiState.update { it.copy(isLoading = false, apiError = e.message) }
            }
        }
    }

    fun registerWithGoogle() {
        // TODO: Implement Google Sign-In
    }

    private fun validate(): Boolean {
        val s = _uiState.value
        val errors = RegisterFormError(
            name  = if (s.name.isBlank()) "empty" else null,
            email = when {
                s.email.isBlank() -> "empty"
                !android.util.Patterns.EMAIL_ADDRESS.matcher(s.email).matches() -> "invalid"
                else -> null
            },
            phone    = if (s.phone.isBlank()) "empty" else null,
            password = when {
                s.password.isBlank() -> "empty"
                s.password.length < 8 -> "too_short"
                else -> null
            },
            confirmPassword = when {
                s.confirmPassword.isBlank() -> "empty"
                s.confirmPassword != s.password -> "mismatch"
                else -> null
            },
        )
        _uiState.update { it.copy(errors = errors) }
        return errors.name == null && errors.email == null &&
               errors.phone == null && errors.password == null &&
               errors.confirmPassword == null
    }
}
