# GravidNavHost.kt

    /*
     * The MIT License
     *
     * Original work sponsored and donated by The Danish Health Data Authority (http://www.sundhedsdatastyrelsen.dk)
     *
     * Copyright (C) 2023 The Danish Health Data Authority (http://www.sundhedsdatastyrelsen.dk)
     *
     *
     * Permission is hereby granted, free of charge, to any person obtaining a copy of
     * this software and associated documentation files (the "Software"), to deal in
     * the Software without restriction, including without limitation the rights to
     * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
     * of the Software, and to permit persons to whom the Software is furnished to do
     * so, subject to the following conditions:
     *
     *
     * The above copyright notice and this permission notice shall be included in all
     * copies or substantial portions of the Software.
     *
     *
     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
     * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
     * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
     * SOFTWARE.
     */
    package dk.nsp.mingraviditet.ui.main.navigation

    import androidx.compose.runtime.Composable
    import androidx.compose.runtime.rememberCoroutineScope
    import androidx.compose.ui.Modifier
    import androidx.navigation.NavController
    import androidx.navigation.compose.NavHost
    import androidx.navigation.navOptions
    import dk.nsp.mingraviditet.BuildConfig
    import dk.nsp.mingraviditet.feature.authentication.navigation.authenticationScreen
    import dk.nsp.mingraviditet.feature.authentication.onboarding.navigation.navigateToOnboarding
    import dk.nsp.mingraviditet.feature.authentication.onboarding.navigation.onboardingNavigationRoute
    import dk.nsp.mingraviditet.feature.authentication.onboarding.navigation.onboardingScreen
    import dk.nsp.mingraviditet.feature.authentication.signup.signupScreen
    import dk.nsp.mingraviditet.feature.careplanactivities.navigation.careplanActivitiesScreen
    import dk.nsp.mingraviditet.feature.journal.navigation.journalGraph
    import dk.nsp.mingraviditet.feature.knowledge.navigation.knowledgeGraph
    import dk.nsp.mingraviditet.feature.knowledge.navigation.navigateToArticleDetailsScreen
    import dk.nsp.mingraviditet.feature.knowledge.navigation.navigateToKnowledgeGraph
    import dk.nsp.mingraviditet.feature.more.navigation.moreGraph
    import dk.nsp.mingraviditet.feature.overview.navigation.overviewNavigationRoute
    import dk.nsp.mingraviditet.feature.overview.navigation.overviewScreen
    import dk.nsp.mingraviditet.ui.main.GravidAppState
    import kotlinx.coroutines.Dispatchers
    import kotlinx.coroutines.launch
    import kotlinx.coroutines.withContext

    @Composable
    fun GravidNavHost(
        appState: GravidAppState,
        modifier: Modifier = Modifier,
        startDestination: String = onboardingNavigationRoute,
    ) {
        val navController = appState.navController
        val coroutineScope = rememberCoroutineScope()

        NavHost(
            navController = navController,
            startDestination = startDestination,
            modifier = modifier,
        ) {
            authenticationScreen(
                navController = navController,
                navigateToOnboarding = {
                    coroutineScope.launch {
                        resetApp(navController)
                    }
                },
            )

            onboardingScreen(navController = navController)

            signupScreen(navController = navController)

            overviewScreen(
                navController = navController,
                navigateToKnowledge = {
                    navController.navigateToKnowledgeGraph(
                        navOptions {
                            popUpTo(overviewNavigationRoute) {
                                saveState = true
                            }
                            launchSingleTop = true
                            restoreState = false
                        },
                    )
                },
                onArticleClicked = { articleId, sectionId ->
                    navController.navigateToArticleDetailsScreen(
                        articleId,
                        sectionId,
                        navOptions = navOptions {
                            popUpTo(overviewNavigationRoute) {
                                saveState = true
                            }

                            launchSingleTop = true
                            restoreState = false
                        },
                    )
                },
                logOut = {
                    coroutineScope.launch {
                        resetApp(navController)
                    }
                },
            )

            careplanActivitiesScreen(navController = navController)

            knowledgeGraph(navController = navController)

            journalGraph(navController = navController)

            moreGraph(
                navController = navController,
                logOut = {
                    coroutineScope.launch {
                        resetApp(navController)
                    }
                },
                buildVersion = BuildConfig.VERSION_NAME,
                buildCode = BuildConfig.VERSION_CODE,
            )
        }
    }

    private suspend fun resetApp(navController: NavController) {
        withContext(Dispatchers.Main) {
            navController.navigateToOnboarding(
                navOptions = navOptions {
                    popUpTo(0) { inclusive = true }
                    launchSingleTop = true
                },
            )
        }
    }