@file:Suppress("AssignedValueIsNeverRead")

package eu.gaudian.translator.view.translation

import android.content.ClipData
import android.content.ClipboardManager
import android.content.Context
import android.content.Intent
import androidx.compose.animation.Crossfade
import androidx.compose.animation.core.FastOutSlowInEasing
import androidx.compose.animation.core.RepeatMode
import androidx.compose.animation.core.animateFloat
import androidx.compose.animation.core.infiniteRepeatable
import androidx.compose.animation.core.rememberInfiniteTransition
import androidx.compose.animation.core.tween
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxHeight
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.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.VerticalDivider
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.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalClipboard
import androidx.compose.ui.platform.LocalConfiguration
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.unit.dp
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
import androidx.lifecycle.compose.LocalLifecycleOwner
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.navigation.NavHostController
import eu.gaudian.translator.R
import eu.gaudian.translator.utils.Log
import eu.gaudian.translator.utils.TextToSpeechHelper
import eu.gaudian.translator.utils.findActivity
import eu.gaudian.translator.view.LocalConnectionConfigured
import eu.gaudian.translator.view.NoConnectionScreen
import eu.gaudian.translator.view.composable.AppCard
import eu.gaudian.translator.view.composable.AppOutlinedCard
import eu.gaudian.translator.view.dialogs.AddVocabularyDialog
import eu.gaudian.translator.view.hints.HintDefinition
import eu.gaudian.translator.view.settings.SettingsRoutes
import eu.gaudian.translator.viewmodel.LanguageViewModel
import eu.gaudian.translator.viewmodel.SettingsViewModel
import eu.gaudian.translator.viewmodel.TranslationViewModel
import kotlinx.coroutines.launch

@Composable
fun TranslationScreen(
    translationViewModel: TranslationViewModel,
    languageViewModel: LanguageViewModel,
    onHistoryClick: () -> Unit,
    onSettingsClick: () -> Unit,
    navController: NavHostController
) {
    val context = LocalContext.current
    val activity = LocalContext.current.findActivity()
    val settingsViewModel: SettingsViewModel = hiltViewModel(viewModelStoreOwner = activity)


    val isInitializationComplete by settingsViewModel.isInitialized.collectAsStateWithLifecycle(
        initialValue = true,
        lifecycleOwner = LocalLifecycleOwner.current
    )

    val connectionConfigured = LocalConnectionConfigured.current


    if (isInitializationComplete && !connectionConfigured) {
        NoConnectionScreen(onSettingsClick = { navController.navigate(SettingsRoutes.API_KEY) })
        return
    }

    val isUiReady = isInitializationComplete

    @Suppress("HardCodedStringLiteral")
    Crossfade(targetState = isUiReady, label = "loading_transition") { ready ->
        if (!ready) {
            TranslationScreenSkeleton()
        } else {
            // Real Content
            LoadedTranslationContent(
                translationViewModel = translationViewModel,
                languageViewModel = languageViewModel,
                settingsViewModel = settingsViewModel,
                onHistoryClick = onHistoryClick,
                onSettingsClick = onSettingsClick,
                onNavigateBack = {
                    if (!navController.popBackStack()) {
                        navController.navigate(eu.gaudian.translator.view.composable.Screen.Home.route) {
                            launchSingleTop = true
                            restoreState = false
                        }
                    }
                },
                context = context
            )
        }
    }
}

@Composable
private fun LoadedTranslationContent(
    translationViewModel: TranslationViewModel,
    languageViewModel: LanguageViewModel,
    settingsViewModel: SettingsViewModel,
    onHistoryClick: () -> Unit,
    onSettingsClick: () -> Unit,
    onNavigateBack: () -> Unit,
    context: Context
) {
    val inputText by translationViewModel.inputText.collectAsState()
    val translatedText by translationViewModel.translatedText.collectAsState()
    val targetLanguage by languageViewModel.selectedTargetLanguage.collectAsState()
    val isTranslating by translationViewModel.isTranslating.collectAsState()
    val isExplanationOn by translationViewModel.showExplanation.collectAsState()
    val explanationText by translationViewModel.explanationText.collectAsState()
    val canGoBack by translationViewModel.canGoBack.collectAsState()
    val canGoForward by translationViewModel.canGoForward.collectAsState()

    // Defer history logic
    val translationHistory by translationViewModel.translationHistory.collectAsState()
    val historyCursor by translationViewModel.historyCursor.collectAsState()

    val clipboard = LocalClipboard.current
    val coroutineScope = rememberCoroutineScope()
    var isPlayable by remember { mutableStateOf(false) }
    var showAddVocabularyDialog by remember { mutableStateOf(false) }

    val currentHistoryItem = remember(historyCursor, translationHistory) {
        if (historyCursor >= 0 && historyCursor < translationHistory.size) {
            translationHistory[historyCursor]
        } else {
            null
        }
    }
    val translationSource = currentHistoryItem?.translationSource
    val translationModel = currentHistoryItem?.translationModel

    if (showAddVocabularyDialog) {
        AddVocabularyDialog(
            initialWord = inputText,
            translation = translatedText,
            onDismissRequest = { showAddVocabularyDialog = false },
            showMultiple = false
        )
    }

    AppOutlinedCard {
        Column(
            modifier = Modifier
                .fillMaxSize()
                .padding(0.dp)
        ) {
            TopBarActions(
                languageViewModel = languageViewModel,
                onSettingsClick = onSettingsClick,
                onNavigateBack = onNavigateBack,
                hintContent = HintDefinition.TRANSLATION.hint()
            )

            AppCard(modifier = Modifier.padding(8.dp, end = 8.dp, bottom = 8.dp, top = 0.dp)) {
                val configuration = LocalConfiguration.current
                val isLandscape = configuration.orientation == android.content.res.Configuration.ORIENTATION_LANDSCAPE

                if (isLandscape) {
                    Row(modifier = Modifier.fillMaxSize()) {
                        InputCard(
                            modifier = Modifier.weight(1f),
                            text = inputText,
                            onTextChange = { translationViewModel.setInputText(it) },
                            onClearClick = { translationViewModel.clearInputAndOutputText() },
                            onPasteClick = {
                                coroutineScope.launch {
                                    val clipEntry = clipboard.getClipEntry()
                                    val text = clipEntry?.clipData?.getItemAt(0)?.coerceToText(context)?.toString()
                                    if (!text.isNullOrEmpty()) translationViewModel.setInputText(text)
                                }
                            },
                            onTranslateClick = { if (inputText.isNotBlank()) translationViewModel.translateSentence(inputText) },
                            isTranslating = isTranslating,
                            onHistoryClick = onHistoryClick,
                            showBackButton = canGoBack,
                            showForwardButton = canGoForward,
                            onBackClick = { translationViewModel.goBackInHistory() },
                            onForwardClick = { translationViewModel.goForwardInHistory() }
                        )

                        VerticalDivider(
                            modifier = Modifier.padding(vertical = 4.dp),
                            color = MaterialTheme.colorScheme.outline.copy(alpha = 0.3f)
                        )

                        OutputCard(
                            modifier = Modifier.weight(1f),
                            text = translatedText ?: "",
                            explanationText = explanationText,
                            isExplanationOn = isExplanationOn,
                            translationSource = translationSource,
                            translationModel = translationModel,
                            onCopyClick = { translatedText?.let { context.copyToClipboard(it) } },
                            onPlayClick = {
                                translatedText?.let { text ->
                                    targetLanguage?.let { lang ->
                                        coroutineScope.launch {
                                            val voice = settingsViewModel.getTtsVoiceForLanguage(lang.code, lang.region)
                                            TextToSpeechHelper.speakOut(context, text, lang, voice)
                                        }
                                    }
                                }
                            },
                            isPlayEnabled = isPlayable,
                            onShareClick = { translatedText?.let { shareText(context, it) } },
                            onAddToDictionaryClick = { if (!translatedText.isNullOrBlank()) showAddVocabularyDialog = true },
                            onExplanationToggle = { translationViewModel.toggleExplanation() },
                            onRequestAlternatives = { word, cb ->
                                coroutineScope.launch {
                                    val ctx = translatedText ?: ""
                                    cb(translationViewModel.getMultipleTranslations(word, ctx.ifBlank { null }))
                                }
                            },
                            onApplyAlternative = { original, chosen -> translationViewModel.applyAlternative(original, chosen) }
                        )
                    }
                } else {
                    InputCard(
                        modifier = Modifier.weight(1f),
                        text = inputText,
                        onTextChange = { translationViewModel.setInputText(it) },
                        onClearClick = { translationViewModel.clearInputAndOutputText() },
                        onPasteClick = {
                            coroutineScope.launch {
                                val clipEntry = clipboard.getClipEntry()
                                val text = clipEntry?.clipData?.getItemAt(0)?.coerceToText(context)?.toString()
                                if (!text.isNullOrEmpty()) translationViewModel.setInputText(text)
                            }
                        },
                        onTranslateClick = { if (inputText.isNotBlank()) translationViewModel.translateSentence(inputText) },
                        isTranslating = isTranslating,
                        onHistoryClick = onHistoryClick,
                        showBackButton = canGoBack,
                        showForwardButton = canGoForward,
                        onBackClick = { translationViewModel.goBackInHistory() },
                        onForwardClick = { translationViewModel.goForwardInHistory() }
                    )

                    HorizontalDivider(
                        modifier = Modifier.padding(horizontal = 4.dp),
                        color = MaterialTheme.colorScheme.outline.copy(alpha = 0.3f)
                    )

                    OutputCard(
                        modifier = Modifier.weight(1f),
                        text = translatedText ?: "",
                        explanationText = explanationText,
                        isExplanationOn = isExplanationOn,
                        translationSource = translationSource,
                        translationModel = translationModel,
                        onCopyClick = { translatedText?.let { context.copyToClipboard(it) } },
                        onPlayClick = {
                            translatedText?.let { text ->
                                targetLanguage?.let { lang ->
                                    coroutineScope.launch {
                                        val voice = settingsViewModel.getTtsVoiceForLanguage(lang.code, lang.region)
                                        TextToSpeechHelper.speakOut(context, text, lang, voice)
                                    }
                                }
                            }
                        },
                        isPlayEnabled = isPlayable,
                        onShareClick = { translatedText?.let { shareText(context, it) } },
                        onAddToDictionaryClick = { if (!translatedText.isNullOrBlank()) showAddVocabularyDialog = true },
                        onExplanationToggle = { translationViewModel.toggleExplanation() },
                        onRequestAlternatives = { word, cb ->
                            coroutineScope.launch {
                                val ctx = translatedText ?: ""
                                cb(translationViewModel.getMultipleTranslations(word, ctx.ifBlank { null }))
                            }
                        },
                        onApplyAlternative = { original, chosen -> translationViewModel.applyAlternative(original, chosen) }
                    )
                }
            }
        }
    }

    LaunchedEffect(targetLanguage) {
        isPlayable = TextToSpeechHelper.isPlayable(context, targetLanguage)
    }
}
@Suppress("HardCodedStringLiteral")
@Composable
fun TranslationScreenSkeleton() {
    Log.d("TranslationScreenSkeleton", "Skeleton started")

    val infiniteTransition = rememberInfiniteTransition(label = "shimmer")
    val alpha by infiniteTransition.animateFloat(
        initialValue = 0.3f,
        targetValue = 0.6f,
        animationSpec = infiniteRepeatable(
            animation = tween(1000, easing = FastOutSlowInEasing),
            repeatMode = RepeatMode.Reverse
        ),
        label = "alpha"
    )

    AppOutlinedCard {
        Column(modifier = Modifier.fillMaxSize()) {
            // Header Skeleton
            AppCard(Modifier.padding(horizontal = 8.dp, vertical = 8.dp)) {
                Row(
                    modifier = Modifier.fillMaxWidth().height(48.dp).padding(8.dp),
                    verticalAlignment = Alignment.CenterVertically
                ) {
                    Box(Modifier.weight(1f).fillMaxHeight().clip(RoundedCornerShape(8.dp)).background(Color.Gray.copy(alpha = alpha)))
                    Spacer(Modifier.width(8.dp))
                    Box(Modifier.size(24.dp).clip(CircleShape).background(Color.Gray.copy(alpha = alpha)))
                    Spacer(Modifier.width(8.dp))
                    Box(Modifier.size(24.dp).clip(CircleShape).background(Color.Gray.copy(alpha = alpha)))
                }
            }

            // Body Skeleton
            AppCard(modifier = Modifier.padding(8.dp, end = 8.dp, bottom = 8.dp, top = 0.dp)) {
                Column(Modifier.fillMaxSize()) {
                    // Input Area
                    Box(
                        Modifier
                            .weight(1f)
                            .fillMaxWidth()
                            .padding(16.dp)
                            .clip(RoundedCornerShape(8.dp))
                            .background(Color.Gray.copy(alpha = alpha / 2))
                    )

                    // Divider
                    Box(Modifier.fillMaxWidth().height(1.dp).background(Color.LightGray.copy(alpha = 0.2f)))

                    // Output Area
                    Box(
                        Modifier
                            .weight(1f)
                            .fillMaxWidth()
                            .padding(16.dp)
                            .clip(RoundedCornerShape(8.dp))
                            .background(Color.Gray.copy(alpha = alpha / 2))
                    )

                    // Bottom Buttons Row Skeleton
                    Row(Modifier.fillMaxWidth().padding(8.dp)) {
                        Box(Modifier.size(48.dp).clip(CircleShape).background(Color.Gray.copy(alpha = alpha)))
                        Spacer(Modifier.width(8.dp))
                        Box(Modifier.size(48.dp).clip(CircleShape).background(Color.Gray.copy(alpha = alpha)))
                    }
                }
            }
        }
    }
}

fun Context.copyToClipboard(text: String, label: String = getString(R.string.copied_text)) {
    val clipboard = getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
    val clip = ClipData.newPlainText(label, text)
    clipboard.setPrimaryClip(clip)
}

private fun shareText(context: Context, text: String) {
    val sendIntent: Intent = Intent().apply {
        action = Intent.ACTION_SEND
        putExtra(Intent.EXTRA_TEXT, text)
        type = "text/plain"
    }
    val shareIntent = Intent.createChooser(sendIntent, null)
    context.startActivity(shareIntent)
}