package eu.gaudian.translator.view.dictionary

import android.content.ClipData
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.clickable
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.Spacer
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.lazy.LazyRow
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.text.selection.SelectionContainer
import androidx.compose.material3.Button
import androidx.compose.material3.Card
import androidx.compose.material3.CardDefaults
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha
import androidx.compose.ui.platform.LocalClipboard
import androidx.compose.ui.platform.toClipEntry
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.style.TextDecoration
import androidx.compose.ui.text.withStyle
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.navigation.NavController
import androidx.navigation.compose.rememberNavController
import eu.gaudian.translator.R
import eu.gaudian.translator.model.DictionaryEntry
import eu.gaudian.translator.model.EntryPart
import eu.gaudian.translator.model.Language
import eu.gaudian.translator.model.repository.DictionaryWordEntry
import eu.gaudian.translator.utils.Log
import eu.gaudian.translator.utils.formatMarkdownText
import eu.gaudian.translator.view.composable.AppCard
import eu.gaudian.translator.view.composable.AppIcons
import eu.gaudian.translator.view.composable.AutoResizeSingleLineText
import eu.gaudian.translator.view.composable.ClickableText
import eu.gaudian.translator.viewmodel.DictionaryViewModel
import kotlinx.coroutines.launch
import kotlinx.serialization.json.JsonArray
import kotlinx.serialization.json.JsonPrimitive

@Composable
fun DictionaryResultBreadcrumbs(
    breadcrumbs: List<BreadcrumbItem>,
    navController: NavController
) {
    @Suppress("HardCodedStringLiteral")
    Log.d("DictionaryResultComponents", "[Breadcrumb] DictionaryResultBreadcrumbs called with ${breadcrumbs.size} items: ${breadcrumbs.map { it.word }}")
    
    // Only show breadcrumbs if there are 2 or more entries (meaning there's something to navigate back to)
    if (breadcrumbs.size >= 2) {
        @Suppress("HardCodedStringLiteral")
        Log.d("DictionaryResultComponents", "[Breadcrumb] Rendering breadcrumbs: ${breadcrumbs.map { it.word }}")
        LazyRow(
            modifier = Modifier
                .fillMaxWidth()
                .padding(horizontal = 16.dp, vertical = 8.dp),
            verticalAlignment = Alignment.CenterVertically
        ) {
            items(breadcrumbs) { item ->
                val isLast = item == breadcrumbs.last()
                @Suppress("HardCodedStringLiteral")
                Log.d("DictionaryResultComponents", "[Breadcrumb] Rendering item: '${item.word}' (isLast: $isLast)")
                Row(
                    verticalAlignment = Alignment.CenterVertically,
                    modifier = Modifier.clickable(enabled = !isLast) {
                        // Navigate back to this item by popping the back stack the required number of times
                        val index = breadcrumbs.indexOf(item)
                        if (index != -1) {
                            val stepsToPop = (breadcrumbs.size - 1) - index
                            repeat(stepsToPop) {
                                navController.popBackStack()
                            }
                        }
                    }
                ) {
                    Text(
                        text = item.word,
                        style = MaterialTheme.typography.bodyMedium,
                        fontWeight = if (isLast) FontWeight.Bold else FontWeight.Normal,
                        color = if (isLast) MaterialTheme.colorScheme.onSurface else MaterialTheme.colorScheme.primary
                    )
                    if (!isLast) {
                        Icon(
                            imageVector = AppIcons.ArrowRight,
                            contentDescription = null,
                            modifier = Modifier.size(16.dp),
                            tint = MaterialTheme.colorScheme.onSurfaceVariant
                        )
                    }
                }
            }
        }
        HorizontalDivider()
    } else {
        @Suppress("HardCodedStringLiteral")
        Log.d("DictionaryResultComponents", "[Breadcrumb] Breadcrumbs list has ${breadcrumbs.size} items - not rendering (need 2 or more for navigation)")
    }
}

@Composable
fun DictionaryResultEntryHeader(
    entry: DictionaryEntry
) {
    AutoResizeSingleLineText(
        text = entry.word,
        style = MaterialTheme.typography.displaySmall,
        fontWeight = FontWeight.Bold,
        modifier = Modifier.padding(top = 16.dp)
    )
}

@Composable
fun DictionaryResultLocalEntriesSection(
    localEntries: List<DictionaryWordEntry>,
    dictionaryViewModel: DictionaryViewModel,
    allLanguages: List<Language>,
    isDeveloperModeEnabled: Boolean
) {
    if (localEntries.isNotEmpty()) {

        localEntries.forEach { entry ->



            LocalWordEntryDisplay(
                entry = entry,
                dictionaryViewModel = dictionaryViewModel,
                allLanguages = allLanguages,
                expandable = localEntries.size>1
            )

            HorizontalDivider(modifier = Modifier.padding(vertical = 8.dp))
        }
        WiktionaryContentAcknowledgment()

        // Developer mode: Show raw JSON of local dictionary entries
        if (isDeveloperModeEnabled) {
            DictionaryResultDeveloperJsonSection(localEntries)
        }
    }
}

@Composable
fun WiktionaryContentAcknowledgment(
    modifier: Modifier = Modifier,
    wordUrl: String = "https://www.wiktionary.org/"
) {

    val licenseUrl = "https://creativecommons.org/licenses/by-sa/3.0/"

    val annotatedText = buildAnnotatedString {
        append(stringResource(R.string.text_content_sourced_from))

        // Wiktionary Link
        pushStringAnnotation(tag = "URL", annotation = wordUrl)
        withStyle(
            style = SpanStyle(
                color = MaterialTheme.colorScheme.primary,
                textDecoration = TextDecoration.Underline
            )
        ) {
            append(stringResource(R.string.label_wiktionary))
        }
        pop()

        append(". " + (stringResource(R.string.licensed_under) + " "))

        // License Link
        pushStringAnnotation(tag = "URL", annotation = licenseUrl)
        withStyle(
            style = SpanStyle(
                color = MaterialTheme.colorScheme.primary,
                textDecoration = TextDecoration.Underline
            )
        ) {
            @Suppress("HardCodedStringLiteral")
            append("CC BY-SA 3.0")
        }
        pop()
        append(".")
    }

    Box(
        modifier = modifier
            .fillMaxWidth()
            .padding(vertical = 8.dp),
        contentAlignment = Alignment.Center
    ) {
        ClickableText(
            text = annotatedText,
            style = MaterialTheme.typography.bodySmall.copy(
                textAlign = TextAlign.Center,
                color = MaterialTheme.colorScheme.onSurfaceVariant
            ),
        )
    }
}

@Preview(showBackground = true)
@Composable
fun WiktionaryAcknowledgmentPreview() {
    MaterialTheme {
        WiktionaryContentAcknowledgment()
    }
}

@Suppress("HardCodedStringLiteral")
@Composable
fun DictionaryResultDeveloperJsonSection(
    localEntries: List<DictionaryWordEntry>
) {
    HorizontalDivider(modifier = Modifier.padding(vertical = 8.dp))
    Text(
        text = stringResource(R.string.label_developer_json),
        style = MaterialTheme.typography.headlineSmall,
        color = MaterialTheme.colorScheme.primary,
        modifier = Modifier.padding(bottom = 8.dp)
    )
    
    val clipboard  = LocalClipboard.current
    val scope = rememberCoroutineScope()

    Button(
        onClick = {
            val allJson = localEntries.joinToString("\n\n") { entry ->
                "Entry ${entry.word} (${entry.langCode}):\n${entry.json}"
            }
            scope.launch {
                val clipData = ClipData.newPlainText(allJson, allJson)
                clipboard.setClipEntry(clipData.toClipEntry())
            }
            Log.d("DictionaryResultDeveloperJsonSection", "Copied JSON to clipboard:\n$allJson")
        },
        modifier = Modifier
            .fillMaxWidth()
            .padding(bottom = 8.dp)
    ) {
        @Suppress("HardCodedStringLiteral")
        Text(text = "Copy All JSON")
    }
    
    localEntries.forEachIndexed { index, entry ->
        // Log the JSON for debugging
        @Suppress("HardCodedStringLiteral")
        Log.d("DictionaryResultScreen", "Local Dictionary Entry ${index + 1}: ${entry.json}")

        Card(
            modifier = Modifier
                .fillMaxWidth()
                .padding(bottom = 8.dp),
            colors = CardDefaults.cardColors(containerColor = MaterialTheme.colorScheme.surfaceVariant.copy(alpha = 0.3f))
        ) {
            Column(
                modifier = Modifier.padding(12.dp)
            ) {
                Text(
                    text = "Entry ${index + 1} - ${entry.word} (${entry.langCode})",
                    style = MaterialTheme.typography.bodyMedium,
                    fontWeight = FontWeight.Bold,
                    color = MaterialTheme.colorScheme.primary
                )
                if (entry.pos != null) {
                    Text(
                        text = "POS: ${entry.pos}",
                        style = MaterialTheme.typography.bodySmall,
                        color = MaterialTheme.colorScheme.onSurfaceVariant
                    )
                }
                Spacer(modifier = Modifier.height(8.dp))
                SelectionContainer {
                    Text(
                        text = entry.json,
                        style = MaterialTheme.typography.bodySmall,
                        color = MaterialTheme.colorScheme.onSurface
                    )
                }
            }
        }
    }
}

// Keep the existing components that are already well-structured
@Composable
fun GeneratingAnimation() {
    @Suppress("HardCodedStringLiteral") val infiniteTransition = rememberInfiniteTransition(label = "pulsing")
    @Suppress("HardCodedStringLiteral") val alpha by infiniteTransition.animateFloat(
        initialValue = 0.3f,
        targetValue = 1f,
        animationSpec = infiniteRepeatable(
            animation = tween(1000),
            repeatMode = RepeatMode.Reverse
        ),
        label = "alpha"
    )

    Card(
        modifier = Modifier
            .fillMaxWidth()
            .padding(vertical = 8.dp),
        colors = CardDefaults.cardColors(containerColor = MaterialTheme.colorScheme.surfaceVariant.copy(alpha = 0.3f))
    ) {
        Row(
            modifier = Modifier
                .padding(16.dp)
                .fillMaxWidth(),
            verticalAlignment = Alignment.CenterVertically,
            horizontalArrangement = Arrangement.Center
        ) {
            Icon(
                imageVector = AppIcons.Refresh, // Or a brain icon if available
                contentDescription = null,
                modifier = Modifier
                    .size(24.dp)
                    .padding(end = 8.dp)
                    .alpha(alpha),
                tint = MaterialTheme.colorScheme.primary
            )
            Text(
                text = stringResource(R.string.text_contacting_ai),
                style = MaterialTheme.typography.bodyLarge,
                color = MaterialTheme.colorScheme.primary,
                modifier = Modifier.alpha(alpha)
            )
        }
    }
}

@Composable
fun DefinitionPart(part: EntryPart) {

    AppCard(
        modifier = Modifier.fillMaxWidth(),
        expandable = part.content.toString().length > 250,
        initiallyExpanded = true,
        title = part.title,
        icon = AppIcons.AI
    ) {
        Column(
            modifier = Modifier.padding(8.dp),
            verticalArrangement = Arrangement.spacedBy(8.dp)
        ) {

            // Safely extraction logic
            val contentText = remember(part.content) {
                try {
                    when (val contentElement = part.content) {
                        is JsonPrimitive -> contentElement.content
                        is JsonArray -> contentElement.joinToString(separator = "\n") { element ->
                            // Check if the element inside the array is actually a primitive
                            if (element is JsonPrimitive) {
                                "• ${element.content}"
                            } else {
                                // If it's an Object or Array, convert to string safely instead of crashing
                                "• $element"
                            }
                        }
                        // Fallback for JsonObject or other top-level types
                        else -> contentElement.toString()
                    }
                } catch (_: Exception) {
                    // Ultimate fallback if something else goes wrong during parsing
                    part.content.toString()
                }
            }

            SelectionContainer {
                Text(
                    text = formatMarkdownText(contentText),
                    style = MaterialTheme.typography.bodyLarge,
                    lineHeight = MaterialTheme.typography.bodyLarge.lineHeight
                )
            }
        }
    }
}



@Suppress("HardCodedStringLiteral")
@Preview(showBackground = true)
@Composable
fun DictionaryResultBreadcrumbsPreview() {
    val mockBreadcrumbs = listOf(
        BreadcrumbItem("Word1", 1),
        BreadcrumbItem("Word2", 2),
        BreadcrumbItem("Current", 3)
    )
    DictionaryResultBreadcrumbs(
        breadcrumbs = mockBreadcrumbs,
        navController = rememberNavController()
    )
}

@Suppress("HardCodedStringLiteral")
@Preview(showBackground = true)
@Composable
fun DictionaryResultEntryHeaderPreview() {
    val mockEntry = DictionaryEntry(
        id = 1,
        word = "Example",
        languageCode = 1,
        definition = emptyList(),
        languageName = "English",
    )
    DictionaryResultEntryHeader(
        entry = mockEntry
    )
}

@Suppress("HardCodedStringLiteral")
@Preview(showBackground = true)
@Composable
fun DictionaryResultDeveloperJsonSectionPreview() {
    val mockEntry = DictionaryWordEntry(
        word = "Example",
        langCode = "en",
        pos = "noun",
        json = """{"word": "example", "pos": "noun", "definition": "something that is typical"}"""
    )
    val mockEntries = listOf(mockEntry)
    
    DictionaryResultDeveloperJsonSection(
        localEntries = mockEntries
    )
}

@Preview(showBackground = true)
@Composable
fun GeneratingAnimationPreview() {
    GeneratingAnimation()
}

@Suppress("HardCodedStringLiteral")
@Preview(showBackground = true)
@Composable
fun DefinitionPartPreview() {
    val mockPart = EntryPart(
        title = "Definition",
        content = JsonPrimitive("A word or phrase used to describe something")
    )
    
    DefinitionPart(part = mockPart)
}

data class BreadcrumbItem(
    val word: String,
    val entryId: Int
)