package ru.myitschool.work.ui.login

import android.content.Context
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import dagger.Lazy
import dagger.hilt.android.lifecycle.HiltViewModel
import dagger.hilt.android.qualifiers.ApplicationContext
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asSharedFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import ru.myitschool.work.R
import ru.myitschool.work.domain.auth.CheckValidLoginUseCase
import ru.myitschool.work.domain.auth.LoginUseCase
import ru.myitschool.work.utils.MutablePublishFlow
import javax.inject.Inject

@HiltViewModel
class LoginViewModel @Inject constructor(
    @ApplicationContext private val context: Context,
    private val checkValidLoginUseCase: Lazy<CheckValidLoginUseCase>,
    private val loginUseCase: Lazy<LoginUseCase>,
) : ViewModel() {

    private val _action = MutablePublishFlow<Action>()
    val action = _action.asSharedFlow()

    private val _state = MutableStateFlow<State>(initialState)
    val state = _state.asStateFlow()

    private var login: String = ""

    fun clickLogin() {
        viewModelScope.launch {
            _state.update { State.Loading }
            loginUseCase.get().invoke(login = login).fold(
                onSuccess = {
                    _action.emit(Action.OpenProfile)
                },
                onFailure = { error ->
                    _state.update {
                        State.Error(
                            errorText = error.localizedMessage
                                ?: context.resources.getString(R.string.login_error)
                        )
                    }
                }
            )
        }
    }

    fun inputLogin(login: String) {
        this.login = login
        viewModelScope.launch {
            _state.update {
                State.Show(
                    isLoginButtonEnabled = checkValidLoginUseCase.get().invoke(login = login)
                )
            }
        }
    }

    sealed interface Action {
        data object OpenProfile : Action
    }

    sealed interface State {
        data object Loading : State

        data class Error(
            val errorText: String,
        ) : State

        data class Show(
            val isLoginButtonEnabled: Boolean
        ) : State
    }

    private companion object {
        val initialState = State.Show(
            isLoginButtonEnabled = false
        )
    }
}