@file:Suppress("HardCodedStringLiteral", "AssignedValueIsNeverRead")

package eu.gaudian.translator.view.vocabulary

import androidx.activity.ComponentActivity
import androidx.activity.compose.LocalActivity
import androidx.compose.animation.animateContentSize
import androidx.compose.animation.core.animateDpAsState
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.FloatingActionButton
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.layout.onSizeChanged
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
import androidx.navigation.NavController
import androidx.navigation.NavGraph.Companion.findStartDestination
import androidx.navigation.NavHostController
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.currentBackStackEntryAsState
import androidx.navigation.compose.rememberNavController
import eu.gaudian.translator.R
import eu.gaudian.translator.model.Exercise
import eu.gaudian.translator.model.MatchingPairsQuestion
import eu.gaudian.translator.model.Question
import eu.gaudian.translator.model.VocabularyCategory
import eu.gaudian.translator.model.VocabularyStage
import eu.gaudian.translator.ui.theme.ThemePreviews
import eu.gaudian.translator.utils.Log
import eu.gaudian.translator.view.composable.AppDialog
import eu.gaudian.translator.view.composable.AppIcons
import eu.gaudian.translator.view.composable.AppOutlinedCard
import eu.gaudian.translator.view.composable.AppSlider
import eu.gaudian.translator.view.composable.AppTabLayout
import eu.gaudian.translator.view.composable.OptionItemSwitch
import eu.gaudian.translator.view.composable.TabItem
import eu.gaudian.translator.view.dialogs.StartExerciseDialog
import eu.gaudian.translator.view.dialogs.VocabularyMenu
import eu.gaudian.translator.viewmodel.ExerciseViewModel
import eu.gaudian.translator.viewmodel.VocabularyViewModel
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.launch


@Suppress("HardCodedStringLiteral")
enum class VocabularyTab(
    override val title: String,
    override val icon: ImageVector,
    val route: String
) : TabItem {
    Dashboard(title = "title_dashboard", icon = AppIcons.Dashboard, route = "dashboard"),
    Statistics(title = "label_all_vocabulary", icon = AppIcons.BarChart, route = "statistics")
}

//Used to avoid the warning of unused variables in strings.xml

@Suppress("unused", "HardCodedStringLiteral", "UnusedVariable")
@Composable
fun Dummy() {

    val dummy = listOf(
        stringResource(id = R.string.title_dashboard),
        stringResource(id = R.string.label_all_vocabulary),
    )
}

@Composable
fun MainVocabularyScreen(
    navController: NavController
) {

    val activity = LocalActivity.current as ComponentActivity
    val vocabularyViewModel: VocabularyViewModel = hiltViewModel(viewModelStoreOwner = activity)
    val exerciseViewModel: ExerciseViewModel = hiltViewModel(activity)
    val vocabularyNavController = rememberNavController()
    val coroutineScope = rememberCoroutineScope()
    var showCustomExerciseDialog by remember { mutableStateOf(false) }
    var startDailyExercise by remember { mutableStateOf(false) }
    var showWordPairExerciseDialog by remember { mutableStateOf(false) }

    // Word Pair settings and temporary selections
    var showWordPairSettingsDialog by remember { mutableStateOf(false) }
    var tempWpCategories by remember { mutableStateOf<List<VocabularyCategory>>(emptyList()) }
    var tempWpStages by remember { mutableStateOf<List<VocabularyStage>>(emptyList()) }
    var tempWpLanguageIds by remember { mutableStateOf<List<Int>>(emptyList()) }

    var wpQuestionCount by remember { mutableIntStateOf(5) }
    var wpShuffleQuestions by remember { mutableStateOf(true) }
    var wpShuffleWordOrder by remember { mutableStateOf(true) }
    var wpTrainingMode by remember { mutableStateOf(false) }
    var wpDueTodayOnly by remember { mutableStateOf(false) }

    var isScrolling by remember { mutableStateOf(false) }


    if (showCustomExerciseDialog) {
        StartExerciseDialog(
            onDismiss = { showCustomExerciseDialog = false },
            onConfirm = { categories, stages, languageIds ->
                showCustomExerciseDialog = false
                val categoryIds = categories.joinToString(",") { it.id.toString() }
                val stageNames = stages.joinToString(",") { it.name }
                val languageIdsStr = languageIds.joinToString(",") { it.toString() }
                @Suppress("HardCodedStringLiteral")
                navController.navigate("vocabulary_exercise/false?categories=$categoryIds&stages=$stageNames&languages=$languageIdsStr")
            }
        )
    }

    if (showWordPairExerciseDialog) {
        StartExerciseDialog(
            onDismiss = { showWordPairExerciseDialog = false },
            onConfirm = { categories, stages, languageIds ->
                // Store selections and open settings dialog instead of starting immediately
                tempWpCategories = categories
                tempWpStages = stages
                tempWpLanguageIds = languageIds
                showWordPairExerciseDialog = false
                showWordPairSettingsDialog = true
            }
        )
    }

    val textWordPairSettings = stringResource(R.string.text_word_pair_settings)

    // Settings dialog for Word Pair Exercise
    if (showWordPairSettingsDialog) {
        AppDialog(
            onDismissRequest = { showWordPairSettingsDialog = false },
            title = { Text(textWordPairSettings) }
        ) {
                Column(
                    modifier = Modifier
                        .fillMaxWidth()
                        .padding(8.dp),
                    horizontalAlignment = Alignment.CenterHorizontally,
                    verticalArrangement = Arrangement.spacedBy(4.dp)
                ) {
                    // Amount of questions
                    Text(
                        stringResource(
                            R.string.text_amount_of_questions_2d,
                            wpQuestionCount
                        ))
                    AppSlider(
                        value = wpQuestionCount.toFloat(),
                        onValueChange = { wpQuestionCount = it.toInt().coerceIn(1, 20) },
                        valueRange = 1f..20f,
                        steps = 18
                    )

                    // Toggles
                    Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween) {
                        OptionItemSwitch(
                            title = stringResource(R.string.text_shuffle_questions),
                            checked = wpShuffleQuestions,
                            onCheckedChange = { wpShuffleQuestions = it },
                        )
                    }
                    Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween) {
                        OptionItemSwitch(
                            title = stringResource(R.string.text_shuffle_card_order),
                            description = stringResource(R.string.text_swap_sides),
                            checked = wpShuffleWordOrder,
                            onCheckedChange = { wpShuffleWordOrder = it },
                        )
                    }
                    Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween) {
                        OptionItemSwitch(
                            title = stringResource(R.string.tetx_training_mode),
                            description = stringResource(R.string.text_no_progress),
                            checked = wpTrainingMode,
                            onCheckedChange = { wpTrainingMode = it },
                        )
                    }
                    Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween) {
                        OptionItemSwitch(
                            title = stringResource(R.string.text_due_today_only),
                            checked = wpDueTodayOnly,
                            onCheckedChange = { wpDueTodayOnly = it },
                        )
                    }

                    Row(
                        modifier = Modifier
                            .fillMaxWidth()
                            .padding(top = 8.dp),
                        horizontalArrangement = Arrangement.End
                    ) {
                        TextButton(onClick = { showWordPairSettingsDialog = false }) {
                            Text(stringResource(id = R.string.label_cancel))
                        }
                        val textMatchThePairs = stringResource(R.string.text_match_the_pairs)
                        val textWordPairExercise = stringResource(R.string.text_word_pair_exercise)
                        val textTrainingModeDescription = stringResource(R.string.text_training_mode_description)
                        val labelTrainingMode = stringResource(R.string.label_training_mode)
                        TextButton(onClick = {
                            showWordPairSettingsDialog = false
                            // Build a Word Pair Exercise using matching pairs from selected vocabulary with options
                            coroutineScope.launch {
                                val items = vocabularyViewModel.filterVocabularyItems(
                                    languages = tempWpLanguageIds, 
                                    query = null,
                                    categoryIds = tempWpCategories.map { it.id },
                                    stage = tempWpStages.firstOrNull(),
                                    sortOrder = VocabularyViewModel.SortOrder.NEWEST_FIRST,
                                    dueTodayOnly = wpDueTodayOnly
                                ).first()

                                val maxPairsPerQuestion = 5
                                var pairsList = items.mapNotNull { item ->
                                    val k = item.wordFirst.trim()
                                    val v = item.wordSecond.trim()
                                    if (k.isNotBlank() && v.isNotBlank()) k to v else null
                                }
                                if (wpShuffleWordOrder) {
                                    pairsList = pairsList.map { (a, b) -> if ((0..1).random() == 0) a to b else b to a }
                                }
                                if (pairsList.isEmpty()) return@launch


                                val shuffledPairs = if (wpShuffleQuestions) pairsList.shuffled() else pairsList

                                val chunked = shuffledPairs.chunked(maxPairsPerQuestion)
                                val limitedChunks = chunked.take(wpQuestionCount)
                                val questions = mutableListOf<Question>()
                                var qId = 1
                                limitedChunks.forEach { chunk ->
                                    if (chunk.size >= 2) {
                                        questions.add(
                                            MatchingPairsQuestion(
                                                id = qId++,
                                                name = textMatchThePairs,
                                                pairs = chunk.toMap()
                                            )
                                        )
                                    }
                                }
                                if (questions.isEmpty()) return@launch

                                @Suppress("HardCodedStringLiteral") val exercise = Exercise(
                                    id = "wordpair-" + System.currentTimeMillis().toString(),
                                    title = textWordPairExercise,
                                    questions = questions.map { it.id },
                                    contextTitle = if (wpTrainingMode) labelTrainingMode else null,
                                    contextText = if (wpTrainingMode) textTrainingModeDescription else null
                                )
                                exerciseViewModel.startAdHocExercise(exercise, questions)
                                @Suppress("HardCodedStringLiteral")
                                navController.navigate("exercise_session")
                            }
                        }) {
                            Text(stringResource(id = R.string.label_start_exercise))
                        }
                    }
            }
        }
    }

    // Use LaunchedEffect to handle the navigation side effect
    LaunchedEffect(startDailyExercise) {
        if (startDailyExercise) {
            @Suppress("HardCodedStringLiteral")
            Log.d("DailyExercise", "Starting daily exercise")
            @Suppress("HardCodedStringLiteral")
            navController.navigate("vocabulary_exercise/false?categories=&stages=&languages=&dailyOnly=true")
            startDailyExercise = false
        }
    }

    val navBackStackEntry by vocabularyNavController.currentBackStackEntryAsState()
    val currentRoute = navBackStackEntry?.destination?.route
    val selectedTab = remember(currentRoute) {
        VocabularyTab.entries.find { it.route == currentRoute } ?: VocabularyTab.Dashboard
    }

    val showFabText = selectedTab == VocabularyTab.Dashboard && !isScrolling

    val repoEmpty =
        vocabularyViewModel.vocabularyItems.collectAsState(initial = emptyList()).value.isEmpty()

    if (repoEmpty) {
        NoVocabularyScreen()
        return
    }

    Box(modifier = Modifier.fillMaxSize()) {
        Column(modifier = Modifier.fillMaxSize()) {
            AppTabLayout(
                tabs = VocabularyTab.entries,
                selectedTab = selectedTab,
                onTabSelected = { tab ->
                    vocabularyNavController.navigate(tab.route) {
                        popUpTo(vocabularyNavController.graph.findStartDestination().id) {
                            saveState = true
                        }
                        launchSingleTop = true
                        restoreState = true
                    }
                }
            )

            NavHost(
                navController = vocabularyNavController,
                startDestination = VocabularyTab.Dashboard.route,
                modifier = Modifier.weight(1f)
            ) {
                composable(VocabularyTab.Dashboard.route) {
                    DashboardContent(
                        navController = navController,
                        onShowCustomExerciseDialog = { showCustomExerciseDialog = true },
                        onNavigateToCategoryDetail = { categoryId ->
                            navController.navigate("category_detail/$categoryId")
                        },
                        startDailyExercise = { startDailyExercise = true },
                        onNavigateToCategoryList = {
                            navController.navigate("category_list_screen")
                        },
                        onShowWordPairExerciseDialog = { showWordPairExerciseDialog = true },
                        onScroll = { isScrolling = it }
                     )
                 }
                 composable(VocabularyTab.Statistics.route) {
                    StatisticsContent(navController = navController)
                }
                composable("category_detail/{categoryId}") { backStackEntry ->

                    val categoryId = backStackEntry.arguments?.getString("categoryId")?.toIntOrNull()

                    if (categoryId != null) {
                        CategoryDetailScreen(
                            categoryId = categoryId,
                            onBackClick = { vocabularyNavController.popBackStack() },
                            onNavigateToItem = { item ->
                                navController.navigate("vocabulary_detail/${item.id}")
                            },
                            navController = navController as NavHostController
                        )
                    }
                }
                composable("vocabulary_exercise/{isSpelling}") { backStackEntry ->
                    backStackEntry.arguments?.getString("isSpelling")?.toBooleanStrict() ?: false
                    VocabularyExerciseHostScreen(
                        categoryIdsAsJson = null,
                        stageNamesAsJson = null,
                        languageIdsAsJson = null,
                        onClose = { navController.popBackStack() },
                        navController = navController,
                        dailyOnlyAsJson = null
                    )
                }
                composable("vocabulary_exercise/{dailyOnly}") { backStackEntry ->
                    backStackEntry.arguments?.getString("dailyOnly")?.toBooleanStrict() ?: false
                    VocabularyExerciseHostScreen(
                        categoryIdsAsJson = null,
                        stageNamesAsJson = null,
                        languageIdsAsJson = null,
                        onClose = { navController.popBackStack() },
                        navController = navController,
                        dailyOnlyAsJson = "{\"dailyOnly\": true}"
                    )
                }
            }
        }

        var menuHeightPx by remember { mutableIntStateOf(0) }
        val density = LocalDensity.current
        val menuHeightDp = (menuHeightPx / density.density).dp
        val animatedBottomPadding by animateDpAsState(targetValue = 16.dp + 8.dp + menuHeightDp, label = "FBottomPadding")

        Column(
            modifier = Modifier
                .align(Alignment.BottomEnd)
                .padding(16.dp),
            horizontalAlignment = Alignment.End
        ) {
            VocabularyMenu(modifier = Modifier.onSizeChanged { menuHeightPx = it.height }, showFabText = showFabText)
        }

        // Place the FAB separately and animate its bottom padding based on the menu height
        FloatingActionButton(
            onClick = { showCustomExerciseDialog = true },
            containerColor = MaterialTheme.colorScheme.primary,
            contentColor = MaterialTheme.colorScheme.onPrimary,
            modifier = Modifier
                .align(Alignment.BottomEnd)
                .padding(end = 16.dp, bottom = animatedBottomPadding)
        ) {
            Row(
                verticalAlignment = Alignment.CenterVertically,
                horizontalArrangement = Arrangement.spacedBy(8.dp),
                modifier = Modifier
                    .padding(horizontal = 16.dp)
                    .animateContentSize()
            ) {
                Icon(
                    imageVector = AppIcons.Quiz,
                    contentDescription = null
                )
                if(showFabText) {
                Text(
                    text = stringResource(R.string.label_start_exercise),
                    style = MaterialTheme.typography.labelLarge
                )}
            }
        }
    }
}

@Composable
fun StatisticsContent(
    navController: NavController
) {

    AppOutlinedCard {
                    VocabularyListScreen(
                        categoryId = null,
                        showDueTodayOnly = false,
                        onNavigateToItem = { item ->
                            navController.navigate("vocabulary_detail/${item.id}")
                        },
                        onNavigateBack = null,
                        navController = navController as NavHostController,
                        enableNavigationButtons = true
                    )
    }
}

@ThemePreviews
@Composable
fun VocabularyDashboardScreenPreview() {
    val navController = rememberNavController()
    MainVocabularyScreen(navController = navController)
}


@ThemePreviews
@Composable
fun StatisticsContentPreview() {
    val navController = rememberNavController()
    StatisticsContent(navController = navController)
}