package com.gh.gamecenter.tag

import android.annotation.SuppressLint
import android.app.Application
import androidx.lifecycle.MutableLiveData
import com.gh.gamecenter.feature.exposure.ExposureSource
import com.gh.common.exposure.ExposureUtils
import com.gh.gamecenter.core.utils.UrlFilterUtils
import com.gh.common.view.ConfigFilterView
import com.gh.gamecenter.common.baselist.ListViewModel
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.entity.SubjectSettingEntity
import com.gh.gamecenter.entity.TagEntity
import com.gh.gamecenter.common.retrofit.BiResponse
import com.gh.gamecenter.retrofit.RetrofitManager
import io.reactivex.Observable
import io.reactivex.Single
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers

class TagsListViewModel(application: Application) : ListViewModel<GameEntity, GameEntity>(application) {

    val refresh = MutableLiveData<Boolean>()
    val requestTagsError = MutableLiveData<Boolean>()
    val tags = MutableLiveData<ArrayList<TagEntity>>()

    var basicExposureSourceList = arrayListOf<ExposureSource>()

    var mSortType = ConfigFilterView.SortType.RECOMMENDED
    private var mSortSize = SubjectSettingEntity.Size()

    var selectedTag = TagEntity()

    override fun provideDataObservable(page: Int): Observable<List<GameEntity>>? {
        return null
    }

    override fun provideDataSingle(page: Int): Single<List<GameEntity>> {
        return RetrofitManager.getInstance()
            .api
            .getGamesWithSpecificTag(getSortSize(), getSortType(), page)
    }

    override fun mergeResultLiveData() {
        mResultLiveData.addSource(mListLiveData) {
            ExposureUtils.updateExposureInfo(it)
            mResultLiveData.postValue(it)
        }
    }

    fun changeSelectedTag(tagEntity: TagEntity) {
        if (selectedTag != tagEntity) {
            selectedTag = tagEntity

            refresh.postValue(true)
        }
    }

    fun updateSortConfig(
        sortSize: SubjectSettingEntity.Size? = null,
        sortType: ConfigFilterView.SortType? = null
    ) {
        if (sortSize != null && sortSize != mSortSize) {
            mSortSize = sortSize
            refresh.postValue(true)
        } else if (sortType != null && sortType != mSortType) {
            mSortType = sortType
            refresh.postValue(true)
        }
    }

    fun getSortTypeInChinese() = if (mSortType == ConfigFilterView.SortType.RECOMMENDED) "推荐" else "最新"

    @SuppressLint("CheckResult")
    fun getTags(tagName: String) {
        RetrofitManager.getInstance()
            .api
            .getRelatedTags(UrlFilterUtils.getFilterQuery("tag", tagName))
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(object : BiResponse<ArrayList<TagEntity>>() {
                override fun onSuccess(data: ArrayList<TagEntity>) {
                    val tagToShow = data.find { tag ->
                        tag.name == tagName
                    } ?: TagEntity()
                    changeSelectedTag(tagToShow)

                    tags.postValue(data)
                }

                override fun onFailure(exception: Exception) {
                    super.onFailure(exception)
                    requestTagsError.postValue(true)
                }
            })
    }

    private fun getSortSize(): String? {
        return UrlFilterUtils.getFilterQuery(
            "tag_id", selectedTag.id,
            "min_size", mSortSize.min.toString(),
            "max_size", mSortSize.max.toString()
        )
    }

    private fun getSortType(): String? {
        return if (mSortType == ConfigFilterView.SortType.RECOMMENDED) {
            "download:-1"
        } else {
            "publish:-1"
        }
    }

}