package com.mobiuz.app.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.activity.viewModels
import androidx.annotation.IdRes
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.app.AppCompatDelegate
import androidx.core.os.bundleOf
import androidx.core.view.GravityCompat
import androidx.core.view.isVisible
import androidx.drawerlayout.widget.DrawerLayout
import androidx.lifecycle.LiveData
import androidx.lifecycle.lifecycleScope
import androidx.navigation.NavController
import com.google.android.material.bottomnavigation.BottomNavigationView
import com.google.firebase.FirebaseApp
import com.google.firebase.analytics.FirebaseAnalytics
import com.google.firebase.messaging.FirebaseMessaging
import com.mobiuz.app.BuildConfig
import com.mobiuz.app.R
import com.mobiuz.app.databinding.ActivityMainBinding
import com.mobiuz.app.dev.model.SharedPref
import com.mobiuz.app.dev.network.model.UiStateObject
import com.mobiuz.app.dev.ui.auth.AuthActivity
import com.mobiuz.app.dev.ui.global.ButtonClick
import com.mobiuz.app.dev.ui.global.CONSTANTS
import com.mobiuz.app.dev.utils.LocaleHelper
import com.mobiuz.app.dev.utils.NetworkUtil
import com.mobiuz.app.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 MainActivity : AppCompatActivity() {

    @Inject
    lateinit var pref: SharedPref

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

    private lateinit var bottomNavigationView: BottomNavigationView
    private var currentNavController: LiveData<NavController>? = null
    private val viewModel: MainViewModel by viewModels()
    private lateinit var receiver: BroadcastReceiver

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

    private lateinit var mFirebaseAnalytics: FirebaseAnalytics

    override fun onCreate(savedInstanceState: Bundle?) {
        LocaleHelper.setLocale(this)
        super.onCreate(savedInstanceState)
        _bn = ActivityMainBinding.inflate(layoutInflater)
        setContentView(bn.root)
        pref.isShowPin = false

        if (savedInstanceState == null) {
            setupBottomNavigationBar()
        }


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

        AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO)
        FirebaseApp.initializeApp(this@MainActivity)
        mFirebaseAnalytics = FirebaseAnalytics.getInstance(this@MainActivity)

        FirebaseMessaging.getInstance().token.addOnCompleteListener {
            if (it.isSuccessful) pref.deviceToken = it.result.toString()
        }

        setUpUI()
        collects()

        receiver = object : BroadcastReceiver() {
            override fun onReceive(context: Context?, intent: Intent?) {
                if (intent?.action == CONSTANTS.CONNECTIVITY_CHANGE){
                    sendBroadcast(Intent(CONSTANTS.MY_CONNECTIVITY_CHANGE))
                }
                if (intent?.action == CONSTANTS.MY_CONNECTIVITY_CHANGE){
                    type = NetworkUtil.getConnectivityStatus(this@MainActivity)
                    bn.btnTryAgain.isVisible = (type == 0) && (currentNavController?.value?.currentDestination?.id != R.id.fullScreenFragment)
                    if (type == 0) {
                        showMessage(getString(R.string.not_internet_connect))
                    }
                }
            }
        }
        val intentFilter = IntentFilter()
        intentFilter.addAction(CONSTANTS.CONNECTIVITY_CHANGE)
        intentFilter.addAction(CONSTANTS.MY_CONNECTIVITY_CHANGE)
        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(this@MainActivity, AuthActivity::class.java)
                        intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_TASK_ON_HOME
                        startActivity(intent)
                        pref.clearUserData()
                        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.safetyFragment)
                }
            })

            header.headerLayout.setOnClickListener(object : ButtonClick() {
                override fun onSingleClick(v: View?) {
                    navigateToSettingsScreen(R.id.profileFragment)
                }
            })
            txtRedactData.setOnClickListener {
                navigateUri(CONSTANTS.MAIN_URL1)
            }

            txtPublicOferta.setOnClickListener {
                navigateUri(CONSTANTS.MAIN_URL2)
            }
        }
    }

    private fun navigateToOffline() {
        val intent = Intent(this, 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)
        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.fullScreenFragment &&
                currentNavController?.value?.currentDestination?.id != R.id.ussdFragment){
                bn.btnTryAgain.isVisible = false
                currentNavController?.value?.navigate(R.id.fullScreenFragment, bundleOf(CONSTANTS.TYPE_PIN to CONSTANTS.TYPE_AFTER))
            }
        }
    }


    private fun navigateToSettingsScreen(@IdRes resId: Int) {
        val window = 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
                }
            }
        }

    }

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

            val controller = bottomNavigationView.setupWithNavController(
                navGraphIds = navGraphIds,
                fragmentManager = supportFragmentManager,
                containerId = R.id.nav_host_fragment,
                intent = intent
            )
            currentNavController = controller
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

    override fun onSupportNavigateUp(): Boolean {
        return currentNavController?.value?.navigateUp() ?: false
    }

    override fun onDestroy() {
        _bn = null
        unregisterReceiver(receiver)
        pref.blockedTime = 0
        super.onDestroy()
    }
}