@file:Suppress("HardCodedStringLiteral")

package eu.gaudian.translator.view

import androidx.compose.animation.core.FastOutSlowInEasing
import androidx.compose.animation.core.tween
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.animation.scaleIn
import androidx.compose.animation.slideInHorizontally
import androidx.compose.animation.slideOutHorizontally
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.navigation.NavGraphBuilder
import androidx.navigation.NavHostController
import androidx.navigation.NavType
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.navArgument
import androidx.navigation.navigation
import eu.gaudian.translator.model.VocabularyStage
import eu.gaudian.translator.view.composable.Screen
import eu.gaudian.translator.view.dictionary.DictionaryResultScreen
import eu.gaudian.translator.view.dictionary.EtymologyResultScreen
import eu.gaudian.translator.view.dictionary.MainDictionaryScreen
import eu.gaudian.translator.view.exercises.ExerciseSessionScreen
import eu.gaudian.translator.view.exercises.MainExerciseScreen
import eu.gaudian.translator.view.exercises.StartExerciseScreen
import eu.gaudian.translator.view.exercises.YouTubeBrowserScreen
import eu.gaudian.translator.view.exercises.YouTubeExerciseScreen
import eu.gaudian.translator.view.home.HomeScreen
import eu.gaudian.translator.view.library.LibraryScreen
import eu.gaudian.translator.view.settings.DictionaryOptionsScreen
import eu.gaudian.translator.view.settings.SettingsRoutes
import eu.gaudian.translator.view.settings.TranslationSettingsScreen
import eu.gaudian.translator.view.settings.settingsGraph
import eu.gaudian.translator.view.stats.StatsScreen
import eu.gaudian.translator.view.translation.TranslationScreen
import eu.gaudian.translator.view.vocabulary.AllCardsListScreen
import eu.gaudian.translator.view.vocabulary.CategoryDetailScreen
import eu.gaudian.translator.view.vocabulary.CategoryListScreen
import eu.gaudian.translator.view.vocabulary.LanguageProgressScreen
import eu.gaudian.translator.view.vocabulary.NewWordReviewScreen
import eu.gaudian.translator.view.vocabulary.NewWordScreen
import eu.gaudian.translator.view.vocabulary.NoGrammarItemsScreen
import eu.gaudian.translator.view.vocabulary.StageDetailScreen
import eu.gaudian.translator.view.vocabulary.VocabularyCardHost
import eu.gaudian.translator.view.vocabulary.VocabularyExerciseHostScreen
import eu.gaudian.translator.view.vocabulary.VocabularyHeatmapScreen
import eu.gaudian.translator.view.vocabulary.VocabularySortingScreen

private const val TRANSITION_DURATION = 300

object NavigationRoutes {
    const val NEW_WORD = "new_word"
    const val NEW_WORD_REVIEW = "new_word_review"
    const val VOCABULARY_DETAIL = "vocabulary_detail"
    const val START_EXERCISE = "start_exercise"
    const val CATEGORY_DETAIL = "category_detail"
    const val CATEGORY_LIST = "category_list_screen"
    const val STATS_VOCABULARY_HEATMAP = "stats/vocabulary_heatmap"
    const val STATS_LANGUAGE_PROGRESS = "stats/language_progress"
    const val STATS_CATEGORY_DETAIL = "stats/category_detail"
    const val STATS_CATEGORY_LIST = "stats/category_list_screen"
    const val STATS_VOCABULARY_SORTING = "stats/vocabulary_sorting"
    const val STATS_NO_GRAMMAR_ITEMS = "stats/no_grammar_items"
    const val STATS_VOCABULARY_LIST = "stats/vocabulary_list"
}

@Composable
fun AppNavHost(
    navController: NavHostController,
    modifier: Modifier = Modifier
) {



    // 1. Define your Main Tab "Leaf" Routes (the actual start destinations of your graphs)
    val mainTabRoutes = setOf(
        Screen.Home.route,
        Screen.Library.route,
        Screen.Stats.route,
        Screen.Translation.route,
        Screen.Dictionary.route,
        Screen.Exercises.route,
        SettingsRoutes.LIST
    )

    // Helper to check if a route is a top-level tab
    fun isTabTransition(initial: String?, target: String?): Boolean {
        return mainTabRoutes.contains(initial) && mainTabRoutes.contains(target)
    }

    NavHost(
        navController = navController,
        startDestination = Screen.Home.route,
        modifier = modifier,

        // ENTER TRANSITION
        enterTransition = {
            if (isTabTransition(initialState.destination.route, targetState.destination.route)) {
                // Tab Switch: Just Fade In (Subtle Scale for modern feel)
                fadeIn(animationSpec = tween(TRANSITION_DURATION)) +
                        scaleIn(initialScale = 0.96f, animationSpec = tween(TRANSITION_DURATION))
            } else {
                // Detail Screen: Slide in from Right
                slideInHorizontally(
                    initialOffsetX = { fullWidth -> (fullWidth * 0.1f).toInt() },
                    animationSpec = tween(TRANSITION_DURATION, easing = FastOutSlowInEasing)
                ) + fadeIn(animationSpec = tween(TRANSITION_DURATION))
            }
        },

        // EXIT TRANSITION
        exitTransition = {
            if (isTabTransition(initialState.destination.route, targetState.destination.route)) {
                // Tab Switch: Just Fade Out
                fadeOut(animationSpec = tween(TRANSITION_DURATION))
            } else {
                // Detail Screen: Slide out to Left
                slideOutHorizontally(
                    targetOffsetX = { fullWidth -> -(fullWidth * 0.1f).toInt() },
                    animationSpec = tween(TRANSITION_DURATION, easing = FastOutSlowInEasing)
                ) + fadeOut(animationSpec = tween(TRANSITION_DURATION))
            }
        },

        // POP ENTER (Pressing Back) -> Always Slide back from left
        popEnterTransition = {
            slideInHorizontally(
                initialOffsetX = { fullWidth -> -(fullWidth * 0.1f).toInt() },
                animationSpec = tween(TRANSITION_DURATION, easing = FastOutSlowInEasing)
            ) + fadeIn(animationSpec = tween(TRANSITION_DURATION))
        },

        // POP EXIT (Pressing Back) -> Always Slide away to right
        popExitTransition = {
            slideOutHorizontally(
                targetOffsetX = { fullWidth -> (fullWidth * 0.1f).toInt() },
                animationSpec = tween(TRANSITION_DURATION, easing = FastOutSlowInEasing)
            ) + fadeOut(animationSpec = tween(TRANSITION_DURATION))
        }
    ) {
        composable(Screen.Home.route) {
            HomeScreen(navController = navController)
        }

        composable(NavigationRoutes.NEW_WORD) {
            NewWordScreen(navController = navController)
        }

        composable(NavigationRoutes.NEW_WORD_REVIEW) {
            NewWordReviewScreen(navController = navController)
        }

        composable(NavigationRoutes.START_EXERCISE) {
            StartExerciseScreen(navController = navController)
        }

        // Define all other navigation graphs at the same top level.
        homeGraph(navController)
        libraryGraph(navController)
        statsGraph(navController)
        translationGraph(navController)
        dictionaryGraph(navController)
        exerciseGraph(navController)
        settingsGraph(navController)
    }
}

fun NavGraphBuilder.homeGraph(navController: NavHostController) {
    navigation(
        startDestination = "main_home",
        route = Screen.Home.route
    ) {
        composable("main_home") {
            HomeScreen(navController = navController)
        }
    }
}

fun NavGraphBuilder.libraryGraph(navController: NavHostController) {
    navigation(
        startDestination = "main_library",
        route = Screen.Library.route
    ) {
        composable("main_library") {
            LibraryScreen(navController = navController)
        }
        composable("vocabulary_sorting") {
            VocabularySortingScreen(
                navController = navController
            )
        }
        composable("vocabulary_detail/{itemId}") { backStackEntry ->
            val itemId = backStackEntry.arguments?.getString("itemId")?.toIntOrNull()
            if (itemId != null) {
                VocabularyCardHost(
                    navController = navController,
                    itemId = itemId,
                    onBackPressed = { navController.popBackStack() }
                )
            } else {
                Text("Error: Invalid Vocabulary Item ID")
            }
        }
        composable("dictionary_result/{entryId}") { backStackEntry ->
            val entryId = backStackEntry.arguments?.getString("entryId")?.toIntOrNull()
            if (entryId != null) {
                DictionaryResultScreen(
                    entryId = entryId,
                    navController = navController,
                )
            } else {
                Text("Error: Invalid Entry ID")
            }
        }
        composable("vocabulary_list/{showDueTodayOnly}/{categoryId}") { backStackEntry ->
            val showDueTodayOnly = backStackEntry.arguments?.getString("showDueTodayOnly")?.toBoolean() ?: false
            val categoryId = backStackEntry.arguments?.getString("categoryId")?.toIntOrNull()
            AllCardsListScreen(
                navController = navController,
                showDueTodayOnly = showDueTodayOnly,
                categoryId = categoryId,
                onNavigateToItem = { item ->
                    navController.navigate("vocabulary_detail/${item.id}")
                },
                onNavigateBack = { navController.popBackStack() },
                enableNavigationButtons = true
            )
        }
        composable("language_progress") {
            LanguageProgressScreen(
                navController = navController
            )

        }
        composable(NavigationRoutes.STATS_VOCABULARY_HEATMAP) {
            VocabularyHeatmapScreen(
                navController = navController,
            )
        }
        composable("vocabulary_list/{showDueTodayOnly}/{stage}") { backStackEntry ->
            val showDueTodayOnly = backStackEntry.arguments?.getString("showDueTodayOnly")?.toBoolean() ?: false
            val stageString = backStackEntry.arguments?.getString("stage")
            val stage = stageString?.let {
                if (it.equals("null", ignoreCase = true)) null else VocabularyStage.valueOf(it)
            }

            AllCardsListScreen(
                navController = navController,
                showDueTodayOnly = showDueTodayOnly,
                stage = stage,
                onNavigateToItem = { item ->
                    navController.navigate("vocabulary_detail/${item.id}")
                },
                onNavigateBack = { navController.popBackStack() },
                categoryId = 0,
                enableNavigationButtons = true
            )
        }
        composable(
            route = "vocabulary_exercise/{isSpelling}?categories={categories}&stages={stages}&languages={languages}&dailyOnly={dailyOnly}",
            arguments = listOf(
                navArgument("isSpelling") { type = NavType.BoolType },
                navArgument("categories") { type = NavType.StringType; nullable = true },
                navArgument("stages") { type = NavType.StringType; nullable = true },
                navArgument("languages") { type = NavType.StringType; nullable = true },
                navArgument("dailyOnly") {
                    type = NavType.BoolType
                    defaultValue = false
                },
            )
        ) { backStackEntry ->
            val arguments = backStackEntry.arguments

            val dailyOnly = arguments?.getBoolean("dailyOnly") ?: false

            val categoryIds = arguments?.getString("categories")
            val stageNames = arguments?.getString("stages")
            val languageIds = arguments?.getString("languages")

            val dailyOnlyJson = "{\"dailyOnly\": $dailyOnly}"

            VocabularyExerciseHostScreen(
                categoryIdsAsJson = categoryIds,
                stageNamesAsJson = stageNames,
                languageIdsAsJson = languageIds,
                dailyOnlyAsJson = dailyOnlyJson,
                onClose = { navController.popBackStack() },
                navController = navController
            )
        }
        composable(
            route = "vocabulary_exercise/{dailyOnly}?",
            arguments = listOf(
                navArgument("dailyOnly") { type = NavType.BoolType },
            )
        ) { _ ->

            VocabularyExerciseHostScreen(
                categoryIdsAsJson = null,
                stageNamesAsJson = null,
                languageIdsAsJson = null,
                onClose = { navController.popBackStack() },
                navController = navController,
                dailyOnlyAsJson = "{\"dailyOnly\": true}"
            )
        }
        composable(
            "stage_detail/{stage}",
            arguments = listOf(
                navArgument("stage") {
                    type = NavType.EnumType(VocabularyStage::class.java)
                }
            )
        )

        { backStackEntry ->
            @Suppress("DEPRECATION") val stage = backStackEntry.arguments?.getSerializable("stage") as VocabularyStage
            //NOTE: can ignore warning for now, once moved away from min SDK 28, use:
            // val stage = backStackEntry.arguments?.getSerializable("stage", VocabularyStage::class.java)
            StageDetailScreen(
                navController = navController,
                stage = stage
            )
        }
        composable("category_detail/{categoryId}") { backStackEntry ->
            val categoryId = backStackEntry.arguments?.getString("categoryId")?.toIntOrNull()

            if (categoryId != null) {
                CategoryDetailScreen(
                    categoryId = categoryId,
                    onBackClick = { navController.popBackStack() },
                    onNavigateToItem = { item ->
                        navController.navigate("vocabulary_detail/${item.id}")
                    },
                    navController = navController
                )
            }
        }
        composable("category_list_screen") {
            CategoryListScreen(
                onNavigateBack = { navController.popBackStack() },
                onCategoryClicked = { categoryId ->
                    navController.navigate("category_detail/$categoryId")
                }
            )
        }
        composable(
            route = "vocabulary_sorting?mode={mode}", // Route now accepts an optional 'mode'
            arguments = listOf(
                navArgument("mode") { // Define the argument
                    type = NavType.StringType
                    nullable = true
                }
            )
        ) { backStackEntry ->
            VocabularySortingScreen(
                navController = navController,
                // Pass the argument to the screen
                initialFilterMode = backStackEntry.arguments?.getString("mode")
            )
        }
        composable("no_grammar_items") {
            NoGrammarItemsScreen(
                navController = navController
            )
        }
    }
}

fun NavGraphBuilder.statsGraph(
    navController: NavHostController,
) {
    navigation(
        startDestination = "main_stats",
        route = Screen.Stats.route
    ) {
        composable("main_stats") {
            StatsScreen(navController = navController)
        }
        composable("stats/vocabulary_sorting") {
            VocabularySortingScreen(
                navController = navController
            )
        }
        composable("stats/vocabulary_list/{showDueTodayOnly}/{categoryId}") { backStackEntry ->
            val showDueTodayOnly = backStackEntry.arguments?.getString("showDueTodayOnly")?.toBoolean() ?: false
            val categoryId = backStackEntry.arguments?.getString("categoryId")?.toIntOrNull()
            AllCardsListScreen(
                navController = navController,
                showDueTodayOnly = showDueTodayOnly,
                categoryId = categoryId,
                onNavigateToItem = { item ->
                    navController.navigate("vocabulary_detail/${item.id}")
                },
                onNavigateBack = { navController.popBackStack() },
                enableNavigationButtons = true
            )
        }
        composable(NavigationRoutes.STATS_LANGUAGE_PROGRESS) {
            LanguageProgressScreen(
                navController = navController
            )
        }
        composable(NavigationRoutes.STATS_VOCABULARY_HEATMAP) {
            VocabularyHeatmapScreen(
                navController = navController,
            )
        }
        composable("stats/vocabulary_list/{showDueTodayOnly}/{stage}") { backStackEntry ->
            val showDueTodayOnly = backStackEntry.arguments?.getString("showDueTodayOnly")?.toBoolean() ?: false
            val stageString = backStackEntry.arguments?.getString("stage")
            val stage = stageString?.let {
                if (it.equals("null", ignoreCase = true)) null else VocabularyStage.valueOf(it)
            }

            AllCardsListScreen(
                navController = navController,
                showDueTodayOnly = showDueTodayOnly,
                stage = stage,
                onNavigateToItem = { item ->
                    navController.navigate("vocabulary_detail/${item.id}")
                },
                onNavigateBack = { navController.popBackStack() },
                categoryId = 0,
                enableNavigationButtons = true
            )
        }
        composable("stats/category_detail/{categoryId}") { backStackEntry ->
            val categoryId = backStackEntry.arguments?.getString("categoryId")?.toIntOrNull()

            if (categoryId != null) {
                CategoryDetailScreen(
                    categoryId = categoryId,
                    onBackClick = { navController.popBackStack() },
                    onNavigateToItem = { item ->
                        navController.navigate("vocabulary_detail/${item.id}")
                    },
                    navController = navController
                )
            }
        }
        composable("stats/category_list_screen") {
            CategoryListScreen(
                onNavigateBack = { navController.popBackStack() },
                onCategoryClicked = { categoryId ->
                    navController.navigate("stats/category_detail/$categoryId")
                }
            )
        }
        composable(
            route = "stats/vocabulary_sorting?mode={mode}",
            arguments = listOf(
                navArgument("mode") {
                    type = NavType.StringType
                    nullable = true
                }
            )
        ) { backStackEntry ->
            VocabularySortingScreen(
                navController = navController,
                initialFilterMode = backStackEntry.arguments?.getString("mode")
            )
        }
        composable("stats/no_grammar_items") {
            NoGrammarItemsScreen(
                navController = navController
            )
        }
    }
}

@OptIn(androidx.compose.animation.ExperimentalAnimationApi::class)
fun NavGraphBuilder.translationGraph(navController: NavHostController) {
    navigation(
        startDestination = "main_translation",
        route = Screen.Translation.route
    ) {
        composable("main_translation") {
            TranslationScreen(navController = navController)
        }
        composable("custom_translation_prompt") {
            TranslationSettingsScreen(navController = navController)
        }
    }
}

@OptIn(androidx.compose.animation.ExperimentalAnimationApi::class)
fun NavGraphBuilder.dictionaryGraph(navController: NavHostController) {
    navigation(
        startDestination = "main_dictionary",
        route = Screen.Dictionary.route
    ) {
        composable("main_dictionary") {
            MainDictionaryScreen(navController = navController)
        }
        composable("dictionary_result/{entryId}") { backStackEntry ->
            val entryId = backStackEntry.arguments?.getString("entryId")?.toIntOrNull()
            if (entryId != null) {
                DictionaryResultScreen(
                    entryId = entryId,
                    navController = navController,
                )
            } else {
                Text("Error: Invalid Entry ID")
            }
        }
        composable("dictionary_options") {
            DictionaryOptionsScreen(navController = navController)
        }
        composable("etymology_result/{word}/{languageCode}") { backStackEntry ->
            val word = backStackEntry.arguments?.getString("word") ?: ""
            val languageCode = backStackEntry.arguments?.getString("languageCode")?.toIntOrNull() ?: 1
            EtymologyResultScreen(
                navController = navController,
                word = word,
                languageCode = languageCode
            )
        }

    }
}

@OptIn(androidx.compose.animation.ExperimentalAnimationApi::class)
fun NavGraphBuilder.exerciseGraph(
    navController: NavHostController,
) {
    navigation(
        startDestination = "main_exercise",
        route = Screen.Exercises.route
    ) {
        composable("main_exercise") {
            MainExerciseScreen(
                navController = navController,
            )
        }
        composable("exercise_session") {
            ExerciseSessionScreen(
                navController = navController,
            )
        }
        composable("youtube_exercise") {
            YouTubeExerciseScreen(
                navController = navController
            )
        }
        composable("youtube_browse") {
            YouTubeBrowserScreen(
                navController = navController,
            )
        }
    }
}