package com.gh.gamecenter.forum.detail

import android.annotation.SuppressLint
import android.app.Application
import androidx.lifecycle.*
import com.gh.gamecenter.common.entity.CommunityEntity
import com.gh.gamecenter.eventbus.EBForumRecordChange
import com.gh.gamecenter.common.mvvm.Resource
import com.gh.gamecenter.qa.entity.*
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.entity.*
import com.gh.gamecenter.feature.entity.AnswerEntity
import com.gh.gamecenter.feature.entity.ForumVideoEntity
import com.gh.gamecenter.feature.entity.UserEntity
import com.gh.gamecenter.retrofit.RetrofitManager
import com.gh.gamecenter.room.AppDatabase
import com.halo.assistant.HaloApp
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers
import okhttp3.ResponseBody
import org.greenrobot.eventbus.EventBus
import retrofit2.HttpException

class ForumDetailViewModel(application: Application, val bbsId: String) : AndroidViewModel(application) {

    private val mApi = RetrofitManager.getInstance().api
    private val mNewApi = RetrofitManager.getInstance().newApi
    private val mForumDao = AppDatabase.getInstance().forumDao()
    var forumDetail = MutableLiveData<Resource<ForumDetailEntity>>()
    val answerLiveData = MediatorLiveData<AnswerEntity>()
    val statusEntity = MutableLiveData<ApplyModeratorStatusEntity?>()
    val sectionListLiveData = MutableLiveData<List<ForumDetailEntity.Section>>()

    var selectedSection = ForumDetailEntity.Section("", "全部")

    init {
        postForumRead()
        getForumDetail()
        getModeratorsApplyStatus()
        getSections()
    }

    @SuppressLint("CheckResult")
    fun postForumRead() {
        mApi.postForumRead(bbsId)
            .compose(singleToMain())
            .subscribe(EmptyResponse())
    }

    fun getForumDetail() {
        mApi.getForumDetail(bbsId)
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(object : Response<ForumDetailEntity>() {
                override fun onResponse(response: ForumDetailEntity?) {
                    super.onResponse(response)
                    forumDetail.postValue(Resource.success(response))
                    response?.run {
                        mForumDao.addForum(convertForumDetailEntityToForumEntity())
                        EventBus.getDefault().post(EBForumRecordChange(convertForumDetailEntityToForumEntity()))
                    }
                }

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

    fun getModeratorsApplyStatus() {
        RetrofitManager.getInstance().api.getApplyModeratorStatus(bbsId)
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(object : Response<ApplyModeratorStatusEntity>() {
                override fun onResponse(response: ApplyModeratorStatusEntity?) {
                    super.onResponse(response)
                    statusEntity.postValue(response)
                }

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

    @SuppressLint("CheckResult")
    fun followForum(onSuccess: () -> Unit) {
        RetrofitManager.getInstance().api
            .followForum(bbsId)
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(object : BiResponse<ResponseBody>() {
                override fun onSuccess(data: ResponseBody) {
                    onSuccess.invoke()
                }
            })
    }

    @SuppressLint("CheckResult")
    fun unFollowForum(onSuccess: () -> Unit) {
        RetrofitManager.getInstance().api
            .unFollowForum(bbsId)
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(object : BiResponse<ResponseBody>() {
                override fun onSuccess(data: ResponseBody) {
                    onSuccess.invoke()
                }
            })
    }

    fun getArticleData(articleId: String) {
        mApi.getCommunityArticleDetail(articleId)
            .compose(observableToMain())
            .subscribe(object : Response<ArticleDetailEntity>() {
                override fun onResponse(response: ArticleDetailEntity?) {
                    response?.run {
                        answerLiveData.postValue(convertArticleDetailToAnswer(response))
                    }

                }
            })
    }

    fun getQuestionDetail(questionId: String) {
        mApi.getQuestionsById(questionId)
            .compose(observableToMain())
            .subscribe(object : Response<QuestionsDetailEntity>() {
                override fun onResponse(response: QuestionsDetailEntity?) {
                    response?.run {
                        answerLiveData.postValue(convertQuestionDetailToAnswer(response))
                    }
                }
            })
    }

    fun getVideoDetail(videoId: String) {
        mApi.getBbsVideoDetail(videoId)
            .compose(observableToMain())
            .subscribe(object : Response<ForumVideoEntity>() {
                override fun onResponse(response: ForumVideoEntity?) {
                    response?.run {
                        answerLiveData.postValue(convertVideoDetailToAnswer(response))
                    }
                }
            })
    }

    fun getSections() {
        mNewApi.getForumSections(bbsId)
            .compose(observableToMain())
            .subscribe(object : Response<List<ForumDetailEntity.Section>>() {
                override fun onResponse(response: List<ForumDetailEntity.Section>?) {
                    response?.run {
                        val sectionList = ArrayList(this)
                        sectionList.add(0, ForumDetailEntity.Section("", "全部"))
                        sectionListLiveData.postValue(sectionList)
                    }
                }
            })
    }

    fun convertArticleDetailToAnswer(articleDetailEntity: ArticleDetailEntity): AnswerEntity {
        val answerEntity = AnswerEntity()

        answerEntity.id = articleDetailEntity.id
        answerEntity.articleTitle = articleDetailEntity.title
        answerEntity.brief = articleDetailEntity.content.removeVideoContent().clearHtmlFormatCompletely()
        answerEntity.count = articleDetailEntity.count
        articleDetailEntity.community.id = articleDetailEntity.communityId
        answerEntity.bbs = articleDetailEntity.community
        answerEntity.time = articleDetailEntity.time.create
        answerEntity.user = articleDetailEntity.user
        answerEntity.images = articleDetailEntity.images
        answerEntity.imagesInfo = articleDetailEntity.imagesInfo
        answerEntity.videos = articleDetailEntity.videos
        answerEntity.status = articleDetailEntity.status ?: ""
        answerEntity.type = "community_article"
        answerEntity.sectionIdList = articleDetailEntity.sectionIdList

        return answerEntity
    }

    fun convertQuestionDetailToAnswer(questionDetailEntity: QuestionsDetailEntity): AnswerEntity {
        val answerEntity = AnswerEntity()

        answerEntity.id = questionDetailEntity.id ?: ""
        answerEntity.articleTitle = questionDetailEntity.title
        answerEntity.brief = questionDetailEntity.description?.removeVideoContent()?.clearHtmlFormatCompletely() ?: ""
        answerEntity.description =
            questionDetailEntity.description?.removeVideoContent()?.clearHtmlFormatCompletely() ?: ""
        answerEntity.count = questionDetailEntity.count
        answerEntity.bbs = questionDetailEntity.community
        answerEntity.time = questionDetailEntity.time.create
        answerEntity.user = questionDetailEntity.user
        answerEntity.images = questionDetailEntity.images
        answerEntity.imagesInfo = questionDetailEntity.imagesInfo
        answerEntity.videos = questionDetailEntity.videos
        answerEntity.status = questionDetailEntity.status
        answerEntity.type = "question"

        return answerEntity
    }

    fun convertVideoDetailToAnswer(forumVideoEntity: ForumVideoEntity): AnswerEntity {
        val answerEntity = AnswerEntity()

        answerEntity.id = forumVideoEntity.id
        answerEntity.articleTitle = forumVideoEntity.title
        answerEntity.des = forumVideoEntity.des
        answerEntity.url = forumVideoEntity.url
        answerEntity.status = forumVideoEntity.status
        answerEntity.poster = forumVideoEntity.poster
        answerEntity.length = forumVideoEntity.length
        answerEntity.videoInfo = forumVideoEntity.videoInfo
        answerEntity.count = forumVideoEntity.count
        answerEntity.bbs = forumVideoEntity.bbs ?: CommunityEntity()
        answerEntity.time = forumVideoEntity.time.upload
        forumVideoEntity.user.run {
            answerEntity.user = UserEntity(
                id = id,
                name = name,
                icon = icon,
                auth = auth,
                badge = badge,
                border = border
            )
        }
        answerEntity.type = "video"

        return answerEntity
    }

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