package com.gh.gamecenter.gamecollection.publish

import android.annotation.SuppressLint
import android.app.Application
import android.content.Context
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.MediatorLiveData
import androidx.lifecycle.MutableLiveData
import com.gh.common.util.ApkActiveUtils
import com.gh.common.util.CheckLoginUtils
import com.gh.gamecenter.common.base.fragment.WaitingDialogFragment
import com.gh.gamecenter.common.retrofit.BiResponse
import com.gh.gamecenter.common.retrofit.Response
import com.gh.gamecenter.core.runOnIoThread
import com.gh.gamecenter.core.utils.ToastUtils
import com.gh.gamecenter.entity.*
import com.gh.gamecenter.common.mvvm.Resource
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.retrofit.RetrofitManager
import com.gh.gamecenter.room.AppDatabase
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers
import okhttp3.ResponseBody
import org.json.JSONObject
import retrofit2.HttpException

class GameCollectionEditViewModel(application: Application) : AndroidViewModel(application) {
    var imagePath = ""
    var imageUrl = ""
    var tags = ArrayList<TagInfoEntity>()
    var selectActivityTag: ActivityLabelEntity? = null
    var gameCollectionPatch: GamesCollectionEntity? = null
    var uploadImageSuccessLiveData = MutableLiveData<String>()
    var detailLiveData = MutableLiveData<GamesCollectionEntity>()
    var draftLiveData = MutableLiveData<GameCollectionDraft>()
    val postLiveData = MutableLiveData<Resource<String>>()
    val processDialog = MediatorLiveData<WaitingDialogFragment.WaitingDialogData>()
    private val mApi = RetrofitManager.getInstance().api
    private val mDraftDao = AppDatabase.getInstance().gameCollectionDraftDao()

    fun getGameDigest(gameId: String, callback: (gameEntity: GameEntity?) -> Unit) {
        mApi.getGameDigest(gameId)
            .map(ApkActiveUtils.filterMapper)
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(object : Response<GameEntity>() {
                override fun onResponse(response: GameEntity?) {
                    response?.let { callback.invoke(it) }
                }

                override fun onFailure(e: HttpException?) {
                    callback.invoke(null)
                }
            })
    }

    fun uploadPoster() {
        if (imagePath.isEmpty()) return
        UploadImageUtils.uploadImage(
            UploadImageUtils.UploadType.game_list_poster,
            imagePath,
            object : UploadImageUtils.OnUploadImageListener {
                override fun onSuccess(imageUrl: String) {
                    this@GameCollectionEditViewModel.imageUrl = imageUrl
                    uploadImageSuccessLiveData.postValue(imageUrl)
                }

                override fun onError(e: Throwable?) {
                    uploadImageSuccessLiveData.postValue("")
                    if (e is HttpException) {
                        val entity = e.response()?.errorBody()?.string()?.toObject<ErrorEntity>()
                        if (entity?.code == 403033) {
                            ToastUtils.showToast("图片违规，请重新上传")
                        } else {
                            ToastUtils.showToast("图片上传失败")
                        }
                    }
                }

                override fun onProgress(total: Long, progress: Long) {}
            })
    }

    fun uploadContent(context: Context, requestMap: HashMap<String, Any>) {
        CheckLoginUtils.checkLogin(context, "") {
            val id = requestMap["id"]?.toString() ?: ""
            requestMap.remove("id")
            postContent(requestMap, id)
        }
    }

    private fun postContent(requestMap: HashMap<String, Any>, gameCollectionId: String) {
        processDialog.postValue(WaitingDialogFragment.WaitingDialogData("提交中...", true))
        val requestBody = requestMap.toRequestBody()
        val observable = if (gameCollectionId.isEmpty()) {
            mApi.createGameCollection(requestBody)
        } else {
            mApi.patchGameCollection(requestBody, gameCollectionId)
        }
        observable
            .compose(observableToMain())
            .subscribe(object : Response<ResponseBody>() {
                override fun onResponse(response: ResponseBody?) {
                    super.onResponse(response)
                    val data = response?.string()
                    val id = if (!data.isNullOrEmpty()) {
                        JSONObject(data).optString("_id")
                    } else ""
                    postLiveData.postValue(Resource.success(id))
                    processDialog.postValue(WaitingDialogFragment.WaitingDialogData("", false))
                    deleteAllDraft()
                }

                override fun onFailure(e: HttpException?) {
                    super.onFailure(e)
                    postLiveData.postValue(Resource.error(e))
                    processDialog.postValue(WaitingDialogFragment.WaitingDialogData("", false))
                }
            })
    }

    fun getGameCollectionDetail(gameCollectionId: String) {
        if (gameCollectionId.isEmpty()) return
        processDialog.postValue(WaitingDialogFragment.WaitingDialogData("加载中...", true))
        mApi.getGameCollectionDetailForDraft(gameCollectionId)
            .compose(observableToMain())
            .subscribe(object : Response<GamesCollectionEntity>() {
                override fun onResponse(response: GamesCollectionEntity?) {
                    super.onResponse(response)
                    if (response != null) {
                        detailLiveData.postValue(response)
                        processDialog.postValue(WaitingDialogFragment.WaitingDialogData("", false))
                    }
                }

                override fun onFailure(e: HttpException?) {
                    super.onFailure(e)
                    processDialog.postValue(WaitingDialogFragment.WaitingDialogData("", false))
                }
            })
    }

    @SuppressLint("CheckResult")
    fun getDraft() {
        mDraftDao.getAllDraft()
            .compose(singleToMain())
            .subscribe(object : BiResponse<List<GameCollectionDraft>>() {
                override fun onSuccess(data: List<GameCollectionDraft>) {
                    if (data.isNotEmpty()) {
                        val draftEntity = data[0]
                        draftLiveData.postValue(draftEntity)
                    }
                }
            })
    }

    fun addDraft(entity: GameCollectionDraft) {
        runOnIoThread {
            val drafts = mDraftDao.getDrafts()
            mDraftDao.delete(drafts)
            mDraftDao.addDraft(entity)
        }
    }

    fun deleteAllDraft() {
        runOnIoThread {
            val drafts = mDraftDao.getDrafts()
            mDraftDao.delete(drafts)
        }
    }
}