package com.gh.common.util

import android.annotation.SuppressLint
import android.app.Activity
import android.app.Application
import android.os.Build
import android.os.Bundle
import android.view.Gravity
import android.view.View
import android.widget.ImageView
import android.widget.ProgressBar
import com.gh.gamecenter.common.base.activity.ToolBarActivity
import com.gh.gamecenter.R
import com.gh.gamecenter.common.retrofit.BiResponse
import com.gh.gamecenter.common.utils.singleToMain
import com.gh.gamecenter.common.utils.tryWithDefaultCatch
import com.gh.gamecenter.core.GHThreadFactory
import com.gh.gamecenter.core.runOnUiThread
import com.gh.gamecenter.core.utils.CurrentActivityHolder
import com.gh.gamecenter.gamecollection.detail.GameCollectionDetailActivity
import com.gh.gamecenter.gamecollection.square.GameCollectionSquareActivity
import com.gh.gamecenter.retrofit.RetrofitManager
import com.halo.assistant.HaloApp
import com.lzf.easyfloat.EasyFloat
import com.lzf.easyfloat.enums.ShowPattern
import com.lzf.easyfloat.enums.SidePattern
import okhttp3.ResponseBody
import java.util.concurrent.ExecutorService
import java.util.concurrent.Executors

/**
 * 浏览游戏单广场任务辅助类
 */
@SuppressLint("StaticFieldLeak")
object GameCollectionSquareBrowseTaskHelper {

    const val KEY_IS_FORM_BROWSE_TASK = "is_from_browse_task"
    private const val FLOATING_SQUARE_BROWSE_TASK_VIEW = "floating_square_browse_task_view"

    private var mBrowseTimeCount = 0
    private var mIsBrowseTimeCountEnabled = false // 游戏单广场浏览时间统计是否开启
    private var mBrowseTimeTimeout = 15
    private var mIsBrowseTimeCountValid = false // 游戏单广场浏览时间统计是否有效
    private var mBrowsePro: ProgressBar? = null
    private var mIsFinished = false
    private var mNeedShowFloatView = false
    private var mIsFirstEnterSquare = true

    private val mThreadService: ExecutorService by lazy {
        Executors.newSingleThreadExecutor(GHThreadFactory("BROWSE_SQUARE_THREAD"))
    }

    private val mActivityLifecycleCallbacks by lazy {
        object : Application.ActivityLifecycleCallbacks {
            override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {}
            override fun onActivityStopped(activity: Activity) {}
            override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) {}
            override fun onActivityStarted(activity: Activity) {}

            override fun onActivityResumed(activity: Activity) {
                if (isTopActivityGameCollectionRelated(activity) && mIsBrowseTimeCountEnabled) {
                    resumeTimeCount()
                } else if (isGameCollectionSquare(activity) && mNeedShowFloatView) {
                    showOrUpdateFloatView(activity, mBrowseTimeTimeout)
                }
            }

            override fun onActivityPaused(activity: Activity) {
                if (isTopActivityGameCollectionRelated(activity) && mIsBrowseTimeCountEnabled) {
                    pauseTimeCount()
                }
                if (isGameCollectionSquare(activity)) {
                    dismissFloatView()
                }
            }

            override fun onActivityDestroyed(activity: Activity) {
                if (isGameCollectionSquare(activity) && mIsBrowseTimeCountEnabled) {
                    disableBrowseTimeCount()
                    unregisterActivityLifecycleCallbacks()
                }
            }
        }
    }

    fun enableBrowseTimeCount(timeout: Int, isFinished: Boolean) {
        mIsBrowseTimeCountEnabled = true
        mBrowseTimeTimeout = timeout
        mIsFinished = isFinished
        mNeedShowFloatView = true
        mIsFirstEnterSquare = true

        resumeTimeCount()

        HaloApp.getInstance().registerActivityLifecycleCallbacks(mActivityLifecycleCallbacks)
    }

    fun disableBrowseTimeCount() {
        mBrowseTimeCount = 0
        mIsBrowseTimeCountEnabled = false
        mBrowsePro = null
        mIsFinished = false
        mIsFirstEnterSquare = true
    }

    fun unregisterActivityLifecycleCallbacks() {
        mNeedShowFloatView = false
        HaloApp.getInstance().unregisterActivityLifecycleCallbacks(mActivityLifecycleCallbacks)
    }

    private fun resumeTimeCount() {
        if (!mIsBrowseTimeCountEnabled) return

        mIsBrowseTimeCountValid = true

        mThreadService.execute {
            while (mIsBrowseTimeCountEnabled && mIsBrowseTimeCountValid) {
                val topActivity = CurrentActivityHolder.getCurrentActivity() ?: continue
                checkFirstEnterSquare(topActivity)
                runBrowseTask(topActivity)
                Thread.sleep(1000)
            }
        }
    }

    private fun checkFirstEnterSquare(topActivity: Activity) {
        if (isGameCollectionSquare(topActivity, false) && mIsFirstEnterSquare) {
            mIsFirstEnterSquare = false
            topActivity.intent.putExtra(KEY_IS_FORM_BROWSE_TASK, true)
        }
    }

    private fun runBrowseTask(topActivity: Activity) {
        if (isTopActivityGameCollectionRelated(topActivity)) {
            tryWithDefaultCatch {
                showOrUpdateFloatView(topActivity, if (mIsFinished) mBrowseTimeTimeout else mBrowseTimeCount)
                if (mIsFinished) {
                    disableBrowseTimeCount()
                } else {
                    countBrowseTimeout(topActivity)
                }
            }
        }
    }

    private fun countBrowseTimeout(topActivity: Activity) {
        mBrowseTimeCount++
        if (mBrowseTimeCount >= mBrowseTimeTimeout) {
            showOrUpdateFloatView(topActivity, mBrowseTimeTimeout)
            postBrowseFinish()
        }
    }

    private fun pauseTimeCount() {
        if (!mIsBrowseTimeCountEnabled) return

        mIsBrowseTimeCountValid = false
    }

    // 从任务跳转的游戏单广场/此游戏单广场进入的游戏单详情都计时
    private fun isTopActivityGameCollectionRelated(activity: Activity): Boolean {
        return isGameCollectionSquare(activity)
                || (activity is GameCollectionDetailActivity
                && activity.intent.getBundleExtra(ToolBarActivity.NORMAL_FRAGMENT_BUNDLE)
            ?.getBoolean(KEY_IS_FORM_BROWSE_TASK) == true)
    }

    private fun isGameCollectionSquare(activity: Activity, checkIsFromTask: Boolean = true): Boolean {
        return activity is GameCollectionSquareActivity
                && (!checkIsFromTask || activity.intent.getBooleanExtra(KEY_IS_FORM_BROWSE_TASK, false))
    }

    private fun showOrUpdateFloatView(activity: Activity, time: Int) {
        // 不支持 Android 4.1 的设备
        if (Build.VERSION.SDK_INT == Build.VERSION_CODES.JELLY_BEAN) return

        // 游戏单广场才显示FloatView
        if (!isGameCollectionSquare(activity)) return

        runOnUiThread {
            val isFinished = time == mBrowseTimeTimeout
            val floatView = EasyFloat.getFloatView(FLOATING_SQUARE_BROWSE_TASK_VIEW)
            if (floatView != null) {
                updateFloatView(floatView, isFinished, time)
            } else {
                showFloatView(activity, isFinished)
            }
        }
    }

    private fun showFloatView(activity: Activity, isFinished: Boolean) {
        EasyFloat.with(activity)
            .setLayout(R.layout.layout_square_browse_task_float)
            .setTag(FLOATING_SQUARE_BROWSE_TASK_VIEW)
            .setAnimator(null)
            .setGravity(Gravity.END.or(Gravity.CENTER_VERTICAL), 0, 0)
            .setSidePattern(SidePattern.RIGHT)
            .setShowPattern(ShowPattern.CURRENT_ACTIVITY)
            .setDragEnable(false)
            .registerCallback {
                createResult { _, _, view ->
                    initFloatView(view, isFinished)
                }
            }
            .show()
    }

    private fun initFloatView(view: View?, isFinished: Boolean) {
        if (isFinished) {
            view?.findViewById<ProgressBar>(R.id.browsePro)?.run {
                max = mBrowseTimeTimeout
                progress = mBrowseTimeTimeout
            }
            view?.findViewById<ImageView>(R.id.browsePic)
                ?.setImageResource(R.drawable.pic_browse_square_finish)
        } else {
            view?.findViewById<ProgressBar>(R.id.browsePro)?.run {
                mBrowsePro = this
                max = mBrowseTimeTimeout
                progress = 0
            }
            view?.findViewById<ImageView>(R.id.browsePic)
                ?.setImageResource(R.drawable.pic_browse_square)
        }
    }

    private fun updateFloatView(floatView: View, isFinished: Boolean, time: Int) {
        if (mBrowsePro == null) {
            mBrowsePro = floatView.findViewById(R.id.browsePro)
        }
        mBrowsePro?.progress = time
        if (isFinished) {
            floatView.findViewById<ImageView>(R.id.browsePic)
                .setImageResource(R.drawable.pic_browse_square_finish)
        }
    }

    private fun dismissFloatView() {
        EasyFloat.dismiss(FLOATING_SQUARE_BROWSE_TASK_VIEW)
    }

    @SuppressLint("CheckResult")
    private fun postBrowseFinish() {
        RetrofitManager.getInstance()
            .newApi
            .postGameCollectionTask("browse_game_list_square", "0")
            .compose(singleToMain())
            .subscribe(object : BiResponse<ResponseBody>() {
                override fun onSuccess(data: ResponseBody) {
                    disableBrowseTimeCount()
                }
            })
    }
}