package com.adealink.weparty.module.widget.form.dialog

import android.annotation.SuppressLint
import android.text.Editable
import android.text.TextWatcher
import com.adealink.frame.aab.util.getCompatString
import com.adealink.frame.mvvm.view.viewBinding
import com.adealink.frame.util.onClick
import com.adealink.weparty.R
import com.adealink.weparty.commonui.ext.gone
import com.adealink.weparty.commonui.ext.show
import com.adealink.weparty.commonui.text.filter.addDecimalInputFilter
import com.adealink.weparty.commonui.toast.util.showToast
import com.adealink.weparty.commonui.widget.BottomDialogFragment
import com.adealink.weparty.databinding.WidgetDialogInputPriceBinding
import com.adealink.weparty.util.formatNumberStr

class PriceInputDialog : BottomDialogFragment(R.layout.widget_dialog_input_price) {

    private val binding by viewBinding(WidgetDialogInputPriceBinding::bind)

    private var title: String? = null
    private var desc: String? = null
    private var callback: IInputCallback? = null

    private var price: Double? = null

    private var minPrice: Double? = null
    private var maxPrice: Double? = null

    fun setTitle(title: String?) {
        this.title = title
    }

    fun setDesc(desc: String?) {
        this.desc = desc
    }

    fun setPrice(price: Double?) {
        this.price = price
    }

    fun setRange(min: Double?, max: Double?) {
        this.minPrice = min
        this.maxPrice = max
    }

    fun setCallback(callback: IInputCallback) {
        this.callback = callback
    }

    override fun initViews() {
        super.initViews()
        binding.tvTitle.text = title?.ifEmpty {
            getCompatString(R.string.common_input_price_title)
        } ?: getCompatString(R.string.common_input_price_title)

        if (desc.isNullOrEmpty()) {
            binding.tvDesc.gone()
        } else {
            binding.tvDesc.show()
            binding.tvDesc.text = desc
        }

        binding.etPriceInput.addDecimalInputFilter(
            maxValue = maxPrice ?: Double.MAX_VALUE,
            onInputTooMax = {
                showToast(
                    getCompatString(
                        R.string.common_input_number_max_limit,
                        (maxPrice ?: Double.MAX_VALUE).toString()
                    )
                )
            }
        )
        binding.etPriceInput.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
            ) {
            }

            @SuppressLint("SetTextI18n")
            override fun afterTextChanged(s: Editable?) {
                val input = s?.trim()?.toString()
                if (input.isNullOrEmpty()) {
                    binding.btnConfirm.isEnabled = false
                    binding.etPriceInput.hint =
                        getCompatString(R.string.common_input_price_hint)
                } else {
                    binding.btnConfirm.isEnabled = true
                    binding.etPriceInput.hint = null
                }
            }
        })
        binding.etPriceInput.setText(
            price?.let {
                formatNumberStr(it, false)
            }
        )
        binding.btnConfirm.isEnabled = price != null

        binding.btnConfirm.onClick {
            confirm()
        }
    }

    private fun confirm() {
        val price = binding.etPriceInput.text?.toString()?.toDoubleOrNull()
        if (price == null || price < 0) {
            showToast(R.string.common_input_price_invalid)
            return
        }
        val min = minPrice
        val max = maxPrice
        if ((min != null && price < min) || (max != null && price > max)) {
            showToast(
                getCompatString(
                    R.string.common_input_price_range_error,
                    formatNumberStr(min ?: 0.0, false),
                    formatNumberStr(max ?: 0.0, false)
                )
            )
            return
        }
        callback?.onInput(price)
        dismiss()
    }

    interface IInputCallback {
        fun onInput(price: Double)
    }

}