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

import android.os.Bundle
import android.text.method.DigitsKeyListener
import android.util.Log
import android.view.View
import android.view.inputmethod.EditorInfo
import androidx.core.os.bundleOf
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.mobiuz.ui.fast_action.animation.getColorCompat
import uz.agr.sdk.core.entity.card.CardRegistration
import uz.agr.sdk.coreui.extension.hideSoftInput
import uz.agr.sdk.coreui.extension.showSoftInput
import uz.agr.sdk.coreui.extension.visible
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.pgw_core.mobi.BaseListener
import uz.agr.sdk.pgw_core.mobi.MobiUz
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 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) {
                        viewModel.cardRegistration(pref.userPhone.filter { it.isDigit() }, cardNumberValid!!, cardExpiryValid!!)
                    }
                }
            })
        }

    }


    override fun collects() {
        viewLifecycleOwner.lifecycleScope.launchWhenStarted {
            viewModel.cardRegistrationUiState.collect {
                when (it) {
                    is UiStateObject.SUCCESS -> {
                        showProgressDialog(false)
                        showToastMessage("success:${it.data.maskedPhoneNumber}")
                        navController.navigate(R.id.cardConfirmFragment, bundleOf(CONSTANTS.CARD_ID to it.data.cardId))

                    }
                    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.visible(true)
                    tvErrorMsg.text = getString(uz.agr.mobiuz.R.string.agr_mobi_uz_card_format_error)
                }
                if (valid) {
                    etCardNumber.setBackgroundResource(uz.agr.mobiuz.R.drawable.agr_edit_text_unchecked)
                    etCardNumber.setTextColor(getColorCompat(uz.agr.mobiuz.R.color.agr_text_color))
                    tvErrorMsg.visible(false)
                } else {
                    etCardNumber.setBackgroundResource(uz.agr.mobiuz.R.drawable.agr_edit_text_error)
                    etCardNumber.setTextColor(getColorCompat(uz.agr.mobiuz.R.color.primary100))
                    tvErrorMsg.visible(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(uz.agr.mobiuz.R.drawable.agr_edit_text_unchecked)
                    etCardExpiry.setTextColor(getColorCompat(uz.agr.mobiuz.R.color.agr_text_color))
                    tvErrorMsgExpiry.visible(false)
                } else {
                    etCardExpiry.setBackgroundResource(uz.agr.mobiuz.R.drawable.agr_edit_text_error)
                    etCardExpiry.setTextColor(getColorCompat(uz.agr.mobiuz.R.color.primary100))
                    tvErrorMsgExpiry.visible(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()
    }
}