package com.gh.gamecenter.qa.questions.edit

import android.annotation.SuppressLint
import android.app.Application
import android.text.TextUtils
import android.view.Gravity
import androidx.lifecycle.MediatorLiveData
import androidx.lifecycle.MutableLiveData
import com.gh.base.BaseRichEditorViewModel
import com.gh.base.RichType
import com.gh.gamecenter.common.base.fragment.WaitingDialogFragment
import com.gh.gamecenter.R
import com.gh.gamecenter.common.utils.singleToMain
import com.gh.gamecenter.common.utils.toJson
import com.gh.gamecenter.common.utils.toRequestBody
import com.gh.gamecenter.common.utils.tryWithDefaultCatch
import com.gh.gamecenter.core.utils.*
import com.gh.gamecenter.entity.ActivityLabelEntity
import com.gh.gamecenter.common.entity.CommunityEntity
import com.gh.gamecenter.entity.GameEntity
import com.gh.gamecenter.entity.Permissions
import com.gh.gamecenter.common.eventbus.EBReuse
import com.gh.gamecenter.login.user.UserManager
import com.gh.gamecenter.common.mvvm.Resource
import com.gh.gamecenter.qa.entity.QuestionDraftEntity
import com.gh.gamecenter.qa.entity.QuestionsDetailEntity
import com.gh.gamecenter.common.retrofit.BiResponse
import com.gh.gamecenter.common.retrofit.Response
import com.gh.gamecenter.energy.EnergyBridge
import com.lightgame.utils.Utils
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers
import okhttp3.MediaType
import okhttp3.RequestBody
import okhttp3.ResponseBody
import org.greenrobot.eventbus.EventBus
import org.json.JSONArray
import org.json.JSONObject
import retrofit2.HttpException

/**
 * Created by khy on 28/04/18.
 */
class QuestionEditViewModel(application: Application) : BaseRichEditorViewModel(application) {

    var communityEntity: CommunityEntity? = null
    var isModeratorPatch: Boolean = false
    var isFromSearch: Boolean = false

    val postLiveData = MediatorLiveData<Resource<String>>()
    val moderatorPostLiveData = MediatorLiveData<Resource<String>>()
    val notSelectForum = MutableLiveData<Boolean>()
    val postQuestionDrafts = MediatorLiveData<Pair<QuestionEditActivity.SaveDraftType, Boolean>>()
    val questionDraftsContent = MutableLiveData<QuestionDraftEntity>()

    // post data
    var title: String? = ""
    var content: String? = ""

    var defaultTags: MutableList<String> = ArrayList()
    var questionEntity: QuestionsDetailEntity? = null
    var questionDraftEntity: QuestionDraftEntity? = null
    val selectedTags: MutableList<String> = ArrayList()
    val selectedTagsChange = MediatorLiveData<Boolean>()
    var selectActivityLabelEntity: ActivityLabelEntity? = null
    var gameEntity: GameEntity? = null

    fun initCommunityDataAndDraft() {
        if (questionEntity != null) {
            communityEntity = questionEntity?.community
        }/* else {
            communityId = CommunityManager.getInstance().community.id
            communityName = CommunityManager.getInstance().community.name
            if (!isFromSearch) checkQuestionDraft()
        }*/
    }

    /**
     * 获取默认标签和确定当前communityId
     */
    fun getDefaultTag(isLoadOver: (() -> Unit)?) {
        mApi.getCommunitiesTags(communityEntity?.id)
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(object : Response<List<String>>() {
                override fun onResponse(response: List<String>?) {
                    defaultTags = response as MutableList<String>
                    isLoadOver?.invoke()
                }

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

    /**
     * 检查标题是否符合规则
     * 根据问题标题获取相应标签(问题编辑无需获取)
     */
    fun checkTitleAndLoadTitleTag(isKeyBoardShow: Boolean = false): Boolean {
        if (TextUtils.isEmpty(title)) {
            ToastUtils.showToast("标题不能为空", if (isKeyBoardShow) Gravity.CENTER else -1)
            return false
        }

        // 检查标题长度限制
        title?.trim()
        //title = title?.replace(" ", "")
        if (title!!.length < TITLE_MIN_LENGTH) {
            ToastUtils.showToast("标题至少${TITLE_MIN_LENGTH}个字", if (isKeyBoardShow) Gravity.CENTER else -1)
            return false
        }
        val articleContent = HtmlUtils.stripHtml(content).length
        if (articleContent < MIN_TEXT_LENGTH) {
            ToastUtils.showToast("正文至少${TITLE_MIN_LENGTH}个字", if (isKeyBoardShow) Gravity.CENTER else -1)
            return false
        }
        if (articleContent > MAX_TEXT_LENGTH) {
            ToastUtils.showToast("帖子最多输入${MAX_TEXT_LENGTH}个字", if (isKeyBoardShow) Gravity.CENTER else -1)
            return false
        }

        if (questionEntity != null && questionEntity?.title == title && questionEntity?.description == content) return false

        if (TextUtils.isEmpty(communityEntity?.id) || TextUtils.isEmpty(communityEntity?.name)) {
            ToastUtils.showToast("论坛不能为空", if (isKeyBoardShow) Gravity.CENTER else -1)
            notSelectForum.postValue(true)
            return false
        }

        // 检查标题结尾是否存在问号,没则主动加上
        if (title!!.length <= QUESTION_TITLE_MAX_LENGTH) {
            val endString = title?.substring(title!!.length - 1, title!!.length)
            if ("?" != endString && "？" != endString)
                title += "？"
        }
        return true
    }


    fun checkData(): Boolean {
        if (TextUtils.isEmpty(communityEntity?.id) || TextUtils.isEmpty(communityEntity?.name)) return false
        if (TextUtils.isEmpty(title)) return false
        // 检查标题长度限制
        title?.trim()
        if (title!!.length < TITLE_MIN_LENGTH) return false
        val articleContent = HtmlUtils.stripHtml(content).length
        if (articleContent < MIN_TEXT_LENGTH) return false
        if (articleContent > MAX_TEXT_LENGTH) return false
        if (questionEntity != null && questionEntity?.title == title && questionEntity?.description == content) return false
        return true
    }

    /**
     * 选择动作(选中标签/移除已选中的标签)
     */
    fun selectTag(tag: String): Boolean {
        return when {
            selectedTags.contains(tag) -> {
                selectedTags.remove(tag)
                selectedTagsChange.postValue(true)
                false
            }
            selectedTags.size < QUESTION_TAG_MAX_COUNT -> {
                selectedTags.add(tag)
                selectedTagsChange.postValue(true)
                true
            }
            else -> {
                Utils.toast(getApplication(), R.string.questionsdetail_max_tag_hint)
                false
            }
        }
    }

    fun uploadPicAndPostQuestion(isForce: Boolean) {
        postQuestion(isForce)
    }

    fun uploadPicAndPatchQuestion(isPatchTags: Boolean) {
        moderatorsPatchQuestion(isPatchTags)
    }

    private fun getRequestParams(): HashMap<String, Any> {
        val map = hashMapOf<String, Any>()
        map["title"] = title ?: ""
        map["content"] = content ?: ""
        map["type"] = type
        map["tag_activity_id"] = selectActivityLabelEntity?.id ?: ""
        map["bbs_id"] = communityEntity?.id ?: ""
        map["game_id"] = gameEntity?.id ?: ""
        map["draft_id"] = questionDraftEntity?.id ?: ""
        return map
    }

    /**
     * 提交问题
     */
    private fun postQuestion(isForce: Boolean) {
        val requestParams = getRequestParams()
        val observable = if (questionEntity != null) {
            mApi.patchQuestions(requestParams.toRequestBody(), questionEntity?.id) // patch
        } else {
            val postContent = if (isForce) { // 标题重复提示后强制提交
                requestParams["again"] = true
                requestParams
            } else {
                requestParams
            }
            mApi.postQuestions(postContent.toRequestBody()) // add
        }

        processDialog.postValue(WaitingDialogFragment.WaitingDialogData("提交中...", true))

        observable.subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(object : Response<ResponseBody>() {
                override fun onResponse(response: ResponseBody?) {
                    processDialog.postValue(WaitingDialogFragment.WaitingDialogData("提交中...", false))
                    MtaHelper.onEvent("发表问题", "提交成功", communityEntity?.name)
                    val data = response?.string() ?: ""
                    postLiveData.postValue(Resource.success(data))
                    EventBus.getDefault().post(EBReuse(QuestionEditActivity.QUESTION_POSTED_TAG))

                    if (!questionDraftEntity?.id.isNullOrEmpty()) {
                        EventBus.getDefault().post(EBReuse(QuestionEditActivity.QUESTION_DRAFT_CHANGE_TAG))
                    }

                    if (questionEntity == null) {
                        tryWithDefaultCatch {
                            EnergyBridge.postEnergyTask("post_question", JSONObject(data).optString("_id"))
                        }
                    }
                }

                override fun onFailure(e: HttpException?) {
                    processDialog.postValue(WaitingDialogFragment.WaitingDialogData("提交中...", false))
                    postLiveData.postValue(Resource.error(e))
                    MtaHelper.onEvent("发表问题", "提交失败", communityEntity?.name)
                }
            })
    }

    private fun moderatorsPatchQuestion(isPatchTags: Boolean) {
        val bodyJson = if (isPatchTags) {
            val tagsJson = JSONObject()
            tagsJson.put("tags", JSONArray(selectedTags))
            tagsJson.toString()
        } else {
            getRequestParams().toJson()
        }

        processDialog.postValue(WaitingDialogFragment.WaitingDialogData("提交中...", true))
        val body = RequestBody.create(MediaType.parse("application/json"), bodyJson)
        mApi.moderatorsPatchQuestion(body, UserManager.getInstance().userId, questionEntity?.id)
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(object : Response<ResponseBody>() {
                override fun onResponse(response: ResponseBody?) {
                    if (questionEntity!!.me.moderatorPermissions.updateQuestion > Permissions.REPORTER && !isPatchTags) {
                        questionEntity?.title = title
                        questionEntity?.description = content
                    }
                    moderatorPostLiveData.postValue(Resource.success(""))
                    processDialog.postValue(WaitingDialogFragment.WaitingDialogData("提交中...", false))
                }

                override fun onFailure(e: HttpException?) {
                    moderatorPostLiveData.postValue(Resource.error(e))
                    processDialog.postValue(WaitingDialogFragment.WaitingDialogData("提交中...", false))
                }
            })
    }

    @SuppressLint("CheckResult")
    fun saveQuestionDraft(saveType: QuestionEditActivity.SaveDraftType) {
        val requestParams = getRequestParams()
        if (questionEntity != null) {
            requestParams["question_id"] = questionEntity?.id ?: ""
        }
        val body = requestParams.toRequestBody()
        val observable = if (!questionDraftEntity?.id.isNullOrEmpty()) {
            mApi.updateQuestionDraft(UserManager.getInstance().userId, questionDraftEntity?.id, body)
        } else {
            mApi.addQuestionDraft(UserManager.getInstance().userId, body)
        }
        observable
            .compose(singleToMain())
            .subscribe(object : BiResponse<ResponseBody>() {
                override fun onSuccess(data: ResponseBody) {
                    val string = data.string()
                    if (!string.isNullOrEmpty() && questionDraftEntity?.id.isNullOrEmpty()) {
                        if (questionDraftEntity == null) questionDraftEntity = QuestionDraftEntity()
                        questionDraftEntity?.id = JSONObject(string).getString("_id")
                    }
                    postQuestionDrafts.postValue(Pair(saveType, true))
                }

                override fun onFailure(exception: Exception) {
                    super.onFailure(exception)
                    postQuestionDrafts.postValue(Pair(saveType, false))
                }
            })
    }

    private fun getQuestionBody(): RequestBody {
        val draftEntity = QuestionDraftEntity(
            communityId = communityEntity?.id ?: "",
            tags = selectedTags.toList(),
            title = title ?: "",
            description = content ?: "",
            type = type,
            gameId = gameEntity?.id ?: "",
            tagActivityId = selectActivityLabelEntity?.id ?: "",
            tagActivityName = selectActivityLabelEntity?.name ?: ""
        )
        if (questionEntity != null) {
            draftEntity.questionId = questionEntity?.id ?: ""
        }
        return draftEntity.toRequestBody()
    }

    @SuppressLint("CheckResult")
    fun getQuestionDraftContent(draftId: String) {
        processDialog.postValue(WaitingDialogFragment.WaitingDialogData("加载中...", true))
        mApi.getQuestionDraft(UserManager.getInstance().userId, draftId)
            .compose(singleToMain())
            .subscribe(object : BiResponse<QuestionDraftEntity>() {
                override fun onSuccess(data: QuestionDraftEntity) {
                    questionDraftsContent.postValue(data)
                    processDialog.postValue(WaitingDialogFragment.WaitingDialogData("加载中...", false))
                }

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

    override fun getRichType(): RichType = RichType.QUESTION

    companion object {
        const val QUESTION_TAG_MAX_COUNT = 5
        const val QUESTION_TITLE_MAX_LENGTH = 50

        const val QUESTION_DRAFT_KEY = "questionDraftKey"
        const val QUESTION_FORM_SEARCH = "fromSearch"
    }

}