package kr.co.vividnext.sodalive.audio_content

import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import com.google.gson.annotations.SerializedName
import com.orhanobut.logger.Logger
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
import io.reactivex.rxjava3.schedulers.Schedulers
import kr.co.vividnext.sodalive.audio_content.category.GetCategoryListResponse
import kr.co.vividnext.sodalive.base.BaseViewModel
import kr.co.vividnext.sodalive.common.SharedPreferenceManager
import kr.co.vividnext.sodalive.explorer.profile.GetAudioContentListResponse

class AudioContentViewModel(private val repository: AudioContentRepository) : BaseViewModel() {

    private val _toastLiveData = MutableLiveData<String?>()
    val toastLiveData: LiveData<String?>
        get() = _toastLiveData

    private var _isLoading = MutableLiveData(false)
    val isLoading: LiveData<Boolean>
        get() = _isLoading

    private var _audioContentListLiveData = MutableLiveData<GetAudioContentListResponse>()
    val audioContentListLiveData: LiveData<GetAudioContentListResponse>
        get() = _audioContentListLiveData

    private var _categoryListLiveData = MutableLiveData<List<GetCategoryListResponse>>()
    val categoryListLiveData: LiveData<List<GetCategoryListResponse>>
        get() = _categoryListLiveData

    private val _sort = MutableLiveData(Sort.NEWEST)
    val sort: LiveData<Sort>
        get() = _sort

    enum class Sort {
        @SerializedName("NEWEST")
        NEWEST,

        @SerializedName("PRICE_HIGH")
        PRICE_HIGH,

        @SerializedName("PRICE_LOW")
        PRICE_LOW
    }

    var isLast = false
    var page = 1
    private val size = 10
    private var selectedCategoryId = 0L

    fun getAudioContentList(userId: Long, onFailure: (() -> Unit)? = null) {
        if (!_isLoading.value!! && !isLast) {
            _isLoading.value = true
            compositeDisposable.add(
                repository.getAudioContentList(
                    id = userId,
                    categoryId = selectedCategoryId,
                    page = page,
                    size = size,
                    token = "Bearer ${SharedPreferenceManager.token}",
                    sort = _sort.value!!
                )
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(
                        {
                            if (it.success && it.data != null) {
                                if (it.data.items.isEmpty()) {
                                    isLast = true
                                }

                                page += 1
                                _audioContentListLiveData.postValue(it.data!!)
                            } else {
                                if (it.message != null) {
                                    _toastLiveData.postValue(it.message)
                                } else {
                                    _toastLiveData.postValue(
                                        "알 수 없는 오류가 발생했습니다. 다시 시도해 주세요."
                                    )
                                }

                                if (onFailure != null) {
                                    onFailure()
                                }
                            }

                            _isLoading.value = false
                        },
                        {
                            _isLoading.value = false
                            it.message?.let { message -> Logger.e(message) }
                            _toastLiveData.postValue("알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.")
                            if (onFailure != null) {
                                onFailure()
                            }
                        }
                    )
            )
        }
    }

    fun changeSort(sort: Sort) {
        page = 1
        isLast = false
        _sort.postValue(sort)
    }

    fun selectCategory(categoryId: Long, userId: Long) {
        isLast = false
        page = 1
        selectedCategoryId = categoryId
        getAudioContentList(userId = userId)
    }

    fun getCategoryList(userId: Long) {
        compositeDisposable.add(
            repository.getCategoryList(
                creatorId = userId,
                token = "Bearer ${SharedPreferenceManager.token}",
            )
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(
                    {
                        if (it.success && it.data != null) {
                            _categoryListLiveData.value = it.data!!
                        } else {
                            if (it.message != null) {
                                _toastLiveData.postValue(it.message)
                            } else {
                                _toastLiveData.postValue(
                                    "알 수 없는 오류가 발생했습니다. 다시 시도해 주세요."
                                )
                            }
                        }

                        _isLoading.value = false
                    },
                    {
                        _isLoading.value = false
                        it.message?.let { message -> Logger.e(message) }
                        _toastLiveData.postValue("알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.")
                    }
                )
        )
    }
}
