package com.gh.gamecenter.floatingwindow

import android.app.Activity
import android.content.Context
import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.RecyclerView
import com.therouter.router.Route
import com.therouter.TheRouter
import com.gh.gamecenter.common.base.fragment.BaseLazyFragment
import com.gh.gamecenter.common.constant.RouteConsts
import com.gh.gamecenter.common.retrofit.BiResponse
import com.gh.gamecenter.common.utils.singleToMain
import com.gh.gamecenter.core.HaloApp
import com.gh.gamecenter.core.provider.IAppProvider
import com.gh.gamecenter.core.provider.IFloatingWindowProvider
import com.gh.gamecenter.core.utils.SPUtils
import com.gh.gamecenter.feature.entity.FloatingWindowEntity
import com.gh.gamecenter.feature.entity.WelcomeDialogEntity
import com.gh.gamecenter.floatingwindow.retrofit.RetrofitManager
import com.lightgame.utils.Utils
import io.reactivex.disposables.Disposable
import java.util.*

@com.therouter.inject.ServiceProvider
class FloatingWindowProviderImpl : IFloatingWindowProvider {

    override fun getAndShowFloatingWindow(
        gameId: String,
        gameName: String,
        location: String,
        fragment: Fragment,
        recyclerView: RecyclerView,
        welcomeDialogCallback: ((welcomeDialogEntity: Any) -> Unit)?
    ): Disposable {
        return RetrofitManager.api
            .getFloatingWindow(gameId)
            .compose(singleToMain())
            .subscribe(object : BiResponse<ArrayList<FloatingWindowEntity>>() {
                override fun onSuccess(data: ArrayList<FloatingWindowEntity>) {
                    if (fragment is BaseLazyFragment) {
                        FloatingWindowManager.showFloatingWindowIfNeeded(
                            filterValidWindow(data),
                            gameId,
                            gameName,
                            location,
                            fragment,
                            recyclerView,
                            welcomeDialogCallback
                        )
                    }
                }
            })
    }

    override fun getFloatingWindowOnly(callback: (ArrayList<*>?, Throwable?) -> Unit): Disposable {
        return RetrofitManager.api
            .getFloatingWindow("")
            .compose(singleToMain())
            .subscribe(object : BiResponse<ArrayList<FloatingWindowEntity>>() {
                override fun onSuccess(data: ArrayList<FloatingWindowEntity>) {
                    callback.invoke(filterValidWindow(data), null)
                }

                override fun onFailure(exception: Exception) {
                    callback.invoke(null, exception)
                }
            })
    }

    override fun showFloatingWindowOnly(
        fragment: Fragment,
        recyclerView: RecyclerView,
        windowEntityList: ArrayList<*>,
        welcomeDialogCallback: ((entity: Any) -> Unit)?
    ) {
        FloatingWindowManager.showFloatingWindowIfNeeded(
            windowEntityList as ArrayList<FloatingWindowEntity>,
            "",
            "",
            "",
            fragment as BaseLazyFragment,
            recyclerView,
            welcomeDialogCallback
        )
    }

    override fun showHiddenWindow(activity: Activity) {
        FloatingWindowManager.showHiddenWindow(activity)
    }

    override fun hideWindow(activity: Activity) {
        FloatingWindowManager.hideWindow(activity)
    }

    private fun filterValidWindow(rawWindowList: ArrayList<FloatingWindowEntity>): ArrayList<FloatingWindowEntity> {
        val appProvider = TheRouter.get(IAppProvider::class.java)
        val isBrandNewInstall = appProvider?.getIsBrandNewInstall() ?: false
        val validWindowEntityList = arrayListOf<FloatingWindowEntity>()

        val sp = HaloApp.getInstance().getSharedPreferences("floating_window", Context.MODE_PRIVATE)
        val splitter = "<->"

        for (window in rawWindowList) {
            var isValid: Boolean

            // 如果是仅首次安装时只显示一次，把它转换为只显示一次的事件
            if (window.pushType == "first") {
                if (isBrandNewInstall) {
                    window.pushType = "1"
                } else {
                    window.pushType = "0"
                }
            }

            // 判断是否还需要显示
            if (window.pushType == "always") {
                isValid = true
                Utils.log(FloatingWindowManager.TAG, "${window.id} 常驻显示")
            } else {
                try {
                    // 使用 window 实体 id 作为 SP 的 key，dayOfYear + 已经显示的次数作为 value 来判断当前是否需要显示
                    val countLimit = window.pushType.toInt()
                    val dateAndCountString = SPUtils.getString(sp, window.id)

                    var currentCount = 0
                    val ignoreCountForThisLaunch =
                        FloatingWindowManager.ignoreCountIdSet.contains(window.id) // 当前启动忽略显示计数，即当前启动显示一次后后续都允许继续显示
                    val currentDayOfYear = Calendar.getInstance().get(Calendar.DAY_OF_YEAR).toString()

                    Utils.log(FloatingWindowManager.TAG, "${window.id} 存储的值为 $dateAndCountString")

                    if (dateAndCountString.isNotEmpty()) {
                        val dateAndCountArray = dateAndCountString.split(splitter)

                        currentCount = dateAndCountArray[1].toInt()

                        if (currentDayOfYear != dateAndCountArray.first()) {
                            isValid = true
                            currentCount = 0

                            Utils.log(FloatingWindowManager.TAG, "${window.id} 显示的日期与存储的日期不一致")
                        } else {
                            Utils.log(
                                FloatingWindowManager.TAG,
                                "${window.id} 历史显示的次数为 $currentCount， 上限为 $countLimit"
                            )

                            if (!ignoreCountForThisLaunch) {
                                currentCount = currentCount + 1
                            }
                            isValid = currentCount <= countLimit
                        }
                    } else {
                        currentCount++
                        isValid = true
                    }

                    if (isValid) {
                        val spValue = currentDayOfYear + splitter + currentCount

                        Utils.log(FloatingWindowManager.TAG, "${window.id} 更新显示数据 $spValue")

                        SPUtils.setString(sp, window.id, spValue)
                    }
                } catch (e: NumberFormatException) {
                    isValid = false
                }
            }

            if (isValid) {
                FloatingWindowManager.ignoreCountIdSet.add(window.id)
                validWindowEntityList.add(window)
            }
        }

        return validWindowEntityList
    }

    override fun logWindowClicked(
        action: String,
        windowId: String,
        source: String,
        gameId: String,
        gameName: String,
        linkId: String,
        linkType: String,
        linkText: String
    ) {
        LogUtils.logFloatingWindowClicked(
            action = action,
            windowId = windowId,
            source = source,
            gameId = gameId,
            gameName = gameName,
            linkId = linkId,
            linkType = linkType,
            linkText = linkText
        )
    }

}