package eu.gaudian.translator.view.vocabulary.card

import androidx.compose.animation.core.animateFloatAsState
import androidx.compose.foundation.BorderStroke
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.IntrinsicSize
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.layout.wrapContentHeight
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.Card
import androidx.compose.material3.CardDefaults
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.LinearProgressIndicator
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.ModalBottomSheet
import androidx.compose.material3.OutlinedCard
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.material3.TextField
import androidx.compose.material3.rememberModalBottomSheetState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
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.draw.blur
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.StrokeCap
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.withStyle
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.zIndex
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
import androidx.navigation.NavController
import eu.gaudian.translator.R
import eu.gaudian.translator.model.Language
import eu.gaudian.translator.model.VocabularyItem
import eu.gaudian.translator.model.grammar.GrammaticalFeature
import eu.gaudian.translator.model.grammar.VocabularyFeatures
import eu.gaudian.translator.model.grammar.formatGrammarDetails
import eu.gaudian.translator.model.jsonParser
import eu.gaudian.translator.ui.theme.semanticColors
import eu.gaudian.translator.utils.StatusAction
import eu.gaudian.translator.utils.StatusMessageService
import eu.gaudian.translator.utils.TextToSpeechHelper
import eu.gaudian.translator.utils.findActivity
import eu.gaudian.translator.view.composable.AppIcons
import eu.gaudian.translator.view.composable.AutoResizeSingleLineText
import eu.gaudian.translator.view.composable.SingleLanguageDropDown
import eu.gaudian.translator.view.composable.insertBreakOpportunities
import eu.gaudian.translator.viewmodel.DictionaryViewModel
import eu.gaudian.translator.viewmodel.LanguageConfigViewModel
import eu.gaudian.translator.viewmodel.LanguageViewModel
import eu.gaudian.translator.viewmodel.MessageDisplayType
import eu.gaudian.translator.viewmodel.SettingsViewModel
import eu.gaudian.translator.viewmodel.VocabularyViewModel
import kotlinx.coroutines.launch


@Composable
fun VocabularyDisplayCard(
    vocabularyItem: VocabularyItem,
    navController: NavController,
    isFlipped: Boolean,
    switchOrder: Boolean,
    onStatisticsClick: () -> Unit = {},
    onMoveToCategoryClick: () -> Unit = {},
    onMoveToStageClick: () -> Unit = {},
    onDeleteClick: () -> Unit = {},
    onEditStateChange: ((Boolean) -> Unit)? = null,
    onEditActionHandlersReady: ((onSave: () -> Unit, onCancel: () -> Unit) -> Unit)? = null,
) {
    VocabularyCardContent(
        vocabularyItem = vocabularyItem,
        navController = navController,
        isExerciseMode = false,
        isFlipped = isFlipped,
        switchOrder = switchOrder,
        onStatisticsClick = onStatisticsClick,
        onMoveToCategoryClick = onMoveToCategoryClick,
        onMoveToStageClick = onMoveToStageClick,
        onDeleteClick = onDeleteClick,
        onEditStateChange = onEditStateChange,
        onEditActionHandlersReady = onEditActionHandlersReady,
    )
}

@Composable
fun VocabularyExerciseCard(
    vocabularyItem: VocabularyItem,
    navController: NavController,
    isFlipped: Boolean,
    switchOrder: Boolean,
    userSpellingAnswer: String? = null,
    isUserSpellingCorrect: Boolean? = null,
) {
    VocabularyCardContent(
        vocabularyItem = vocabularyItem,
        navController = navController,
        isExerciseMode = true,
        isFlipped = isFlipped,
        switchOrder = switchOrder,
        userSpellingAnswer = userSpellingAnswer,
        isUserSpellingCorrect = isUserSpellingCorrect,
    )
}

@Composable
private fun VocabularyCardContent(
    vocabularyItem: VocabularyItem,
    navController: NavController,
    isExerciseMode: Boolean,
    isFlipped: Boolean,
    switchOrder: Boolean,
    onStatisticsClick: () -> Unit = {},
    onMoveToCategoryClick: () -> Unit = {},
    onMoveToStageClick: () -> Unit = {},
    onDeleteClick: () -> Unit = {},
    userSpellingAnswer: String? = null,
    isUserSpellingCorrect: Boolean? = null,
    onEditStateChange: ((Boolean) -> Unit)? = null,
    onEditActionHandlersReady: ((onSave: () -> Unit, onCancel: () -> Unit) -> Unit)? = null,
) {

    val activity = LocalContext.current.findActivity()
    val vocabularyViewModel: VocabularyViewModel = hiltViewModel(viewModelStoreOwner = activity)
    val languageViewModel: LanguageViewModel = hiltViewModel(viewModelStoreOwner = activity)
    val dictionaryViewModel: DictionaryViewModel = hiltViewModel(viewModelStoreOwner = activity)

    val coroutineScope = rememberCoroutineScope()
    val itemState by vocabularyViewModel.getVocabularyItemFlow(vocabularyItem.id)
        .collectAsState(initial = vocabularyItem)
    val item = itemState ?: vocabularyItem


    var editedFeatures by remember(item.id) {
        mutableStateOf(
            item.features?.let {
                try {
                    jsonParser.decodeFromString<VocabularyFeatures>(it)
                } catch (e: Exception) {
                    StatusMessageService.triggerNonSuspend(
                        StatusAction.ShowMessage(
                            text = e.toString(),
                            type = MessageDisplayType.ERROR,
                            timeoutInSeconds = 3
                        )
                    )
                    VocabularyFeatures()
                }
            } ?: VocabularyFeatures()
        )
    }

    val languageFirst by languageViewModel.getLanguageByIdFlow(item.languageFirstId ?: 0)
        .collectAsState(initial = null)
    val languageSecond by languageViewModel.getLanguageByIdFlow(item.languageSecondId ?: 0)
        .collectAsState(initial = null)

    var isEditing by remember(item.id) { mutableStateOf(false) }
    var showActionPanel by remember { mutableStateOf(false) }

    LaunchedEffect(key1 = item.features, key2 = isEditing) {
        if (!isEditing) {
            editedFeatures = item.features?.let {
                try {
                    jsonParser.decodeFromString<VocabularyFeatures>(it)
                } catch (e: Exception) {
                    StatusMessageService.triggerNonSuspend(
                        StatusAction.ShowMessage(
                            text = e.toString(),
                            type = MessageDisplayType.ERROR,
                            timeoutInSeconds = 3
                        )
                    )
                    VocabularyFeatures()
                }
            } ?: VocabularyFeatures()
        }
    }

    var editedWordFirst by remember(item.id) {
        mutableStateOf(item.wordFirst)
    }
    var editedWordSecond by remember(item.id) {
        mutableStateOf(item.wordSecond)
    }
    var editedLangFirstId by remember(item.id) {
        mutableStateOf(item.languageFirstId)
    }
    var editedLangSecondId by remember(item.id) {
        mutableStateOf(item.languageSecondId)
    }


    var showGrammarDialogFor by remember(item.id) { mutableStateOf<String?>(null) }
    var showBottomSheet by remember(item.id) { mutableStateOf(false) }
    var bottomSheetTerm by remember(item.id) { mutableStateOf<String?>(null) }



    val entryToNavigate by dictionaryViewModel.navigateToEntry.collectAsState()
    LaunchedEffect(key1 = entryToNavigate) {
        entryToNavigate?.let { entry ->
            // Set flag indicating navigation is from external source (not DictionaryResultScreen)
            dictionaryViewModel.setNavigatingFromDictionaryResult(false)
            @Suppress("HardCodedStringLiteral")
            navController.navigate("dictionary_result/${entry.id}")
            dictionaryViewModel.onNavigationDone()
        }
    }

    val handleSave = remember(editedWordFirst, editedWordSecond, editedLangFirstId, editedLangSecondId, editedFeatures) {
        {
            coroutineScope.launch {
                val updatedItem = item.copy(
                    wordFirst = editedWordFirst,
                    wordSecond = editedWordSecond,
                    languageFirstId = editedLangFirstId!!,
                    languageSecondId = editedLangSecondId,
                    features = jsonParser.encodeToString(editedFeatures)
                )
                vocabularyViewModel.editVocabularyItem(updatedItem)
                isEditing = false
                onEditStateChange?.invoke(false)
            }
        }
    }

    val handleCancel = remember {
        {
            editedWordFirst = item.wordFirst
            editedWordSecond = item.wordSecond
            editedLangFirstId = item.languageFirstId
            editedLangSecondId = item.languageSecondId
            editedFeatures = item.features?.let { jsonParser.decodeFromString<VocabularyFeatures>(it) } ?: VocabularyFeatures()
            isEditing = false
            onEditStateChange?.invoke(false)
        }
    }

    LaunchedEffect(key1 = true) {
        if(vocabularyItem.zipfFrequencyFirst == null || vocabularyItem.zipfFrequencySecond == null){
            vocabularyViewModel.editVocabularyItem(vocabularyItem)
        }
    }

    val rotationY by animateFloatAsState(
        targetValue = if (isFlipped) 180f else 0f,
        label = "rotationY"
    )

    if (languageFirst == null || languageSecond == null) {
        Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
            CircularProgressIndicator()
        }
        return
    }

    OutlinedCard(
        modifier = Modifier
            .fillMaxSize()
            .padding(2.dp),
        shape = RoundedCornerShape(24.dp),
        elevation = CardDefaults.cardElevation(defaultElevation = 0.dp),
        border = BorderStroke(1.dp, MaterialTheme.colorScheme.outline.copy(alpha = 0.5f))
    ) {
        Box(
            modifier = Modifier.fillMaxSize()
        ) {

            Card(
                modifier = Modifier
                    .fillMaxSize()
                    .padding(start = 0.dp, top = 0.dp, bottom = 0.dp, end = 0.dp)
                    .graphicsLayer { this.rotationY = rotationY },
                shape = RoundedCornerShape(24.dp),
                elevation = CardDefaults.cardElevation(defaultElevation = 0.dp),
                colors = CardDefaults.cardColors(containerColor = Color.Transparent)
            ) {
                Column(
                    modifier = Modifier
                        .fillMaxSize()
                        .padding(start = 0.dp, top = 0.dp, bottom = 0.dp, end = 0.dp)
                        .verticalScroll(rememberScrollState())
                ) {
                    val isFrontFace = rotationY < 90f
                    val baseModifier = Modifier.weight(1f, fill = false)

                    val frontFaceModifier = if (isFrontFace) {
                        baseModifier
                    } else {
                        baseModifier.graphicsLayer { this.rotationY = 180f }
                    }

                    val backFaceModifier = if (isFrontFace) {
                        baseModifier
                    } else {
                        baseModifier.graphicsLayer { this.rotationY = 180f }
                    }

                    CardFace(
                        modifier = frontFaceModifier,
                        isFront = true,
                        isFirst = !switchOrder,
                        languageViewModel = languageViewModel,
                        isEditing = isEditing,
                        word = if (isEditing) (if (!switchOrder) editedWordFirst else editedWordSecond) else (if (!switchOrder) item.wordFirst else item.wordSecond),
                        onWordChange = { if (!switchOrder) editedWordFirst = it else editedWordSecond = it },
                        language = if (!switchOrder) languageFirst else languageSecond,
                        onLanguageIdChange = { if (!switchOrder) editedLangFirstId = it else editedLangSecondId = it },
                        isRevealed = isFrontFace || isExerciseMode,
                        userSpellingAnswer = userSpellingAnswer,
                        isUserSpellingCorrect = isUserSpellingCorrect,
                        correctWord = if (switchOrder) item.wordFirst else item.wordSecond,
                        wordDetails = if (!switchOrder) editedFeatures.first else editedFeatures.second,
                        onEditGrammarClick = { showGrammarDialogFor = "first" },
                        isExerciseMode = isExerciseMode,
                        vocabularyItem = item,
                        onMoreClick = {
                            @Suppress("HardCodedStringLiteral")
                            bottomSheetTerm = if (!switchOrder) "first" else "second"
                            showBottomSheet = true
                        }
                    )

                    Box(
                        modifier = Modifier
                            .fillMaxWidth()
                            .height(0.dp) // Take 0 structural space
                            .wrapContentHeight(unbounded = true) // Allow children to render at their full size
                            .zIndex(1f), // Ensure it draws over the bottom CardFace
                        contentAlignment = Alignment.Center
                    ) {
                        Row(
                            verticalAlignment = Alignment.CenterVertically,
                            modifier = Modifier.fillMaxWidth()
                        ) {
                            HorizontalDivider(
                                modifier = Modifier.weight(1f),
                                color = MaterialTheme.colorScheme.outline.copy(alpha = 0.3f)
                            )
                            if (!isExerciseMode && !isEditing && !isFlipped) {
                                IconButton(onClick = { showActionPanel = true }) {
                                    Icon(
                                        imageVector = AppIcons.MoreVert,
                                        contentDescription = stringResource(R.string.more),
                                        tint = MaterialTheme.colorScheme.onSurfaceVariant
                                    )
                                }
                            }
                        }
                    }

                    CardFace(
                        modifier = backFaceModifier,
                        isFront = false,
                        isFirst = switchOrder,
                        languageViewModel = languageViewModel,
                        isEditing = isEditing,
                        word = if (isEditing) (if (switchOrder) editedWordFirst else editedWordSecond) else (if (switchOrder) item.wordFirst else item.wordSecond),
                        onWordChange = { if (switchOrder) editedWordFirst = it else editedWordSecond = it },
                        language = if (switchOrder) languageFirst else languageSecond,
                        onLanguageIdChange = { if (switchOrder) editedLangFirstId = it else editedLangSecondId = it },
                        isRevealed = !(!isFlipped && isExerciseMode),
                        userSpellingAnswer = userSpellingAnswer,
                        isUserSpellingCorrect = isUserSpellingCorrect,
                        correctWord = if (switchOrder) item.wordFirst else item.wordSecond,
                        wordDetails = if (switchOrder) editedFeatures.first else editedFeatures.second,
                        onEditGrammarClick = {
                            @Suppress("HardCodedStringLiteral")
                            showGrammarDialogFor = "second"
                        },
                        isExerciseMode = isExerciseMode,
                        vocabularyItem = item,
                        onMoreClick = {
                            @Suppress("HardCodedStringLiteral")
                            bottomSheetTerm = if (switchOrder) "first" else "second"
                            showBottomSheet = true
                        }
                    )
                }
            }


            !switchOrder
            if(isFlipped || !isExerciseMode)
                DraggableActionPanel(
                    modifier = Modifier
                        .align(Alignment.CenterEnd)
                        .height((IntrinsicSize.Min)),
                    isOpen = showActionPanel,
                    onDismiss = { showActionPanel = false },
                    isEditing = isEditing,
                    onEditClick = {
                        isEditing = true
                        onEditStateChange?.invoke(true)
                        onEditActionHandlersReady?.invoke(
                            { handleSave() },
                            { handleCancel() }
                        )
                    },

                    onStatisticsClick = onStatisticsClick,
                    onMoveToCategoryClick = onMoveToCategoryClick,
                    onMoveToStageClick = onMoveToStageClick,
                    onDeleteClick = onDeleteClick,

                    showAnalyzeGrammarButton = item.features.isNullOrBlank(),
                    onAnalyzeGrammarClick = {
                        vocabularyViewModel.fetchAndApplyGrammaticalDetailsForList(listOf(item))
                    },
                )
        }

        if (showGrammarDialogFor != null) {
            val isFirst = showGrammarDialogFor == "first"
            val featureToEdit = if (isFirst) editedFeatures.first else editedFeatures.second
            val langForDialog = if (isFirst) languageFirst else languageSecond

            if (langForDialog != null) {
                GrammarEditDialog(
                    feature = featureToEdit,
                    language = langForDialog,
                    onDismiss = { showGrammarDialogFor = null },
                    onSave = { newFeature ->
                        editedFeatures = if (isFirst) {
                            editedFeatures.copy(first = newFeature)
                        } else {
                            editedFeatures.copy(second = newFeature)
                        }
                        showGrammarDialogFor = null
                    }
                )
            }
        }

        if (showBottomSheet) {
            val sheetState = rememberModalBottomSheetState()
            ModalBottomSheet(
                onDismissRequest = {
                    showBottomSheet = false
                    bottomSheetTerm = null
                },
                sheetState = sheetState
            ) {
                AdditionalContentBottomSheet(
                    vocabularyItemId = item.id,
                    term = bottomSheetTerm ?: "first",
                    navController = navController
                )
            }
        }
    }
}

@Suppress("HardCodedStringLiteral")
@Preview
@Composable
fun VocabularyCardPreview() {
    val item = VocabularyItem(
        id = 1,
        wordFirst = "Hello",
        wordSecond = "Hola",
        languageFirstId = R.string.language_1,
        languageSecondId = R.string.language_2
    )
    val navController = NavController(LocalContext.current)
    VocabularyDisplayCard(
        vocabularyItem = item,
        navController = navController,
        isFlipped = false,
        switchOrder = false,
        onStatisticsClick = {},
        onMoveToCategoryClick = {},
        onMoveToStageClick = {},
        onDeleteClick = {},
    )
}

@Composable
private fun FrequencyPill(zipfFrequency: Float?) {
    if (zipfFrequency == null) return

    val semanticColors = MaterialTheme.semanticColors

    // Determine the label and color based on the Zipf value
    val (label, color) = when {
        zipfFrequency <= 2.0f -> Pair(stringResource(R.string.text_rare), semanticColors.wrongContainer)
        zipfFrequency <= 3.0f -> Pair(stringResource(R.string.text_infrequent), semanticColors.stageGradient2)
        zipfFrequency <= 4.0f -> Pair(stringResource(R.string.text_uncommon), semanticColors.stageGradient3)
        zipfFrequency <= 5.5f -> Pair(stringResource(R.string.text_common), semanticColors.stageGradient4)
        zipfFrequency <= 6.0f -> Pair(stringResource(R.string.text_frequent), semanticColors.stageGradient5)
        else -> Pair(stringResource(R.string.text_very_frequent), semanticColors.successContainer)
    }

    // Normalize progress: Zipf 1.0 to 8.0 mapped to 0f to 1f
    val progress = ((zipfFrequency - 1f) / (8f - 1f)).coerceIn(0f, 1f)

    Column(
        modifier = Modifier
            .padding(horizontal = 4.dp)
            .width(100.dp),
        horizontalAlignment = Alignment.CenterHorizontally
    ) {
        Surface(
            shape = RoundedCornerShape(16.dp),
            color = color.copy(alpha = 0.2f),
        ) {
            Text(
                text = label,
                style = MaterialTheme.typography.labelSmall,
                color = MaterialTheme.colorScheme.onSurface,
                modifier = Modifier.padding(horizontal = 8.dp, vertical = 2.dp)
            )
        }

        Spacer(modifier = Modifier.height(4.dp))

        // The "Slider" representation
        LinearProgressIndicator(
            progress = { progress },
            modifier = Modifier
                .fillMaxWidth()
                .height(4.dp)
                .clip(CircleShape),
            color = color,
            trackColor = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.1f),
            strokeCap = StrokeCap.Round
        )
    }
}

@Composable
private fun GrammarPill(
    wordDetails: GrammaticalFeature?,
    language: Language?,
    isEditing: Boolean,
    isRevealed: Boolean,
    onEditGrammarClick: () -> Unit
) {
    val activity = LocalContext.current.findActivity()
    val configViewModel: LanguageConfigViewModel = hiltViewModel(viewModelStoreOwner = activity)
    val allConfigs by configViewModel.configs.collectAsState()
    val languageConfig = language?.code?.let { allConfigs[it] }
    val categoryConfig = wordDetails?.category?.let { languageConfig?.categories?.get(it) }

    val propertiesString = remember(wordDetails, categoryConfig) {
        if (wordDetails == null) {
            ""
        } else {
            formatGrammarDetails(wordDetails, categoryConfig)
        }
    }

    when {
        isEditing && wordDetails == null -> {
            // Show "add grammar details" pill with plus icon
            Surface(
                shape = RoundedCornerShape(16.dp),
                color = MaterialTheme.colorScheme.primary.copy(alpha = 0.3f),
                modifier = Modifier
                    .padding(horizontal = 4.dp)
                    .clickable { onEditGrammarClick() }
            ) {
                Row(
                    verticalAlignment = Alignment.CenterVertically,
                    modifier = Modifier.padding(horizontal = 8.dp, vertical = 2.dp)
                ) {
                    Icon(
                        imageVector = AppIcons.Add,
                        contentDescription = stringResource(R.string.text_add_grammar_details),
                        modifier = Modifier.size(12.dp),
                        tint = MaterialTheme.colorScheme.onSurface
                    )
                    Spacer(Modifier.width(4.dp))
                    Text(
                        text = stringResource(R.string.text_add_grammar_details),
                        style = MaterialTheme.typography.labelMedium,
                        color = MaterialTheme.colorScheme.onSurface
                    )
                }
            }
        }
        isEditing && wordDetails != null -> {
            // Show existing grammar details as clickable pill
            Surface(
                shape = RoundedCornerShape(16.dp),
                color = MaterialTheme.colorScheme.primary.copy(alpha = 0.3f),
                modifier = Modifier
                    .padding(horizontal = 4.dp)
                    .clickable { onEditGrammarClick() }
            ) {
                Text(
                    text = propertiesString,
                    style = MaterialTheme.typography.labelMedium,
                    color = MaterialTheme.colorScheme.onSurface,
                    modifier = Modifier.padding(horizontal = 8.dp, vertical = 2.dp)
                )
            }
        }
        wordDetails != null && isRevealed -> {
            // Show grammar details as non-clickable pill
            Surface(
                shape = RoundedCornerShape(16.dp),
                color = MaterialTheme.colorScheme.secondary.copy(alpha = 0.3f),
                modifier = Modifier.padding(horizontal = 4.dp)
            ) {
                Text(
                    text = propertiesString,
                    style = MaterialTheme.typography.labelMedium,
                    color = MaterialTheme.colorScheme.onSurface,
                    modifier = Modifier.padding(horizontal = 8.dp, vertical = 2.dp)
                )
            }
        }
    }
}

@Composable
private fun CardFace(
    modifier: Modifier = Modifier,
    isFront: Boolean,
    isFirst: Boolean,
    languageViewModel: LanguageViewModel,
    isEditing: Boolean,
    word: String,
    onWordChange: (String) -> Unit,
    language: Language?,
    onLanguageIdChange: (Int?) -> Unit,
    isRevealed: Boolean = true,
    userSpellingAnswer: String?,
    isUserSpellingCorrect: Boolean?,
    correctWord: String,
    wordDetails: GrammaticalFeature?,
    onEditGrammarClick: () -> Unit,
    isExerciseMode: Boolean = false,
    vocabularyItem: VocabularyItem? = null,
    onMoreClick: (() -> Unit)? = null,
) {


    val coroutineScope = rememberCoroutineScope()
    val context = LocalContext.current
    val activity = LocalContext.current.findActivity()
    val settingsViewModel: SettingsViewModel = hiltViewModel(viewModelStoreOwner = activity)
    var playable by remember { mutableStateOf(false) }

    LaunchedEffect(language) {
        if (language != null) {
            playable = TextToSpeechHelper.isPlayable(context,language)
        }
        if (isEditing) {
            if (isFirst) {
                languageViewModel.setSelectedSourceLanguage(language?.nameResId)
            } else {
                languageViewModel.setSelectedTargetLanguage(language?.nameResId)
            }
        }
    }

    val showSpellingCorrection = !isEditing && isRevealed && (userSpellingAnswer != null)
    if(!isExerciseMode) {
        Row(
            verticalAlignment = Alignment.Top,
            modifier = Modifier.padding(start = 8.dp, end = 8.dp, top = 8.dp, bottom = 0.dp)
        ){
            val zipfFrequency = if(isFirst) vocabularyItem?.zipfFrequencyFirst else vocabularyItem?.zipfFrequencySecond

            FrequencyPill(zipfFrequency = zipfFrequency)

            GrammarPill(
                wordDetails = wordDetails,
                language = language,
                isEditing = isEditing,
                isRevealed = isRevealed,
                onEditGrammarClick = onEditGrammarClick
            )
        }
    }

    Box(modifier = modifier.fillMaxSize()) {
        Column(
            modifier = Modifier
                .fillMaxSize()
                .padding(horizontal = 0.dp, vertical = 0.dp),
            horizontalAlignment = Alignment.CenterHorizontally,
            verticalArrangement = Arrangement.Center
        ) {

            Row(
                verticalAlignment = Alignment.CenterVertically
            ) {
                if (isEditing) {
                    SingleLanguageDropDown(
                        modifier = Modifier.weight(1f),
                        languageViewModel = languageViewModel,
                        selectedLanguage = language,
                        onLanguageSelected = { selected -> onLanguageIdChange(selected.nameResId) },
                    )
                } else {
                    Text(
                        text = language?.name ?: stringResource(R.string.text_unknown_language),
                        style = MaterialTheme.typography.titleMedium,
                        maxLines = 1,
                        fontWeight = FontWeight.Bold,
                    )
                }
                if (!isEditing && playable && isRevealed) {
                    IconButton(onClick = {
                        coroutineScope.launch {
                            settingsViewModel.speakingSpeed.value
                            val voice = settingsViewModel.getTtsVoiceForLanguage(language!!.code, language.region)
                            TextToSpeechHelper.speakOut(context, word,
                                language, voice)
                        }
                    }) {
                        Icon(AppIcons.TextToSpeech, stringResource(R.string.cd_text_to_speech))
                    }
                }
            }

            Spacer(Modifier.height(2.dp))

            Column(
                horizontalAlignment = Alignment.CenterHorizontally,
                modifier = Modifier.padding(horizontal = 4.dp)
            ) {
                Box(
                    modifier = Modifier
                        .then(if (!isRevealed) Modifier.blur(10.dp) else Modifier),
                    contentAlignment = Alignment.Center
                ) {
                    if (showSpellingCorrection && !isFront && isExerciseMode) {
                        Column(horizontalAlignment = Alignment.CenterHorizontally) {
                            val userAnswerAnnotatedString = buildAnnotatedString {
                                if (isUserSpellingCorrect == false) {
                                    for (i in userSpellingAnswer.indices) {
                                        val userChar = userSpellingAnswer.getOrNull(i)
                                        val correctChar = correctWord.getOrNull(i)
                                        if (userChar != null && correctChar != null && userChar.equals(correctChar, ignoreCase = true)) {
                                            withStyle(style = SpanStyle(color = MaterialTheme.colorScheme.onSurface)) { append(userChar) }
                                        } else {
                                            withStyle(style = SpanStyle(color = MaterialTheme.colorScheme.error)) { append(userChar.toString()) }
                                        }
                                    }
                                } else {
                                    withStyle(style = SpanStyle(color = MaterialTheme.colorScheme.primary)) { append(
                                        userSpellingAnswer
                                    ) }
                                }
                            }
                            Text(text = userAnswerAnnotatedString, style = MaterialTheme.typography.headlineLarge, textAlign = TextAlign.Center)
                            if (isUserSpellingCorrect == false) {
                                Text(text = correctWord, style = MaterialTheme.typography.headlineLarge, color = MaterialTheme.colorScheme.primary, textAlign = TextAlign.Center)
                            }
                        }
                    }
                    else if (isEditing) {
                        TextField(
                            value = word,
                            onValueChange = onWordChange,
                            textStyle = MaterialTheme.typography.headlineLarge.copy(textAlign = TextAlign.Center)
                        )
                    } else {
                        val hasCompoundDelimiters = word.any { it == '-' || it == '–' || it == '—' || it == '‑' || it == '/' || it == '·' }
                        val isSingleToken = word.isNotBlank() && !word.any { it.isWhitespace() }
                        if (isSingleToken && !hasCompoundDelimiters) {
                            AutoResizeSingleLineText(
                                text = word,
                                style = MaterialTheme.typography.headlineLarge,
                                textAlign = TextAlign.Center
                            )
                        } else {
                            val displayText = insertBreakOpportunities(word)
                            Text(
                                text = displayText,
                                style = MaterialTheme.typography.headlineLarge,
                                textAlign = TextAlign.Center
                            )
                        }
                    }
                }

            }


            if (!isEditing) {
                Box(modifier = Modifier
                    .weight(2f, fill = false)
                    .padding(0.dp)) { }
            }
        }

        // Info icon in bottom left
        if (onMoreClick != null && !isEditing && (!isExerciseMode)) {
            IconButton(
                onClick = onMoreClick,
                modifier = Modifier
                    .align(Alignment.BottomStart)
                    .padding(8.dp)
            ) {
                Icon(
                    imageVector = AppIcons.Info,
                    contentDescription = stringResource(R.string.more),
                    tint = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.7f)
                )
            }
        }
    }
}

@Preview
@Composable
private fun FrequencyPillPreview() {
    FrequencyPill(zipfFrequency = 4.2f)
}

@Suppress("HardCodedStringLiteral")
@Preview
@Composable
private fun CardFacePreview() {
    val activity = LocalContext.current.findActivity()
    val languageViewModel: LanguageViewModel = hiltViewModel(viewModelStoreOwner = activity)
    val language = Language(
        code = "en",
        region = "US",
        nameResId = R.string.language_1,
        name = "English",
        englishName = "English"
    )
    val vocabularyItem = VocabularyItem(
        id = 1,
        wordFirst = "example",
        wordSecond = "Beispiel",
        languageFirstId = R.string.language_1,
        languageSecondId = R.string.language_2,
        zipfFrequencyFirst = 5.0f
    )

    CardFace(
        isFront = true,
        isFirst = true,
        languageViewModel = languageViewModel,
        isEditing = false,
        word = "example",
        onWordChange = {},
        language = language,
        onLanguageIdChange = {},
        isRevealed = true,
        userSpellingAnswer = null,
        isUserSpellingCorrect = null,
        correctWord = "example",
        wordDetails = null,
        onEditGrammarClick = {},
        isExerciseMode = false,
        vocabularyItem = vocabularyItem
    )
}