package com.gh.gamecenter.qa.video.detail

import android.annotation.SuppressLint
import android.app.Application
import android.net.Uri
import android.text.TextUtils
import androidx.lifecycle.*
import com.gh.gamecenter.common.constant.Constants
import com.gh.common.history.HistoryDatabase
import com.gh.gamecenter.common.json.json
import com.gh.gamecenter.core.runOnIoThread
import com.gh.common.util.*
import com.gh.gamecenter.common.utils.observableToMain
import com.gh.gamecenter.common.utils.toRequestBody
import com.gh.gamecenter.common.utils.tryCatchInRelease
import com.gh.gamecenter.core.utils.*
import com.gh.gamecenter.entity.*
import com.gh.gamecenter.common.mvvm.Resource
import com.gh.gamecenter.common.retrofit.BiResponse
import com.gh.gamecenter.common.retrofit.Response
import com.gh.gamecenter.feature.entity.ForumVideoEntity
import com.gh.gamecenter.feature.entity.Permissions
import com.gh.gamecenter.feature.entity.User
import com.gh.gamecenter.retrofit.RetrofitManager
import com.google.gson.JsonObject
import com.halo.assistant.HaloApp
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers
import okhttp3.ResponseBody
import retrofit2.HttpException
import tv.danmaku.ijk.media.exo2.ExoSourceManager

class ForumVideoDetailViewModel(
    application: Application,
    val videoId: String,
    val recommendId: String
) :
    AndroidViewModel(application) {
    private val mApi = RetrofitManager.getInstance().api
    var videoIsMuted = SPUtils.getBoolean(Constants.SP_VIDEO_PLAY_MUTE, true)
    val detailLiveData = MediatorLiveData<Resource<ForumVideoEntity>>()
    val updateDetailLiveData = MediatorLiveData<ForumVideoEntity>()
    var needToUpdateShareCount = MutableLiveData<Int>()
    var deleteLiveData = MutableLiveData<Boolean>()
    val highlight = MutableLiveData<Boolean>()
    val cancelHighlight = MutableLiveData<Boolean>()
    val applyHighlight = MutableLiveData<Boolean>()
    val top = MutableLiveData<Boolean>()
    var currentToolbarStatus = true

    init {
        getVideoDetail()
    }

    fun getVideoDetail() {
        mApi.getBbsVideoDetail(videoId)
            .compose(observableToMain())
            .subscribe(object : Response<ForumVideoEntity>() {
                override fun onResponse(response: ForumVideoEntity?) {
                    super.onResponse(response)
                    if (response != null) {
                        detailLiveData.postValue(Resource.success(response))

                        NewLogUtils.logForumContentBrowser(videoId, "bbs_video", recommendId)
                    }
                }

                override fun onFailure(e: HttpException?) {
                    super.onFailure(e)
                    detailLiveData.postValue(Resource.error(e))
                }
            })
    }

    @SuppressLint("CheckResult")
    fun shareVideoStatistics(videoEntity: ForumVideoEntity?) {
        if (videoEntity == null) return
        mApi.shareVideoStatistics(videoEntity.id)
            .subscribeOn(Schedulers.io())
            .subscribe(object : BiResponse<JsonObject>() {
                override fun onSuccess(data: JsonObject) {
                    val msg = data.get("msg").asString
                    if ("success" == msg) {
                        videoEntity.let {
                            it.share++
                        }
                        needToUpdateShareCount.postValue(videoEntity.share)
                    }
                }
            })

    }

    fun deleteVideo(videoId: String) {
        mApi.deleteVideo(videoId)
            .compose(observableToMain())
            .subscribe(object : Response<ResponseBody>() {
                override fun onResponse(response: ResponseBody?) {
                    deleteLiveData.postValue(true)
                }

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


    //版主加精
    fun doHighlightThisVideo(videoId: String) {
        mApi.highlightCommunityVideo(videoId)
            .compose(observableToMain())
            .subscribe(object : Response<ResponseBody>() {
                override fun onResponse(response: ResponseBody?) {
                    super.onResponse(response)
                    highlight.postValue(true)
                }

                override fun onFailure(e: HttpException?) {
                    super.onFailure(e)
                    ErrorHelper.handleError(HaloApp.getInstance().application, e?.response()?.errorBody()?.string())
                }
            })
    }

    //版主取消精选
    fun cancelHighlightThisVideo(videoId: String) {
        mApi.cancelHighlightCommunityVideo(videoId)
            .compose(observableToMain())
            .subscribe(object : Response<ResponseBody>() {
                override fun onResponse(response: ResponseBody?) {
                    super.onResponse(response)
                    cancelHighlight.postValue(true)
                }

                override fun onFailure(e: HttpException?) {
                    super.onFailure(e)
                    ErrorHelper.handleError(HaloApp.getInstance().application, e?.response()?.errorBody()?.string())
                }
            })
    }

    //用户申请加精
    fun doApplyHighlightCommunityVideo(videoId: String) {
        mApi.applyHighlightCommunityVideo(videoId)
            .compose(observableToMain())
            .subscribe(object : Response<ResponseBody>() {
                override fun onResponse(response: ResponseBody?) {
                    super.onResponse(response)
                    applyHighlight.postValue(true)
                }

                override fun onFailure(e: HttpException?) {
                    super.onFailure(e)
                    applyHighlight.postValue(false)
                }
            })
    }

    fun modifyVideoActivityTag(videoEntity: ForumVideoEntity?, label: ActivityLabelEntity?) {
        val body = json { "tag_activity_id" to label?.id }.toRequestBody()
        mApi.modifyVideoActivityTag(videoEntity?.bbsId, videoId, body)
            .compose(observableToMain())
            .subscribe(object : Response<ResponseBody>() {
                override fun onResponse(response: ResponseBody?) {
                    super.onResponse(response)
                    videoEntity?.apply {
                        if (me.moderatorPermissions.updateVideoActivityTag == Permissions.ADMIN) {
                            tagActivityId = label?.id ?: ""
                            tagActivityName = label?.name ?: ""
                            updateDetailLiveData.postValue(this)
                            ToastUtils.showToast("修改活动标签成功")
                        } else {
                            ToastUtils.showToast("提交成功")
                        }
                    }
                }

                override fun onFailure(e: HttpException?) {
                    super.onFailure(e)
                    ToastUtils.showToast("修改活动标签失败")
                }
            })
    }

    fun addHistoryRecord(videoEntity: ForumVideoEntity) {
        val videoHistory = MyVideoEntity().apply {
            id = videoEntity.id
            poster = videoEntity.poster
            url = videoEntity.url
            vote = videoEntity.count.vote
            length = videoEntity.length
            time = System.currentTimeMillis()
            title = videoEntity.title
            user = User(
                videoEntity.user.id ?: "", videoEntity.user.name ?: "", videoEntity.user.icon ?: ""
            )
            commentCount = videoEntity.count.comment
            videoStreamRecord = 0
        }

        runOnIoThread { tryCatchInRelease { HistoryDatabase.instance.videoHistoryDao().addVideo(videoHistory) } }
    }

    fun topCommunityVideo(topCategoryId: String) {
        detailLiveData.value?.data?.let { videoDetail ->
            mApi.topCommunityVideo(
                videoDetail.id,
                mapOf(
                    "title" to videoDetail.title,
                    "top_category_id" to topCategoryId
                ).toRequestBody()
            )
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(object : Response<ResponseBody>() {
                    override fun onResponse(response: ResponseBody?) {
                        getVideoDetail()
                        top.postValue(true)
                    }
                })
        }
    }

    fun cancelTopCommunityVideo() {
        detailLiveData.value?.data
            ?.also {videoDetail ->
                videoDetail.top?.let { communityTop ->
                mApi.cancelTopCommunityVideo(
                    videoDetail.id,
                    mapOf(
                        "video_top_id" to communityTop.id
                    ).toRequestBody()
                )
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(object : Response<ResponseBody>() {
                        override fun onResponse(response: ResponseBody?) {
                            getVideoDetail()
                            top.postValue(false)
                        }
                    })
            }

        }
    }

    fun isTopVideoPartlyCached(topVideoUrl: String): Boolean {
        val cache = ExoSourceManager.getCacheSingleInstance(HaloApp.getInstance().application, null)
        val key = Uri.parse(topVideoUrl).toString()
        return if (!TextUtils.isEmpty(key)) {
            val cachedSpans = cache.getCachedSpans(key)
            cachedSpans.size != 0
        } else {
            false
        }
    }

    class Factory(private val videoId: String, private val recommendId: String) :
        ViewModelProvider.NewInstanceFactory() {
        override fun <T : ViewModel> create(modelClass: Class<T>): T {
            return ForumVideoDetailViewModel(
                HaloApp.getInstance().application,
                videoId,
                recommendId
            ) as T
        }
    }
}