package llc.arma.ble.app.ui.screen.password

import androidx.lifecycle.SavedStateHandle
import androidx.lifecycle.viewModelScope
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.launch
import llc.arma.ble.app.ui.common.BaseViewModel
import llc.arma.ble.domain.usecase.ChangeBlePassword
import javax.inject.Inject

@HiltViewModel
class ChangePasswordViewModel @Inject constructor(
    private val savedStateHandle: SavedStateHandle,
    private val changeBlePassword: ChangeBlePassword
) : BaseViewModel<ChangePasswordContract.State, ChangePasswordContract.Event, ChangePasswordContract.Effect>() {

    override fun setInitialState() = ChangePasswordContract.State("", "", null, null)

    override fun handleEvents(event: ChangePasswordContract.Event) {
        when(event){
            is ChangePasswordContract.Event.OnPasswordChanged -> reduce(viewState.value, event)
            is ChangePasswordContract.Event.OnRePasswordChanged -> reduce(viewState.value, event)
            is ChangePasswordContract.Event.OnChange -> reduce(viewState.value, event)
            is ChangePasswordContract.Event.OnNavigateUp -> reduce(viewState.value, event)
        }
    }

    private fun reduce(
        state: ChangePasswordContract.State,
        event: ChangePasswordContract.Event.OnPasswordChanged
    ) {

        setState {
            copy(
                password = event.password
            )
        }

    }

    private fun reduce(
        state: ChangePasswordContract.State,
        event: ChangePasswordContract.Event.OnRePasswordChanged
    ) {

        setState {
            copy(
                rePassword = event.password
            )
        }

    }

    private fun reduce(
        state: ChangePasswordContract.State,
        event: ChangePasswordContract.Event.OnChange
    ) {

        if(state.password.length != 6 || state.rePassword.length != 6){
            setState {
                state.copy(
                    exception = ChangePasswordContract.State.ValidationException.WrongLength
                )
            }
        } else {

            if(state.password != state.rePassword){
                setState {
                    state.copy(
                        exception = ChangePasswordContract.State.ValidationException.PasswordsNotMatch
                    )
                }
            } else {

                viewModelScope.launch {

                    setState {
                        state.copy(
                            loading = ChangePasswordContract.State.LoadingState.Loading,
                            exception = null
                        )
                    }

                    changeBlePassword.invoke(
                        state.password,
                        savedStateHandle.get<String>("serial")!!
                    ).fold(
                        onSuccess = {
                            setState {
                                state.copy(
                                    loading = ChangePasswordContract.State.LoadingState.Success,
                                    exception = null
                                )
                            }
                        },
                        onFailure = {
                            setState {
                                state.copy(
                                    loading = ChangePasswordContract.State.LoadingState.Failure,
                                    exception = null
                                )
                            }
                        }
                    )

                }

            }

        }

    }

    private fun reduce(
        state: ChangePasswordContract.State,
        event: ChangePasswordContract.Event.OnNavigateUp
    ) {

        setEffect {
            ChangePasswordContract.Effect.Navigation.NavigateUp
        }

    }

}