package com.adealink.weparty.account.login.phone.fragment

import android.os.Build
import android.text.SpannableStringBuilder
import android.text.method.LinkMovementMethod
import android.text.style.TypefaceSpan
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.view.updateLayoutParams
import androidx.fragment.app.activityViewModels
import com.adealink.frame.aab.util.getCompatColor
import com.adealink.frame.aab.util.getCompatString
import com.adealink.frame.ext.findAndSetSpan
import com.adealink.frame.ext.isViewBindingValid
import com.adealink.frame.mvvm.view.viewBinding
import com.adealink.frame.util.removeUiCallbacks
import com.adealink.frame.util.runOnUiThread
import com.adealink.weparty.account.R
import com.adealink.weparty.account.databinding.FragmentAccountVerifyPhoneBinding
import com.adealink.weparty.account.login.phone.data.Page
import com.adealink.weparty.account.login.phone.viewmodel.PhoneLoginViewModel
import com.adealink.weparty.account.login.viewmodel.LoginViewModel
import com.adealink.weparty.account.viewModel.AccountViewModelFactory
import com.adealink.weparty.commonui.BaseFragment
import com.adealink.weparty.commonui.DEFAULT_FONT_BOLD
import com.adealink.weparty.commonui.ext.gone
import com.adealink.weparty.commonui.ext.show
import com.adealink.weparty.commonui.toast.util.showFailedToast
import com.adealink.weparty.module.account.comp.VerifyCodeComp
import com.adealink.weparty.util.applyImmersive
import com.tencent.qcloud.tuikit.timcommon.util.TextUtil
import kotlin.math.max
import com.adealink.weparty.R as APP_R

class VerifyPhoneFragment : BaseFragment(R.layout.fragment_account_verify_phone) {

    private val binding by viewBinding(FragmentAccountVerifyPhoneBinding::bind)
    private val phoneViewModel by activityViewModels<PhoneLoginViewModel> { AccountViewModelFactory() }
    private val loginViewModel by activityViewModels<LoginViewModel>() { AccountViewModelFactory() }


    override fun initViews() {
        super.initViews()
        binding.topBar.backCallback = {
            phoneViewModel.showPage(Page.INPUT_PHONE)
        }
        activity.applyImmersive { top ->
            binding.topBar.updateLayoutParams<ConstraintLayout.LayoutParams> {
                topMargin = top
            }
        }

        val resendBtn = getCompatString(APP_R.string.account_resend_verify_code_content)
        val resendText = getCompatString(APP_R.string.account_resend_verify_code_title, resendBtn)
        binding.tvResend.text = SpannableStringBuilder(resendText).apply {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
                findAndSetSpan(
                    TypefaceSpan(DEFAULT_FONT_BOLD),
                    resendBtn
                )
            }
            findAndSetSpan(
                TextUtil.ForegroundColorClickableSpan(
                    getCompatColor(APP_R.color.color_FF3FBFBD)
                ) {
                    resendVerifyCode()
                },
                resendBtn
            )
        }
        binding.tvResend.movementMethod = LinkMovementMethod.getInstance()
    }

    override fun initComponents() {
        super.initComponents()
        VerifyCodeComp(
            this,
            listOf(
                binding.vVerifyCode.et1,
                binding.vVerifyCode.et2,
                binding.vVerifyCode.et3,
                binding.vVerifyCode.et4
            )
        ) { code ->
            checkVerifyCode(code)
        }.attach()
    }

    override fun observeViewModel() {
        super.observeViewModel()
        phoneViewModel.verifyPhoneNumberLD.observe(viewLifecycleOwner) { number ->
            binding.tvDesc.text =
                getCompatString(APP_R.string.account_input_verify_code_desc, number)
        }
        phoneViewModel.sendVerifyEnableLD.observe(viewLifecycleOwner) {
            updateResendText(it)
        }
    }

    private var resendCountDownS = 0L

    private val updateResendDurationRunnable = {
        updateResendDuration()
    }

    private fun updateResendDuration() {
        if (isViewBindingValid()) {
            resendCountDownS = max(resendCountDownS - 1, 0)
            binding.tvResendDuration.text = getCompatString(
                APP_R.string.account_resend_verify_code_duration,
                resendCountDownS.toString()
            )
            if (resendCountDownS > 0) {
                runOnUiThread(updateResendDurationRunnable, 1000)
            }
        }
    }

    private fun updateResendText(enableSend: Boolean) {
        if (enableSend) {
            binding.tvResendDuration.gone()
            binding.tvResend.show()
        } else {
            binding.tvResendDuration.show()
            val countDown =
                max(
                    PhoneLoginViewModel.lastSendVerifyCodeTs + PhoneLoginViewModel.SEND_DURATION - System.currentTimeMillis(),
                    0
                ) / 1000
            resendCountDownS = countDown
            updateResendDuration()
            binding.tvResend.gone()
        }
    }

    private fun resendVerifyCode() {
        showLoading()
        phoneViewModel.resendVerifyCode().observe(viewLifecycleOwner) {
            dismissLoading()
            showFailedToast(it.rlt)
        }
    }

    private fun checkVerifyCode(verifyCode: String?) {
        val regionCode = phoneViewModel.verifyPhoneRegion
        val phoneNumber = phoneViewModel.verifyPhoneNumber
        if (regionCode.isNullOrEmpty() || phoneNumber.isNullOrEmpty() || verifyCode.isNullOrEmpty()) {
            return
        }
        showLoading()
        loginViewModel.phoneLogin(regionCode, phoneNumber, verifyCode)
    }

    override fun onDestroyView() {
        super.onDestroyView()
        removeUiCallbacks(updateResendDurationRunnable)
    }

    override fun onBackPressed(): Boolean {
        phoneViewModel.showPage(Page.INPUT_PHONE)
        return true
    }

}