package xyz.apiote.bimba.czwek.dashboard

import android.Manifest
import android.content.Intent
import android.content.pm.PackageManager
import android.os.Bundle
import android.view.View
import android.widget.Toast
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import androidx.core.content.edit
import androidx.core.view.WindowCompat
import androidx.core.view.get
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
import androidx.fragment.app.FragmentManager.FragmentLifecycleCallbacks
import androidx.navigation.fragment.NavHostFragment
import androidx.navigation.ui.setupWithNavController
import com.google.android.material.bottomnavigation.BottomNavigationView
import xyz.apiote.bimba.czwek.R
import xyz.apiote.bimba.czwek.api.Line
import xyz.apiote.bimba.czwek.api.QueryableV1
import xyz.apiote.bimba.czwek.api.StopV1
import xyz.apiote.bimba.czwek.dashboard.ui.home.HomeFragment
import xyz.apiote.bimba.czwek.dashboard.ui.map.MapFragment
import xyz.apiote.bimba.czwek.dashboard.ui.voyage.VoyageFragment
import xyz.apiote.bimba.czwek.databinding.ActivityMainBinding
import xyz.apiote.bimba.czwek.departures.DeparturesActivity
import xyz.apiote.bimba.czwek.search.ResultsActivity
import xyz.apiote.bimba.czwek.settings.ServerChooserActivity
import xyz.apiote.bimba.czwek.settings.feeds.FeedChooserActivity


class MainActivity : AppCompatActivity() {
	private lateinit var binding: ActivityMainBinding
	private lateinit var locationPermissionRequest: ActivityResultLauncher<Array<String>>

	private lateinit var permissionAsker: Fragment

	override fun onCreate(savedInstanceState: Bundle?) {
		super.onCreate(savedInstanceState)
		binding = ActivityMainBinding.inflate(layoutInflater)
		setContentView(binding.root)

		getSharedPreferences("shp", MODE_PRIVATE).edit(true) {
			putBoolean("firstRun", false)
		}

		supportFragmentManager.registerFragmentLifecycleCallbacks(
			object : FragmentLifecycleCallbacks() {
				override fun onFragmentViewCreated(
					fm: FragmentManager, f: Fragment, v: View, savedInstanceState: Bundle?
				) {
					setNavbarIcons(f)
					super.onFragmentViewCreated(fm, f, v, savedInstanceState)
				}
			}, true
		)

		binding.navigationDrawer.setNavigationItemSelectedListener {
			when (it.itemId) {
				R.id.drawer_servers -> {
					startActivity(Intent(this, ServerChooserActivity::class.java))
				}
				R.id.drawer_cities -> {
					startActivity(Intent(this, FeedChooserActivity::class.java))
				}
			}
			false
		}

		WindowCompat.setDecorFitsSystemWindows(window, false)
		val navView: BottomNavigationView = binding.bottomNavigation
		val navHostFragment =
			supportFragmentManager.findFragmentById(R.id.nav_host_fragment_activity_main) as NavHostFragment
		val navController = navHostFragment.navController
		navView.setupWithNavController(navController)

		locationPermissionRequest = registerForActivityResult(
			ActivityResultContracts.RequestMultiplePermissions()
		) { permissions ->
			when {
				permissions[Manifest.permission.ACCESS_FINE_LOCATION] ?: false ||
								permissions[Manifest.permission.ACCESS_COARSE_LOCATION] ?: false -> {
					when (permissionAsker) {
						is HomeFragment -> {
							showResults(ResultsActivity.Mode.MODE_LOCATION)
						}
						is MapFragment -> {
							(permissionAsker as MapFragment).showLocation()
						}
					}
				}
				else -> {
					// todo(ux,ui) dialog
					Toast.makeText(this, "No location access given", Toast.LENGTH_SHORT).show()
				}
			}
		}
	}

	@Suppress(
		"OVERRIDE_DEPRECATION",
		"DEPRECATION"
	)  // fixme later https://developer.android.com/reference/androidx/activity/OnBackPressedDispatcher
	override fun onBackPressed() {
		if (binding.container.isDrawerOpen(binding.navigationDrawer)) {
			binding.container.closeDrawer(binding.navigationDrawer)
		} else {
			super.onBackPressed()
		}
	}

	fun onNavigationClicked() {
		if (binding.container.isDrawerOpen(binding.navigationDrawer)) {
			binding.container.closeDrawer(binding.navigationDrawer)
		} else {
			binding.container.openDrawer(binding.navigationDrawer)
		}
	}

	fun onGpsClicked(fragment: Fragment) {
		when (PackageManager.PERMISSION_GRANTED) {
			ContextCompat.checkSelfPermission(
				this,
				Manifest.permission.ACCESS_COARSE_LOCATION
			) -> {
				when (fragment) {
					is HomeFragment -> {
						showResults(ResultsActivity.Mode.MODE_LOCATION)
					}
					is MapFragment -> {
						fragment.showLocation()
					}
				}
			}
			else -> {
				permissionAsker = fragment
				locationPermissionRequest.launch(
					arrayOf(
						Manifest.permission.ACCESS_FINE_LOCATION,
						Manifest.permission.ACCESS_COARSE_LOCATION
					)
				)
			}
		}
	}

	fun onSuggestionClicked(queryable: QueryableV1) {
		when (queryable) {
			is StopV1 -> {
				val intent = Intent(this, DeparturesActivity::class.java).apply {
					putExtra("code", queryable.code)
					putExtra("name", queryable.name)
				}
				startActivity(intent)
			}
			is Line -> {
				TODO("[3.1] start line graph activity")
			}
		}
	}

	fun onSearchClicked(text: CharSequence?) {
		showResults(ResultsActivity.Mode.MODE_SEARCH, text.toString())
	}

	private fun showResults(mode: ResultsActivity.Mode, query: String = "") {
		/* todo [3.1] (ux,low) animation
			https://developer.android.com/guide/fragments/animate
			https://github.com/raheemadamboev/fab-explosion-animation-app
		*/
		val intent = Intent(this, ResultsActivity::class.java).apply {
			putExtra("mode", mode)
			putExtra("query", query)
		}
		startActivity(intent)
	}

	private fun setNavbarIcons(f: Fragment) {
		// todo [voyage-planning]
		// binding.bottomNavigation.menu[2].setIcon(R.drawable.voyage_outline)
		binding.bottomNavigation.menu[1].setIcon(R.drawable.home_outline)
		binding.bottomNavigation.menu[0].setIcon(R.drawable.map_outline)
		when (f) {
			is HomeFragment -> {
				binding.bottomNavigation.menu[1].setIcon(R.drawable.home_black)
			}
			is VoyageFragment -> {
				binding.bottomNavigation.menu[2].setIcon(R.drawable.voyage_black)
			}
			is MapFragment -> {
				binding.bottomNavigation.menu[0].setIcon(R.drawable.map_black)
			}
			else -> {
				binding.bottomNavigation.menu[1].setIcon(R.drawable.home_black)
			}
		}
	}
}