package com.gh.gamecenter.wrapper

import android.annotation.SuppressLint
import androidx.annotation.WorkerThread
import androidx.lifecycle.MutableLiveData
import com.gh.common.util.HomeBottomBarHelper
import com.gh.common.util.NewFlatLogUtils
import com.gh.common.util.ViewPagerFragmentHelper
import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.entity.LaunchRedirect
import com.gh.gamecenter.common.retrofit.BiResponse
import com.gh.gamecenter.common.utils.SensorsBridge
import com.gh.gamecenter.core.utils.GsonUtils
import com.gh.gamecenter.core.utils.SPUtils
import com.gh.gamecenter.core.utils.SingletonHolder
import com.gh.gamecenter.core.utils.TimeUtils
import com.gh.gamecenter.entity.BottomTab
import com.gh.gamecenter.entity.DataUnionEntity
import com.gh.gamecenter.entity.DiverterEntity
import com.gh.gamecenter.entity.MultiTabNav
import com.gh.gamecenter.home.custom.model.CustomPageData
import com.gh.gamecenter.retrofit.RetrofitManager
import com.halo.assistant.HaloApp
import io.reactivex.Observable
import io.reactivex.disposables.Disposable
import io.reactivex.schedulers.Schedulers
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.SharedFlow
import kotlinx.coroutines.launch
import java.util.concurrent.TimeUnit
import java.util.concurrent.TimeoutException

class MainWrapperRepository {
    private val mNewApi = RetrofitManager.getInstance().newApi
    private var mMainDataIsLoaded = false // 首页数据是否已加载

    private var mHighPrioritySelectedBottomType = "" // 首页底部 tab 选中的类型 (优先级最高)

    private var mHighPrioritySelectedBottomTabId = "" // 首页底部 tab 选中的id (优先级比 default 高)
    private var mHighPrioritySelectedTopTabId = "" // 首页顶部 tab 选中的id (优先级比 default 高)
    private var mHighPrioritySelectedNavId = "" // 首页顶部 tab 所属的 navId

    val highPrioritySelectedNavId
        get() = mHighPrioritySelectedNavId
    val highPrioritySelectedTopTabId
        get() = mHighPrioritySelectedTopTabId

    var defaultNavId = ""
    var defaultCustomPageId = ""
    var defaultBottomTabIndex = 0

    val bottomTabListLiveData = MutableLiveData<List<BottomTab>>()
    val multiTabNavLiveData = MutableLiveData<MultiTabNav?>()
    val customPageLiveData = MutableLiveData<CustomPageData?>()
    val errorLiveData = MutableLiveData<Exception>()

    val diverterList = arrayListOf<DiverterEntity>()

    private val mTabSelectEventFlow = MutableSharedFlow<MainSelectedEvent>()
    val tabSelectEventFlow = mTabSelectEventFlow as SharedFlow<MainSelectedEvent>

    private var mDisposable: Disposable? = null
    private var mCheckGidCount = 0

    fun init() {
        // 若 timeout 后数据未加载完成，则即便还没有回调也使用默认数据生成底部 tab
        emitDefaultTabDataAfterTimeout()
        checkGidAndGetBypassList()
    }

    /**
     * 发送首次启动跳转事件的选中事件
     */
    fun sendSelectTabEvent(launchRedirect: LaunchRedirect) {
        if (!mMainDataIsLoaded) {
            mHighPrioritySelectedBottomTabId = launchRedirect.link ?: ""
            mHighPrioritySelectedTopTabId = launchRedirect.topTabLink?.link ?: ""
            mHighPrioritySelectedNavId = launchRedirect.navTabLink?.link ?: ""
        } else {
            CoroutineScope(SupervisorJob()).launch {
                val bottomTabIndex = bottomTabListLiveData.value?.indexOfFirst {
                    it.id == launchRedirect.link
                } ?: -1
                val topTabIndex = multiTabNavLiveData.value?.linkMultiTabNav?.indexOfFirst {
                    it.id == launchRedirect.topTabLink?.link
                } ?: -1
                mTabSelectEventFlow.emit(
                    MainSelectedEvent.SelectedTab(
                        bottomTabIndex = bottomTabIndex,
                        navTabId = launchRedirect.navTabLink?.link ?: "",
                        topTabIndex = topTabIndex,
                        topTabId = launchRedirect.topTabLink?.link ?: ""
                    )
                )
            }
        }
    }

    /**
     * 发送首页底部 tab 选中事件，选中找到的第一个 type (优先级最高)
     * @param bottomTabType 底部 tab 选中的类型
     */
    fun sendSelectTabEvent(bottomTabType: String) {
        if (!mMainDataIsLoaded) {
            mHighPrioritySelectedBottomType = bottomTabType
        } else {
            CoroutineScope(SupervisorJob()).launch {
                val bottomTabIndex = bottomTabListLiveData.value?.indexOfFirst {
                    it.link?.type == bottomTabType
                } ?: -1
                mTabSelectEventFlow.emit(
                    MainSelectedEvent.SelectedTab(
                        bottomTabIndex = bottomTabIndex,
                        navTabId = defaultNavId,
                        topTabIndex = -1,
                        topTabId = ""
                    )
                )
            }
        }
    }

    /**
     * 发送首页选中事件，重新选中默认的顶部和底部 tab
     */
    fun sendReSelectDefaultTabEvent() {
        CoroutineScope(SupervisorJob()).launch {
            mTabSelectEventFlow.emit(
                MainSelectedEvent.SelectedTab(
                    bottomTabIndex = defaultBottomTabIndex,
                    navTabId = defaultNavId,
                    topTabIndex = -1,
                    topTabId = ""
                )
            )
        }
    }

    /**
     * 发送首页选中事件
     * @param bottomTabIndex 底部 tab 选中的 index
     * @param topTabIndex 顶部 tab 选中的 index
     */
    fun sendSelectTabEvent(bottomTabIndex: Int, topTabIndex: Int) {
        CoroutineScope(SupervisorJob()).launch {
            mTabSelectEventFlow.emit(
                MainSelectedEvent.SelectedTab(
                    bottomTabIndex = bottomTabIndex,
                    topTabIndex = topTabIndex
                )
            )
        }
    }

    private fun checkGidAndGetBypassList() {
        if (HaloApp.getInstance().gid.isNullOrEmpty()) {
            stopCheckGid()
            mDisposable = Observable.interval(100, TimeUnit.MILLISECONDS)
                .subscribeOn(Schedulers.computation())
                .subscribe({
                    mCheckGidCount++
                    if (!HaloApp.getInstance().gid.isNullOrEmpty() || mCheckGidCount >= CHECK_GID_MAX_COUNT) {
                        stopCheckGid()
                        getBypassList()
                    }
                }, {
                    stopCheckGid()
                })
        } else {
            getBypassList()
        }
    }

    private fun stopCheckGid() {
        mDisposable?.dispose()
        mDisposable = null
        mCheckGidCount = 0
    }

    @SuppressLint("CheckResult")
    private fun getBypassList() {
        val isInstallFirstAccess = TimeUtils.isToday(SPUtils.getLong(Constants.SP_BRAND_NEW_FIRST_LAUNCH_TIME) / 1000).toString()
        mNewApi.getDiverterList(isInstallFirstAccess, BYPASS_TYPE_BOTTOM_TAB)
            .subscribeOn(Schedulers.computation())
            .timeout(BYPASS_TIME_OUT, TimeUnit.MILLISECONDS)
            .subscribe(object : BiResponse<List<DiverterEntity>>() {
                override fun onSuccess(data: List<DiverterEntity>) {
                    diverterList.clear()
                    diverterList.addAll(data)
                    getDataUnion()
                }

                override fun onFailure(exception: Exception) {
                    super.onFailure(exception)
                    getDataUnion()

                    val reasonString = if (exception is TimeoutException) "分流判断超时" else "分流页面返回为空"
                    SensorsBridge.trackFailByPass("底部tab", "", "", reasonString)
                    NewFlatLogUtils.logFailByPass("底部tab", "", "", reasonString)
                }
            })
    }

    @SuppressLint("CheckResult")
    @WorkerThread
    private fun getDataUnion() {
        var diverter = ""
        diverterList.forEach {
            diverter += "${it.moduleIndex}:${it.diverterData.branchId},"
        }
        mNewApi.getDataUnion(diverter)
            .subscribe(object : BiResponse<DataUnionEntity>() {
                override fun onSuccess(data: DataUnionEntity) {
                    processBottomTabData(data.bottomTab)
                    processMultiTabData(data.multiTabNav)
                    customPageLiveData.postValue(data.customPage)

                    mMainDataIsLoaded = true
                }

                override fun onFailure(exception: Exception) {
                    super.onFailure(exception)
                    processBottomTabData(emptyList())
                    errorLiveData.postValue(exception)
                }
            })
    }

    private fun processBottomTabData(bottomTabList: List<BottomTab>) {
        if (bottomTabList.isNotEmpty()) {
            diverterList.forEach {
                bottomTabList.getOrNull(it.moduleIndex)?.diverter = it
            }

            var preSelectedTab: BottomTab? = null

            // 如果有优先级最高的 tab type，则将优先级更高的选中 tab 设置为 default
            if (mHighPrioritySelectedBottomType.isNotEmpty()) {
                preSelectedTab = bottomTabList.firstOrNull {
                    it.link?.type == mHighPrioritySelectedBottomType
                }

                mHighPrioritySelectedBottomType = ""
            }

            // 如果有优先级高的选中 tab id，则将优先级更高的选中 tab 设置为 default
            if (preSelectedTab == null && mHighPrioritySelectedBottomTabId.isNotEmpty()) {
                preSelectedTab = bottomTabList.firstOrNull {
                    it.id == mHighPrioritySelectedBottomTabId
                }

                mHighPrioritySelectedBottomTabId = ""
            }

            // 将优先级高的选中 tab 设置为 default
            if (preSelectedTab != null) {
                bottomTabList.forEach { it.default = false }
                preSelectedTab.default = true
            }

            bottomTabList.forEachIndexed { index, bottomTab ->
                if (bottomTab.default) {
                    defaultBottomTabIndex = index
                }

                // 如果 jsCode 不是合法的 json，则将 jsCode 置空
                if (!GsonUtils.isJSONValid(bottomTab.jsCode)) {
                    bottomTab.jsCode = ""
                }

                if (bottomTab.link?.type == ViewPagerFragmentHelper.TYPE_VIDEO_STREAM) {
                    bottomTab.isTransparentStyle = true
                }
            }

            HomeBottomBarHelper.updateDefaultHomeBottomTabData(bottomTabList)
            bottomTabListLiveData.postValue(bottomTabList)
            defaultNavId = bottomTabList.find { it.link?.type == ViewPagerFragmentHelper.TYPE_MULTI_TAB_NAV && it.default }?.link?.link ?: ""
            defaultCustomPageId = bottomTabList.find { it.link?.type == ViewPagerFragmentHelper.TYPE_CUSTOM_PAGE && it.default }?.link?.link ?: ""
        } else {
            HomeBottomBarHelper.getDefaultHomeBottomTabData().run {
                val defaultIndex = indexOfFirst { it.default }
                if (defaultIndex != -1) {
                    defaultBottomTabIndex = defaultIndex
                }
                bottomTabListLiveData.postValue(this)
                defaultNavId = find { it.link?.type == ViewPagerFragmentHelper.TYPE_MULTI_TAB_NAV && it.default }?.link?.link ?: ""
                defaultCustomPageId = find { it.link?.type == ViewPagerFragmentHelper.TYPE_CUSTOM_PAGE && it.default }?.link?.link ?: ""
            }
        }
    }

    private fun processMultiTabData(multiTabNav: MultiTabNav?) {
        // 如果有优先级更高的选中 tab id，则将优先级更高的选中 tab 设置为 default
        if (mHighPrioritySelectedTopTabId.isNotEmpty() && mHighPrioritySelectedNavId == multiTabNav?.id) {
            val selectedTab = multiTabNav.linkMultiTabNav.firstOrNull {
                it.id == mHighPrioritySelectedTopTabId
            }

            // 将优先级更高的选中 tab 设置为 default
            if (selectedTab != null) {
                multiTabNav.linkMultiTabNav.forEach { it.default = false }
                selectedTab.default = true
            }

            mHighPrioritySelectedTopTabId = ""
        }

        defaultCustomPageId =
            multiTabNav?.linkMultiTabNav?.find { it.link?.type == ViewPagerFragmentHelper.TYPE_CUSTOM_PAGE && it.default }?.link?.link ?: ""
        multiTabNavLiveData.postValue(multiTabNav)
    }

    private fun emitDefaultTabDataAfterTimeout() {
        CoroutineScope(SupervisorJob()).launch {
            delay(3000)
            if (!mMainDataIsLoaded) {
                processBottomTabData(emptyList())
            }
        }
    }

    companion object : SingletonHolder<MainWrapperRepository>({ MainWrapperRepository() }) {
        private const val BYPASS_TIME_OUT = 1000L
        private const val CHECK_GID_MAX_COUNT = 5
        const val BYPASS_TYPE_BOTTOM_TAB = "bottom_tab"
    }
}

sealed class MainSelectedEvent {

    /**
     * 首页子页面选中
     * @param bottomTabIndex 首页底部 tab 选中的 index
     * @param navTabId 首页顶部 tab 的 id
     * @param topTabIndex 首页顶部 tab 选中的 index
     * @param topTabId 首页顶部 tab 的 id
     */
    data class SelectedTab(
        val bottomTabIndex: Int = -1,
        val navTabId: String = "",
        val topTabIndex: Int = -1,
        val topTabId: String = ""
    ) : MainSelectedEvent()

}