package ru.myitschool.work.ui.profile

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.LogoutUseCase
import ru.myitschool.work.domain.profile.GetUserInfoUseCase
import ru.myitschool.work.utils.MutablePublishFlow
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale
import javax.inject.Inject

@HiltViewModel
class ProfileViewModel @Inject constructor(
    @ApplicationContext private val context: Context,
    private val getUserInfoUseCase: Lazy<GetUserInfoUseCase>,
    private val logoutUseCase: Lazy<LogoutUseCase>,
) : ViewModel() {

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

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

    init {
        updateUserInfo()
    }

    fun clickRefresh() {
        updateUserInfo()
    }

    fun clickLogout() {
        viewModelScope.launch {
            logoutUseCase.get().invoke()
            _action.emit(Action.OpenLogin)
        }
    }

    fun clickScan() {
        viewModelScope.launch {
            _action.emit(Action.OpenScan)
        }
    }

    private fun updateUserInfo() {
        viewModelScope.launch {
            _state.update { State.Loading }
            getUserInfoUseCase.get().invoke().fold(
                onSuccess = { value ->
                    _state.update {
                        State.Show(
                            fullname = value.fullname,
                            imageUrl = value.imageUrl,
                            position = value.position,
                            lastEntry = simpleDateFormat.format(Date(value.lastEntryMillis))
                        )
                    }
                },
                onFailure = { error ->
                    _state.update {
                        State.Error(
                            errorText = error.localizedMessage
                                ?: context.resources.getString(R.string.login_error)
                        )
                    }
                }
            )
        }
    }

    sealed interface State {
        data object Loading : State

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

        data class Show(
            val fullname: String,
            val imageUrl: String,
            val position: String,
            val lastEntry: String,
        ) : State
    }

    sealed interface Action {
        data object OpenLogin : Action
        data object OpenScan : Action
    }

    private companion object {
        private val simpleDateFormat = SimpleDateFormat(
            "yyyy-MM-DD HH:mm",
            Locale.US
        )

        val initialState = State.Loading
    }
}