package com.adealink.weparty.joinus.step1.page

import android.os.Build
import android.text.SpannableStringBuilder
import android.text.method.LinkMovementMethod
import android.text.style.TypefaceSpan
import androidx.core.view.WindowInsetsCompat
import androidx.core.view.updatePadding
import androidx.fragment.app.activityViewModels
import com.adealink.frame.aab.util.getCompatColor
import com.adealink.frame.aab.util.getCompatString
import com.adealink.frame.base.Rlt
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.commonui.BaseFragment
import com.adealink.weparty.commonui.DEFAULT_FONT_BOLD
import com.adealink.weparty.commonui.ext.contentView
import com.adealink.weparty.commonui.ext.fitSystemWindows
import com.adealink.weparty.commonui.ext.gone
import com.adealink.weparty.commonui.ext.onWindowInsets
import com.adealink.weparty.commonui.ext.show
import com.adealink.weparty.commonui.toast.util.showFailedToast
import com.adealink.weparty.joinus.R
import com.adealink.weparty.joinus.data.JoinUsStep
import com.adealink.weparty.joinus.databinding.FragmentJoinUsStep1InputVerifyBinding
import com.adealink.weparty.joinus.step1.JoinUsStep1Fragment
import com.adealink.weparty.joinus.step1.viewmodel.Step1ViewModel
import com.adealink.weparty.joinus.viewmodel.JoinUsViewModel
import com.adealink.weparty.joinus.viewmodel.JoinUsViewModelFactory
import com.adealink.weparty.module.account.comp.VerifyCodeComp
import com.adealink.weparty.viewmodel.parentFragmentViewModels
import com.tencent.qcloud.tuikit.timcommon.util.TextUtil
import kotlin.math.max
import com.adealink.weparty.R as APP_R

class InputVerifyFragment : BaseFragment(R.layout.fragment_join_us_step_1_input_verify) {


    private val binding by viewBinding(FragmentJoinUsStep1InputVerifyBinding::bind)
    private val step1ViewModel by parentFragmentViewModels<Step1ViewModel, JoinUsStep1Fragment>(
        JoinUsStep1Fragment::class.java
    )
    private val joinUsViewModel by activityViewModels<JoinUsViewModel> { JoinUsViewModelFactory() }
    override fun initViews() {
        super.initViews()
        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()
        fitWindow()
    }

    private fun fitWindow() {
        // 关键：只在需要的时候设置
        activity?.window?.fitSystemWindows(false)
        // 内容布局处理键盘
        val contentView = activity?.contentView() ?: return
        contentView.onWindowInsets { view, insets ->
            val ime = insets.getInsets(WindowInsetsCompat.Type.ime())

            // 键盘显示时使用键盘高度，否则使用导航栏高度
            val bottomInset = if (ime.bottom > 0) ime.bottom else 0
            view.updatePadding(bottom = bottomInset)
            insets
        }
    }

    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()
        step1ViewModel.verifyPhoneNumberLD.observe(viewLifecycleOwner) { number ->
            binding.tvDesc.text =
                getCompatString(APP_R.string.account_input_verify_code_desc, number)
        }
        step1ViewModel.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(
                    Step1ViewModel.lastSendVerifyCodeTs + Step1ViewModel.SEND_DURATION - System.currentTimeMillis(),
                    0
                ) / 1000
            resendCountDownS = countDown
            updateResendDuration()
            binding.tvResend.gone()
        }
    }

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

    private fun checkVerifyCode(verifyCode: String?) {
        val regionCode = step1ViewModel.verifyPhoneRegion
        val phoneNumber = step1ViewModel.verifyPhoneNumber
        if (regionCode.isNullOrEmpty() || phoneNumber.isNullOrEmpty() || verifyCode.isNullOrEmpty()) {
            return
        }
        showLoading()
        step1ViewModel.bindPhone(regionCode, phoneNumber, verifyCode)
            .observe(viewLifecycleOwner) { rlt ->
                dismissLoading()
                when (rlt) {
                    is Rlt.Failed -> {
                        showFailedToast(rlt)
                    }

                    is Rlt.Success -> {
                        joinUsViewModel.goStep(JoinUsStep.STEP_2)
                        joinUsViewModel.loadApplyProgress()
                    }
                }
            }
    }

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

}