package uz.mobiuz.mobiservice.dev.ui.auth.verification

import android.os.Bundle
import android.view.KeyEvent
import android.view.View
import android.view.animation.AnimationUtils
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 com.google.android.material.textfield.TextInputEditText
import uz.mobiuz.mobiservice.dev.R
import uz.mobiuz.mobiservice.dev.databinding.FragmentVerificationBinding
import uz.mobiuz.mobiservice.dev.model.SharedPref
import uz.mobiuz.mobiservice.dev.model.UserAuth
import uz.mobiuz.mobiservice.dev.network.model.UiStateObject
import uz.mobiuz.mobiservice.dev.ui.auth.AuthViewModel
import uz.mobiuz.mobiservice.dev.ui.base.BaseFragment
import uz.mobiuz.mobiservice.dev.ui.global.ButtonClick
import uz.mobiuz.mobiservice.dev.ui.global.CONSTANTS
import uz.mobiuz.mobiservice.dev.ui.global.TextWatcherWrapper
import uz.mobiuz.mobiservice.dev.utils.Utils
import uz.mobiuz.mobiservice.dev.utils.extensions.clearText
import uz.mobiuz.mobiservice.dev.utils.extensions.getColorCompat
import uz.mobiuz.mobiservice.dev.utils.extensions.isEmpty
import uz.mobiuz.mobiservice.dev.utils.extensions.isNotEmpty
import uz.mobiuz.mobiservice.dev.utils.hideKeyboard
import uz.mobiuz.mobiservice.dev.utils.showKeyboard
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.flow.collect
import javax.inject.Inject


@AndroidEntryPoint
class VerificationFragment : BaseFragment(R.layout.fragment_verification) {


    @Inject
    lateinit var pref: SharedPref

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


    private var phone = ""
    private var type = ""

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        arguments?.let {
            phone = it.getString(CONSTANTS.PHONE) ?: ""
            type = it.getString(CONSTANTS.TYPE_VERIFICATION) ?: ""
            verificationCode = it.getString(CONSTANTS.PIN_CODE) ?: ""
        }
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        _bn = FragmentVerificationBinding.bind(view)
        setUpUI()
        count(true)
        collects()
    }

    override fun setUpUI() {
        bn.apply {

            toolbar.setNavigationOnClickListener {
                navController.navigateUp()
            }

            loadEdited()

            viewGroup.setOnClickListener(object : ButtonClick() {
                override fun onSingleClick(v: View?) {
                    v?.hideKeyboard()
                }
            })

            frame.setOnClickListener(object : ButtonClick() {
                override fun onSingleClick(v: View?) {
                    checkFocus().showKeyboard()
                    setColorPins(getColorCompat(R.color.black100))
                }
            })
            btnVerification.setOnClickListener(object : ButtonClick() {
                override fun onSingleClick(v: View?) {
                    getLinePinCodes()
                    val auth = UserAuth(phone.replace("+", "").replace(" ", ""), null, code)
                    if (type == CONSTANTS.TYPE_FORGET) {
                        viewModel.checkResetCode(auth)
                    } else {
                        viewModel.verification(auth)
                    }

                }
            })

            sentCodeAgain.setOnClickListener {
                viewModel.resetSmsCode(UserAuth(phone.replace("+", "").replace(" ", "")))
            }
            coutdownView.setOnCountdownEndListener {
                count(false)
            }
//            setVerificationCode()
        }
    }

    private fun setVerificationCode() {
        if(verificationCode.length == 6){
            bn.apply {
                pin1.setText(verificationCode[0].toString())
                pin2.setText(verificationCode[1].toString())
                pin3.setText(verificationCode[2].toString())
                pin4.setText(verificationCode[3].toString())
                pin5.setText(verificationCode[4].toString())
                pin6.setText(verificationCode[5].toString())
                pin6.requestFocus()
                btnVerification.isEnabled = true
            }
        }
    }

    private fun getLinePinCodes() {
        bn.apply {
            code = ""
            code += pin1.text.toString()
            code += pin2.text.toString()
            code += pin3.text.toString()
            code += pin4.text.toString()
            code += pin5.text.toString()
            code += pin6.text.toString()
        }
    }

    private fun setColorPins(color: Int) {
        bn.apply {
            pin1.setTextColor(color)
            pin2.setTextColor(color)
            pin3.setTextColor(color)
            pin4.setTextColor(color)
            pin5.setTextColor(color)
            pin6.setTextColor(color)
        }
    }

    private fun checkFocus(): View {
        bn.apply {
            return when {
                pin1.isEmpty() -> pin1
                pin2.isEmpty() -> pin2
                pin3.isEmpty() -> pin3
                pin4.isEmpty() -> pin4
                pin5.isEmpty() -> pin5
                else -> pin6
            }
        }
    }

    private fun clearLatest(): View {
        bn.apply {
            return when {
                pin6.isNotEmpty() -> pin6.clearText()
                pin5.isNotEmpty() -> pin5.clearText()
                pin4.isNotEmpty() -> pin4.clearText()
                pin3.isNotEmpty() -> pin3.clearText()
                pin2.isNotEmpty() -> pin2.clearText()
                else -> pin1.clearText()
            }
        }
    }

    private fun loadEdited() {
        bn.apply {
            for (i in 0 until pinView.childCount) {
                (pinView.getChildAt(i) as TextInputEditText).apply {
                    this.addTextChangedListener(object : TextWatcherWrapper() {
                        override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
                            super.onTextChanged(s, start, before, count)
                            bn.txtErrorCode.isVisible = false
                            if (s.toString().isNotEmpty()) {
                                if (i == pinView.childCount - 1) {
                                    pin6.hideKeyboard()
                                    btnVerification.isEnabled = true
                                } else pinView.getChildAt(i + 1).requestFocus()
                                this@apply.setBackgroundResource(R.drawable.bgn_ver_checked)
                            } else {
                                if (i == pinView.childCount - 1) {
                                    btnVerification.isEnabled = false
                                }
                                this@apply.setBackgroundResource(R.drawable.bgn_ver_unchecked)
                            }
                        }
                    })
                }
            }
            for (i in 0 until pinView.childCount) {
                pinView.getChildAt(i).setOnKeyListener { _, keyCode, event ->
                    if (event.action == KeyEvent.ACTION_DOWN && keyCode == KeyEvent.KEYCODE_DEL) {
                        clearLatest().requestFocus()
                        return@setOnKeyListener false
                    }
                    false
                }
            }
        }
    }

    override fun collects() {
        viewLifecycleOwner.lifecycleScope.launchWhenStarted {
            viewModel.verificationUiState.collect {
                when (it) {
                    is UiStateObject.SUCCESS -> {
                        showProgressDialog(false)
                        pref.userPhone = phone
                        navController.navigate(R.id.installPinFragment, bundleOf(CONSTANTS.TYPE_PIN  to CONSTANTS.NEW_PIN), Utils.navOptions())
                    }
                    is UiStateObject.ERROR -> {
                        showProgressDialog(false)
                        setColorPins(getColorCompat(R.color.primary100))
                        bn.txtErrorCode.isVisible = true
                        bn.pinView.startAnimation(AnimationUtils.loadAnimation(requireContext(), R.anim.shake))
                        showToastMessage(it.message)
                    }

                    is UiStateObject.LOADING -> {
                        showProgressDialog(true)
                    }
                    else -> Unit
                }
            }
        }
        viewLifecycleOwner.lifecycleScope.launchWhenStarted {
            viewModel.resetSmsCodeUiState.collect {
                when (it) {
                    is UiStateObject.SUCCESS -> {
//                        showToastMessage(it.data)
//                        verificationCode = it.data
//                        setVerificationCode()
                        count(true)
                        showProgressDialog(false)
                    }
                    is UiStateObject.ERROR -> {
                        showProgressDialog(false)
                        showToastMessage(it.message)
                    }

                    is UiStateObject.LOADING -> {
                        showProgressDialog(true)
                    }
                    else -> Unit
                }
            }
        }
        viewLifecycleOwner.lifecycleScope.launchWhenStarted {
            viewModel.checkResetCodeUiState.collect {
                when (it) {
                    is UiStateObject.SUCCESS -> {
                        showProgressDialog(false)
                        pref.userPhone = phone
                        navController.navigate(
                            R.id.registerFragment,
                            bundleOf(
                                CONSTANTS.PHONE to phone,
                                CONSTANTS.TYPE_VERIFICATION to CONSTANTS.TYPE_FORGET,
                                CONSTANTS.PIN_CODE to code,
                            ),
                            Utils.navOptions()
                        )
                    }
                    is UiStateObject.ERROR -> {
                        showProgressDialog(false)
                        setColorPins(getColorCompat(R.color.primary100))
                        bn.pinView.startAnimation(AnimationUtils.loadAnimation(requireContext(), R.anim.shake))
                        showToastMessage(it.message)
                    }
                    is UiStateObject.LOADING -> {
                        showProgressDialog(true)
                    }
                    else -> Unit
                }
            }
        }
    }

    private fun count(status: Boolean) {
        bn.apply {
            sentCodeAgain.isVisible = !status
            coutdownViewHelperText.isVisible = !status
            coutdownView.isVisible = status
            if (status) coutdownView.start(CONSTANTS.RESEND_CODE_TIME)
        }
    }

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

}
