package com.gh.gamecenter.qa.article.edit

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.R
import com.gh.gamecenter.common.base.fragment.WaitingDialogFragment
import com.gh.gamecenter.common.entity.CommunityEntity
import com.gh.gamecenter.common.eventbus.EBReuse
import com.gh.gamecenter.common.retrofit.Response
import com.gh.gamecenter.common.utils.SensorsBridge
import com.gh.gamecenter.core.utils.HtmlUtils
import com.gh.gamecenter.core.utils.ToastUtils
import com.gh.gamecenter.entity.ActivityLabelEntity
import com.gh.gamecenter.entity.ForumDetailEntity
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.login.user.UserManager
import com.gh.gamecenter.qa.entity.ArticleDetailEntity
import com.gh.gamecenter.feature.entity.ArticleDraftEntity
import com.gh.gamecenter.qa.questions.edit.QuestionEditViewModel
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

class ArticleEditViewModel(application: Application) : BaseRichEditorViewModel(application) {
    val postArticle = MediatorLiveData<String>()
    val postArticleDrafts = MediatorLiveData<Pair<ArticleEditActivity.SaveDraftType, Boolean>>()
    val articleDraftsContent = MediatorLiveData<String>()
    val error = MutableLiveData<String>()
    val notSelectForum = MutableLiveData<Boolean>()
    var mSelectCommunityData: CommunityEntity? = null
    val titleTags = MediatorLiveData<List<String>>()
    var defaultTags = MediatorLiveData<List<String>>()
    val selectedTags: MutableList<String> = ArrayList()
    var selectedTagsChange = MediatorLiveData<Boolean>()
    var detailEntity: ArticleDetailEntity? = null
    var detailEntityLiveData = MutableLiveData<ArticleDetailEntity?>()
    var draftEntity: ArticleDraftEntity? = null
    var title: String? = null
    var content: String? = null
    var openArticleInNewPage: Boolean = false
    var selectActivityLabelEntity: ActivityLabelEntity? = null
    var selectSection: ForumDetailEntity.Section? = null
    var gameEntity: GameEntity? = null

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

    /**
     * 检查标题是否符合规则
     * 根据问题标题获取相应标签(问题编辑无需获取)
     */
    fun checkDataAndLoadTitleTag(isKeyBoardShow: Boolean = false): Boolean {
        if (TextUtils.isEmpty(title)) {
            ToastUtils.showToast("标题不能为空", if (isKeyBoardShow) Gravity.CENTER else -1)
            return false
        }
        // 检查标题长度限制
        title?.trim()
        title = title?.replace("\n", "")
        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 (detailEntity != null && detailEntity?.title == title && detailEntity?.content == content) return false
        if (mSelectCommunityData == null) {
            ToastUtils.showToast("请选择论坛", if (isKeyBoardShow) Gravity.CENTER else -1)
            notSelectForum.postValue(true)
            return false
        }
        return true
    }

    fun checkData(): Boolean {
        if (mSelectCommunityData == null) return false
        if (TextUtils.isEmpty(title)) return false
        title = title?.replace("\n", "")
        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 (detailEntity != null && detailEntity?.title == title && detailEntity?.content == content) return false
        return true
    }

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

    fun postArticle(isOriginal: Boolean = false) {
        processDialog.postValue(WaitingDialogFragment.WaitingDialogData("提交中...", true))
        val articleBody = getArticleBody()
        articleBody.put("original", if (isOriginal) "yes" else "")
        if (draftEntity?.id != null) {
            articleBody.put("draft_id", draftEntity?.id)
        }
        val body = RequestBody.create(MediaType.parse("application/json"), articleBody.toString())
        val observable = if (detailEntity == null) {
            mApi.postCommunityArticle(mSelectCommunityData?.id, body)
        } else {
            mApi.patchCommunityArticle(mSelectCommunityData?.id, detailEntity?.id, body)
        }
        observable
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(object : Response<ResponseBody>() {
                override fun onResponse(response: ResponseBody?) {
                    if (detailEntity != null) {
                        detailEntity?.content = content!!
                        detailEntity?.title = title!!
                        detailEntity?.tags = selectedTags
                        detailEntity?.time?.edit = Utils.getTime(getApplication())
                    }
                    processDialog.postValue(WaitingDialogFragment.WaitingDialogData("上传中...", false))
//                        MtaHelper.onEvent("发表文章", "发布成功", CommunityManager.getInstance().community.name)
                    val data = response?.string()
                    postArticle.postValue(data)

                    EventBus.getDefault().post(EBReuse(ArticleEditActivity.ARTICLE_POSTED_TAG))
                    if (draftEntity?.id != null) {
                        EventBus.getDefault().post(EBReuse(ArticleEditActivity.ARTICLE_DRAFT_CHANGE_TAG))
                    }

                    SensorsBridge.trackEvent("ArticlePostResult", "post_result", "成功")
                }

                override fun onFailure(e: HttpException?) {
                    processDialog.postValue(WaitingDialogFragment.WaitingDialogData("上传中...", false))
                    var errorString: String? = null
                    try {
                        errorString = e?.response()?.errorBody()?.string()
                    } catch (e1: Exception) {
                        e1.printStackTrace()
                    }
                    error.postValue(errorString)
//                        MtaHelper.onEvent("发表文章", "发布失败", CommunityManager.getInstance().community.name)
                    SensorsBridge.trackEvent("ArticlePostResult", "post_result", "失败")
                }
            })
    }

    fun getArticleDetail(articleId: String) {
        mApi.getCommunityArticleDetail(articleId)
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(object : Response<ArticleDetailEntity>() {
                override fun onResponse(response: ArticleDetailEntity?) {
                    super.onResponse(response)
                    detailEntityLiveData.postValue(response)
                }

                override fun onFailure(e: HttpException?) {
                    super.onFailure(e)
                    detailEntityLiveData.postValue(null)
                }
            })
    }

    fun postArticleDrafts(saveType: ArticleEditActivity.SaveDraftType) {
        val articleBody = getArticleBody()
        if (mSelectCommunityData != null && mSelectCommunityData!!.id.isNotEmpty()) {
            articleBody.put("community_id", mSelectCommunityData!!.id)
        }
        val body = RequestBody.create(MediaType.parse("application/json"), articleBody.toString())
        val observable = if (draftEntity?.id != null) {
            mApi.patchCommunityArticleDrafts(UserManager.getInstance().userId, draftEntity?.id, body)
        } else {
            mApi.postCommunityArticleDrafts(UserManager.getInstance().userId, body)
        }
        observable
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(object : Response<ResponseBody>() {
                override fun onResponse(response: ResponseBody?) {
                    val string = response?.string()
                    if (!string.isNullOrEmpty() && draftEntity?.id == null) {
                        if (draftEntity == null) draftEntity = ArticleDraftEntity()
                        draftEntity?.id = JSONObject(string).getString("_id")
                    }

                    postArticleDrafts.postValue(Pair(saveType, true))
                }

                override fun onFailure(e: HttpException?) {
                    postArticleDrafts.postValue(Pair(saveType, false))
                }
            })
    }

    private fun getArticleBody(): JSONObject {
        val jsonObject = JSONObject()
        jsonObject.put("title", title)
        jsonObject.put("content", content)
        if (detailEntity != null) {
            jsonObject.put("article_id", detailEntity?.id)
        }
        if (selectActivityLabelEntity != null) {
            jsonObject.put("tag_activity_id", selectActivityLabelEntity?.id)
            jsonObject.put("tag_activity_name", selectActivityLabelEntity?.name)
        }
        if (type.isNotEmpty()) {
            jsonObject.put("type", type)
        }
        if (gameEntity != null) {
            jsonObject.put("game_id", gameEntity?.id)
        }
        if (selectSection != null) {
            jsonObject.put("section_id", selectSection?.id)
        }
        jsonObject.put("tags", JSONArray())
        return jsonObject
    }

    fun getArticleDraftsContent(draftId: String) {
        processDialog.postValue(WaitingDialogFragment.WaitingDialogData("加载中...", true))
        mApi.getArticleDraftsContent(UserManager.getInstance().userId, draftId)
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(object : Response<ResponseBody>() {
                override fun onResponse(response: ResponseBody?) {
                    val string = response?.string()
                    if (string != null) {
                        val jsonObject = JSONObject(string)
                        val content = jsonObject.getString("content")
                        articleDraftsContent.postValue(content)
                    }

                    processDialog.postValue(WaitingDialogFragment.WaitingDialogData("加载中...", false))
                }

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

    override fun getRichType(): RichType = RichType.ARTICLE
}
