package com.gh.gamecenter.qa.comment.conversation

import android.annotation.SuppressLint
import android.app.Application
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import com.gh.gamecenter.common.retrofit.BiResponse
import com.gh.gamecenter.feature.entity.CommentEntity
import com.gh.gamecenter.qa.article.detail.CommentItemData
import com.gh.gamecenter.qa.comment.base.BaseCommentViewModel
import io.reactivex.Observable
import io.reactivex.Single
import io.reactivex.schedulers.Schedulers
import retrofit2.HttpException

class CommentConversationViewModel(
    application: Application,
    articleId: String = "",
    videoId: String = "",
    questionId: String = "",
    communityId: String = "",
    gameCollectionId: String = "",
    var commentId: String = "",
    topCommentId: String = ""
) : BaseCommentViewModel(application, articleId, videoId, questionId, communityId, topCommentId) {
    var commentDetail: CommentEntity? = null
    var positionInOriginList = -1

    override fun provideDataObservable(page: Int): Observable<MutableList<CommentEntity>>? = null

    override fun provideDataSingle(page: Int): Single<MutableList<CommentEntity>>? {
        val map = hashMapOf<String, Any>()
        if (!isHandleTopComment && topCommentId.isNotEmpty()) {
            map["top_comment_id"] = topCommentId
        }
        return when {
            articleId.isNotEmpty() -> {
                mApi.getCommunityArticleCommentReply(
                    commentId,
                    currentSortType.value,
                    page,
                    map
                )
            }
            videoId.isNotEmpty() -> {
                mApi.getVideoCommentReply(videoId, commentId, currentSortType.value, page, map)
            }
            questionId.isNotEmpty() -> {
                mApi.getQuestionCommentReply(questionId, commentId, currentSortType.value, page, map)
            }
            gameCollectionId.isNotEmpty() -> {
                mApi.getGameCollectionCommentReply(gameCollectionId, commentId, page, map)
            }
            else -> null
        }
    }

    @SuppressLint("CheckResult")
    fun getComment() {
        val single = when {
            articleId.isNotEmpty() -> {
                mApi.getCommunityArticleComment(commentId)
            }
            videoId.isNotEmpty() -> {
                mApi.getCommunityVideoComment(commentId)
            }
            questionId.isNotEmpty() -> {
                mApi.getCommunityQuestionComment(questionId, commentId)
            }
            gameCollectionId.isNotEmpty() -> {
                mApi.getGameCollectionComment(gameCollectionId, commentId)
            }
            else -> null
        } ?: return
        single.subscribeOn(Schedulers.io())
            .subscribe(object : BiResponse<CommentEntity>() {
                @SuppressLint("CheckResult")
                override fun onSuccess(data: CommentEntity) {
                    commentDetail = data
                    commentDetail?.floor = positionInOriginList
                    commentCount = data.reply
                    topItemData = CommentItemData(commentTop = data)
                    loadResultLiveData.postValue(LoadResult.SUCCESS)
                    mergeListData(mListLiveData.value, hasFilter = topCommentId.isNotBlank())
                }

                override fun onFailure(exception: Exception) {
                    if (exception is HttpException && exception.code().toString().contains("404")) {
                        loadResultLiveData.postValue(LoadResult.DELETED)
                    } else {
                        loadResultLiveData.postValue(LoadResult.NETWORK_ERROR)
                    }
                }
            })
    }

    override fun mergeResultLiveData() {
        mResultLiveData.addSource(mListLiveData) { mergeListData(it, hasFilter = topCommentId.isNotBlank()) }
    }

    override fun onUpdateCommentTopSuccess() {
        commentDetail?.run {
            val cloneComment = clone()
            cloneComment.isTop = !cloneComment.isTop
            updateComment(cloneComment)
        }
    }

    override fun updateComment(cloneComment: CommentEntity) {
        mResultLiveData.value?.let {
            it.forEachIndexed { index, commentItemData ->
                commentItemData?.run {
                    when {
                        commentNormal?.id == cloneComment.id -> it[index] =
                            CommentItemData(commentNormal = cloneComment)
                        commentTop?.id == cloneComment.id -> {
                            commentDetail = cloneComment
                            it[index] = CommentItemData(commentTop = cloneComment)
                        }
                    }
                }
            }
            mResultLiveData.postValue(it)
        }
    }

    class Factory(
        private val application: Application,
        private val articleId: String = "",
        private val videoId: String = "",
        private val questionId: String = "",
        private val communityId: String = "",
        private val gameCollectionId: String = "",
        private val commentId: String,
        private val topCommentId: String
    ) : ViewModelProvider.NewInstanceFactory() {

        override fun <T : ViewModel> create(modelClass: Class<T>): T {
            return CommentConversationViewModel(
                application = application,
                articleId = articleId,
                videoId = videoId,
                questionId = questionId,
                communityId = communityId,
                gameCollectionId = gameCollectionId,
                commentId = commentId,
                topCommentId = topCommentId
            ) as T
        }
    }
}