package com.gh.gamecenter.gamedetail.rating.edit

import android.annotation.SuppressLint
import android.app.Application
import android.os.Build
import androidx.lifecycle.*
import com.gh.gamecenter.common.base.fragment.WaitingDialogFragment
import com.gh.gamecenter.common.mvvm.Resource
import com.gh.gamecenter.common.retrofit.BiResponse
import com.gh.gamecenter.common.retrofit.EmptyResponse
import com.gh.gamecenter.common.retrofit.Response
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.energy.EnergyBridge
import com.gh.gamecenter.entity.RatingDraftEntity
import com.gh.gamecenter.retrofit.RetrofitManager
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers
import okhttp3.RequestBody
import okhttp3.ResponseBody
import org.json.JSONObject
import retrofit2.HttpException

class RatingEditViewModel(
    application: Application,
    private val mGameId: String
) : AndroidViewModel(application) {

    private val mApi = RetrofitManager.getInstance().api

    var deviceName: MutableLiveData<String> = MutableLiveData()
    var guideTags: MutableLiveData<List<String>> = MutableLiveData() // 引导标签
    val postLiveData = MediatorLiveData<Resource<String>>()
    val ratingDraftLiveData = MediatorLiveData<RatingDraftEntity?>()
    val postRatingDrafts = MediatorLiveData<Pair<RatingEditActivity.SaveDraftType, RatingDraftEntity>>()
    val processDialog = MediatorLiveData<WaitingDialogFragment.WaitingDialogData>()

    /**
     * 获取引导标签
     */
    fun getGuideTags() {
        mApi.guideTags()
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(object : Response<List<String>>() {
                override fun onResponse(response: List<String>?) {
                    super.onResponse(response)
                    if (response != null) {
                        guideTags.postValue(response)
                    } else {
                        guideTags.postValue(arrayListOf())
                    }
                }
            })
    }

    @SuppressLint("CheckResult")
    fun getDeviceName() {
        mApi.getDeviceAlias(Build.MODEL)
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(object : BiResponse<ResponseBody>() {
                override fun onSuccess(data: ResponseBody) {
                    val json = JSONObject(data.string())
                    val alias = json.getString("alias")
                    deviceName.postValue(alias)
                }
            })
    }

    @SuppressLint("CheckResult")
    fun postGameComment(commentId: String, body: RequestBody) {
        processDialog.postValue(WaitingDialogFragment.WaitingDialogData("提交中...", true))
        val observable = if (commentId.isNotEmpty()) {
            mApi.patchGameRating(mGameId, commentId, body)
        } else {
            mApi.postGameComment(mGameId, body)
        }
        observable
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(object : BiResponse<ResponseBody>() {
                override fun onSuccess(data: ResponseBody) {
                    processDialog.postValue(WaitingDialogFragment.WaitingDialogData("提交中...", false))
                    postLiveData.postValue(Resource.success(""))
                    deleteRatingDraft()

                    if (commentId.isEmpty()) {
                        tryWithDefaultCatch {
                            EnergyBridge.postEnergyTask("post_game_comment", JSONObject(data.string()).optString("_id"))
                        }
                    }
                }

                override fun onFailure(exception: Exception) {
                    processDialog.postValue(WaitingDialogFragment.WaitingDialogData("提交中...", false))
                    val httpException = if (exception is HttpException) {
                        exception
                    } else null
                    postLiveData.postValue(Resource.error(httpException))
                }

            })
    }

    @SuppressLint("CheckResult")
    fun getRatingDraft() {
        processDialog.postValue(WaitingDialogFragment.WaitingDialogData("加载中...", true))
        mApi.getRatingDraft(mGameId)
            .compose(singleToMain())
            .subscribe(object : BiResponse<RatingDraftEntity>() {
                override fun onSuccess(data: RatingDraftEntity) {
                    ratingDraftLiveData.postValue(data)
                    processDialog.postValue(WaitingDialogFragment.WaitingDialogData("加载中...", false))
                }

                override fun onFailure(exception: Exception) {
                    ratingDraftLiveData.postValue(null)
                    processDialog.postValue(WaitingDialogFragment.WaitingDialogData("加载中...", false))
                }

            })
    }

    @SuppressLint("CheckResult")
    fun saveRatingDraft(
        saveType: RatingEditActivity.SaveDraftType,
        draft: RatingDraftEntity
    ) {
        val map = mapOf(
            "star" to draft.star,
            "show_device" to draft.showDevice,
            "content" to draft.content,
        )
        mApi.saveRatingDraft(mGameId, map.toRequestBody())
            .compose(singleToMain())
            .subscribe(object : BiResponse<ResponseBody>() {
                override fun onSuccess(data: ResponseBody) {
                    postRatingDrafts.postValue(Pair(saveType, draft))
                }
            })
    }

    @SuppressLint("CheckResult")
    fun deleteRatingDraft() {
        mApi.deleteRatingDraft(mGameId)
            .compose(singleToMain())
            .subscribe(EmptyResponse())
    }

    class Factory(
        private val mApplication: Application,
        private val mGameId: String
    ) : ViewModelProvider.NewInstanceFactory() {
        override fun <T : ViewModel> create(modelClass: Class<T>): T {
            return RatingEditViewModel(mApplication, mGameId) as T
        }
    }
}