package de.trainingstagebuch.app.ui.navigation

import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.navigation.NavType
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController
import androidx.navigation.navArgument
import androidx.navigation.navDeepLink
import de.trainingstagebuch.app.network.AuthEventBus
import de.trainingstagebuch.app.ui.AppMenuActions
import de.trainingstagebuch.app.ui.ProvideAppMenuActions
import de.trainingstagebuch.app.ui.screens.ActivateScreen
import de.trainingstagebuch.app.ui.screens.ClubSettingsScreen
import de.trainingstagebuch.app.ui.screens.CreateClubScreen
import de.trainingstagebuch.app.ui.screens.DatenschutzScreen
import de.trainingstagebuch.app.ui.screens.DiaryScreen
import de.trainingstagebuch.app.ui.screens.ForgotPasswordScreen
import de.trainingstagebuch.app.ui.screens.HomeScreen
import de.trainingstagebuch.app.ui.screens.ImpressumScreen
import de.trainingstagebuch.app.ui.screens.LoginScreen
import de.trainingstagebuch.app.ui.screens.LogsScreen
import de.trainingstagebuch.app.ui.screens.MemberTransferSettingsScreen
import de.trainingstagebuch.app.ui.screens.MembersScreen
import de.trainingstagebuch.app.ui.screens.MyTischtennisAccountScreen
import de.trainingstagebuch.app.ui.screens.PendingApprovalsScreen
import de.trainingstagebuch.app.ui.screens.PermissionsScreen
import de.trainingstagebuch.app.ui.screens.PersonalSettingsScreen
import de.trainingstagebuch.app.ui.screens.PredefinedActivitiesScreen
import de.trainingstagebuch.app.ui.screens.RegisterScreen
import de.trainingstagebuch.app.ui.screens.ResetPasswordScreen
import de.trainingstagebuch.app.ui.screens.ScheduleScreen
import de.trainingstagebuch.app.ui.screens.ShowClubScreen
import de.trainingstagebuch.app.ui.screens.TeamManagementScreen
import de.trainingstagebuch.app.ui.screens.TournamentsScreen
import de.trainingstagebuch.app.ui.screens.TrainingStatsScreen
import de.trainingstagebuch.app.viewmodel.AppViewModel

@Composable
fun AppNavGraph(appViewModel: AppViewModel) {
    val appState by appViewModel.state.collectAsState()
    val navController = rememberNavController()
    val authenticatedStartRoute = resolveAuthenticatedStartRoute(appState.currentClub)
    val appMenuActions = AppMenuActions(
        currentClubId = appState.currentClub,
        onNavigateToCreateClub = {
            navController.navigate(AppRoute.CreateClub.route) {
                launchSingleTop = true
            }
        },
        onNavigateToShowClub = { clubId ->
            navController.navigate(AppRoute.ShowClub.create(clubId)) {
                launchSingleTop = true
            }
        },
        onNavigateToTrainingStats = {
            navController.navigate(AppRoute.TrainingStats.route) {
                launchSingleTop = true
            }
        },
        onNavigateToMembers = {
            navController.navigate(AppRoute.Members.route) {
                launchSingleTop = true
            }
        },
        onNavigateToDiary = {
            navController.navigate(AppRoute.Diary.route) {
                launchSingleTop = true
            }
        },
        onNavigateToSchedule = {
            navController.navigate(AppRoute.Schedule.route) {
                launchSingleTop = true
            }
        },
        onNavigateToTournaments = {
            navController.navigate(AppRoute.Tournaments.route) {
                launchSingleTop = true
            }
        },
        onNavigateToClubSettings = {
            navController.navigate(AppRoute.ClubSettings.route) {
                launchSingleTop = true
            }
        },
        onNavigateToPendingApprovals = {
            navController.navigate(AppRoute.PendingApprovals.route) {
                launchSingleTop = true
            }
        },
        onNavigateToPermissions = {
            navController.navigate(AppRoute.Permissions.route) {
                launchSingleTop = true
            }
        },
        onNavigateToTeamManagement = {
            navController.navigate(AppRoute.TeamManagement.route) {
                launchSingleTop = true
            }
        },
        onNavigateToMemberTransferSettings = {
            navController.navigate(AppRoute.MemberTransferSettings.route) {
                launchSingleTop = true
            }
        },
        onNavigateToPredefinedActivities = {
            navController.navigate(AppRoute.PredefinedActivities.route) {
                launchSingleTop = true
            }
        },
        onNavigateToMyTischtennisAccount = {
            navController.navigate(AppRoute.MyTischtennisAccount.route) {
                launchSingleTop = true
            }
        },
        onNavigateToLogs = {
            navController.navigate(AppRoute.Logs.route) {
                launchSingleTop = true
            }
        },
        onNavigateToPersonalSettings = {
            navController.navigate(AppRoute.PersonalSettings.route) {
                launchSingleTop = true
            }
        },
        onNavigateToImpressum = {
            navController.navigate(AppRoute.Impressum.route) {
                launchSingleTop = true
            }
        },
        onNavigateToDatenschutz = {
            navController.navigate(AppRoute.Datenschutz.route) {
                launchSingleTop = true
            }
        },
        onLogout = {
            appViewModel.logout()
            navController.navigate(AppRoute.Login.route) {
                popUpTo(navController.graph.id) { inclusive = true }
                launchSingleTop = true
            }
        }
    )

    LaunchedEffect(navController) {
        AuthEventBus.unauthorizedEvents.collect {
            appViewModel.logout()
            navController.navigate(AppRoute.Login.route) {
                popUpTo(navController.graph.id) { inclusive = true }
                launchSingleTop = true
            }
        }
    }

    if (!appState.isSessionLoaded) {
        Column(
            modifier = Modifier.fillMaxSize(),
            verticalArrangement = Arrangement.Center,
            horizontalAlignment = Alignment.CenterHorizontally
        ) {
            CircularProgressIndicator()
        }
        return
    }

    ProvideAppMenuActions(actions = appMenuActions) {
        NavHost(
            navController = navController,
            startDestination = if (appState.isAuthenticated) authenticatedStartRoute else AppRoute.Login.route
        ) {
        composable(AppRoute.Register.route) {
            RegisterScreen(
                onRegistrationSuccess = {
                    navController.navigate(AppRoute.Login.route) {
                        popUpTo(AppRoute.Register.route) { inclusive = true }
                        launchSingleTop = true
                    }
                },
                onNavigateToLogin = {
                    navController.navigate(AppRoute.Login.route) {
                        popUpTo(AppRoute.Register.route) { inclusive = true }
                        launchSingleTop = true
                    }
                }
            )
        }
        composable(AppRoute.Login.route) {
            LoginScreen(
                onLoginSuccess = {
                    navController.navigate(resolveAuthenticatedStartRoute(appState.currentClub)) {
                        popUpTo(AppRoute.Login.route) { inclusive = true }
                        launchSingleTop = true
                    }
                },
                onNavigateToRegister = {
                    navController.navigate(AppRoute.Register.route) {
                        launchSingleTop = true
                    }
                },
                onNavigateToForgotPassword = {
                    navController.navigate(AppRoute.ForgotPassword.route) {
                        launchSingleTop = true
                    }
                }
            )
        }
        composable(
            route = AppRoute.Activate.route,
            arguments = listOf(navArgument("activationCode") { type = NavType.StringType }),
            deepLinks = listOf(
                navDeepLink { uriPattern = "trainingstagebuch://auth/activate/{activationCode}" }
            )
        ) {
            ActivateScreen(
                activationCode = it.arguments?.getString("activationCode").orEmpty(),
                onActivationSuccess = {
                    navController.navigate(AppRoute.Login.route) {
                        popUpTo(AppRoute.Activate.route) { inclusive = true }
                        launchSingleTop = true
                    }
                }
            )
        }
        composable(
            route = AppRoute.ForgotPassword.route,
            deepLinks = listOf(
                navDeepLink { uriPattern = "trainingstagebuch://auth/forgot-password" }
            )
        ) {
            ForgotPasswordScreen(
                onNavigateToLogin = {
                    navController.navigate(AppRoute.Login.route) {
                        popUpTo(AppRoute.ForgotPassword.route) { inclusive = true }
                        launchSingleTop = true
                    }
                }
            )
        }
        composable(
            route = AppRoute.ResetPassword.route,
            arguments = listOf(navArgument("token") { type = NavType.StringType }),
            deepLinks = listOf(
                navDeepLink { uriPattern = "trainingstagebuch://auth/reset-password/{token}" }
            )
        ) {
            ResetPasswordScreen(
                token = it.arguments?.getString("token").orEmpty(),
                onNavigateToLogin = {
                    navController.navigate(AppRoute.Login.route) {
                        popUpTo(AppRoute.ResetPassword.route) { inclusive = true }
                        launchSingleTop = true
                    }
                }
            )
        }

        composable(
            route = AppRoute.Home.route,
            deepLinks = listOf(navDeepLink { uriPattern = "trainingstagebuch://app/home" })
        ) {
            HomeScreen(
                currentClubId = appState.currentClub,
                onSelectClubAndOpenStats = { clubId ->
                    appViewModel.setCurrentClub(clubId)
                    navController.navigate(AppRoute.TrainingStats.route) {
                        launchSingleTop = true
                    }
                },
                onNavigateToCreateClub = {
                    navController.navigate(AppRoute.CreateClub.route) {
                        launchSingleTop = true
                    }
                },
                onNavigateToShowClub = { clubId ->
                    navController.navigate(AppRoute.ShowClub.create(clubId)) {
                        launchSingleTop = true
                    }
                },
                onNavigateToMembers = {
                    navController.navigate(AppRoute.Members.route) {
                        launchSingleTop = true
                    }
                },
                onNavigateToDiary = {
                    navController.navigate(AppRoute.Diary.route) {
                        launchSingleTop = true
                    }
                },
                onNavigateToSchedule = {
                    navController.navigate(AppRoute.Schedule.route) {
                        launchSingleTop = true
                    }
                },
                onNavigateToTournaments = {
                    navController.navigate(AppRoute.Tournaments.route) {
                        launchSingleTop = true
                    }
                },
                onNavigateToTrainingStats = {
                    navController.navigate(AppRoute.TrainingStats.route) {
                        launchSingleTop = true
                    }
                },
                onNavigateToPredefinedActivities = {
                    navController.navigate(AppRoute.PredefinedActivities.route) {
                        launchSingleTop = true
                    }
                },
                onNavigateToClubSettings = {
                    navController.navigate(AppRoute.ClubSettings.route) {
                        launchSingleTop = true
                    }
                },
                onNavigateToPendingApprovals = {
                    navController.navigate(AppRoute.PendingApprovals.route) {
                        launchSingleTop = true
                    }
                },
                onNavigateToPermissions = {
                    navController.navigate(AppRoute.Permissions.route) {
                        launchSingleTop = true
                    }
                },
                onNavigateToTeamManagement = {
                    navController.navigate(AppRoute.TeamManagement.route) {
                        launchSingleTop = true
                    }
                },
                onNavigateToMemberTransferSettings = {
                    navController.navigate(AppRoute.MemberTransferSettings.route) {
                        launchSingleTop = true
                    }
                },
                onNavigateToMyTischtennisAccount = {
                    navController.navigate(AppRoute.MyTischtennisAccount.route) {
                        launchSingleTop = true
                    }
                },
                onNavigateToLogs = {
                    navController.navigate(AppRoute.Logs.route) {
                        launchSingleTop = true
                    }
                },
                onNavigateToPersonalSettings = {
                    navController.navigate(AppRoute.PersonalSettings.route) {
                        launchSingleTop = true
                    }
                },
                onNavigateToImpressum = {
                    navController.navigate(AppRoute.Impressum.route) {
                        launchSingleTop = true
                    }
                },
                onNavigateToDatenschutz = {
                    navController.navigate(AppRoute.Datenschutz.route) {
                        launchSingleTop = true
                    }
                },
                onLogout = {
                    appViewModel.logout()
                    navController.navigate(AppRoute.Login.route) {
                        popUpTo(navController.graph.id) { inclusive = true }
                        launchSingleTop = true
                    }
                }
            )
        }
        composable(AppRoute.CreateClub.route) {
            CreateClubScreen(
                onClubCreated = {
                    navController.navigate(AppRoute.Home.route) {
                        popUpTo(AppRoute.CreateClub.route) { inclusive = true }
                        launchSingleTop = true
                    }
                },
                onNavigateBack = {
                    navController.popBackStack()
                }
            )
        }
        composable(
            route = AppRoute.ShowClub.route,
            arguments = listOf(navArgument("clubId") { type = NavType.StringType }),
            deepLinks = listOf(navDeepLink { uriPattern = "trainingstagebuch://app/showclub/{clubId}" })
        ) {
            ShowClubScreen(it.arguments?.getString("clubId").orEmpty())
        }
        composable(
            route = AppRoute.Members.route,
            deepLinks = listOf(navDeepLink { uriPattern = "trainingstagebuch://app/members" })
        ) { MembersScreen() }
        composable(
            route = AppRoute.Diary.route,
            deepLinks = listOf(navDeepLink { uriPattern = "trainingstagebuch://app/diary" })
        ) { DiaryScreen() }
        composable(AppRoute.PendingApprovals.route) { PendingApprovalsScreen() }
        composable(
            route = AppRoute.Schedule.route,
            deepLinks = listOf(navDeepLink { uriPattern = "trainingstagebuch://app/schedule" })
        ) { ScheduleScreen() }
        composable(
            route = AppRoute.Tournaments.route,
            deepLinks = listOf(navDeepLink { uriPattern = "trainingstagebuch://app/tournaments" })
        ) { TournamentsScreen() }
        composable(
            route = AppRoute.TrainingStats.route,
            deepLinks = listOf(navDeepLink { uriPattern = "trainingstagebuch://app/training-stats" })
        ) { TrainingStatsScreen() }
        composable(AppRoute.ClubSettings.route) { ClubSettingsScreen() }
        composable(AppRoute.PredefinedActivities.route) { PredefinedActivitiesScreen() }
        composable(AppRoute.MyTischtennisAccount.route) { MyTischtennisAccountScreen() }
        composable(AppRoute.TeamManagement.route) { TeamManagementScreen() }
        composable(AppRoute.Permissions.route) { PermissionsScreen() }
        composable(AppRoute.Logs.route) { LogsScreen() }
        composable(AppRoute.MemberTransferSettings.route) { MemberTransferSettingsScreen() }
        composable(AppRoute.PersonalSettings.route) { PersonalSettingsScreen() }
        composable(AppRoute.Impressum.route) { ImpressumScreen() }
        composable(AppRoute.Datenschutz.route) { DatenschutzScreen() }
        }
    }
}

private fun resolveAuthenticatedStartRoute(currentClub: String?): String {
    return when {
        currentClub.equals("new", ignoreCase = true) -> AppRoute.CreateClub.route
        currentClub.isNullOrBlank() -> AppRoute.Home.route
        else -> AppRoute.TrainingStats.route
    }
}
