package com.cheng.blzb.ui.fragment.login.onekey

import android.annotation.SuppressLint
import android.text.TextUtils
import com.alibaba.fastjson.JSONObject
import com.bytedance.ads.convert.event.ConvertReportHelper
import com.example.base.browser.BrowserActivity
import com.example.base.common.RxBus
import com.example.base.extensions.getColor
import com.example.base.extensions.gone
import com.example.base.extensions.onClick
import com.example.base.extensions.toast
import com.example.base.extensions.visible
import com.example.base.ui.BaseFragment
import com.example.base.utils.L
import com.example.base.utils.SpanUtils
import com.example.base.utils.Utils
import com.g.gysdk.EloginActivityParam
import com.g.gysdk.GYManager
import com.g.gysdk.GYResponse
import com.g.gysdk.GyCallBack
import com.google.gson.JsonObject
import com.tencent.mm.opensdk.modelmsg.SendAuth
import com.tencent.mm.opensdk.openapi.IWXAPI
import com.tencent.mm.opensdk.openapi.WXAPIFactory
import com.cheng.blzb.R
import com.cheng.blzb.common.Constants
import com.cheng.blzb.common.EventConstants
import com.cheng.blzb.databinding.FragmentOnekeyLoginBinding
import com.cheng.blzb.event.LoginSuccessEvent
import com.cheng.blzb.event.WxLoginEvent
import com.cheng.blzb.manager.EventReportManager
import com.cheng.blzb.manager.LoginManager
import com.cheng.blzb.manager.UserConfigManager
import com.cheng.blzb.ui.activity.LoginActivity
import com.cheng.blzb.ui.activity.MainActivity
import com.cheng.blzb.ui.activity.PublicActivity
import com.cheng.blzb.ui.dialog.AccountListDialog
import com.cheng.blzb.ui.dialog.LoginTipDialog
import com.cheng.blzb.ui.fragment.login.LoginFragment
import com.cheng.blzb.utils.UrlHelper
import okhttp3.RequestBody.Companion.toRequestBody
import org.jetbrains.anko.startActivity

/**
 * 一健登录
 */
class OneKeyLoginFragment : BaseFragment<FragmentOnekeyLoginBinding, OnekeyLoginViewModel>() {
    private val from by lazy { arguments?.getInt("from") ?: 0 }
    private lateinit var api: IWXAPI

    private var gyuid = ""

    private var isVisible = false

    private var isWxRequesting = false

    @SuppressLint("SetTextI18n")
    override fun initView() {
        super.initView()
        setHomeAsUp(from != 0 || requireActivity() !is LoginActivity)
        binding.mTitleBar.background = null

        initLoginType()
        initPrivacyTv()
    }

    override fun initData() {
        super.initData()
        api = WXAPIFactory.createWXAPI(requireContext(), Constants.WechatAppId)

        if (from != 2 && requireActivity() is LoginActivity) mViewModel.accountList()
        if (GYManager.getInstance().isPreLoginResultValid) {
            initOneKeyLogin()//预登录有效，启动登录授权页
        } else {
            //预登录
            GYManager.getInstance().ePreLogin(5000, object : GyCallBack {
                override fun onSuccess(gyResponse: GYResponse) {
                    initOneKeyLogin()
                    L.d("TAG-->>GYManager ePreLogin onSuccess =${gyResponse.code}")
                }

                override fun onFailed(gyResponse: GYResponse) {
                    L.d("TAG-->>GYManager ePreLogin onFailed =${gyResponse.code}")
                }
            })
        }
    }

    override fun onStart() {
        super.onStart()
        isVisible = true
    }

    override fun onStop() {
        super.onStop()
        isVisible = false
    }

    override fun initListener() {
        super.initListener()
        binding.ivWxLogin.onClick {
            if (!api.isWXAppInstalled) {
                toast("您没有安装微信客户端,请先下载安装")
                return@onClick
            }
            if (!binding.cbAgree.isChecked) {
                val loginTipDialog = LoginTipDialog.newInstance(1)
                loginTipDialog.setOnSelectListener {
                    binding.cbAgree.isChecked = true
                    wxAuth()
                }
                loginTipDialog.show(childFragmentManager, loginTipDialog::class.java.simpleName)
            } else {
                wxAuth()
            }
        }
        binding.ivPhoneLogin.onClick {
            if (requireActivity() is LoginActivity) {
                PublicActivity.start(requireContext(), LoginFragment::class.java)
            } else {
                requireActivity().finish()
            }
        }
    }

    override fun initObserve() {
        super.initObserve()
        mViewModel.accountLiveData.observe(this) {
            if (it.isNotEmpty()) {
                AccountListDialog.newInstance(it).show(childFragmentManager, AccountListDialog::class.java.simpleName)
            }
        }
        mViewModel.onekeyLoginLiveData.observe(this) {
            EventReportManager.eventReport(EventConstants.LOGIN, "onekey", gyuid)
            ConvertReportHelper.onEventRegister("onekey",true)
            LoginManager.saveLastLoginType("onekey")
            loginSuccess(it)
        }
        mViewModel.wxLoginLiveData.observe(this) {
            EventReportManager.eventReport(EventConstants.LOGIN, "weixin", "")
            ConvertReportHelper.onEventRegister("weixin",true)
            LoginManager.saveLastLoginType("weixin")
            loginSuccess(it)
        }
        val wxLoginEvent = RxBus.defaultInstance.toObservable(WxLoginEvent::class.java).subscribe {
            isWxRequesting = false
            if (!TextUtils.isEmpty(it.code) && isVisible && it.state.endsWith("onekey")) loginByWx(it.code)
        }
        addDisposable(wxLoginEvent)
        val loginSuccessEvent = RxBus.defaultInstance.toObservable(LoginSuccessEvent::class.java).subscribe {
            requireActivity().finish()
        }
        addDisposable(loginSuccessEvent)
    }

    private fun initOneKeyLogin() {
        val eloginActivityParam = EloginActivityParam()
            .setActivity(requireActivity())
            .setNumberTextview(binding.tvPhoneNumber)
            .setSloganTextview(binding.tvSlogan)
            .setLoginButton(binding.loginBtn)
            .setPrivacyCheckbox(binding.cbAgree)
            .setPrivacyTextview(binding.tvAgree)
            .setUiErrorListener { //隐私协议未打勾、界面不合规、setLoginOnClickListener抛出异常等情况下的回调
                mViewModel.dismissDialog()
            }
            .setLoginOnClickListener {
                L.d("一键登录按钮 onLoginClick:")
                if (!binding.cbAgree.isChecked) {
                    val loginTipDialog = LoginTipDialog.newInstance(1)
                    loginTipDialog.setOnSelectListener {
                        binding.cbAgree.isChecked = true
                    }
                    loginTipDialog.show(childFragmentManager, loginTipDialog::class.java.simpleName)
                    // 抛出异常，避免sdk进行后续登录动作（否则eAccountLogin会回调onFailed错误）
                    throw IllegalStateException("请先仔细阅读协议并勾选，然后再点击登录")
                }
            }
        // 请在预登录成功之后、设置好privacyTv的内容之后再调用eAccountLogin
        GYManager.getInstance().eAccountLogin(eloginActivityParam, 5000, object : GyCallBack {
            override fun onSuccess(response: GYResponse) {
                try {
                    val jsonObject = JSONObject.parseObject(response.msg)
                    val data = jsonObject.getJSONObject("data")
                    val token = data.getString("token")
                    gyuid = response.gyuid
                    mViewModel.oneKeyLogin(response.gyuid, token)
                } catch (e: Exception) {
                    e.printStackTrace()
                }
            }

            override fun onFailed(response: GYResponse) {
                L.e("登录失败 response:$response")
                try {
                    val jsonObject = JSONObject.parseObject(response.msg)
                    val errorCode = jsonObject.getIntValue("errorCode")
                    if (errorCode != -20301) { //关闭一键登录界面不用提示
                        toast("一键登录失败:$response")
                    }
                } catch (e: Exception) {
                    e.printStackTrace()
                }
            }
        })
    }

    private fun loginSuccess(entity: com.cheng.blzb.bean.LoginEntity) {
        LoginManager.saveToken(entity.token)
        UserConfigManager.userConfig {
            requireActivity().startActivity<MainActivity>()
            RxBus.defaultInstance.post(LoginSuccessEvent())
        }
    }

    private fun initLoginType() {
        val loginType = UserConfigManager.getLoginType()
        if (loginType.contains("weixin")) {
            binding.ivWxLogin.visible()
        } else {
            binding.ivWxLogin.gone()
        }
    }

    /**
     * 初始化隐私协议，请在onCreate/预登录成功之后&调用eAccountLogin之前就设置好，不允许动态改变
     *
     * @param textView
     */
    private fun initPrivacyTv() {
        val preLoginResult = GYManager.getInstance().preLoginResult
        SpanUtils.with(binding.tvAgree)
            .append("我已同意并阅读了")
            .append("《${preLoginResult.privacyName}》")
            .setClickSpan(getColor(R.color.color_125ffe), false) {
                BrowserActivity.start(requireContext(), preLoginResult.privacyName, preLoginResult.privacyUrl)
            }
            .append("、")
            .append("《用户协议》")
            .setClickSpan(getColor(R.color.color_125ffe), false) {
                UrlHelper.startUserAgreement(requireContext())
            }
            .append("和")
            .append("《隐私政策》")
            .setClickSpan(getColor(R.color.color_125ffe), false) {
                UrlHelper.startPrivacyPolicy(requireContext())
            }
            .create()
    }

    /**
     * 微信登录
     */
    private fun loginByWx(wechatCode: String) {
        val jsonWx = JsonObject()
        jsonWx.addProperty("code", wechatCode)
        jsonWx.addProperty("code_type", "")

        val jsonObject = JsonObject()
        jsonObject.addProperty("login_type", "weixin")
        jsonObject.add("weixin", jsonWx)
        mViewModel.loginByWx(jsonObject.toString().toRequestBody())
    }

    private fun wxAuth() {
        if (isWxRequesting) return
        if (!api.isWXAppInstalled) {
            toast("未安装微信客户端，请先下载安装微信客户端")
            return
        }
        isWxRequesting = true
        val req = SendAuth.Req()
        req.scope = "snsapi_userinfo" // 只能填 snsapi_userinfo
        req.state = Utils.getApp().packageName + Math.random() * 1000 + "_onekey"
        api.sendReq(req)
    }
}