package com.mobiuz.app.ui.auth.verification

import android.os.Bundle
import android.view.View
import android.view.animation.AnimationUtils
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 com.mobiuz.app.R
import com.mobiuz.app.databinding.FragmentVerificationBinding
import com.mobiuz.app.model.SharedPref
import com.mobiuz.app.model.UserAuth
import com.mobiuz.app.network.model.UiStateObject
import com.mobiuz.app.ui.auth.AuthViewModel
import com.mobiuz.app.ui.base.BaseFragment
import com.mobiuz.app.ui.global.ButtonClick
import com.mobiuz.app.ui.global.CONSTANTS
import com.mobiuz.app.ui.global.TextWatcherWrapper
import com.mobiuz.app.utils.Utils
import com.mobiuz.app.utils.extensions.showCustomDialog
import com.mobiuz.app.utils.hideKeyboard
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 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) ?: ""
        }
    }

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

    override fun setUpUI() {
        bn.apply {

            toolbar.setNavigationOnClickListener {
                navController.navigateUp()
            }

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

            lineField.addTextChangedListener(object : TextWatcherWrapper() {
                override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
                    super.onTextChanged(s, start, before, count)
                    btnLogin.isEnabled = (s.toString().length == 6)
                }
            })


            btnLogin.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 {
                count(true)
            }
            coutdownView.setOnCountdownEndListener {
                count(false)
            }
        }
    }

    private fun getLinePinCodes() {
        code = bn.lineField.text.toString()
    }

    override fun collects() {
        viewLifecycleOwner.lifecycleScope.launchWhenStarted {
            viewModel.verificationUiState.collect {
                when (it) {
                    is UiStateObject.SUCCESS -> {
                        showProgressDialog(false)
                        bn.helperLineField.isVisible = false
                        pref.userPhone = phone
                        navController.navigate(R.id.pinFragment, null, Utils.navOptions())
                    }
                    is UiStateObject.ERROR -> {
                        showProgressDialog(false)
                        bn.lineField.startAnimation(AnimationUtils.loadAnimation(requireContext(), R.anim.shake))
                        bn.helperLineField.isVisible = false
                        showCustomDialog(it.message, false) {}
                    }
                    is UiStateObject.ERRORS -> {
                        showProgressDialog(false)
                        it.errors.forEach {
                            if (it.key == "code") {
                                bn.helperLineField.isVisible = true
                                bn.helperLineField.text = it.message
                            } else bn.helperLineField.isVisible = false
                        }
                        bn.lineField.startAnimation(AnimationUtils.loadAnimation(requireContext(), R.anim.shake))
                    }
                    is UiStateObject.LOADING -> {
                        bn.helperLineField.isVisible = false
                        showProgressDialog(true)
                    }
                    else -> Unit
                }
            }
        }
        viewLifecycleOwner.lifecycleScope.launchWhenStarted {
            viewModel.checkResetCodeUiState.collect {
                when (it) {
                    is UiStateObject.SUCCESS -> {
                        showProgressDialog(false)
                        bn.helperLineField.isVisible = 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)
                        bn.lineField.startAnimation(AnimationUtils.loadAnimation(requireContext(), R.anim.shake))
                        bn.helperLineField.isVisible = false
                        showCustomDialog(it.message, false) {}
                    }
                    is UiStateObject.ERRORS -> {
                        showProgressDialog(false)
                        it.errors.forEach {
                            if (it.key == "code") {
                                bn.helperLineField.isVisible = true
                                bn.helperLineField.text = it.message
                            } else bn.helperLineField.isVisible = false
                        }
                        bn.lineField.startAnimation(AnimationUtils.loadAnimation(requireContext(), R.anim.shake))
                    }
                    is UiStateObject.LOADING -> {
                        bn.helperLineField.isVisible = false
                        showProgressDialog(true)
                    }
                    else -> Unit
                }
            }
        }
    }

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

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

}
