package com.abbidot.tracker.ui.activity.subscribe

import android.text.InputFilter
import android.text.InputFilter.LengthFilter
import android.text.InputType
import android.text.TextUtils
import android.view.View
import android.view.View.OnFocusChangeListener
import androidx.appcompat.widget.AppCompatEditText
import androidx.core.widget.addTextChangedListener
import androidx.lifecycle.lifecycleScope
import com.abbidot.baselibrary.constant.ResultCode
import com.abbidot.baselibrary.util.AppUtils
import com.abbidot.tracker.R
import com.abbidot.tracker.base.BaseActivity
import com.abbidot.tracker.base.BaseDialog
import com.abbidot.tracker.bean.CreditCardBean
import com.abbidot.tracker.constant.ConstantString
import com.abbidot.tracker.database.MyDatabase
import com.abbidot.tracker.databinding.ActivityAddCreditCardPaymentBinding
import com.abbidot.tracker.util.Util
import com.abbidot.tracker.util.ViewUtil
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch


class AddCreditCardPaymentActivity :
    BaseActivity<ActivityAddCreditCardPaymentBinding>(ActivityAddCreditCardPaymentBinding::inflate),
    OnFocusChangeListener {

    private var mCreditCard: CreditCardBean? = null
    private var mOldCard: CreditCardBean? = null
    private var isEdit = false

    override fun getTopBar() = mViewBinding.ilAddPaymentMethodTopInfo.titleTopBar

    override fun initData() {
        super.initData()
        intent.extras?.apply {
            mCreditCard = Util.getParcelableAdaptive(
                intent, ConstantString.Card, CreditCardBean::class.java
            )
            isEdit = getBoolean(ConstantString.Edit, false)
        }
        if (null == mCreditCard) mCreditCard = CreditCardBean()

        if (isEdit) {
            mOldCard = mCreditCard
            setTopBarTitle(R.string.txt_edit_pay_method)
            mRightImageButton = addRightImageButton(R.drawable.icon_delete_svg)
        } else {
            setTopBarTitle(R.string.txt_add_payment)
        }
        setLeftBackImage(R.drawable.icon_white_back_svg)

        mViewBinding.apply {

            ilAddCardNameOnCard.let {
                it.tvInputView2NameTitle.setText(R.string.txt_name_card)
                it.etInputView2Content.setFilters(arrayOf<InputFilter>(InputFilter.AllCaps()))
                it.etInputView2Content.onFocusChangeListener = this@AddCreditCardPaymentActivity
                showEditViewContent(it.etInputView2Content, mCreditCard!!.cardName)
            }

            ilAddCardNumber.let {
                it.tvInputView2NameTitle.setText(R.string.txt_card_number)
                it.etInputView2Content.let { cardText ->
                    cardText.filters = arrayOf<InputFilter>(LengthFilter(24))
                    cardText.compoundDrawablePadding = AppUtils.dpToPx(6)
                    cardText.inputType = InputType.TYPE_CLASS_NUMBER
                    cardText.onFocusChangeListener = this@AddCreditCardPaymentActivity
                    cardText.addTextChangedListener { numberStr ->
                        numberStr?.apply {
                            val formatCardNumber = Util.formatCardNumber(numberStr.toString())
                            if (formatCardNumber.length > numberStr.length) {
                                cardText.setText(formatCardNumber)
                                // 设置光标位置
                                cardText.setSelection(formatCardNumber.length)
                            }
                            val cardLogoImageId =
                                Util.getCreditCardType(numberStr.toString().replace(" ", ""))
                            if (cardLogoImageId == 0) {
                                cardText.setCompoundDrawablesWithIntrinsicBounds(
                                    0, 0, 0, 0
                                )
                            } else {
                                cardText.setCompoundDrawablesWithIntrinsicBounds(
                                    cardLogoImageId, 0, 0, 0
                                )
                            }
                        }
                    }
                }
                showEditViewContent(it.etInputView2Content, mCreditCard!!.cardNumber)
            }
            etAddCardMmDdContent.let {
                it.onFocusChangeListener = this@AddCreditCardPaymentActivity
                it.addTextChangedListener { cardExpiry ->
                    formatCardExpiry(cardExpiry.toString())
                }
                showEditViewContent(it, mCreditCard!!.expirationDate)
            }
            etAddCardCvcContent.let {
                it.onFocusChangeListener = this@AddCreditCardPaymentActivity
                showEditViewContent(it, mCreditCard!!.cvv)
            }
            cbAddCardSetPrimarySwitch.isChecked = mCreditCard!!.isPrimary

            setOnClickListenerViews(
                btnSaveNewCreditCard,
                ilAddCardNameOnCard.root,
                ilAddCardNumber.root,
                llAddCardCvcLayout,
                llAddCardMmDdLayout
            )
        }
    }

    /**
     * 编辑时显示还原内容
     */
    private fun showEditViewContent(editText: AppCompatEditText, content: String) {
        if (TextUtils.isEmpty(content)) return
        editText.apply {
            visibility = View.VISIBLE
            setText(content)
        }
    }

    /**
     * 格式化有效期
     */
    private fun formatCardExpiry(cardExpiry: String) {
        var formatCardExpiry = cardExpiry
        val separator = "/"
        if (formatCardExpiry.length == 3) {
            formatCardExpiry = if (formatCardExpiry.contains(separator)) {
                cardExpiry.substring(0, 2)
            } else {
                cardExpiry.substring(0, 2) + separator + cardExpiry.last()
            }
            mViewBinding.etAddCardMmDdContent.apply {
                setText(formatCardExpiry)
                setSelection(formatCardExpiry.length)
            }
        }
    }

    /**
     * 点击输入框并显示
     */
    private fun setClickEditViewVisible(editText: AppCompatEditText) {
        editText.apply {
            visibility = View.VISIBLE
            requestFocus()
            //弹出软键盘
            showInputMethod(this)
        }
    }

    /**
     * 输入框失去焦点隐藏
     */
    private fun setEditViewNoFocusHide(editText: AppCompatEditText, hasFocus: Boolean) {
        editText.apply {
            val content = text.toString()
            if (!hasFocus) {
                if (TextUtils.isEmpty(content)) visibility = View.GONE
            }
        }
    }

    override fun listenHideKeyboard() {
        mViewBinding.apply {
            setEditViewNoFocusHide(etAddCardCvcContent, false)
            setEditViewNoFocusHide(etAddCardMmDdContent, false)
            setEditViewNoFocusHide(ilAddCardNameOnCard.etInputView2Content, false)
            setEditViewNoFocusHide(ilAddCardNumber.etInputView2Content, false)
        }
    }

    private fun confirmSaveCard() {
        val cardNumber =
            mViewBinding.ilAddCardNumber.etInputView2Content.text.toString().replace(" ", "")
        val cardName = mViewBinding.ilAddCardNameOnCard.etInputView2Content.text.toString()
        val creditCardValidity = mViewBinding.etAddCardMmDdContent.text.toString()
        val cvv = mViewBinding.etAddCardCvcContent.text.toString()

        if (TextUtils.isEmpty(cardNumber) || TextUtils.isEmpty(cardName) || TextUtils.isEmpty(
                creditCardValidity
            ) || TextUtils.isEmpty(cvv)
        ) {
            showToast(R.string.txt_not_null)
            return
        }

        if (!creditCardValidity.contains("/")) {
            showToast(R.string.txt_card_validity_format)
            return
        } else {
            val dates = creditCardValidity.split("/")
            try {
                if (dates[0].toInt() > 12) {
                    showToast(R.string.txt_card_validity_format)
                    return
                }
            } catch (e: Exception) {
                showToast(R.string.txt_card_validity_format)
                return
            }
        }
        if (Util.getCreditCardType(cardNumber) == 0 || cardNumber.length < 9) {
            showToast(R.string.txt_card_number_format)
            return
        }

        lifecycleScope.launch(Dispatchers.IO) {

            val list = MyDatabase.creditCardDao().findAll(MyDatabase.CREDIT_CARD_TABLE)
            var existCard: CreditCardBean? = null
            list?.apply {
                if (isNotEmpty()) {
                    for (c in list) {
                        if (!isEdit && c.cardNumber == cardNumber) {
                            existCard = c
                            break
                        } else if (isEdit && null != mOldCard && c.cardNumber == mOldCard!!.cardNumber) {
                            existCard = c
                            break
                        }
                    }
                }
            }
            if (isEdit) {
                existCard?.let {
                    it.cardName = cardName
                    it.cardNumber = cardNumber
                    it.expirationDate = creditCardValidity
                    it.cvv = cvv
                    it.isPrimary = mViewBinding.cbAddCardSetPrimarySwitch.isChecked
                    if (null != mOldCard && mOldCard!!.cardNumber != cardNumber) {
                        MyDatabase.creditCardDao().delete(mOldCard!!)
                    }
                    saveCard(list)
                }
            } else {
                if (null != existCard) {
                    launch(Dispatchers.Main) {
                        ViewUtil.instance.showDialog(
                            mContext,
                            R.string.txt_credit_card_exists,
                            object : BaseDialog.OnDialogOkListener {
                                override fun onOkClick(dialog: BaseDialog<*>) {
                                    dialog.dismiss()
                                    lifecycleScope.launch(Dispatchers.IO) {
                                        saveCard(list)
                                    }
                                }
                            },
                            okTextResId = R.string.start_txt_yes,
                            cancelTextResId = R.string.txt_no
                        )
                    }
                } else saveCard(list)
            }
        }
    }

    /**
     * 保存信用卡
     */
    private fun saveCard(list: List<CreditCardBean>?) {
        mViewBinding.apply {
            val cardNumber = ilAddCardNumber.etInputView2Content.text.toString().replace(" ", "")
            val cardName = ilAddCardNameOnCard.etInputView2Content.text.toString()
            val creditCardValidity = etAddCardMmDdContent.text.toString()
            val cvv = etAddCardCvcContent.text.toString()
            if (cbAddCardSetPrimarySwitch.isChecked) {
                mCreditCard?.isPrimary = true
                list?.apply {
                    if (isNotEmpty()) {
                        for (c in list) {
                            if (c.isPrimary) {
                                c.isPrimary = false
                                MyDatabase.creditCardDao().update(c)
                            }
                        }
                    }
                }
            }

            mCreditCard?.let {
                if (isEdit) {
                    list?.apply {
                        if (isNotEmpty()) {
                            for (c in list) {
                                //因卡号唯一，编辑卡号删除存在的信用卡
                                if (c.cardNumber == it.cardNumber) {
                                    MyDatabase.creditCardDao().delete(c)
                                }
                            }
                        }
                    }
                }
                it.cardNumber = cardNumber
                it.cardName = cardName
                it.expirationDate = creditCardValidity
                it.cvv = cvv
                MyDatabase.creditCardDao().insert(it)
            }

            runOnUiThread {
//                val intent = Intent()
//                intent.putExtra(ConstantString.Card, mCreditCard)
                setResult(ResultCode.ResultCode_1, null)
                showToast(R.string.txt_save_successful, isFinish = true)
            }
        }
    }

    private fun deleteCard() {
        ViewUtil.instance.showDialog(
            mContext, R.string.txt_sure_delete_card, object : BaseDialog.OnDialogOkListener {
                override fun onOkClick(dialog: BaseDialog<*>) {
                    lifecycleScope.launch(Dispatchers.IO) {
                        mCreditCard?.apply {
                            MyDatabase.creditCardDao().delete(this)
                        }
                    }
                    dialog.dismiss()
                    setResult(ResultCode.ResultCode_1, null)
                    showToast(R.string.txt_delete_succe, isFinish = true)
                }
            }, okTextResId = R.string.start_txt_yes
        )
    }

    override fun onClick(v: View?) {
        mViewBinding.apply {
            when (v!!) {
                btnSaveNewCreditCard -> confirmSaveCard()
                llAddCardMmDdLayout -> setClickEditViewVisible(etAddCardMmDdContent)
                llAddCardCvcLayout -> setClickEditViewVisible(etAddCardCvcContent)
                ilAddCardNameOnCard.root -> setClickEditViewVisible(ilAddCardNameOnCard.etInputView2Content)
                ilAddCardNumber.root -> setClickEditViewVisible(ilAddCardNumber.etInputView2Content)
                mRightImageButton -> deleteCard()
            }
        }
    }

    override fun onFocusChange(v: View?, hasFocus: Boolean) {
        mViewBinding.apply {
            when (v!!) {
                ilAddCardNameOnCard.etInputView2Content -> {
                    setEditViewNoFocusHide(ilAddCardNameOnCard.etInputView2Content, hasFocus)
                }

                ilAddCardNumber.etInputView2Content -> {
                    setEditViewNoFocusHide(ilAddCardNumber.etInputView2Content, hasFocus)
                }

                etAddCardMmDdContent -> {
                    setEditViewNoFocusHide(etAddCardMmDdContent, hasFocus)
                }

                etAddCardCvcContent -> {
                    setEditViewNoFocusHide(etAddCardCvcContent, hasFocus)
                }
            }
        }
    }
}