package com.develop.food.base.ui

import android.content.Context
import android.content.pm.ActivityInfo
import android.os.*
import android.provider.Settings
import android.view.*
import android.view.inputmethod.InputMethodManager
import android.widget.EditText
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.viewbinding.ViewBinding
import com.blankj.utilcode.util.LanguageUtils
import com.develop.base.R
import com.develop.food.base.router.Screens
import com.develop.food.base.router.navigateTo
import com.develop.food.base.utils.FragmentKit
import com.develop.food.base.utils.TimeDownUtil
import com.develop.food.base.widgets.CancelConfirmDialog
import com.develop.food.base.widgets.CommonDialog
import com.kuyuntech.cofarcooking.device.sdk.constant.core.DevStatus
import com.kuyuntech.cofarcooking.device.sdk.eventbus.event.DevPromptEvent
import com.kuyuntech.cofarcooking.device.sdk.util.core.CofarSDK
import com.smarx.notchlib.NotchScreenManager
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe


abstract class BaseActivity<T : ViewBinding> : AppCompatActivity() {


    protected lateinit var binding: T
    private val plainDialogView by lazy {
        PlainDialogView(this, R.layout.dialog_easy_view)
    }

    val mainHandler by lazy {
        Handler(Looper.getMainLooper())
    }

    private val commonDialog by lazy {
        CommonDialog()
    }

    private val cancelConfirmDialog = CancelConfirmDialog()

    private val viewModelProviderOfActivity: ViewModelProvider by lazy {
        ViewModelProvider(this)
    }

    fun <T : ViewModel> getViewModel(type: Class<T>): T {
        return viewModelProviderOfActivity.get(type)
    }

    private var timeDownUtil: TimeDownUtil? = null

    abstract fun createViewBinding(inflater: LayoutInflater): T

    protected var hasShowScreenSaver = false

    private var screenSaverTime = 3 //minute
    override fun onCreate(savedInstanceState: Bundle?) {
        EventBus.getDefault().register(this)
        super.onCreate(savedInstanceState)
        // 支持显示到刘海区域
        requestWindowFeature(Window.FEATURE_NO_TITLE)
        window.setFlags(
            WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS,
            WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
        );
        supportActionBar?.hide()
        NotchScreenManager.getInstance().setDisplayInNotch(this)
        binding = createViewBinding(layoutInflater)
        setContentView(binding.root)

        val time =  (Settings.System.getInt(contentResolver, Settings.System.SCREEN_OFF_TIMEOUT) / 1000 / 60)
        if (time != 0) {
            screenSaverTime = time
        }
        cancelConfirmDialog.apply {
            onDialogClickListener = object : CancelConfirmDialog.OnDialogClickListener {
                override fun onConfirm() {
                    navigateTo(Screens.Setting.SCREEN_SAVER)
                }

                override fun onCancel() {
                    if (!hasShowScreenSaver) startCount()
                }

            }
        }



    }

    override fun attachBaseContext(newBase: Context) {
        super.attachBaseContext(LanguageUtils.attachBaseContext(newBase))
    }

    override fun onResume() {
        super.onResume()
        requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;//设置屏幕为竖屏, 设置后会锁定方向
        if (!hasShowScreenSaver) {
            startCount()
        } else {
            timeDownUtil?.cancel()
            timeDownUtil = null
        }
    }

    override fun onPause() {
        super.onPause()
        timeDownUtil?.cancel()
        timeDownUtil = null
    }

    override fun onWindowFocusChanged(hasFocus: Boolean) {
        super.onWindowFocusChanged(hasFocus)
        setFullscreen()
    }

    private fun setFullscreen() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
            window.attributes.layoutInDisplayCutoutMode =
                WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES
        }

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
            window.setDecorFitsSystemWindows(false)
            window.insetsController?.apply {
                hide(WindowInsets.Type.statusBars() or WindowInsets.Type.navigationBars())
                systemBarsBehavior = WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
            }
        } else {
            window.decorView.systemUiVisibility = (View.SYSTEM_UI_FLAG_FULLSCREEN
                    or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
                    or View.SYSTEM_UI_FLAG_IMMERSIVE
                    or View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                    or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                    or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION)
        }

    }


    fun addFragment(layoutId: Int, fragment: Fragment) {
        FragmentKit.addFragment(this, fragment::class.java, layoutId)
    }

    fun replaceFragment(layoutId: Int, fragment: Fragment) {
        FragmentKit.replaceFragment(this, fragment::class.java, layoutId)
    }

    fun replaceFragment(layoutId: Int, fragment: Fragment, bundle: Bundle) {
        FragmentKit.replaceFragment(this, fragment::class.java, layoutId, bundle, false)
    }

    fun replaceFragmentInstance(layoutId: Int, fragment: Fragment) {
        supportFragmentManager
            .beginTransaction()
            .replace(layoutId, fragment)
            .commitAllowingStateLoss()
    }

    fun showDialog(cancelable: Boolean = false) {
        plainDialogView.showDialog(cancelable)
    }

    fun dismissDialog() {
        plainDialogView.hideDialog()
    }

    override fun dispatchTouchEvent(ev: MotionEvent): Boolean {
        when (ev.action) {
            MotionEvent.ACTION_UP -> if (!hasShowScreenSaver) startCount()
            else -> cancelCount()
        }
        if (ev.action == MotionEvent.ACTION_DOWN) {
            //全局点击外面关闭软键盘
            // 获得当前得到焦点的View，一般情况下就是EditText（特殊情况就是轨迹求或者实体案件会移动焦点）
            val v = currentFocus
            if (isShouldHideInput(v, ev)) {
                hideSoftInput(v?.windowToken)
            }
        }
        return super.dispatchTouchEvent(ev)

    }

    private fun startCount() {

        if (CofarSDK.devInfo().status != DevStatus.STOP.toInt()) {
            return
        }
        cancelCount()
        val totalTime = screenSaverTime * 60 * 1000L
        timeDownUtil = object : TimeDownUtil(totalTime, 1000) {
            override fun onTick(millisUntilFinished: Long) {
                if (millisUntilFinished == 30 * 1000L) {
                    runOnUiThread {
                        showScreenSaverDialog()
                    }
                }
            }

            override fun onFinish() {
                runOnUiThread {
                    cancelConfirmDialog.removeSelf()
                    navigateTo(Screens.Setting.SCREEN_SAVER)
                }
            }
        }
        timeDownUtil?.start()
    }

    private fun showScreenSaverDialog() {
        //隐藏提示
//        cancelConfirmDialog.showDialog(supportFragmentManager, "cancelConfirmDialog")
//        cancelConfirmDialog.title = getString(R.string.screen_saver_title)
    }

    fun showCommonDialog(msg: String) {
        commonDialog.msg = msg
        commonDialog.showDialog(supportFragmentManager, "common")
    }

    fun hideCommonDialog() {
        commonDialog.removeSelf()
    }

    override fun onDestroy() {
        EventBus.getDefault().unregister(this)
        super.onDestroy()
        hideCommonDialog()
        cancelConfirmDialog.removeSelf()

    }

    private fun cancelCount() {
        timeDownUtil?.cancel()
        timeDownUtil = null
    }

    /**
     * 隐藏软键盘
     */
    private fun hideSoftInput(token: IBinder?) {
        if (token != null) {
            val manager: InputMethodManager =
                getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
            manager.hideSoftInputFromWindow(token, InputMethodManager.HIDE_NOT_ALWAYS)
        }
    }

    /**
     * 根据EditText所在坐标和用户点击的坐标相对比，来判断是否隐藏键盘，因为当用户点击EditText时没必要隐藏
     *
     * @param v
     * @param event
     * @return
     */
    private fun isShouldHideInput(v: View?, event: MotionEvent): Boolean {
        if (v != null && v is EditText) {
            val l = intArrayOf(0, 0)
            v.getLocationInWindow(l)
            val left = l[0]
            val top = l[1]
            val bottom = top + v.height
            val right = (left
                    + v.width)
            return !(event.x > left && event.x < right && event.y > top && event.y < bottom)
        }
        // 如果焦点不是EditText则忽略，这个发生在视图刚绘制完，第一个焦点不在EditView上，和用户用轨迹球选择其他的焦点
        return false
    }

    var confirmCancelDialog = CancelConfirmDialog()
    @Subscribe
    fun onCookDevMsgEvent(event: DevPromptEvent) {

        //            //已显示弹窗不重复显示
//            if(FloatWindowManager.confirmCancelDialog.isAdded){
//                return
//            }



        confirmCancelDialog.showCancel = event.isShowCancelBtn
        confirmCancelDialog.showConfirm = event.isShowConfirmBtn

        confirmCancelDialog.cancelStr = resources.getString(
            resources.getIdentifier(
                event.cancelBtnText,
                "string",
                this.packageName
            )
        )
        confirmCancelDialog.confirmStr = resources.getString(
            resources.getIdentifier(
                event.confirmButtonText,
                "string",
                this.packageName
            )
        )
        confirmCancelDialog.title =
            resources.getString(resources.getIdentifier(event.msg, "string", this.packageName))

        confirmCancelDialog.showDialog(supportFragmentManager, "confirmCancelDialog")

        confirmCancelDialog.onDialogClickListener =
            object : CancelConfirmDialog.OnDialogClickListener {
                override fun onConfirm() {
                    if (event.confirm != null) {
                        event.confirm.callback();
                    }
                    cancelConfirmDialog.removeSelf();
                }

                override fun onCancel() {
                    if (event.confirm != null) {
                        event.confirm.callback();
                    }
                    cancelConfirmDialog.removeSelf();
                }

            }

    }




}