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

import android.annotation.SuppressLint
import android.text.TextUtils
import android.view.View
import com.bytedance.ads.convert.event.ConvertReportHelper
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.SpanUtils
import com.example.base.utils.Utils
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.FragmentLoginBinding
import com.cheng.blzb.event.LoginSuccessEvent
import com.cheng.blzb.event.WxLoginEvent
import com.cheng.blzb.impl.TextWatcherImpl
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.onekey.OneKeyLoginFragment
import com.cheng.blzb.utils.UrlHelper
import org.jetbrains.anko.sdk27.listeners.onCheckedChange
import org.jetbrains.anko.sdk27.listeners.onClick
import org.jetbrains.anko.startActivity

/**
 * 登录
 */
class LoginFragment : BaseFragment<FragmentLoginBinding, LoginViewModel>() {
    private val from by lazy { arguments?.getInt("from") ?: 0 }
    private lateinit var api: IWXAPI

    private var isAgree = false
    var timestamp = ""

    private var isVisible = false

    private var isWxRequesting = false

    private val textWatcher = object : TextWatcherImpl() {
        @SuppressLint("SetTextI18n")
        override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
            binding.ivClearText.visibility = if (TextUtils.isEmpty(s)) View.INVISIBLE else View.VISIBLE
        }
    }

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

        binding.tvAppName.typeface = Constants.almmsht

        initLoginType()
        initPrivacyTv()
    }

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

        if (from != 2 && requireActivity() is LoginActivity) mViewModel.accountList()
    }

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

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

    override fun initListener() {
        super.initListener()
        binding.edPhone.addTextChangedListener(textWatcher)

        binding.ivClearText.onClick {
            binding.edPhone.setText("")
        }

        binding.ivWxLogin.onClick {
            if (!api.isWXAppInstalled) {
                toast("您没有安装微信客户端,请先下载安装")
                return@onClick
            }
            if (!isAgree) {
                val loginTipDialog = LoginTipDialog.newInstance()
                loginTipDialog.setOnSelectListener {
                    isAgree = true
                    binding.cbAgree.isChecked = true
                    wxAuth()
                }
                loginTipDialog.show(childFragmentManager, loginTipDialog::class.java.simpleName)
            } else {
                wxAuth()
            }
        }
        binding.ivOnekeyLogin.onClick {
            if (requireActivity() is LoginActivity) {
                PublicActivity.start(requireContext(), OneKeyLoginFragment::class.java)
            } else {
                requireActivity().finish()
            }
        }
        binding.tvSendCode.onClick {
            sendCode()
        }
        binding.loginBtn.onClick {
            loginByPhone()
        }
        binding.cbAgree.onCheckedChange { _, isChecked ->
            isAgree = isChecked
        }
        binding.tvAgree.onClick {
            binding.cbAgree.isChecked = !binding.cbAgree.isChecked
        }
    }

    @SuppressLint("SetTextI18n")
    override fun initObserve() {
        super.initObserve()
        mViewModel.accountLiveData.observe(this) {
            if (it.isNotEmpty()) {
                AccountListDialog.newInstance(it).show(childFragmentManager, AccountListDialog::class.java.simpleName)
            }
        }
        mViewModel.sendCodeLiveData.observe(this) { timestamp = it.timestamp }
        mViewModel.countTimeLiveEvent.observe(this) {
            if (it > 0) {
                binding.tvSendCode.text = "重新获取(${it}s)"
                binding.tvSendCode.isEnabled = false
                binding.tvSendCode.alpha = 0.5f
            } else {
                binding.tvSendCode.text = "重新获取"
                binding.tvSendCode.isEnabled = true
                binding.tvSendCode.alpha = 1f
            }
        }
        mViewModel.phoneLoginLiveData.observe(this) {
            EventReportManager.eventReport(EventConstants.LOGIN, "phone", binding.edPhone.text.toString())
            ConvertReportHelper.onEventRegister("phone",true)
            LoginManager.saveLastLoginType("phone")
            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("phone")) loginByWx(it.code)
        }
        addDisposable(wxLoginEvent)
        val loginSuccessEvent = RxBus.defaultInstance.toObservable(LoginSuccessEvent::class.java).subscribe {
            requireActivity().finish()
        }
        addDisposable(loginSuccessEvent)
    }

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

    private fun initPrivacyTv() {
        SpanUtils.with(binding.tvAgree)
            .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 loginSuccess(entity: com.cheng.blzb.bean.LoginEntity) {
        LoginManager.saveToken(entity.token)
        UserConfigManager.userConfig {
            requireActivity().startActivity<MainActivity>()
            RxBus.defaultInstance.post(LoginSuccessEvent())
        }
    }

    /**
     * 手机号登录
     */
    private fun loginByPhone() {
        val phone = binding.edPhone.text?.trim().toString()
        val code = binding.edCode.text?.trim().toString()
        if (TextUtils.isEmpty(phone)) {
            toast("请输入手机号")
            return
        }
        if (phone.length != 11) {
            toast("请输入正确的手机号")
            return
        }
        if (TextUtils.isEmpty(code)) {
            toast("请输入验证码")
            return
        }
        if (!isAgree) {
            val loginTipDialog = LoginTipDialog.newInstance()
            loginTipDialog.setOnSelectListener {
                isAgree = true
                binding.cbAgree.isChecked = true
                mViewModel.loginByPhone(timestamp, phone, code)
            }
            loginTipDialog.show(childFragmentManager, "")
        } else {
            mViewModel.loginByPhone(timestamp, phone, code)
        }
    }

    private fun sendCode() {
        val phone = binding.edPhone.text?.trim().toString()
        if (TextUtils.isEmpty(phone)) {
            toast("请输入手机号")
            return
        }
        if (phone.length != 11) {
            toast("请输入正确的手机号")
            return
        }
        EventReportManager.eventReport(EventConstants.GET_CODE, "code_login", phone)
        mViewModel.sendCode(phone)
    }

    /**
     * 微信登录
     */
    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(wechatCode)
    }

    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 + "_phone"
        api.sendReq(req)
    }

    override fun onDestroyView() {
        binding.edPhone.removeTextChangedListener(textWatcher)
        super.onDestroyView()
    }
}
