package com.rdiot.yx485.ui.login

import android.graphics.Color
import android.os.Bundle
import android.text.Spannable
import android.text.SpannableString
import android.text.TextPaint
import android.text.method.LinkMovementMethod
import android.text.style.ClickableSpan
import android.view.View
import android.widget.TextView
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope
import androidx.navigation.findNavController
import com.gyf.immersionbar.ktx.immersionBar
import com.lindroy.iosdialog.IAlertDialog
import com.lindroy.iosdialog.ICustomDialog
import com.rdiot.yx485.BuildConfig
import com.rdiot.yx485.R
import com.rdiot.yx485.base.AppManager
import com.rdiot.yx485.base.BaseActivity
import com.rdiot.yx485.base.LocalData
import com.rdiot.yx485.databinding.ActLoginBinding
import com.rdiot.yx485.ui.login.model.LoginType
import com.rdiot.yx485.ui.login.model.LoginViewModel
import com.rdiot.yx485.ui.web.WebActivity
import com.rdiot.yx485.util.checkUpdate
import com.rdiot.yx485.util.clearGoTo
import com.rdiot.yx485.util.curTime
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch

/**
 * 登录页面
 * @author mR2hao
 * @date 2022/11/15
 */
class LoginActivity : BaseActivity<ActLoginBinding>() {
    override fun getLayoutId() = R.layout.act_login
    private lateinit var loginVM: LoginViewModel

    var isTokenInvalid: Boolean = false
    var isResetPwd: Boolean = false
    private var dialog: IAlertDialog? = null

    companion object {
        const val TOKEN_INVALID = "tokenInvalid"
        const val RESET_PWD = "resetPwd"
    }

    /** 检查验证码的工作 */
    private var checkTimeJob: Job = Job()

    override fun initView(savedInstanceState: Bundle?) {
        immersionBar {
            statusBarView(binding.v)
            statusBarColor(R.color.transparent)
            navigationBarColor(R.color.main_bg_color)
            statusBarDarkFont(true)
        }
        loginVM = ViewModelProvider(this)[LoginViewModel::class.java]
        isTokenInvalid = intent.getBooleanExtra(TOKEN_INVALID, false)

        checkTime()

        //首次安装 弹出协议通知
        if (LocalData.firstTimeInstallApp) {
            showAgreementDialog()
        }

        LocalData.appVersionData.observe(this) { data ->

            //如果首次安装 先不弹更新
            if (!LocalData.firstTimeInstallApp) {
                checkUpdate(data)
            }
        }
    }


    override fun onStart() {
        super.onStart()
        isResetPwd = intent.getBooleanExtra(RESET_PWD, false)
        loginVM.isResetPwd.set(isResetPwd)
        if (isResetPwd) {
            findNavController(R.id.fcv).navigate(R.id.resetPwdFragment)
            return
        }

        if (LocalData.lastLoginRecord?.loginType == LoginType.PWD) {
            findNavController(R.id.fcv).navigate(R.id.action_loginSmsFragment_to_loginPwdFragment)
        }
    }

    /** 检查时间 */
    private fun checkTime() {
        // 切到子线程去循环查询验证码剩余时间
        checkTimeJob = lifecycleScope.launch(Dispatchers.IO) {
            // 页面还没有想要关闭的情况下
            while (!isFinishing) {
                val last = LocalData.lastGetCodeTime
                val less = (60 - (curTime - last) / 1000).coerceAtLeast(0)
                // 更新剩余时间
                if (loginVM.lessTimeSecond.value != less.toInt())
                    loginVM.lessTimeSecond.postValue(less.toInt())
                // 每隔一秒钟去检查一次时间
                delay(1000)
            }
        }
    }


    override fun onBackPressed() {
        //如果是重置密码，则直接结束
        if (loginVM.isResetPwd.get() == true) {
            finish()
        } else {
            //如果是找回密码页面，则先回退
            val fcv = findNavController(R.id.fcv)
            if (fcv.currentDestination?.id == R.id.resetPwdFragment) {
                fcv.popBackStack()
            } else {
                moveTaskToBack(true)
            }
        }
    }

    private fun showAgreementDialog() {
        dialog?.dismiss()

        ICustomDialog.build(this)
            .apply {
                setCancelOutside(BuildConfig.DEBUG)
            }
            .setAlpha(1.0F)
            .setWidthScale(0.7F)
            .setBackgroundColorRes(R.color.white)
            .setView(R.layout.dialog_simple_msg)
            .setOnViewHandler { holder, dialog ->
                holder.setText(R.id.tv_title, R.string.agreement_title)
                val spanText = getString(R.string.agreement_dialog_msg).toClickSpan(
                    97..103,
                    getColor(R.color.login_btn_color),
                ) {
                    clearGoTo(
                        WebActivity.getNewWebIntent(
                            this,
                            "https://app.yongxulvjian.com/#/ServiceAgreement",
                            "用户协议"
                        )
                    )
                }.toClickSpan(
                    104..110,
                    getColor(R.color.login_btn_color),
                ) {
                    clearGoTo(
                        WebActivity.getNewWebIntent(
                            this,
                            "https://app.yongxulvjian.com/#/PrivacyPolicy",
                            "隐私政策"
                        )
                    )
                }
                holder.getView<TextView>(R.id.tv_msg).apply {
                    movementMethod = LinkMovementMethod.getInstance()
                    text = spanText
                }

                holder.setTextColor(R.id.btnConfirm, getColor(R.color.warning))
                holder.setText(R.id.btnConfirm, getString(R.string.agree))
                holder.setText(R.id.btnCancel, getString(R.string.disagree))

                //暂不使用
                holder.setOnClickListener(R.id.btnCancel) {
                    dialog.dismiss()
                    AppManager.instance.appExit()
                }

                //同意
                holder.setOnClickListener(R.id.btnConfirm) {
                    dialog.dismiss()

                    LocalData.firstTimeInstallApp = false
                    loginVM.isRead.postValue(true)
                    LocalData.appVersionData.value?.let { data ->
                        if (data.needUpdate) {
                            checkUpdate(data)
                        }
                    }
                }

            }
            .show()
    }
}

/**
 * 将一段文字中指定range的文字添加颜色和点击事件
 * @param range 目标文字的范围
 */
fun CharSequence.toClickSpan(
    range: IntRange,
    color: Int = Color.RED,
    clickAction: (() -> Unit)?
): CharSequence {
    return SpannableString(this).apply {
        val clickableSpan = object : ClickableSpan() {
            override fun onClick(widget: View) {
                clickAction?.invoke()
            }

            override fun updateDrawState(ds: TextPaint) {
                ds.color = color
                ds.isUnderlineText = false;
            }
        }
        setSpan(clickableSpan, range.first, range.last, Spannable.SPAN_INCLUSIVE_EXCLUSIVE)
    }
}
