@file:Suppress("HardCodedStringLiteral")

package eu.gaudian.translator.view.vocabulary

import androidx.activity.compose.BackHandler
import androidx.compose.animation.AnimatedContent
import androidx.compose.animation.ExperimentalAnimationApi
import androidx.compose.animation.slideInHorizontally
import androidx.compose.animation.slideOutHorizontally
import androidx.compose.animation.togetherWith
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.CircularProgressIndicator
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.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
import androidx.navigation.NavController
import eu.gaudian.translator.R
import eu.gaudian.translator.utils.Log
import eu.gaudian.translator.utils.findActivity
import eu.gaudian.translator.view.composable.AppAlertDialog
import eu.gaudian.translator.view.composable.Screen
import eu.gaudian.translator.viewmodel.ScreenState
import eu.gaudian.translator.viewmodel.VocabularyExerciseViewModel
import eu.gaudian.translator.viewmodel.VocabularyViewModel
import kotlinx.serialization.Serializable
import kotlinx.serialization.json.Json


@Serializable
private data class DailyOnly(val dailyOnly: Boolean)

@Composable
fun VocabularyExerciseHostScreen(
    categoryIdsAsJson: String?,
    stageNamesAsJson: String?,
    languageIdsAsJson: String?,
    dailyOnlyAsJson: String?,
    onClose: () -> Unit,
    navController: NavController
) {
    val activity = LocalContext.current.findActivity()
    val vocabularyViewModel: VocabularyViewModel = hiltViewModel(viewModelStoreOwner = activity)
    val exerciseViewModel: VocabularyExerciseViewModel = hiltViewModel(viewModelStoreOwner = activity)

    val cardSet by vocabularyViewModel.cardSet.collectAsState()
    val screenState by exerciseViewModel.screenState.collectAsState()
    val pendingConfig by exerciseViewModel.pendingExerciseConfig.collectAsState()

    var finalScore by remember { mutableIntStateOf(0) }
    var finalWrongAnswers by remember { mutableIntStateOf(0) }


    val dailyOnly = try {
        dailyOnlyAsJson?.let { Json.decodeFromString<DailyOnly>(it).dailyOnly } ?: false
    } catch (_: Exception) {
        false
    }

    LaunchedEffect(categoryIdsAsJson, stageNamesAsJson, languageIdsAsJson, dailyOnly) {
        Log.d("ExerciseHost", "LaunchedEffect filters: categories=$categoryIdsAsJson, stages=$stageNamesAsJson, languages=$languageIdsAsJson, dailyOnly=$dailyOnly")
        // Only reset and prepare if the host is opened via explicit filters.
        if (!categoryIdsAsJson.isNullOrBlank() || !stageNamesAsJson.isNullOrBlank() || !languageIdsAsJson.isNullOrBlank() || dailyOnly) {
            Log.d("ExerciseHost", "Preparing exercise from filters")
            exerciseViewModel.resetExercise()
            vocabularyViewModel.prepareExercise(
                categoryIdsAsJson,
                stageNamesAsJson,
                languageIdsAsJson,
                dailyOnly = dailyOnly,
            )
        } else {
            Log.d("ExerciseHost", "No filters provided; skipping prepareExercise")
        }
    }

    LaunchedEffect(cardSet, screenState, pendingConfig) {
        Log.d("ExerciseHost", "State update: screenState=$screenState, cardSet=${cardSet?.cards?.size ?: 0}, pendingCount=${pendingConfig.exerciseItemCount}")
        if (cardSet != null && screenState == ScreenState.START) {
            val items = cardSet?.cards.orEmpty()
            if (items.isNotEmpty()) {
                val selectedCount = pendingConfig.exerciseItemCount
                    .takeIf { it > 0 }
                    ?: items.size
                val finalItems = if (pendingConfig.shuffleCards) {
                    items.shuffled().take(selectedCount)
                } else {
                    items.take(selectedCount)
                }
                Log.d("ExerciseHost", "Auto-starting exercise with ${finalItems.size} items")
                exerciseViewModel.startExerciseWithConfig(
                    finalItems,
                    pendingConfig.copy(
                        exerciseItemCount = finalItems.size,
                        originalExerciseItems = finalItems
                    )
                )
            } else {
                Log.d("ExerciseHost", "CardSet present but empty")
            }
        }
    }

    when (screenState) {
        ScreenState.START -> {
            Log.d("ExerciseHost", "Rendering START screen")
            Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
                CircularProgressIndicator()
            }
        }
        ScreenState.EXERCISE -> {
            Log.d("ExerciseHost", "Rendering EXERCISE screen")
            ExerciseScreen(
                viewModel = exerciseViewModel,
                onClose = onClose,
                onFinish = { score, wrong ->
                    @Suppress("AssignedValueIsNeverRead")
                    finalScore = score
                    @Suppress("AssignedValueIsNeverRead")
                    finalWrongAnswers = wrong
                    exerciseViewModel.finishExercise(score, wrong)
                },
                navController = navController
            )
        }
        ScreenState.RESULT -> {
            Log.d("ExerciseHost", "Rendering RESULT screen")
            val totalItems by exerciseViewModel.totalItems.collectAsState()
            val originalItems by exerciseViewModel.originalItems.collectAsState()
            ResultScreen(
                score = finalScore,
                wrongAnswers = finalWrongAnswers,
                totalItems = totalItems,
                onRestart = {
                    vocabularyViewModel.clearCardSet()
                    exerciseViewModel.resetExercise()
                },
                onRetryWrong = { _ ->
                    exerciseViewModel.retryWrongAnswers(originalItems)
                },
                onClose = {
                    navController.navigate(Screen.Home.route) {
                        popUpTo(Screen.Home.route) { inclusive = true }
                        launchSingleTop = true
                    }
                }
            )
        }
    }
}







@OptIn(ExperimentalAnimationApi::class)
@Composable
private fun ExerciseScreen(
    viewModel: VocabularyExerciseViewModel,
    onClose: () -> Unit,
    onFinish: (score: Int, wrongAnswers: Int) -> Unit,
    navController: NavController
) {
    val exerciseState by viewModel.exerciseState.collectAsState()
    val totalItems by viewModel.totalItems.collectAsState()
    val score by viewModel.correctAnswers.collectAsState()
    val wrongAnswers by viewModel.wrongAnswers.collectAsState()

    val currentExerciseState = exerciseState

    var showExitDialog by remember { mutableStateOf(false) }

    val onExitConfirmed = {
        showExitDialog = false
        onClose()
    }

    BackHandler(enabled = true) {
        showExitDialog = true
    }

    if (showExitDialog) {
        AppAlertDialog(
            onDismissRequest = {
                @Suppress("AssignedValueIsNeverRead")
                showExitDialog = false
            },
            title = { Text(stringResource(R.string.label_quit_exercise_qm)) },
            text = { Text(stringResource(R.string.text_are_you_sure_you_want_to_quit_your_progress_in_this_session_will_be_lost)) },
            confirmButton = {
                TextButton(onClick = onExitConfirmed) {
                    Text(stringResource(R.string.quit))
                }
            },
            dismissButton = {
                TextButton(onClick = {
                    @Suppress("AssignedValueIsNeverRead")
                    showExitDialog = false
                }) {
                    Text(stringResource(R.string.label_cancel))
                }
            }
        )
    }

    LaunchedEffect(currentExerciseState, score, wrongAnswers) {
        // Only trigger completion when:
        // 1. Current exercise state is null (no more items to show)
        // 2. We have answered all items (score + wrong = total)
        // 3. We have at least one item to process
        // 4. We're not already in a completed state (prevent duplicate triggers)
        if (currentExerciseState == null && 
            (score + wrongAnswers) >= totalItems && 
            totalItems > 0 &&
            (score + wrongAnswers) > 0) {
            onFinish(score, wrongAnswers)
        }
    }

    Column(modifier = Modifier.fillMaxSize()) {
        ExerciseProgressIndicator(
            correctAnswers = score,
            wrongAnswers = wrongAnswers,
            totalItems = totalItems,
            onClose = {
                @Suppress("AssignedValueIsNeverRead")
                showExitDialog = true
            }
        )

        Box(modifier = Modifier.weight(1f)) {
            AnimatedContent(
                targetState = currentExerciseState?.item?.id,
                transitionSpec = {
                    slideInHorizontally { height -> height }.togetherWith(slideOutHorizontally { height -> -height })
                },
                label = "VocabularyCardAnimation"
            ) { targetState ->
                if (currentExerciseState != null && targetState == currentExerciseState.item.id) {
                    VocabularyExerciseRenderer(
                        state = currentExerciseState,
                        onAction = viewModel::onAction,
                        navController = navController
                    )
                }
            }
        }

        ExerciseControls(
            state = currentExerciseState,
            onAction = viewModel::onAction
        )
    }
}