package cn.yyxx.eyuangame.core.impl.login

import android.app.Activity
import android.content.DialogInterface
import android.content.Intent
import android.os.*
import android.view.*
import android.view.inputmethod.InputMethodManager
import android.widget.EditText
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.content.ContextCompat
import androidx.core.view.ViewCompat
import androidx.fragment.app.FragmentActivity
import cn.yyxx.eyuangame.base.entity.SdkEvent
import cn.yyxx.eyuangame.base.utils.Logger
import cn.yyxx.eyuangame.core.entity.ClickType
import cn.yyxx.eyuangame.core.entity.LoginType
import cn.yyxx.eyuangame.core.entity.Session
import cn.yyxx.eyuangame.core.impl.SdkBridgeImpl
import cn.yyxx.eyuangame.core.impl.login.fragment.LauncherFragment
import cn.yyxx.eyuangame.core.internal.IImplCallback
import cn.yyxx.eyuangame.core.linking.Linking
import cn.yyxx.eyuangame.core.ui.NoScrollViewPager
import cn.yyxx.eyuangame.core.ui.dialog.AutoLoginDialog
import cn.yyxx.eyuangame.core.ui.dialog.ChooseLoginDialog
import cn.yyxx.eyuangame.core.utils.SessionUtils
import cn.yyxx.eyuangame.core.utils.TimeDownUtils
import cn.yyxx.support.AndroidBug5497Workaround
import cn.yyxx.support.DensityUtils
import cn.yyxx.support.ResUtils
import com.google.android.material.tabs.TabLayout

/**
 * @author #Suyghur.
 * Created on 2021/06/17
 */
class LoginActivity : FragmentActivity(), View.OnClickListener {

    lateinit var userSignInImpl: UserSignInImpl
        private set

    private lateinit var rootContainer: ConstraintLayout

    //    private lateinit var loginContainer: ViewStub
    private lateinit var loginContainer: ConstraintLayout
    private lateinit var tabLayout: TabLayout
    private lateinit var viewPager: NoScrollViewPager

    private var autoLoginDialog: AutoLoginDialog? = null
    private var chooseDialog: ChooseLoginDialog? = null

    private var leftSelect = 0
    private var leftSelected = 0
    private var rightSelect = 0
    private var rightSelected = 0

    private var showChooseDialog = true
    private var showAutoLoginDialog = false

    private val handler = object : Handler(Looper.getMainLooper()) {
        override fun handleMessage(msg: Message) {
            when (msg.what) {
                101 -> {
                    val time = msg.obj
                    autoLoginDialog?.tvNum?.text = "(${time}s)"
                    if (time == 0) {
                        sendEmptyMessage(200)
                    }
                }
                200 -> {
                    Logger.d("发起自动登录")
                    if (isCancelLogin) {
                        return
                    }
                    session?.apply {
                        if (!this@LoginActivity.isFinishing) {
                            //TODO showLoadingDialog()
                            userAutoLogin()
                        }
                    }
                }
            }
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        userSignInImpl = UserSignInImpl(this, object : UserSignInImpl.ISignInCallback {
            override fun onSuccess(result: String) {
                hideAutoLoginDialog()
                hideChooseDialog()
                this@LoginActivity.finish()
                implCallback?.onResult(0, result)
            }

            override fun onFailed(result: String) {
                if (showAutoLoginDialog) {
                    showAutoLoginDialog = false
                    showChooseDialog = true
                    hideAutoLoginDialog()
                }
                if (loginContainer.visibility == View.GONE) {
                    showChooseDialog()
                }
                implCallback?.onResult(-1, result)
            }

        })
        showAutoLoginDialog()
        showChooseDialog()
        initView()
    }


    private fun showAutoLoginDialog() {
        autoLoginDialog?.apply {
            dismiss()
            autoLoginDialog = null
        }

        session = SessionUtils.instance.getLocalLastSession(this)

        if (session == null || !isAutoLogin) {
            showChooseDialog = true
            showAutoLoginDialog = false
            return
        }

        autoLoginDialog = AutoLoginDialog(this)
        var tips = ""
        session?.apply {
            if (isAutoLogin) {
                showChooseDialog = false
                showAutoLoginDialog = true
                when (loginType) {
                    LoginType.TYPE_ACCOUNT_LOGIN -> {
                        var userName = session!!.userName
                        if (userName.length > 15) {
                            userName = userName.substring(3, 15) + "..."
                        }
                        tips = userName
                    }
                    LoginType.TYPE_GUEST_LOGIN -> tips = ResUtils.getResString(this@LoginActivity, "yyxx_tv_login_guest")
                    LoginType.TYPE_FACEBOOK_LOGIN -> tips = ResUtils.getResString(this@LoginActivity, "yyxx_tv_login_facebook")
                    LoginType.TYPE_GOOGLE_LOGIN -> tips = ResUtils.getResString(this@LoginActivity, "yyxx_tv_login_google")
                }
            }
        }

        autoLoginDialog?.apply {
            tvAccount.text = tips
//            handler.sendEmptyMessageDelayed(200, 2000)
            changeTimeNum()
            btnSwitch.setOnClickListener {
                hideAutoLoginDialog()
                showChooseDialog = true
                showChooseDialog()
            }
            show()
        }
    }

    private fun showChooseDialog() {
        chooseDialog?.apply {
            dismiss()
            chooseDialog = null
        }

        if (!showChooseDialog) {
            return
        }

        chooseDialog = ChooseLoginDialog(this)

        chooseDialog?.apply {
            typeGoogle.tag = ClickType.ACTION_GOOGLE_MODE
            typeGoogle.setOnClickListener(this@LoginActivity)

            typeFacebook.tag = ClickType.ACTION_FACEBOOK_MODE
            typeFacebook.setOnClickListener(this@LoginActivity)

            typeAccount.tag = ClickType.ACTION_ACCOUNT_MODE
            typeAccount.setOnClickListener(this@LoginActivity)

            typeGuest.tag = ClickType.ACTION_GUEST_MODE
            typeGuest.setOnClickListener(this@LoginActivity)

            setOnKeyListener(object : DialogInterface.OnKeyListener {
                override fun onKey(dialog: DialogInterface?, keyCode: Int, event: KeyEvent?): Boolean {
                    if (keyCode == KeyEvent.KEYCODE_BACK) {
                        hideChooseDialog()
                        this@LoginActivity.finish()
                        return true
                    }
                    return false
                }

            })
            show()
            val sdkEvent = SdkEvent()
            sdkEvent.eventName = "choose_login_page"
            Linking.instance.sdkEvent(this@LoginActivity, sdkEvent)
        }

    }

    private fun initView() {
        if (SdkBridgeImpl.isLand) {
            window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN)
        }
        setContentView(ResUtils.getResId(this, "yyxx_login", "layout"))

        if (!SdkBridgeImpl.isLand) {
            AndroidBug5497Workaround.assistActivity(this)
        }

        rootContainer = findViewById(ResUtils.getResId(this, "yyxx_login_container", "id"))

        loginContainer = findViewById(ResUtils.getResId(this, "yyxx_cl_login", "id"))
        loginContainer.visibility = View.VISIBLE

        tabLayout = findViewById(ResUtils.getResId(this, "yyxx_tl", "id"))
        //横屏下反射修改TabLayout的requestedTabMinWidth
        if (SdkBridgeImpl.isLand) {
            val requestedTabMinWidth = TabLayout::class.java.getDeclaredField("requestedTabMinWidth")
            requestedTabMinWidth.isAccessible = true
            requestedTabMinWidth.set(tabLayout, DensityUtils.dip2px(this, 160f))
        }

        viewPager = findViewById(ResUtils.getResId(this, "yyxx_vp", "id"))
        val fragmentManager = supportFragmentManager
        //使用适配器将ViewPager和Fragment绑定在一起
        val tabs = this.resources.getStringArray(ResUtils.getResId(this, "yyxx_login_tab", "array"))
        val pagerAdapter = LoginFragmentPagerAdapter(tabs, fragmentManager)
        viewPager.adapter = pagerAdapter
        //将TabLayout与ViewPager绑定在一起
        tabLayout.setupWithViewPager(viewPager)
        leftSelect = ResUtils.getResId(this, "yyxx_tab_left_select", "drawable")
        leftSelected = ResUtils.getResId(this, "yyxx_tab_left_selected", "drawable")
        rightSelect = ResUtils.getResId(this, "yyxx_tab_right_select", "drawable")
        rightSelected = ResUtils.getResId(this, "yyxx_tab_right_selected", "drawable")
        setTabBackground(leftSelected, rightSelect)
        tabLayout.addOnTabSelectedListener(object : TabLayout.OnTabSelectedListener {
            override fun onTabSelected(tab: TabLayout.Tab?) {
                when (tabLayout.selectedTabPosition) {
                    0 -> setTabBackground(leftSelected, rightSelect)
                    1 -> setTabBackground(leftSelect, rightSelected)
                }
            }

            override fun onTabUnselected(tab: TabLayout.Tab?) {
                if (pagerAdapter.currentFragment is LauncherFragment) {
                    //TODO 收起下拉列表
                    (pagerAdapter.currentFragment as LauncherFragment).hideAccountList()
                }
            }

            override fun onTabReselected(tab: TabLayout.Tab?) {

            }
        })

        loginContainer.visibility = View.GONE
    }

    private fun setTabBackground(left: Int, right: Int) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
            val tabStrip = tabLayout.getChildAt(0) as ViewGroup
            val tabView1 = tabStrip.getChildAt(0)
            val tabView2 = tabStrip.getChildAt(1)
            if (tabView1 != null) {
                val paddingStart = tabView1.paddingStart
                val paddingTop = tabView1.paddingTop
                val paddingEnd = tabView1.paddingEnd
                val paddingBottom = tabView1.paddingBottom
                ViewCompat.setBackground(
                    tabView1, ContextCompat.getDrawable(tabView1.context, left)
                )
                ViewCompat.setPaddingRelative(tabView1, paddingStart, paddingTop, paddingEnd, paddingBottom)
            }
            if (tabView2 != null) {
                val paddingStart = tabView2.paddingStart
                val paddingTop = tabView2.paddingTop
                val paddingEnd = tabView2.paddingEnd
                val paddingBottom = tabView2.paddingBottom
                ViewCompat.setBackground(tabView2, ContextCompat.getDrawable(tabView2.context, right))
                ViewCompat.setPaddingRelative(tabView2, paddingStart, paddingTop, paddingEnd, paddingBottom)
            }
        }
    }

    override fun dispatchTouchEvent(ev: MotionEvent?): Boolean {
        ev?.let {
            if (it.action == MotionEvent.ACTION_DOWN) {
                val v = currentFocus
                if (isShouldHideInput(v, it)) {
                    val imm =
                        this@LoginActivity.getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager
                    imm.hideSoftInputFromWindow(v!!.windowToken, 0)
                }
                return super.dispatchTouchEvent(it)
            }
        }
        // 必不可少，否则所有的组件都不会有TouchEvent了
        return if (window.superDispatchTouchEvent(ev)) {
            true
        } else onTouchEvent(ev)
    }

    private fun hideBar() {
        // The UI options currently enabled are represented by a bitfield.
        // getSystemUiVisibility() gives us that bitfield.
        val uiOptions = window.decorView.systemUiVisibility
        var newUiOptions = uiOptions
        val isImmersiveModeEnabled = uiOptions or View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY == uiOptions
        if (!isImmersiveModeEnabled) {
            if (Build.VERSION.SDK_INT >= 14) {
                newUiOptions = newUiOptions or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
            }
            if (Build.VERSION.SDK_INT >= 16) {
                newUiOptions = newUiOptions or View.SYSTEM_UI_FLAG_FULLSCREEN
            }
            if (Build.VERSION.SDK_INT >= 18) {
                newUiOptions = newUiOptions or View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
            }
            window.decorView.systemUiVisibility = newUiOptions
        }
    }


    private fun isShouldHideInput(v: View?, event: MotionEvent): Boolean {
        if (v is EditText) {
            val leftTop = intArrayOf(0, 0)
            //获取输入框当前的location位置
            v.getLocationInWindow(leftTop)
            val left = leftTop[0]
            val top = leftTop[1]
            val bottom = top + v.getHeight()
            val right = left + v.getWidth()
            // 点击的是输入框区域，保留点击EditText的事件
            return event.x <= left || event.x >= right || event.y <= top || event.y >= bottom
        }
        return false
    }

    private fun hideAutoLoginDialog() {
        autoLoginDialog?.apply {
            dismiss()
            TimeDownUtils.cancel()
            chooseDialog = null
        }
    }

    private fun hideChooseDialog() {
        chooseDialog?.apply {
            dismiss()
            chooseDialog = null
        }
    }


    override fun onClick(v: View?) {
        v?.apply {
            when (tag as Int) {
                ClickType.ACTION_GOOGLE_MODE -> {
                    userSignInImpl.googleLogin(this@LoginActivity)
                }
                ClickType.ACTION_FACEBOOK_MODE -> {
                    userSignInImpl.facebookLogin(this@LoginActivity)
                }
                ClickType.ACTION_ACCOUNT_MODE -> {
                    chooseDialog?.dismiss()
                    chooseDialog = null
                    loginContainer.visibility = View.VISIBLE
                }
                ClickType.ACTION_GUEST_MODE -> {
                    userSignInImpl.guestLogin(this@LoginActivity)
                }
            }
        }
    }

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

    override fun onDestroy() {
        super.onDestroy()
        TimeDownUtils.cancel()
    }


    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        data?.apply {
            userSignInImpl.onSignInResult(requestCode, resultCode, this)
        }
    }

    fun showLoginView() {
        loginContainer.visibility = View.VISIBLE
    }

    fun hideLoginView() {
        loginContainer.visibility = View.GONE
    }

    private fun userAutoLogin() {
        session?.apply {
            if (showAutoLoginDialog) {
                showAutoLoginDialog = false
                showChooseDialog = true
                hideAutoLoginDialog()
            }
            when (loginType) {
                LoginType.TYPE_GUEST_LOGIN -> userSignInImpl.guestLogin(this@LoginActivity)
                LoginType.TYPE_FACEBOOK_LOGIN -> userSignInImpl.facebookLogin(this@LoginActivity)
                LoginType.TYPE_GOOGLE_LOGIN -> userSignInImpl.googleLogin(this@LoginActivity)
                LoginType.TYPE_ACCOUNT_LOGIN -> userSignInImpl.accountLogin(this@LoginActivity, userName, pwd)
            }
        }
    }

    private fun changeTimeNum() {
        if (!TimeDownUtils.isRunning) {
            TimeDownUtils.start(2, object : TimeDownUtils.TimeCallback {
                override fun onTime(time: Int) {
                    val msg = Message.obtain()
                    msg.what = 101
                    msg.obj = time
                    handler.sendMessage(msg)
                }
            })
        } else {
            TimeDownUtils.resetCallback(object : TimeDownUtils.TimeCallback {
                override fun onTime(time: Int) {
                    val msg = Message.obtain()
                    msg.what = 101
                    msg.obj = time
                    handler.sendMessage(msg)
                }
            })
        }
    }

    companion object {

        private var implCallback: IImplCallback? = null
        private var session: Session? = null
        private var isAutoLogin = false
        private var isCancelLogin = false

        fun login(activity: Activity, isAuto: Boolean, callback: IImplCallback) {
            implCallback = callback
            isAutoLogin = isAuto
            isCancelLogin = false
            activity.startActivity(Intent(activity, LoginActivity::class.java).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK))
        }
    }


}