package ru.myitschool.work.ui.admin

import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.launch
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
import ru.myitschool.work.api.admin.AdminJson
import ru.myitschool.work.api.admin.ApiServiceAdmin
import ru.myitschool.work.api.list.ListInfo
import ru.myitschool.work.api.main.ApiServiceMain
import ru.myitschool.work.api.main.Authorities
import ru.myitschool.work.api.main.UserInfo
import ru.myitschool.work.ui.list.ListRepository
import javax.inject.Inject

@HiltViewModel
class AdminViewModel @Inject constructor(
    private val apiService: ApiServiceAdmin,
    private val apiServiceData: ApiServiceMain,
    private val listRepository: ListRepository
) : ViewModel() {

    private val _state = MutableStateFlow<ResultState>(ResultState.Initial)
    val state = _state.asStateFlow()

    private val _stateData = MutableStateFlow<ResultStateData>(ResultStateData.Initial)
    val stateData = _stateData.asStateFlow()

    fun block(login: String, authority: Boolean) {
        viewModelScope.launch {
            _state.value = ResultState.Loading

            try {
                val response = apiService.block(
                    login = login,
                    data = AdminJson(
                        if (authority) Authorities.ROLE_BLOCK
                        else Authorities.ROLE_USER
                    )
                )

                when (response.code()) {
                    200 -> {
                        _state.value = ResultState.Success
                    }
                    403 -> {
                        _state.value = ResultState.InvalidCredentials
                    }
                    401 -> {
                        _state.value = ResultState.Error
                    }
                    else -> {
                        _state.value = ResultState.Error
                    }
                }
            } catch (t: Throwable) {
                _state.value = ResultState.Error
            }
        }
    }

    fun getUserData(login: String) {
        viewModelScope.launch {
            _stateData.value = ResultStateData.Loading


            apiServiceData.getDataUser(login).enqueue(object : Callback<UserInfo> {
                override fun onResponse(call: Call<UserInfo>, response: Response<UserInfo>) {

                    when {
                        response.isSuccessful -> {
                            val userInfo = response.body()
                            _stateData.value = userInfo?.let { ResultStateData.Success(it) }!!
                        }
                        response.code() == 401 -> {
                            _stateData.value = ResultStateData.Error("Unauthorized")
                        }
                        response.code() == 403 -> {
                            _stateData.value = ResultStateData.Error("Block")
                        }
                        else -> {
                            _stateData.value = ResultStateData.Error("Error")
                        }
                    }
                }

                override fun onFailure(call: Call<UserInfo>, t: Throwable) {
                    _stateData.value = ResultStateData.Error("Network Error")
                }
            })
        }
    }

    private val _listState = MutableStateFlow<ListState>(ListState.Loading)
    val listState: StateFlow<ListState> = _listState

    sealed class ListState {
        data object Loading : ListState()
        data class Success(val data: List<ListInfo>) : ListState()
        data class Error(val message: String) : ListState()
    }

    fun loadList(login: String) {
        viewModelScope.launch {
            _listState.value = ListState.Loading
            try {
                val list = listRepository.getList(login)
                _listState.value = ListState.Success(list)
            } catch (e: Exception) {
                _listState.value = ListState.Error(e.message ?: "Unknown error")
            }
        }
    }

    sealed class ResultState {
        data object Initial : ResultState()
        data object InvalidCredentials : ResultState()
        data object Loading : ResultState()
        data object Success : ResultState()
        data object Error : ResultState()
    }

    sealed class ResultStateData {
        data object Initial : ResultStateData()
        data object Loading : ResultStateData()
        data class Success(val userInfo: UserInfo) : ResultStateData()
        data class Error(val message: String) : ResultStateData()
    }
}