package uz.mobiuz.mobiservice.dev

import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.net.Uri
import android.os.Bundle
import android.view.View
import androidx.annotation.IdRes
import androidx.core.os.bundleOf
import androidx.core.view.GravityCompat
import androidx.core.view.isVisible
import androidx.drawerlayout.widget.DrawerLayout
import androidx.fragment.app.Fragment
import androidx.lifecycle.LiveData
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope
import androidx.navigation.NavController
import androidx.navigation.fragment.NavHostFragment
import com.google.android.material.bottomnavigation.BottomNavigationView
import uz.mobiuz.mobiservice.dev.databinding.FragmentMainBinding
import uz.mobiuz.mobiservice.dev.model.SharedPref
import uz.mobiuz.mobiservice.dev.network.model.UiStateObject
import uz.mobiuz.mobiservice.dev.ui.auth.AuthActivity
import uz.mobiuz.mobiservice.dev.ui.global.ButtonClick
import uz.mobiuz.mobiservice.dev.ui.global.CONSTANTS
import uz.mobiuz.mobiservice.dev.utils.extensions.*
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launch
import javax.inject.Inject


@AndroidEntryPoint
class MainFragment : Fragment(R.layout.fragment_main) {

    @Inject
    lateinit var pref: SharedPref

    private var _bn: FragmentMainBinding? = null
    private val bn get() = _bn ?: throw NullPointerException("cannot inflate")

    private lateinit var bottomNavigationView: BottomNavigationView
    private var currentNavController: LiveData<NavController>? = null
    private lateinit var viewModel: MainViewModel
    private lateinit var receiver: BroadcastReceiver
    private val intentFilter = IntentFilter()
    private val bottomNavSelectedItemIdKey = "BOTTOM_NAV_SELECTED_ITEM_ID_KEY"
    private var bottomNavSelectedItemId = R.id.nav_graph_home // Must be your starting destination
    private val navController: NavController by lazy(LazyThreadSafetyMode.NONE) { NavHostFragment.findNavController(this) }


    // if offline type == 0
    private var type = 0

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        viewModel = ViewModelProvider(requireActivity())[MainViewModel::class.java]

    }


    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        _bn = FragmentMainBinding.bind(view)
        pref.isShowPin = false
        savedInstanceState?.let {
            bottomNavSelectedItemId =
                savedInstanceState.getInt(bottomNavSelectedItemIdKey, bottomNavSelectedItemId)
        }


        setupBottomNavigationBar(view)


//        val data = intent?.getStringExtra(CONSTANTS.FIRST)
//        if (data != null && data == CONSTANTS.FIRST) {
//            currentNavController?.value?.popBackStack()
//            currentNavController?.value?.navigate(R.id.homeFragment)
//        }


        setUpUI()
        collects()

        receiver = object : BroadcastReceiver() {
            override fun onReceive(context: Context?, intent: Intent?) {
                if (intent?.action == CONSTANTS.INTENT_ACTION_NAVIGATE) {
                    val id = intent.getIntExtra(CONSTANTS.FRAGMENT_ID, 0)
                    customLog("INTENT_ACTION_NAVIGATE: id: $id")
                    navController.navigate(id)
                }

            }
        }

//        intentFilter.addAction(CONSTANTS.INTENT_ACTION_NAVIGATE)
        requireActivity().registerReceiver(receiver, intentFilter)

    }


    private fun setUpUI() {

        bn.apply {
            bn.btnTryAgain.setOnClickListener {
                if (type == 0) {
                    navigateToOffline()
                }
            }

            txtVersion.text = "v ${BuildConfig.VERSION_NAME}"
            header.txtUserPhone.text = pref.userPhone.customMasketHome()
            when (pref.language) {
                CONSTANTS.UZ -> txtLanguage.text = getString(R.string.uzbek)
                CONSTANTS.RU -> txtLanguage.text = getString(R.string.russian)
                CONSTANTS.EN -> txtLanguage.text = getString(R.string.english)
            }
            btnExit.setOnClickListener(object : ButtonClick() {
                override fun onSingleClick(v: View?) {
                    showCustomExitDialog {
                        GlobalScope.launch {
                            viewModel.logOut()
                        }
                        val intent = Intent(requireContext(), AuthActivity::class.java)
                        intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_TASK_ON_HOME
                        startActivity(intent)
                        pref.clearUserData()
                        requireActivity().finish()

                    }
                }
            })

            btnLanguage.setOnClickListener(object : ButtonClick() {
                override fun onSingleClick(v: View?) {
                    navigateToSettingsScreen(R.id.languageFragment)
                }
            })

            btnSupport.setOnClickListener(object : ButtonClick() {
                override fun onSingleClick(v: View?) {
                    navigateToSettingsScreen(R.id.supportFragment)
                }
            })

            btnSafety.setOnClickListener(object : ButtonClick() {
                override fun onSingleClick(v: View?) {
                    navigateToSettingsScreen(R.id.securityFragment)
                }
            })

            header.headerLayout.setOnClickListener(object : ButtonClick() {
                override fun onSingleClick(v: View?) {
                    navigateToSettingsScreen(R.id.profileFragment)
                }
            })
            txtLicenseAgreement.setOnClickListener {
                navigateUri(
                    when (pref.language) {
                        CONSTANTS.UZ -> CONSTANTS.LICENSE_UZ
                        CONSTANTS.RU -> CONSTANTS.LICENSE_RU
                        else -> CONSTANTS.LICENSE_EN
                    }
                )
            }

            txtPrivacyPolicy.setOnClickListener {
                navigateUri(
                    when (pref.language) {
                        CONSTANTS.UZ -> CONSTANTS.PRIVACY_POLICY_UZ
                        CONSTANTS.RU -> CONSTANTS.PRIVACY_POLICY_RU
                        else -> CONSTANTS.PRIVACY_POLICY_EN
                    }
                )
            }

//            lifecycleScope.launchWhenCreated {
//                viewModel.navigateUiState.collect {
//                    when (it) {
//                        is UiStateObject.SUCCESS -> {
//                           bn.drawerLayout.openDrawer(GravityCompat.START)
//                        }
//                        else -> Unit
//                    }
//                }
//            }

        }
    }

    private fun navigateToOffline() {
        val intent = Intent(requireContext(), OfflineActivity::class.java)
        intent.putExtra(CONSTANTS.TYPE_SERVICE, CONSTANTS.FROM_ONLINE)
        intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_TASK_ON_HOME
        startActivity(intent)
        requireActivity().finish()
    }

    private fun navigateUri(link: String) {
        val uri = Uri.parse(link)
        val intent = Intent(Intent.ACTION_VIEW)
        intent.data = uri
        startActivity(intent)
        pref.isShowPin = false
    }

    override fun onStop() {
        super.onStop()
        pref.blockedTime = System.currentTimeMillis()
        bn.drawerLayout.closeDrawer(GravityCompat.START)
    }


    override fun onResume() {
        super.onResume()
        if (pref.isShowPin) {
//            showPinCode()
        } else {
            pref.blockedTime = System.currentTimeMillis()
            pref.isShowPin = true
        }
    }

    private fun showPinCode() {
        if (pref.blockedTime < System.currentTimeMillis() - CONSTANTS.BLOCKED_TIME) {
            if (currentNavController?.value?.currentDestination?.id != R.id.pinFragment &&
                currentNavController?.value?.currentDestination?.id != R.id.ussdFragment
            ) {
                bn.btnTryAgain.isVisible = false
                currentNavController?.value?.navigate(R.id.pinFragment, bundleOf(CONSTANTS.TYPE_PIN to CONSTANTS.TYPE_AFTER))
            }
        }
    }


    private fun navigateToSettingsScreen(@IdRes resId: Int) {
        val window = requireActivity().window.decorView
        window.systemUiVisibility = window.systemUiVisibility or View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
        currentNavController?.value?.navigate(resId)
        viewModel.bottomSheet(false)
        bn.drawerLayout.closeDrawer(GravityCompat.START)
    }

    private fun collects() {
        lifecycleScope.launchWhenStarted {
            viewModel.mainIndexUiState.collect {
                when (it) {
                    is UiStateObject.SUCCESS -> {
                        bn.drawerLayout.openDrawer(GravityCompat.START)
                    }
                    else -> Unit
                }
            }
        }

        lifecycleScope.launchWhenStarted {
            viewModel.bottomSheetUiState.collect {
                when (it) {
                    is UiStateObject.SUCCESS -> {
                        bn.bottomNavView.isVisible = it.data
                    }
                    else -> Unit
                }
            }
        }

        lifecycleScope.launchWhenStarted {
            viewModel.userNameUiState.collect {
                when (it) {
                    is UiStateObject.SUCCESS -> {
                        pref.userName = it.data
                        bn.header.txtUserName.text = it.data
                        bn.header.txtAvatar.text = it.data[0].toString()
                    }
                    else -> Unit
                }
            }
        }

        lifecycleScope.launchWhenStarted {
            viewModel.swipeDrawerUiState.collect {
                when (it) {
                    is UiStateObject.SUCCESS -> {
                        if (it.data) {
                            bn.drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED)
                        } else {
                            bn.drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED)
                        }
                    }
                    else -> Unit
                }
            }
        }

    }

    // Needed to maintain correct state over rotations
    override fun onSaveInstanceState(outState: Bundle) {
        outState.putInt(bottomNavSelectedItemIdKey, bottomNavSelectedItemId)
        super.onSaveInstanceState(outState)
    }

    private fun setupBottomNavigationBar(view: View) {
        try {
            bottomNavigationView = view.findViewById(R.id.bottom_nav_view)
            val navGraphIds = listOf(
                R.navigation.nav_graph_home,
                R.navigation.nav_graph_services
            )

            val controller = bottomNavigationView.setupWithNavController(
                fragmentManager = childFragmentManager,
                backButtonBehaviour = BackButtonBehaviour.POP_HOST_FRAGMENT,
                navGraphIds = navGraphIds,
                containerId = R.id.nav_host_fragment,
                firstItemId = R.id.nav_graph_home,
                intent = requireActivity().intent
            )
            controller.observe(viewLifecycleOwner, { navController ->
//                NavigationUI.setupWithNavController(bottomNavigationView,navController)
                bottomNavSelectedItemId = navController.graph.id // Needed to maintain correct state on return
            })

            currentNavController = controller
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }


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