package com.prodhack.moscow2025.presentation.screens.register

import androidx.lifecycle.viewModelScope
import com.prodhack.moscow2025.domain.models.AuthField
import com.prodhack.moscow2025.domain.models.RegisterData
import com.prodhack.moscow2025.domain.usecase.auth.RegisterUserUseCase
import com.prodhack.moscow2025.domain.usecase.auth.ValidateFieldsUseCase
import com.prodhack.moscow2025.presentation.utils.UIState
import com.prodhack.moscow2025.presentation.utils.base.BaseViewModel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import org.koin.android.annotation.KoinViewModel
import kotlin.random.Random

data class RegisterFormState(
	val email: String = "",
	val password: String = "",
	val confirmPassword: String = "",
	val errors: Map<AuthField, String> = emptyMap()
)

@KoinViewModel
class RegisterViewModel(
	private val registerUserUseCase: RegisterUserUseCase,
	private val validateFieldsUseCase: ValidateFieldsUseCase
) : BaseViewModel() {

	private val _formStateSignUp = MutableStateFlow(RegisterFormState())
	val formStateSignUp: StateFlow<RegisterFormState> = _formStateSignUp


	private val _registerState = MutableUIStateFlow<String>()
	val registerState: StateFlow<UIState<String>> = _registerState


	fun onEmailChange(value: String) {
		_formStateSignUp.update { it.copy(email = value, errors = it.errors - AuthField.Email) }
	}

	fun onPasswordChange(value: String) {
		_formStateSignUp.update {
			it.copy(
				password = value,
				errors = it.errors - AuthField.Password
			)
		}
	}

	fun onConfirmPasswordChange(value: String) {
		_formStateSignUp.update {
			it.copy(
				confirmPassword = value,
				errors = it.errors - AuthField.ConfirmPassword
			)
		}
	}

	fun fillRandomCredentials() {
		val password = randomPassword()
		val email = randomEmail()
		_formStateSignUp.update {
			it.copy(
				email = email,
				password = password,
				confirmPassword = password,
				errors = emptyMap()
			)
		}
	}

	private fun randomEmail(): String {
		val symbols = "abcdefghijklmnopqrstuvwxyz"
		val name = (1..8).joinToString("") { symbols.random().toString() }
		val domain = (1..5).joinToString("") { symbols.random().toString() }
		return "$name@$domain.com"
	}

	private fun randomPassword(length: Int = 12): String {
		val symbols = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
		return (1..length).joinToString("") { symbols.random().toString() } + "!"
	}

	fun submit() {
		viewModelScope.launch {
			val validation = validateFieldsUseCase.validateSignUp(
				email = _formStateSignUp.value.email,
				password = _formStateSignUp.value.password,
				confirmPassword = _formStateSignUp.value.confirmPassword
			)

			if (!validation.isValid) {
				_formStateSignUp.update { it.copy(errors = validation.errors) }
				return@launch
			}

			_registerState.emit(UIState.Loading())

			val result = registerUserUseCase(
				RegisterData(
					email = _formStateSignUp.value.email,
					password = _formStateSignUp.value.password
				)
			)
			result.collectRequest(_registerState)
		}
	}
}
