package com.mobiuz.app.dev.ui.auth.pin

import android.content.Intent
import android.graphics.Color
import android.os.Bundle
import android.view.View
import android.view.animation.AnimationUtils
import android.widget.TextView
import androidx.core.hardware.fingerprint.FingerprintManagerCompat
import androidx.core.os.bundleOf
import androidx.core.view.isVisible
import androidx.lifecycle.lifecycleScope
import androidx.navigation.NavController
import androidx.navigation.fragment.NavHostFragment
import androidx.recyclerview.widget.LinearLayoutManager
import co.infinum.goldfinger.Goldfinger
import com.mobiuz.app.R
import com.mobiuz.app.databinding.FragmentPinBinding
import com.mobiuz.app.dev.MainActivity
import com.mobiuz.app.dev.model.PinData
import com.mobiuz.app.dev.model.SharedPref
import com.mobiuz.app.dev.ui.auth.AuthActivity
import com.mobiuz.app.dev.ui.base.BaseFragment
import com.mobiuz.app.dev.ui.global.CONSTANTS
import com.mobiuz.app.dev.utils.Utils
import com.mobiuz.app.dev.utils.extensions.*
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.delay
import javax.inject.Inject

@AndroidEntryPoint
class PinFragment : BaseFragment(R.layout.fragment_pin) {

    @Inject
    lateinit var pref: SharedPref
    private var _bn: FragmentPinBinding? = null
    private val bn get() = _bn ?: throw NullPointerException("cannot inflate")
    private val navController: NavController by lazy(LazyThreadSafetyMode.NONE) { NavHostFragment.findNavController(this) }
    private val data = ArrayList<PinData>()
    private val pinAdapter = PinAdapter()
    private var type = ""
    private var titleText = ""
    private var pinCode = ""
    private var count = 3

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        arguments?.let {
            type = it.getString(CONSTANTS.TYPE_PIN, "") ?: ""
            pinCode = it.getString(CONSTANTS.PIN_CODE, "") ?: ""
        }
    }


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

        setUpUI()
        collects()

    }

    override fun setUpUI() {
        bn.apply {
            loadData()
            toolbar.setNavigationOnClickListener {
                when {
                    navController.popBackStack(R.id.registerFragment,false) -> {

                    }
                    navController.popBackStack(R.id.loginFragment,false) -> {

                    }
                    else -> navController.navigateUp()
                }
            }
            rvPin.layoutManager = LinearLayoutManager(requireContext(), LinearLayoutManager.HORIZONTAL, false)
            rvPin.setHasFixedSize(true)

            rvPin.adapter = pinAdapter
            titleText = when (type) {
                CONSTANTS.NEW_PIN -> {
                    getString(R.string.install_pin)
                }
                CONSTANTS.CONFIRM_NEW_PIN -> {
                    getString(R.string.confirm_pin)
                }
                CONSTANTS.CURRENT_PIN -> {
                    topDiv.isVisible = true
                    getString(R.string.enter_old_pin)
                }
                CONSTANTS.CHANGE_NEW_PIN -> {
                    topDiv.isVisible = true
                    getString(R.string.enter_new_pin)
                }
                CONSTANTS.CONFIRM_CHANGE_NEW_PIN -> {
                    topDiv.isVisible = true
                    getString(R.string.confirm_new_pin)
                }
                else -> {
                    getString(R.string.install_pin)
                }
            }

            txtEnterPin.text = titleText
            txtNotPin.isVisible = false

            pinAdapter.setOnDoneListener {
                when (type) {
                    CONSTANTS.NEW_PIN -> {
                        navController.navigate(R.id.pinFragment, bundleOf(CONSTANTS.TYPE_PIN to CONSTANTS.CONFIRM_NEW_PIN, CONSTANTS.PIN_CODE to it),
                            Utils.navOptions())
                    }
                    CONSTANTS.CONFIRM_NEW_PIN -> {
                        if(pinCode == it){
                            pref.pinCode = pinCode
                            navigate()
                        }else{
                            vibrate(requireContext())
                            cardPin.startAnimation(AnimationUtils.loadAnimation(requireContext(), R.anim.shake))
                            txtNotPin.isVisible = true
                        }
                    }
                    CONSTANTS.CURRENT_PIN -> {
                        if(pref.pinCode == it){
                            navController.navigate(R.id.pinFragment, bundleOf( CONSTANTS.TYPE_PIN to CONSTANTS.CHANGE_NEW_PIN), Utils.navOptions())
                        }else{
                            loadError()
                        }
                    }
                    CONSTANTS.CHANGE_NEW_PIN -> {
                        if(pref.pinCode == it){
                            showMessage(getString(R.string.cannot_change_pin))
                        }else{
                            navController.navigate(R.id.pinFragment, bundleOf(CONSTANTS.TYPE_PIN to CONSTANTS.CONFIRM_CHANGE_NEW_PIN, CONSTANTS.PIN_CODE to it), Utils.navOptions())
                        }
                    }
                    CONSTANTS.CONFIRM_CHANGE_NEW_PIN -> {
                        if(pinCode == it){
                            pref.pinCode = pinCode
                            showCustomDialog(getString(R.string.pin_code_updated),true){
                                navController.popBackStack(R.id.safetyFragment, false)
                            }

                        }else{
                            vibrate(requireContext())
                            cardPin.startAnimation(AnimationUtils.loadAnimation(requireContext(), R.anim.shake))
                            txtNotPin.isVisible = true
                        }
                    }
                    else -> {

                    }
                }
            }

            for (i in 0 until btnViewGroup.childCount) {
                btnViewGroup.getChildAt(i).setOnClickListener {
                    bn.txtNotPin.isVisible = false
                    if (it.id == R.id.btn_remove) {
                        pinAdapter.removeItem()
                    } else {
                        val text = it as TextView
                        pinAdapter.addItem(text.text.toString().toInt())
                    }
                }
            }

        }
    }


    private fun loadError(){
        bn.apply {
            count--
            if (count == 0){
                showCustomDialog(getString(R.string.popitok_error),false){
                    navigateToLogin()
                }

            }else{
                vibrate(requireContext())
                cardPin.startAnimation(AnimationUtils.loadAnimation(requireContext(), R.anim.shake))
               showMessage(getString(R.string.popitok,count.toString()))
            }
        }
    }

    private fun navigateToLogin() {
        pref.clearUserData()
        val intent = Intent(requireContext(), AuthActivity::class.java)
        intent.putExtra(CONSTANTS.TYPE_AUTH, CONSTANTS.LOGIN)
        intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_TASK_ON_HOME
        startActivity(intent)
        requireActivity().finishAffinity()
    }

    private fun navigate() {
        val golfing = Goldfinger.Builder(requireContext()).build()
        if (golfing.canAuthenticate()) {
            navController.navigate(R.id.biometricFragment, null, Utils.navOptions())
        } else {
            val intent = Intent(requireContext(), MainActivity::class.java)
            intent.putExtra(CONSTANTS.FIRST, CONSTANTS.FIRST)
            intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_TASK_ON_HOME
            startActivity(intent)
            requireActivity().finishAffinity()
        }
    }

    private fun loadData() {
        data.clear()
        for (i in 0..3) {
            data.add(PinData(-1))
        }
        pinAdapter.submitList(data)
    }

    override fun collects() {

    }

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