package com.gh.gamecenter.wrapper

import android.annotation.SuppressLint
import android.app.Application
import androidx.lifecycle.*
import com.gh.common.util.CheckLoginUtils
import com.gh.common.util.NewFlatLogUtils
import com.gh.common.util.RealNameHelper
import com.gh.gamecenter.common.retrofit.Response
import com.gh.gamecenter.common.utils.SensorsBridge
import com.gh.gamecenter.common.utils.singleToMain
import com.gh.gamecenter.common.utils.toRequestBody
import com.gh.gamecenter.entity.BottomTab
import com.gh.gamecenter.entity.DiverterEntity
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.livedata.Event
import com.gh.gamecenter.login.user.UserManager
import com.gh.gamecenter.retrofit.RetrofitManager
import com.lightgame.utils.Utils
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.transformWhile
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 MainWrapperViewModel(application: Application, private val mRepository: MainWrapperRepository) :
    AndroidViewModel(application) {
    private val mApi = RetrofitManager.getInstance().api
    private val mNewApi = RetrofitManager.getInstance().newApi

    val defaultBottomTabIndex
        get() = mRepository.defaultBottomTabIndex
    val bottomTabListLiveData = mRepository.bottomTabListLiveData
    val errorLiveData = mRepository.errorLiveData

    val accelerateNotificationPopup = MutableLiveData<List<GameEntity>?>()

    private var lastAccelerateNotificationPopupRequestedTime: Long = 0

    val tabSelectedLiveData = mRepository.tabSelectEventFlow
        .map { it as? MainSelectedEvent.SelectedTab }
        .transformWhile { originalEvent ->
            emit(Event(originalEvent))
            true
        }
        .asLiveData()

    val realNameInfoUpdateLiveData = RealNameHelper.realNameInfoUpdateLiveData

    val bottomDoubleTabAction = MutableLiveData<BottomTab>()

    private val byPassVisitBottomTabIdSet = hashSetOf<String>()

    /**
     * 请求各种弹窗的数据
     */
    fun requestAllDialogData() {
        requestAccelerateNotificationPopup()
    }

    fun requestAccelerateNotificationPopup() {
        if (CheckLoginUtils.isLogin()) {
            if (lastAccelerateNotificationPopupRequestedTime != 0L
                && System.currentTimeMillis() - lastAccelerateNotificationPopupRequestedTime < 15 * 1000L) {
                return // 15 秒内不重复请求
            }

            lastAccelerateNotificationPopupRequestedTime = System.currentTimeMillis()

            mApi.getAccelerateNotificationPopup(UserManager.getInstance().userId)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(object : Response<List<GameEntity>>() {
                    override fun onResponse(response: List<GameEntity>?) {
                        super.onResponse(response)
                        accelerateNotificationPopup.postValue(response)
                    }

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

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

    fun handleBypassVisit(bottomTab: BottomTab) {
        if (byPassVisitBottomTabIdSet.contains(bottomTab.id)) return

        bottomTab.diverter?.let {
            val source = "底部tab：${bottomTab.name}"
            SensorsBridge.trackByPassBrowsing(
                source,
                it.diverterData.diverterName,
                it.diverterData.diverterId,
                it.diverterData.branchId,
                it.diverterData.branchName,
                it.diverterData.inprocessTime,
                it.diverterData.bypassVisitTime,
                it.diverterData.linkType,
                it.diverterData.linkId,
                it.diverterData.linkText,
                it.diverterData.bypassStatus,
            )
            NewFlatLogUtils.logByPassBrowsing(
                source,
                it.diverterData.diverterName,
                it.diverterData.diverterId,
                it.diverterData.branchId,
                it.diverterData.branchName,
                it.diverterData.inprocessTime,
                it.diverterData.bypassVisitTime,
                it.diverterData.linkType,
                it.diverterData.linkId,
                it.diverterData.linkText,
                it.diverterData.bypassStatus,
            )
            patchBypassVisitTime(it)
            byPassVisitBottomTabIdSet.add(bottomTab.id)
        }
    }

    @SuppressLint("CheckResult")
    private fun patchBypassVisitTime(diverterEntity: DiverterEntity) {
        val data = mapOf(
            "module_id" to diverterEntity.moduleId,
            "diverter_id" to diverterEntity.diverterData.diverterId
        )
        mNewApi.patchDiverterVisitTime(MainWrapperRepository.BYPASS_TYPE_BOTTOM_TAB, data.toRequestBody())
            .compose(singleToMain())
            .subscribe({
                Utils.log(TAG, "patchDiverterVisitTime onSuccess: ${it.string()}")
            }, {
                Utils.log(TAG, "patchDiverterVisitTime onError: ${it.message}")
            })
    }

    class Factory(
        private val mApplication: Application,
    ) : ViewModelProvider.NewInstanceFactory() {
        override fun <T : ViewModel> create(modelClass: Class<T>): T {
            return MainWrapperViewModel(mApplication, MainWrapperRepository.getInstance()) as T
        }
    }

    companion object {
        private const val TAG = "MainWrapperViewModel"
        const val SHOULD_SHOW_OPENING_DIALOG = "show_opening_dialog"
    }
}