package uz.mobiuz.mobiservice.dev.ui.sdk.card

import android.os.Bundle
import android.text.method.DigitsKeyListener
import android.view.View
import android.view.inputmethod.EditorInfo
import androidx.core.os.bundleOf
import androidx.core.view.isVisible
import androidx.fragment.app.viewModels
import androidx.lifecycle.lifecycleScope
import androidx.navigation.NavController
import androidx.navigation.fragment.NavHostFragment
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.flow.collect
import uz.agr.sdk.core.entity.card.CardInfo
import uz.agr.sdk.coreui.extension.hideSoftInput
import uz.agr.sdk.coreui.extension.showSoftInput
import uz.agr.sdk.coreui.ui.ButtonClick
import uz.agr.sdk.coreui.ui.form.CardDateExpireFormat
import uz.agr.sdk.coreui.ui.form.CardNumberFormat
import uz.agr.sdk.mobi_uz.AGRBilling
import uz.agr.sdk.mobi_uz.CardListener
import uz.mobiuz.mobiservice.dev.R
import uz.mobiuz.mobiservice.dev.databinding.FragmentAddCardBinding
import uz.mobiuz.mobiservice.dev.model.SharedPref
import uz.mobiuz.mobiservice.dev.network.model.UiStateObject
import uz.mobiuz.mobiservice.dev.ui.base.BaseFragment
import uz.mobiuz.mobiservice.dev.ui.global.CONSTANTS
import uz.mobiuz.mobiservice.dev.utils.extensions.getColorCompat
import java.util.*
import javax.inject.Inject

@AndroidEntryPoint
class AddCardFragment : BaseFragment(R.layout.fragment_add_card) {

    @Inject
    lateinit var pref: SharedPref

    private var _bn: FragmentAddCardBinding? = null
    private val bn get() = _bn ?: throw NullPointerException("cannot inflate")
    private val viewModel: CardViewModel by viewModels()
    private val navController: NavController by lazy(LazyThreadSafetyMode.NONE) { NavHostFragment.findNavController(this) }

    private var cardNumberIsValid = false
    private var cardExpiryIsValid = false
    private var cardNumberValid: String? = null
    private var cardExpiryValid: String? = null

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        _bn = FragmentAddCardBinding.bind(view)

        setUpUI()
        collects()

    }

    override fun setUpUI() {
        bn.apply {
            toolbar.setNavigationOnClickListener {
                navController.navigateUp()
            }
            initInputCardNumber()
            initInputCardExpiry()

            btnContinue.setOnClickListener(object : ButtonClick() {
                override fun onSingleClick(v: View?) {
                    if (cardNumberValid != null && cardExpiryValid != null) {
                        AGRBilling.getAllCards(object : CardListener<CardInfo> {
                            override fun error(message: String) {}
                            override fun loading(boolean: Boolean) {
                                showProgressDialog(boolean)
                            }

                            override fun local(localData: List<CardInfo>) {}
                            override fun server(serverData: List<CardInfo>) {
                                val hash = AGRBilling.getHash(cardNumberValid!!, cardExpiryValid!!)
                                val filteredCards = serverData.filter { it.cardHash == hash }

                                if (filteredCards.isEmpty()) {
                                    viewModel.cardRegistration(pref.userPhone.filter { it.isDigit() }, cardNumberValid!!, cardExpiryValid!!)
                                } else {
                                    showToastMessage(getString(R.string.agr_mobi_uz_card_exist))
                                }
                            }
                        })
                    }
                }
            })
        }
    }


    override fun collects() {
        viewLifecycleOwner.lifecycleScope.launchWhenStarted {
            viewModel.cardRegistrationUiState.collect {
                when (it) {
                    is UiStateObject.SUCCESS -> {
                        showProgressDialog(false)
                        navController.navigate(
                            R.id.verificationFragment,
                            bundleOf(
                                CONSTANTS.TYPE_VERIFICATION to CONSTANTS.TYPE_ADD_CARD,
                                CONSTANTS.CARD_ID to it.data.cardId,
                                CONSTANTS.CARD_NUMBER to cardNumberValid,
                                CONSTANTS.CARD_EXPIRE to cardExpiryValid,
                            )
                        )

                    }
                    is UiStateObject.ERROR -> {
                        showProgressDialog(false)
                        showToastMessage("error:${it.message}")

                    }
                    is UiStateObject.LOADING -> {
                        showProgressDialog(true)
                    }
                    else -> Unit
                }
            }
        }


    }

    private fun initInputCardNumber() {
        bn.apply {

            etCardNumber.keyListener = DigitsKeyListener.getInstance("1234567890 ")
            etCardNumber.addTextChangedListener(CardNumberFormat { valid, number ->
                cardNumberIsValid = valid
                if (valid) {
                    etCardExpiry.requestFocus()
                    cardNumberValid = number
                }
                if (!(number.startsWith("8600") || number.startsWith("9860")) || number.filter { it.isDigit() }.length != 16) {
                    tvErrorMsg.isVisible = true
                    tvErrorMsg.text = getString(R.string.agr_mobi_uz_card_format_error)
                }
                if (valid) {
                    etCardNumber.setBackgroundResource(R.drawable.edit_text_unchecked)
                    etCardNumber.setTextColor(getColorCompat(R.color.black100))
                    tvErrorMsg.isVisible = false
                } else {
                    etCardNumber.setBackgroundResource(R.drawable.edit_text_error)
                    etCardNumber.setTextColor(getColorCompat(R.color.primary100))
                    tvErrorMsg.isVisible = true
                }
                checkValidForm()
            })
            activity?.showSoftInput(etCardNumber)
        }
    }

    private fun checkValidForm() {
        bn.apply {
            btnContinue.isEnabled = cardNumberIsValid && cardExpiryIsValid
            if (btnContinue.isEnabled) activity?.hideSoftInput()
        }

    }

    private fun initInputCardExpiry() {
        bn.apply {
            etCardExpiry.keyListener = DigitsKeyListener.getInstance("1234567890/")
            etCardExpiry.addTextChangedListener(CardDateExpireFormat { valid, date ->
                var checkValid = valid
                if (checkValid && date.length == 4) {
                    val calendar: Calendar = Calendar.getInstance()
                    val year = calendar.get(Calendar.YEAR).toString()
                    val currentMonth = calendar.get(Calendar.MONTH).toString().toInt() + 1
                    val inputMonth = date.substring(0, 2).toInt()
                    val inputYY = date.substring(2, 4).toInt()
                    val currentYY = year.substring(2, 4).toInt()
                    if (inputMonth > 12 || inputMonth == 0) checkValid = false
                    else if (inputYY < currentYY) checkValid = false
                    else if (inputYY == currentYY) {
                        if (inputMonth < currentMonth) checkValid = false
                    } else if (inputYY > currentYY && inputYY > currentYY + 5) checkValid = false
                }
                if (checkValid) {
                    cardExpiryValid = date
                    if (!cardNumberIsValid) {
                        etCardNumber.requestFocus()
                    }
                }
                cardExpiryIsValid = checkValid
                if (checkValid) {
                    etCardExpiry.setBackgroundResource(R.drawable.edit_text_unchecked)
                    etCardExpiry.setTextColor(getColorCompat(R.color.black100))
                    tvErrorMsgExpiry.isVisible = false
                } else {
                    etCardExpiry.setBackgroundResource(R.drawable.edit_text_error)
                    etCardExpiry.setTextColor(getColorCompat(R.color.primary100))
                    tvErrorMsgExpiry.isVisible = true
                }
                checkValidForm()
            })
            etCardExpiry.setOnEditorActionListener { _, actionId, _ ->
                if (actionId == EditorInfo.IME_ACTION_DONE) {
                    if (btnContinue.isEnabled) {
                        btnContinue.callOnClick()
                    }
                    !btnContinue.isEnabled
                } else false
            }
        }

    }

    override fun onDestroy() {
        _bn = null
        super.onDestroy()
    }
}