package com.adealink.weparty.wallet.recharge.dialog

import android.text.Editable
import android.text.TextWatcher
import androidx.fragment.app.activityViewModels
import com.adealink.frame.aab.util.getCompatString
import com.adealink.frame.base.Rlt
import com.adealink.frame.ext.isViewBindingValid
import com.adealink.frame.mvvm.view.viewBinding
import com.adealink.frame.util.onClick
import com.adealink.frame.util.removeUiCallbacks
import com.adealink.frame.util.runOnUiThread
import com.adealink.weparty.commonui.text.filter.addDecimalInputFilter
import com.adealink.weparty.commonui.text.watcher.AutoReplaceTextWatcher
import com.adealink.weparty.commonui.toast.util.showFailedToast
import com.adealink.weparty.commonui.toast.util.showToast
import com.adealink.weparty.commonui.widget.BottomDialogFragment
import com.adealink.weparty.module.wallet.data.Currency
import com.adealink.weparty.util.QMUIKeyboardHelper
import com.adealink.weparty.util.formatNumberStr
import com.adealink.weparty.wallet.R
import com.adealink.weparty.wallet.databinding.DialogConvertCurrencyBinding
import com.adealink.weparty.wallet.viewmodel.WalletViewModel
import com.adealink.weparty.wallet.viewmodel.WalletViewModelFactory
import com.adealink.weparty.R as APP_R

class ConvertCurrencyDialog : BottomDialogFragment(R.layout.dialog_convert_currency) {

    var fromCurrency: Currency = Currency.COIN
    var toCurrency: Currency = Currency.DIAMOND

    //    private var exchangeRatio: Double? = null
    private var maxExchangeInput: Double? = null

    private var inputExchange: Double? = null

    private val binding by viewBinding(DialogConvertCurrencyBinding::bind)

    private val walletViewModel by activityViewModels<WalletViewModel> { WalletViewModelFactory() }

    private var inputTextWatcher: AutoReplaceTextWatcher? = null

    override fun initViews() {
        super.initViews()
        binding.tvTitle.text =
            getCompatString(R.string.wallet_convert_currency_title, toCurrency.desc())
        binding.btnClose.onClick {
            dismiss()
        }

        when (fromCurrency) {
            Currency.COIN -> {
                binding.tvFromCurrency.text = getCompatString(R.string.wallet_convert_from_coin)
                binding.ivFromCurrency.setImageResource(APP_R.drawable.common_wallet_coin_ic)
                binding.ivFromCurrencyAmount.setImageResource(APP_R.drawable.common_wallet_coin_ic)
            }

            Currency.DIAMOND -> {
                binding.tvFromCurrency.text = getCompatString(R.string.wallet_convert_from_diamond)
                binding.ivFromCurrency.setImageResource(APP_R.drawable.common_wallet_diamond_ic)
                binding.ivFromCurrencyAmount.setImageResource(APP_R.drawable.common_wallet_diamond_ic)
            }

            Currency.BEAN -> {
                binding.tvFromCurrency.text = getCompatString(R.string.wallet_convert_from_bean)
                binding.ivFromCurrency.setImageResource(APP_R.drawable.common_wallet_bean_ic)
                binding.ivFromCurrencyAmount.setImageResource(APP_R.drawable.common_wallet_bean_ic)
            }
        }

        when (toCurrency) {
            Currency.COIN -> {
                binding.tvToCurrency.text = getCompatString(R.string.wallet_convert_to_coin)
                binding.ivToCurrencyAmount.setImageResource(APP_R.drawable.common_wallet_coin_ic)
            }

            Currency.DIAMOND -> {
                binding.tvToCurrency.text = getCompatString(R.string.wallet_convert_to_diamond)
                binding.ivToCurrencyAmount.setImageResource(APP_R.drawable.common_wallet_diamond_ic)
            }

            Currency.BEAN -> {
                binding.tvToCurrency.text = getCompatString(R.string.wallet_convert_to_bean)
                binding.ivToCurrencyAmount.setImageResource(APP_R.drawable.common_wallet_diamond_ic)
            }
        }

        binding.btnAllConvert.onClick {
            allExchanged()
        }
        binding.clFromDetail.onClick {
            if (binding.etFromCurrencyAmount.isEnabled) {
                QMUIKeyboardHelper.showKeyboard(binding.etFromCurrencyAmount, 50)
                binding.etFromCurrencyAmount.requestFocus()
            }
        }

        binding.etFromCurrencyAmount.isEnabled = false
        binding.btnExchange.onClick {
            confirmExchange()
        }
    }

    override fun observeViewModel() {
        super.observeViewModel()
        when (fromCurrency) {
            Currency.BEAN -> {
                walletViewModel.availableBeanLD.observe(viewLifecycleOwner) {
                    maxExchangeInput = it
                    binding.tvCurrentCurrency.text = formatNumberStr(it, false)
                    initInputText(it)
                    notifyExchangeStateChanged()
                }
            }

            Currency.COIN -> {
                walletViewModel.coinLD.observe(viewLifecycleOwner) {
                    maxExchangeInput = it
                    binding.tvCurrentCurrency.text = formatNumberStr(it, false)
                    initInputText(it)
                    notifyExchangeStateChanged()
                }
            }

            Currency.DIAMOND -> {
                walletViewModel.diamondLD.observe(viewLifecycleOwner) {
                    maxExchangeInput = it
                    binding.tvCurrentCurrency.text = formatNumberStr(it, false)
                    initInputText(it)
                    notifyExchangeStateChanged()
                }
            }
        }
    }

    private fun initInputText(maxValue: Double) {
        binding.etFromCurrencyAmount.addDecimalInputFilter(
            maxValue = maxValue,
            onInputTooMax = {
                showToast(
                    getCompatString(
                        APP_R.string.common_input_number_max_limit,
                        maxValue.toString()
                    )
                )
            }
        )
        binding.etFromCurrencyAmount.addTextChangedListener(object : TextWatcher {
            override fun beforeTextChanged(
                s: CharSequence?,
                start: Int,
                count: Int,
                after: Int
            ) {
            }

            override fun onTextChanged(
                s: CharSequence?,
                start: Int,
                before: Int,
                count: Int
            ) {
            }

            override fun afterTextChanged(s: Editable?) {
                val inputString = s?.toString()
                if (inputString.isNullOrEmpty()) {
                    binding.etFromCurrencyAmount.hint =
                        getCompatString(R.string.wallet_convert_please_fill)
                } else {
                    binding.etFromCurrencyAmount.hint = null
                }
                notifyInputChanged(inputString?.toDoubleOrNull() ?: 0.0)
            }
        })

//        binding.etFromCurrencyAmount.filters = arrayOf(
//            SimplePositiveDecimalFilter(maxValue)
//        )
//        inputTextWatcher?.let {
//            binding.etFromCurrencyAmount.removeTextChangedListener(it)
//        }
//        inputTextWatcher = AutoReplaceTextWatcher(
//            maxValue, 2,
//            setSelection = {
//                binding.etFromCurrencyAmount.setSelection(it)
//            },
//            afterTextChanged = {
//                if (it.isEmpty()) {
//                    binding.etFromCurrencyAmount.hint =
//                        getCompatString(R.string.wallet_convert_please_fill)
//                } else {
//                    binding.etFromCurrencyAmount.hint = null
//                }
//                notifyInputChanged(it.toDoubleOrNull() ?: 0.0)
//            }
//        ).also {
//            binding.etFromCurrencyAmount.addTextChangedListener(it)
//        }

    }

    override fun loadData() {
        super.loadData()
        walletViewModel.refreshWalletData()
//        walletViewModel.loadConvertConfig(fromCurrency, toCurrency)
//            .observe(viewLifecycleOwner) { rlt ->
//                when (rlt) {
//                    is Rlt.Failed -> {
//                        showFailedToast(rlt)
//                        exchangeRatio = null
//                        notifyExchangeStateChanged()
//                    }
//
//                    is Rlt.Success -> {
//                        exchangeRatio = rlt.data
//                        notifyExchangeStateChanged()
//                    }
//                }
//            }
    }

    private fun notifyExchangeStateChanged() {
//        if (exchangeRatio == null || maxExchangeInput == null) {
//            binding.etFromCurrencyAmount.isEnabled = false
//        } else {
//            binding.etFromCurrencyAmount.isEnabled = true
//        }
        if (maxExchangeInput == null) {
            binding.etFromCurrencyAmount.isEnabled = false
        } else {
            binding.etFromCurrencyAmount.isEnabled = true
        }
    }

    private val preConvertRunnable = object : Runnable {
        override fun run() {
            if (!isViewBindingValid()) {
                return
            }
            val inputNumber = inputExchange
            if (inputNumber == null || inputNumber <= 0) {
                binding.tvToCurrencyAmount.text = formatNumberStr(0, false)
                return
            }
            walletViewModel.preConvert(fromCurrency, toCurrency, inputNumber)
                .observe(viewLifecycleOwner) { rlt ->
                    when (rlt) {
                        is Rlt.Failed -> {
                            showFailedToast(rlt)
                        }

                        is Rlt.Success -> {
                            if (rlt.data.first != inputExchange) {
                                return@observe
                            }
                            binding.tvToCurrencyAmount.text =
                                formatNumberStr(rlt.data.second, false)
                        }
                    }
                }
        }

    }

    private fun notifyInputChanged(inputNumber: Double) {
        if (inputExchange == inputNumber) {
            return
        }
        inputExchange = inputNumber
        if (inputNumber <= 0) {
            removeUiCallbacks(preConvertRunnable)
            binding.tvToCurrencyAmount.text = formatNumberStr(0, false)
        } else {
            removeUiCallbacks(preConvertRunnable)
            runOnUiThread(preConvertRunnable, 500)
        }
//        val ratio = exchangeRatio
//        if (ratio == null || ratio == 0.0) {
//            binding.tvToCurrencyAmount.text = formatNumberStr(0.0, false)
//            return
//        }
//        binding.tvToCurrencyAmount.text = formatNumberStr(inputNumber / ratio, false)
    }

    private fun allExchanged() {
        binding.etFromCurrencyAmount.setText(
            maxExchangeInput?.toString()
        )
    }

    private fun confirmExchange() {
        val amount = inputExchange ?: return
        showLoading()
        walletViewModel.convertTo(fromCurrency, toCurrency, amount)
            .observe(viewLifecycleOwner) { rlt ->
                dismissLoading()
                when (rlt) {
                    is Rlt.Failed -> {
                        showFailedToast(rlt)
                    }

                    is Rlt.Success -> {
                        dismiss()
                    }
                }
            }
    }

    override fun onDestroy() {
        super.onDestroy()
        removeUiCallbacks(preConvertRunnable)
    }


}