package com.base.appzxhy.base

import android.app.Activity
import android.app.Dialog
import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.view.LayoutInflater
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.lifecycleScope
import androidx.viewbinding.ViewBinding
import com.base.appzxhy.ui.main.MainActivity
import com.base.appzxhy.R
import com.base.appzxhy.bean.ConstObject.appLanguageCountrySp
import com.base.appzxhy.bean.ConstObject.appLanguageSp
import com.base.appzxhy.helper.EventUtils
import com.base.appzxhy.utils.ActivityLauncher
import com.base.appzxhy.utils.ActivityManagerUtils
import com.base.appzxhy.utils.LogEx
import com.gyf.immersionbar.ktx.immersionBar
import com.hjq.language.MultiLanguages
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import java.util.Locale
import java.util.concurrent.atomic.AtomicBoolean
import kotlin.random.Random

abstract class BaseActivity<VB : ViewBinding>(
    bindingInflater: (LayoutInflater) -> VB
) : AppCompatActivity() {

    open val TAG = javaClass.simpleName
    private val tagNo = Random.nextInt(500)
    val binding by lazy(LazyThreadSafetyMode.NONE) {
        bindingInflater(layoutInflater)
    }

    lateinit var launcher: ActivityLauncher
    private var currentLocale: Locale? = null

    var onCreateI = 0
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        configSystemBar()
        onCreateI++
        LogEx.logDebug(TAG, "lifecycle $tagNo onCreate ${javaClass.simpleName} $onCreateI")
        launcher = ActivityLauncher(this)
        setContentView(binding.root)
        EventUtils.event("page_${javaClass.simpleName}")
        currentLocale = Locale(appLanguageSp, appLanguageCountrySp)
        initView()
        initListener()
    }


    protected open fun initView() {}

    protected open fun initListener() {}


    fun finishToMain(delay: Long = 0) {
        val flag = this !is MainActivity && !ActivityManagerUtils.getInstance().isActivityInStack(MainActivity::class.java)
        if (flag) {
            startActivity(Intent(this, MainActivity::class.java).apply {
                putExtra("where", "finishToMain")
            })
        }
        lifecycleScope.launch(Dispatchers.Main) {
            delay(delay)
            finish()
        }
    }

    fun finishToMainTop() {
        val intent = Intent(this, MainActivity::class.java)
        intent.putExtra("where", "finishToMainTop")
        intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT)
        startActivity(intent)
    }

    var dialog: Dialog? = null
    override fun onDestroy() {
        super.onDestroy()
        ActivityManagerUtils.getInstance().removeActivity(this)
        if (dialog != null) {
            dialog?.dismiss()
            dialog = null
        }
    }

    override fun attachBaseContext(newBase: Context?) {
        super.attachBaseContext(MultiLanguages.attach(newBase))
    }


    fun changeLanguage(currentActivity: Activity, bundle: Bundle = Bundle()): Boolean {
        val spLanguage = Locale(appLanguageSp, appLanguageCountrySp)
        val flag = currentLocale != spLanguage
        val restart = MultiLanguages.setAppLanguage(this, spLanguage)
        LogEx.logDebug(
            TAG, "changeLanguage " +
                    "flag=$flag  restart=$restart currentLocale=$currentLocale spLanguage=$spLanguage"
        )
        if (restart) {
            currentLocale = Locale(appLanguageSp, appLanguageCountrySp)
        }

        if (flag || restart) {
            // 1.使用 recreate 来重启 Activity，效果差，有闪屏的缺陷
//             recreate();

            // 2.使用常规 startActivity 来重启 Activity，有从左向右的切换动画
            // 稍微比 recreate 的效果好一点，但是这种并不是最佳的效果
            // startActivity(new Intent(this, LanguageActivity.class));
            // finish();

            // 3.我们可以充分运用 Activity 跳转动画，在跳转的时候设置一个渐变的效果，相比前面的两种带来的体验是最佳的
            //需要设置启动模式，避免AndroidManifest.xml设置singleTop启动模式导致重复启动不生效
            //这种方式如果设置了singleTop或者singleTask的，再次回到该activity无法改变于语言，因为还在堆栈里没有重新创建
            needRecreate()
            if (needRecreate()) {
                LogEx.logDebug(TAG, "changeLanguage recreate")
                recreate()
            } else {
                startActivity(Intent(this, currentActivity::class.java).apply {
                    putExtras(bundle)
                })
                overridePendingTransition(R.anim.activity_alpha_in, R.anim.activity_alpha_out)
                finish()
            }
            return true
        }
        return false
    }

    /**
     * 判断是否需要重新创建对SingleTop启动模式的有效
     */
    fun needRecreate(): Boolean {
        return TAG.contains("MainActivity")
    }


    /**
     * 避免在onResume--onPause周期内,多次调用
     * 在onStop中重置标志
     */
    private val onResumeCalled = AtomicBoolean(false)
    private var onResumeOneShootI = 0
    open fun onResumeOneShoot() {
        onResumeOneShootI++
        LogEx.logDebug(TAG, "lifecycle $tagNo onResumeOneShoot ${javaClass.simpleName} $onResumeOneShootI")
    }

    private var onResumeI = 0
    override fun onResume() {
        super.onResume()
        onResumeI++
        LogEx.logDebug(TAG, "lifecycle $tagNo onResume ${javaClass.simpleName} $onResumeI")

        if (!onResumeCalled.get()) {
            onResumeCalled.set(true)
            onResumeOneShoot()
        }
    }

    private var onStartI = 0
    override fun onStart() {
        super.onStart()
        onStartI++
        LogEx.logDebug(TAG, "lifecycle $tagNo onStart ${javaClass.simpleName} $onStartI")
    }

    private var onStopI = 0
    override fun onStop() {
        super.onStop()
        onStopI++
        LogEx.logDebug(TAG, "lifecycle $tagNo onStop ${javaClass.simpleName} $onStopI")
        onResumeCalled.set(false)
    }

    private var onPauseI = 0
    override fun onPause() {
        super.onPause()
        onPauseI++
        LogEx.logDebug(TAG, "lifecycle $tagNo onPause ${javaClass.simpleName} $onPauseI")
    }

    open fun configSystemBar() {
        immersionBar {
            statusBarColor("#FFFFFFFF")
            navigationBarColor("#FFFFFFFF")
            statusBarDarkFont(true)
            navigationBarDarkIcon(true)
            fitsSystemWindows(true)
        }
    }
}