package io.nexilis.alpha.ui.main

import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.ArrowBack
import androidx.compose.material.icons.automirrored.filled.Chat
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.ui.Modifier
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.navigation.NavDestination.Companion.hierarchy
import androidx.navigation.NavGraph.Companion.findStartDestination
import androidx.navigation.NavHostController
import androidx.navigation.NavType
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.currentBackStackEntryAsState
import androidx.navigation.compose.rememberNavController
import androidx.navigation.navArgument
import androidx.navigation.navigation
import io.nexilis.alpha.ui.screen.Screen
import io.nexilis.alpha.ui.viewmodel.MainViewModel

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun Main(navController: NavHostController) {
    val navMainController = rememberNavController()
    val hostState = remember { SnackbarHostState() }
    val navBackStackEntry by navMainController.currentBackStackEntryAsState()
    val currentDestination = navBackStackEntry?.destination
    var isHome = true
    currentDestination?.route.let {
        it?.let {
            isHome =
                it == Screen.Home.route || it == Screen.Chats.route || it == Screen.Profile.route
        }
    }
    val mainViewModel: MainViewModel = hiltViewModel()
    val title by mainViewModel.title.observeAsState("")
    Scaffold(
        modifier = Modifier.fillMaxSize(),
        topBar = {
            TopAppBar(
                title = { Text(text = title) },
                navigationIcon = {
                    NavigationIcon(navController = navMainController, isHome = isHome)
                },
                actions = {
                    ActionsMenu(navController = navController, navMainController = navMainController)
                }
            )
        },
        bottomBar = {
            BottomBar(navController = navMainController, isHome = isHome)
        },
        snackbarHost = { SnackbarHost(hostState = hostState) },
        floatingActionButton = {
            FloatingActionButton(
                navController = navMainController,
                isHome = isHome
            )
        }
    ) { contentPadding ->

        NavHost(
            navController = navMainController,
            startDestination = Screen.Home.route,
            modifier = Modifier.padding(contentPadding),
            route = Graph.home
        ) {
            composable(route = Screen.Home.route) {
                Home(mainViewModel = mainViewModel)
            }
            composable(route = Screen.Chats.route) {
                Chats(
                    navController = navMainController,
                    mainViewModel = mainViewModel
                )
            }
            composable(route = Screen.Profile.route) {
                Profile(mainViewModel = mainViewModel)
            }
            navigation(route = Graph.child, startDestination = Screen.Contact.route) {
                composable(route = Screen.Contact.route) {
                    Contact(navController = navMainController, mainViewModel = mainViewModel)
                }
                composable(
                    route = Screen.Chat.route + "/{pin}",
                    arguments = listOf(navArgument("pin") { type = NavType.StringType })
                ) {
                    it.arguments?.getString("pin")
                        ?.let { pin ->
                            Chat(
                                navController = navMainController,
                                pin = pin,
                                mainViewModel = mainViewModel
                            )
                        }
                }
                composable(route = Screen.SignUp.route) {
                    SignUp(navController = navMainController) {
                        if (it) {
                            navMainController.navigate(Graph.home)
                        }
                    }
                }
            }
        }
    }
}

@Composable
fun NavigationIcon(navController: NavHostController, isHome: Boolean) {
    if (!isHome) IconButton(onClick = {
        navController.navigateUp()
    }) {
        Icon(
            imageVector = Icons.AutoMirrored.Filled.ArrowBack,
            contentDescription = ""
        )
    }
}

@Composable
fun BottomBar(navController: NavHostController, isHome: Boolean) {
    val navBackStackEntry by navController.currentBackStackEntryAsState()
    val currentDestination = navBackStackEntry?.destination
    val barItems = listOf(
        Screen.Home,
        Screen.Chats,
        Screen.Profile
    )
    if (isHome) NavigationBar {
        barItems.forEachIndexed { index, screen ->
            NavigationBarItem(
                icon = { Icon(screen.imageVector, contentDescription = screen.title) },
                label = { Text(screen.title) },
                selected = currentDestination?.hierarchy?.any { it.route == screen.route } == true,
                onClick = {
                    navController.navigate(screen.route) {
                        popUpTo(navController.graph.findStartDestination().id) {
                            saveState = true
                        }
                        launchSingleTop = true
                        restoreState = true
                    }
                }
            )
        }
    }
}

@Composable
fun FloatingActionButton(
    navController: NavHostController,
    isHome: Boolean
) {
    if (isHome) Button(onClick = {
        navController.navigate(Screen.Contact.route) {
            launchSingleTop = true
            restoreState = true
        }
    }) {
        Icon(imageVector = Icons.AutoMirrored.Filled.Chat, contentDescription = "")
    }
}