package com.remax.visualnovel.app.base

import android.content.res.Resources
import android.os.Bundle
import android.view.MotionEvent
import android.view.View
import androidx.appcompat.app.AppCompatActivity
import androidx.viewbinding.ViewBinding
import com.remax.visualnovel.app.AbsView
import com.remax.visualnovel.app.widget.LoadingDialog
import com.remax.visualnovel.extension.fixedFontSize
import com.remax.visualnovel.extension.getBgColor
import com.remax.visualnovel.extension.isShouldHideKeyboard
import com.remax.visualnovel.extension.setStatusBarColor
import com.remax.visualnovel.extension.toast
import com.remax.visualnovel.extension.transitionFromAlpha
import com.remax.visualnovel.extension.transitionFromBottom
import com.remax.visualnovel.extension.withTransitionFromAlpha
import com.remax.visualnovel.extension.withTransitionFromBottom
import com.remax.visualnovel.utils.KeyboardUtils
import com.remax.visualnovel.utils.StatusBarUtils
import com.dylanc.loadingstateview.ActivityTransitionType
import com.dylanc.loadingstateview.BgColorType
import com.dylanc.loadingstateview.Decorative
import com.dylanc.loadingstateview.LoadingState
import com.dylanc.loadingstateview.LoadingStateDelegate
import com.dylanc.loadingstateview.OnReloadListener
import com.dylanc.viewbinding.base.ActivityBinding
import com.dylanc.viewbinding.base.ActivityBindingDelegate


/**
 * Activity基类
 */
abstract class BaseBindingActivity<out VB : ViewBinding> : AppCompatActivity(), AbsView,
    LoadingState by LoadingStateDelegate(), OnReloadListener, Decorative,
    ActivityBinding<VB> by ActivityBindingDelegate() {

    private val loadingDialog by lazy {
        createLoadingDialog()
    }

    private fun createLoadingDialog(): LoadingDialog {
        val dialog = LoadingDialog()
        dialog.build(this)
        return dialog
    }

    override fun getResources(): Resources {
        return super.getResources().fixedFontSize(this)
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentViewWithBinding()
        binding.root.decorate(this, this)
        StatusBarUtils.setStatusBarAndNavBarIsLight(this, false)
        setStatusBarColor(backgroundColorType())
        binding.root.setBackgroundColor(getBgColor(backgroundColorType()))
        when (transitionType()) {
            ActivityTransitionType.BOTTOM -> withTransitionFromBottom()
            ActivityTransitionType.ALPHA -> withTransitionFromAlpha()
            else -> {}
        }
        initView()
        initData()
        subscribeUi()
    }

    protected open fun backgroundColorType() = BgColorType.SPECIAL_MAP

    protected abstract fun initView()
    protected open fun subscribeUi() {}
    protected open fun initData() {}

    override fun onResume() {
        super.onResume()
    }

    override fun onPause() {
        super.onPause()
        if (KeyboardUtils.isSoftInputVisible(this)) {
            KeyboardUtils.hideSoftInput(this)
        }
    }

    override fun finish() {
        super.finish()
        when (transitionType()) {
            ActivityTransitionType.BOTTOM -> transitionFromBottom()
            ActivityTransitionType.ALPHA -> transitionFromAlpha()
            else -> {}
        }
    }

    protected open var touchEventFun: ((MotionEvent) -> Unit)? = null
    protected open fun touchHideKeyboardViewList(): List<View>? = null

    override fun dispatchTouchEvent(ev: MotionEvent?): Boolean {
        touchEventFun?.let {
            runCatching { ev?.run(it) }
        }
        if (touchHideKeyboardViewList() != null) {
            if (ev?.action == MotionEvent.ACTION_DOWN && KeyboardUtils.isSoftInputVisible(this) && touchHideKeyboardViewList()?.any {
                    it.isShouldHideKeyboard(
                        ev
                    )
                } == true) {
                KeyboardUtils.hideSoftInput(this)
            }
        }
        return super.dispatchTouchEvent(ev)
    }

    /**
     * 页面开关方向
     */
    protected open fun transitionType() = ActivityTransitionType.DEFAULT

    override fun showLoading() {
        if (!this.isDestroyed) {
            runOnUiThread {
                loadingDialog.show()
            }
        }
    }

    override fun hideLoading() {
        if (!this.isDestroyed) {
            runOnUiThread {
                loadingDialog.dismiss()
            }
        }
    }

    override fun showToast(text: String?) {
        toast(text)
    }

    override fun showToast(resId: Int) {
        toast(resId)
    }

}