package com.gh.gamecenter.personalhome.home

import android.annotation.SuppressLint
import android.app.Application
import android.text.TextUtils
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import com.gh.common.util.ErrorHelper
import com.gh.gamecenter.core.utils.UrlFilterUtils
import com.gh.gamecenter.common.utils.toObject
import com.gh.gamecenter.common.baselist.ListViewModel
import com.gh.gamecenter.common.baselist.LoadType
import com.gh.gamecenter.common.utils.singleToMain
import com.gh.gamecenter.entity.ErrorEntity
import com.gh.gamecenter.entity.ForumVideoEntity
import com.gh.gamecenter.entity.PersonalHistoryEntity
import com.gh.gamecenter.common.retrofit.BiResponse
import com.gh.gamecenter.energy.EnergyBridge
import com.gh.gamecenter.retrofit.RetrofitManager
import com.halo.assistant.HaloApp
import com.lightgame.utils.Utils
import io.reactivex.Observable
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers
import okhttp3.ResponseBody
import retrofit2.HttpException

class UserHistoryViewModel(
    application: Application,
    var userId: String,
    private var mScene: SCENE,
    var type: TYPE
) : ListViewModel<PersonalHistoryEntity, PersonalHistoryEntity>(application) {

    private val mApi = RetrofitManager.getInstance().api
    var videoList = arrayListOf<ForumVideoEntity>()
    var count = MutableLiveData<Int>()

    init {
        setOverLimitSize(1)
    }

    override fun provideDataObservable(page: Int): Observable<MutableList<PersonalHistoryEntity>> {
        getCount()
        return mApi.getPersonalHistory(
            userId, page,
            HaloApp.getInstance().channel, getFilter()
        )
    }

    override fun mergeResultLiveData() {
        mResultLiveData.addSource(mListLiveData) { list ->

            videoList = ArrayList(list.map { it.transformForumVideoEntity() })

            mResultLiveData.postValue(list)
        }
    }

    @SuppressLint("CheckResult")
    private fun getCount() {
        mApi.getPersonalHistoryCount(userId, HaloApp.getInstance().channel, getFilter())
            .compose(singleToMain())
            .subscribe(object : BiResponse<retrofit2.Response<ResponseBody>>() {
                override fun onSuccess(data: retrofit2.Response<ResponseBody>) {
                    val countContent = data.headers().get("Total")
                    count.postValue(if (TextUtils.isEmpty(countContent)) 0 else countContent?.toInt() ?: 0)
                }
            })
    }

    fun voteComment(gameId: String, commentId: String, callback: () -> Unit) {
        mApi.voteGameComment(gameId, commentId)
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(object : com.gh.gamecenter.common.retrofit.Response<ResponseBody>() {
                override fun onResponse(response: ResponseBody?) {
                    Utils.toast(getApplication(), "点赞成功")
                    callback.invoke()

                    EnergyBridge.postEnergyTask("vote_game_comment", commentId)
                }

                override fun onFailure(e: HttpException?) {
                    val string = e?.response()?.errorBody()?.string()
                    val errorEntity = string?.toObject<ErrorEntity>()
                    if (errorEntity?.code == 403008) {
                        onResponse(null)
                        return
                    }
                    ErrorHelper.handleError(getApplication(), string)
                }
            })
    }

    fun unVoteComment(gameId: String, commentId: String, callback: () -> Unit) {
        mApi.unvoteGameComment(gameId, commentId)
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(object : com.gh.gamecenter.common.retrofit.Response<ResponseBody>() {
                override fun onResponse(response: ResponseBody?) {
                    super.onResponse(response)
                    Utils.toast(getApplication(), "取消点赞")
                    callback.invoke()
                }

                override fun onFailure(e: HttpException?) {
                    val string = e?.response()?.errorBody()?.string()
                    ErrorHelper.handleError(getApplication(), string)
                }
            })
    }


    fun changeType(type: TYPE) {
        if (this.type != type) {
            this.type = type
            load(LoadType.REFRESH)
        }
    }

    /**
     * scene -> comment/question_answer
     * type -> question/answer/community_article
     */
    private fun getFilter(): String {
        return if (mScene != SCENE.COMMENT) {
            return UrlFilterUtils.getFilterQuery(
                "scene", mScene.value,
                "type", type.value
            )
        } else {
            UrlFilterUtils.getFilterQuery("scene", mScene.value)
        }
    }

    enum class SCENE(val value: String) {
        COMMENT("comment"),
        QUESTION_ANSWER("question_answer")
    }

    enum class TYPE(val value: String) {
        ALL("all"),
        VIDEO("video"),
        COMMUNITY_ARTICLE("community_article"),
        ANSWER("answer"),
        QUESTION("question");

        companion object {
            @JvmStatic
            fun fromValue(value: String?) = values().find { value == it.value } ?: ALL
        }
    }

    class Factory(
        private val mApplication: Application,
        private val mUserId: String,
        private val mScene: SCENE,
        private val mType: TYPE
    ) : ViewModelProvider.NewInstanceFactory() {
        override fun <T : ViewModel> create(modelClass: Class<T>): T {
            return UserHistoryViewModel(mApplication, mUserId, mScene, mType) as T
        }
    }

}