package com.gh.gamecenter.message.view.message

import android.app.Application
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import com.gh.gamecenter.common.baselist.ListViewModel
import com.gh.gamecenter.common.baselist.LoadStatus
import com.gh.gamecenter.common.retrofit.Response
import com.gh.gamecenter.feature.entity.MessageEntity
import com.gh.gamecenter.login.user.UserManager
import com.gh.gamecenter.message.HaloApp
import com.gh.gamecenter.message.entity.MessageGameEntity
import com.gh.gamecenter.message.entity.MessageItemData
import com.gh.gamecenter.message.entity.MessageKeFuEntity
import com.gh.gamecenter.message.retrofit.RetrofitManager
import com.lightgame.utils.Utils
import io.reactivex.Observable
import io.reactivex.ObservableEmitter
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers
import okhttp3.MediaType
import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.RequestBody
import okhttp3.RequestBody.Companion.toRequestBody
import okhttp3.ResponseBody
import org.json.JSONObject
import retrofit2.HttpException

class MessageListViewModel(application: Application, private val mType: String, private val mGameId: String) :
    ListViewModel<MessageItemData, MessageItemData>(application) {
    private val mApi = RetrofitManager.getInstance().api
    private val mNewApi = RetrofitManager.getInstance().newApi

    override fun provideDataObservable(page: Int): Observable<MutableList<MessageItemData>> {
        return Observable.create {
            when (mType) {
                SortedMessageListAdapter.TYPE_SYSTEM,
                SortedMessageListAdapter.TYPE_SERVICE -> {
                    getPrivateMessageList(mType, page, it)
                }

                SortedMessageListAdapter.TYPE_USER -> {
                    getNormalMessageList(page, it)
                }

                SortedMessageListAdapter.TYPE_GAME -> {
                    getMessageGameList(page, it)
                }

                else -> {
                    it.onError(Throwable("未知类型"))
                }
            }
        }
    }

    private fun getNormalMessageList(page: Int, observableEmitter: ObservableEmitter<MutableList<MessageItemData>>) {
        mApi.getMessage(UserManager.getInstance().userId, "all", Utils.getTime(getApplication()), page)
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(object : Response<List<MessageEntity>>() {
                override fun onResponse(response: List<MessageEntity>?) {
                    super.onResponse(response)
                    val messageItemDataList = arrayListOf<MessageItemData>()
                    response?.forEach {
                        messageItemDataList.add(MessageItemData(normalMessage = it))
                    }
                    observableEmitter.onNext(messageItemDataList)
                    observableEmitter.onComplete()
                }

                override fun onFailure(e: HttpException?) {
                    super.onFailure(e)
                    observableEmitter.onError(Throwable("网络异常"))
                }
            })
    }

    private fun getPrivateMessageList(
        type: String,
        page: Int,
        observableEmitter: ObservableEmitter<MutableList<MessageItemData>>
    ) {
        mApi.getMessageKeFuData(UserManager.getInstance().userId, page, mapOf("filter" to "type:$type"))
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(object : Response<List<MessageKeFuEntity>>() {
                override fun onResponse(response: List<MessageKeFuEntity>?) {
                    val messageItemDataList = arrayListOf<MessageItemData>()
                    response?.forEach {
                        messageItemDataList.add(MessageItemData(privateMessage = it))
                    }
                    observableEmitter.onNext(messageItemDataList)
                    observableEmitter.onComplete()
                }

                override fun onFailure(e: HttpException?) {
                    super.onFailure(e)
                    observableEmitter.onError(Throwable("网络异常"))
                }
            })
    }

    private fun getMessageGameList(page: Int, observableEmitter: ObservableEmitter<MutableList<MessageItemData>>) {
        mNewApi.getMessageGameList(mapOf("filter" to "game_id:$mGameId"), page)
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(object : Response<List<MessageGameEntity>>() {
                override fun onResponse(response: List<MessageGameEntity>?) {
                    val messageItemDataList = arrayListOf<MessageItemData>()
                    response?.forEach {
                        messageItemDataList.add(MessageItemData(gameMessage = it))
                    }
                    observableEmitter.onNext(messageItemDataList)
                    observableEmitter.onComplete()
                }

                override fun onFailure(e: HttpException?) {
                    super.onFailure(e)
                    observableEmitter.onError(Throwable("网络异常"))
                }
            })
    }

    override fun mergeResultLiveData() {
        mResultLiveData.addSource(mListLiveData) {
            mResultLiveData.postValue(it)
        }
    }

    fun postMessageRead(messageId: String) {
        // 更新本地数据以及页面
        val listData = mListLiveData.value
        if (listData != null) {
            for (entity in listData) {
                if (messageId == entity.privateMessage?.id) {
                    entity.privateMessage?.isRead = true
                    mListLiveData.postValue(listData)
                    break
                }
            }
        }

        // 后端同步
        val jsonObject = JSONObject()
        jsonObject.put("type", "system_message")
        val body = jsonObject.toString().toRequestBody("application/json".toMediaTypeOrNull())
        mApi.postMessageRead(UserManager.getInstance().userId, messageId, body)
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(object : Response<ResponseBody>() {
            })
    }

    fun deleteMessage(messageId: String) {
        val deleteObservable = when (mType) {
            SortedMessageListAdapter.TYPE_SYSTEM,
            SortedMessageListAdapter.TYPE_SERVICE -> {
                mApi.deletePrivateMessage(UserManager.getInstance().userId, messageId)
            }

            SortedMessageListAdapter.TYPE_USER -> {
                mApi.deleteMessage(UserManager.getInstance().userId, messageId)
            }

            SortedMessageListAdapter.TYPE_GAME,
            SortedMessageListAdapter.TYPE_BBS -> {
                mNewApi.deleteContentMessage(messageId)
            }
            else -> null
        }
        deleteObservable?.subscribeOn(Schedulers.io())
            ?.observeOn(AndroidSchedulers.mainThread())
            ?.subscribe(object : Response<ResponseBody>() {
                override fun onResponse(response: ResponseBody?) {
                    val listData = mListLiveData.value
                    listData?.let {
                        val iterator = it.iterator()
                        while (iterator.hasNext()) {
                            val data = iterator.next()
                            val id = when (mType) {
                                SortedMessageListAdapter.TYPE_SYSTEM,
                                SortedMessageListAdapter.TYPE_SERVICE -> data.privateMessage?.id
                                SortedMessageListAdapter.TYPE_USER -> data.normalMessage?.id
                                SortedMessageListAdapter.TYPE_GAME -> data.gameMessage?.id
                                else -> ""
                            }
                            if (messageId == id) {
                                it.remove(data)
                                mListLiveData.postValue(listData)
                                if (listData.isEmpty()) {
                                    mLoadStatusLiveData.postValue(LoadStatus.INIT_EMPTY)
                                }
                                break
                            }
                        }
                    }
                }

                override fun onFailure(e: HttpException?) {
                    super.onFailure(e)
                    Utils.toast(getApplication(), "删除失败")
                }
            })
    }

    class Factory(private val mType: String, private val mGameId: String = "") :
        ViewModelProvider.NewInstanceFactory() {
        override fun <T : ViewModel> create(modelClass: Class<T>): T {
            return MessageListViewModel(HaloApp.getInstance(), mType, mGameId) as T
        }
    }
}