package com.mobiuz.app.dev.ui.global

import android.content.Intent
import android.os.Bundle
import android.view.View
import android.view.animation.AnimationUtils
import android.widget.TextView
import androidx.activity.OnBackPressedCallback
import androidx.core.os.bundleOf
import androidx.core.view.isVisible
import androidx.lifecycle.ViewModelProvider
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.FragmentPinDialogBinding
import com.mobiuz.app.dev.MainViewModel
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.auth.pin.PinAdapter
import com.mobiuz.app.dev.ui.base.BaseFragment
import com.mobiuz.app.dev.utils.extensions.SingleBlock
import com.mobiuz.app.dev.utils.extensions.customLog
import com.mobiuz.app.dev.utils.extensions.vibrate
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.delay
import javax.inject.Inject

@AndroidEntryPoint
class FullScreenFragment : BaseFragment(R.layout.fragment_pin_dialog) {

    @Inject
    lateinit var pref: SharedPref
    private var _bn: FragmentPinDialogBinding? = null
    private val bn get() = _bn ?: throw NullPointerException("cannot inflate")
    private val data = ArrayList<PinData>()
    private val pinAdapter = PinAdapter()
    private lateinit var mainViewModel: MainViewModel
    private var type = ""
    private var errorCount = 3

    private val navController: NavController by lazy(LazyThreadSafetyMode.NONE) { NavHostFragment.findNavController(this) }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        type = arguments?.getString(CONSTANTS.TYPE_PIN, "") ?: ""
        mainViewModel = ViewModelProvider(requireActivity())[MainViewModel::class.java]
    }

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

        val window = requireActivity().window.decorView
        window.systemUiVisibility = window.systemUiVisibility or View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
        mainViewModel.bottomSheet(false)
        mainViewModel.swipeDrawer(false)

        setUpUI()

        if (pref.isUseFingerPrint) loadFingerPrint()

    }

    private fun loadFingerPrint() {
        val golfing = Goldfinger.Builder(requireContext()).build()
        if (golfing.canAuthenticate()) {
            val params = Goldfinger.PromptParams.Builder(this)
                .title(getString(R.string.enter_from_finger_or_face))
                .negativeButtonText(getString(R.string.cancel))
                .build()

            golfing.authenticate(params, object : Goldfinger.Callback {
                override fun onResult(result: Goldfinger.Result) {
                    if (result.type() == Goldfinger.Type.SUCCESS) {
                        navigate()
                    }
                }

                override fun onError(e: Exception) {}
            })
        }

    }

    override fun setUpUI() {
        bn.apply {
            loadData()
            rvPin.layoutManager = LinearLayoutManager(requireContext(), LinearLayoutManager.HORIZONTAL, false)

            rvPin.adapter = pinAdapter
            txtNotPin.isVisible = false

            requireActivity().onBackPressedDispatcher.addCallback(viewLifecycleOwner,object : OnBackPressedCallback(true){
                override fun handleOnBackPressed() {
                    requireActivity().finish()
                }
            })

            pinAdapter.setOnDoneListener {
                if (pref.pinCode == it) {
                    txtNotPin.isVisible = false
                    navigate()
                } else {
                    errorCount--
                    if (errorCount == 0){
                        loadWithPassword()
                    }
                    vibrate(requireContext())
                    cardPin.startAnimation(AnimationUtils.loadAnimation(context, R.anim.shake))
                    txtNotPin.isVisible = true
                }
            }


            for (i in 0 until btnViewGroup.childCount) {
                btnViewGroup.getChildAt(i).setOnClickListener {
                    when (it.id) {
                        R.id.btn_remove -> {
                            pinAdapter.removeItem()
                            txtNotPin.isVisible = false
                        }
                        R.id.with_password -> {
                            loadWithPassword()
                        }
                        R.id.btn_finger_print -> {
                            loadFingerPrint()
                        }
                        else -> {
                            val text = it as TextView
                            txtNotPin.isVisible = false
                            pinAdapter.addItem(text.text.toString().toInt())
                        }
                    }
                }
            }

        }
    }

    private fun loadWithPassword() {
        pref.clearUserData()
        val intent = Intent(requireContext(), AuthActivity::class.java)
        intent.putExtra(CONSTANTS.TYPE_AUTH, CONSTANTS.LOGIN)
        startActivity(intent)
        requireActivity().finish()
    }

    private fun navigate() {
        navController.popBackStack()
        requireActivity().sendBroadcast(Intent(CONSTANTS.MY_CONNECTIVITY_CHANGE))
        if(type == CONSTANTS.OFFLINE){
            navController.navigate(R.id.serviceFragment, bundleOf(CONSTANTS.TYPE_SERVICE to CONSTANTS.OFFLINE))
        } else if (type != CONSTANTS.TYPE_AFTER) {
            navController.navigate(R.id.homeFragment)
        }

    }

    override fun collects() {

    }

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


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