package main

import androidx.compose.foundation.*
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.material.Button
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import main.component.dropdownButtonComponent
import androidx.compose.foundation.Canvas
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.ui.geometry.Rect
import androidx.compose.ui.geometry.Size
import androidx.compose.ui.graphics.Paint
import androidx.compose.ui.graphics.Path
import androidx.compose.ui.graphics.drawscope.drawIntoCanvas
import androidx.compose.ui.graphics.toArgb
import androidx.compose.ui.text.*
import androidx.compose.ui.unit.Constraints
import androidx.compose.ui.unit.sp


@Composable
fun compareResults(
    languageManager: LanguageManager,
    glossaryWords: List<Word>,
    codeWords: List<String>,
    onBackClick: () -> Unit,
    onProjectClick: () -> Unit,
    onCodeToVerifyClick: () -> Unit,
) {
    println(glossaryWords)
    val noFileSnackbarVisibleState = remember { mutableStateOf(false) }
    val scrollState = rememberLazyListState()
    val showTableAndLegend = remember { mutableStateOf(true) } // State to control the visibility of the table and legend

    Column(
        modifier = Modifier.fillMaxSize(),
        verticalArrangement = Arrangement.Top,
        horizontalAlignment = Alignment.CenterHorizontally
    ) {

        Text(text = "Comparaison glossaire / code", style = MaterialTheme.typography.h3)

        val glossaryWordsSet = glossaryWords.map { it.name }.toSet()

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

        // Show the table and legend only if showTableAndLegend is true
        if (showTableAndLegend.value) {
            commonWordsTable(glossaryWords, codeWords)

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

            // Légende
            Row(
                modifier = Modifier.fillMaxWidth().padding(16.dp),
                // Espace entre les éléments
                horizontalArrangement = Arrangement.spacedBy(16.dp)
            ) {
                legendItem(color = customGreenColor, label = "Mot dans le glossaire et dans le code")
                legendItem(color = Color.White, label = "Mot seulement dans le glossaire")
                legendItem(color = customYellowColor, label = "Mot seulement dans le code")
            }
        }

        val intersectionWords = mutableListOf<String>()

        Spacer(modifier = Modifier.height(16.dp))
        println("glossaryWords : $glossaryWordsSet")

        for (word in codeWords) {
            if (word in glossaryWords.map { it.name }) {
                intersectionWords.add(word)
                println("inter : $word")
            }
        }

        // Show the Venn diagram only if showTableAndLegend is false
        if (!showTableAndLegend.value) {
            IntersectionCircles(
                intersectionWords,
                glossaryWords,
                codeWords
            )
        }

        Button(
            onClick = { showTableAndLegend.value = !showTableAndLegend.value }, // Toggle the value of showTableAndLegend when the button is clicked
            colors = androidx.compose.material.ButtonDefaults.buttonColors(
                backgroundColor = customRedColor,
                contentColor = Color.White
            )
        ) {
            Text(if (showTableAndLegend.value) "Montrer le diagramme de Venn" else "Montrer le tableau") // Change the button text based on the value of showTableAndLegend
        }

        Button(
            onClick = onBackClick,
            colors = androidx.compose.material.ButtonDefaults.buttonColors(
                backgroundColor = customRedColor,
                contentColor = Color.White
            )
        ) {
            Text(languageManager.getBackText())
        }
    }
    dropdownButtonComponent(
        languageManager = languageManager,
        items = listOf(languageManager.getGlossaryText(), languageManager.getCodeToVerifyText(), languageManager.getCompareText())
    ) { selectedOption ->
        // Handle the selected option
        when (selectedOption) {
            languageManager.getGlossaryText() -> onProjectClick()
            languageManager.getCodeToVerifyText() -> onCodeToVerifyClick()
            languageManager.getCompareText() -> {
                if (mostUsedWordList.isEmpty()) {
                    noFileSnackbarVisibleState.value = true
                    return@dropdownButtonComponent
                } else {
                    currentPage.value = "compareProject"
                }
            }
        }
    }
}

// Ajouter une légende au tableau
@OptIn(ExperimentalFoundationApi::class)
@Composable
fun commonWordsTable(
    glossaryWords: List<Word>,
    codeWords: List<String>
) {
    val glossaryWordsSet = glossaryWords.map { it.name }.toSet()
    println("glossaryWordsSet : $glossaryWordsSet")

    Box(
        modifier = Modifier
            .height(450.dp)
    ) {
        val scrollState = rememberLazyListState()
        LazyColumn(
            state = scrollState,
            modifier = Modifier.fillMaxSize().padding(16.dp),
            content = {
                stickyHeader {
                    commonWordsHeaderRow()
                }
                items(glossaryWords) { word ->
                    commonWordsDataRow(word.name, codeWords, glossaryWordsSet)
                }
                items(codeWords) { word ->
                    if (word !in glossaryWordsSet) {
                        commonWordsDataRow(word, codeWords, glossaryWordsSet)
                    }
                }
            }
        )
        VerticalScrollbar(
            modifier = Modifier.align(Alignment.CenterEnd).fillMaxHeight(),
            adapter = rememberScrollbarAdapter(scrollState)
        )
    }
}

@Composable
fun legendItem(color: Color, label: String) {
    Row(
        verticalAlignment = Alignment.CenterVertically,
        horizontalArrangement = Arrangement.spacedBy(4.dp)
    ) {
        Box(
            modifier = Modifier
                .width(24.dp)
                .height(14.dp)
                .background(color)
                .border(1.dp, Color.Black)
        )
        Text(text = label)
    }
}


@Composable
fun commonWordsHeaderRow() {
    Row(
        modifier = Modifier
            .fillMaxWidth()
            .background(customRedColor)
            .border(1.dp, Color.Black),
        verticalAlignment = Alignment.CenterVertically
    ) {
        listOf("Mot du glossaire", "Mot du code", "Présence commune").forEach { header ->
            Text(
                text = header,
                fontWeight = FontWeight.Bold,
                modifier = Modifier.weight(1f).padding(8.dp),
                color = Color.White
            )
        }
    }
}

@Composable
fun commonWordsDataRow(
    word: String,
    codeWords: List<String>,
    glossaryWordsSet: Set<String>
) {
    val modifier = Modifier
        .fillMaxWidth()

    val isCommon = word in codeWords && word in glossaryWordsSet

    val backgroundColor = when {
        isCommon -> customGreenColor // Couleur pour les mots communs
        word in codeWords -> customYellowColor // Couleur pour les mots du code
        word in glossaryWordsSet -> Color.White // Couleur pour les mots du glossaire
        else -> Color.White
    }

    Row(
        modifier = modifier.background(backgroundColor)
            .border(1.dp, Color.Black)
            .padding(8.dp),
        verticalAlignment = Alignment.CenterVertically
    ) {
        cellContent(word, modifier)
        cellContent(if (word in codeWords) "Oui" else "Non", modifier)
        cellContent(if (isCommon) "Oui" else "Non", modifier)
    }
}
@OptIn(ExperimentalTextApi::class)
@Composable
fun IntersectionCircles(
    glossaryCodeWords: List<String>,
    glossaryWords: List<Word>,
    codeWords: List<String>
) {
    // Take up to 10 words for each category
    val glossaryWordsSubset = glossaryWords.take(10).map { it.name }
    val codeWordsSubset = codeWords.take(10)
    val intersectionWords = glossaryCodeWords.take(10)

    val intersectionSize = intersectionWords.size / 10f // Normalize to [0, 1]

    val circleRadius = 300f // Fixed radius for both circles
    val circleDistance = (1 - intersectionSize) * 2 * circleRadius // Distance between the centers of the circles

    val textMeasurer = rememberTextMeasurer()

    Row (
        modifier = Modifier.fillMaxWidth(),
        horizontalArrangement = Arrangement.SpaceEvenly
    ) {

        drawLegend(100f, 500f)

        Canvas(modifier = Modifier.size(500.dp)) {
            // Draw glossary circle
            drawCircle(
                color = Color(0xFFA1C084),
                center = Offset(x = size.width / 2 - circleDistance / 2, y = size.height / 2),
                radius = circleRadius
            )

            // Draw code circle
            drawCircle(
                color = Color(0xFFE9C46A),
                center = Offset(x = size.width / 2 + circleDistance / 2, y = size.height / 2),
                radius = circleRadius
            )



            // Draw intersection with clipping
            drawIntoCanvas { canvas ->
                val path = Path().apply {
                    addOval(
                        Rect(
                            center = Offset(x = size.width / 2 - circleDistance / 2, y = size.height / 2),
                            radius = circleRadius
                        )
                    )
                }
                canvas.save()
                canvas.clipPath(path)
                drawCircle(
                    color = Color(0xFF6E7271),
                    center = Offset(x = size.width / 2 + circleDistance / 2, y = size.height / 2),
                    radius = circleRadius
                )
                canvas.restore()
            }

            // Draw words on the circles
            val glossaryCircleCenter = Offset(x = size.width / 2 - circleDistance / 2, y = size.height / 2)
            val codeCircleCenter = Offset(x = size.width / 2 + circleDistance / 2, y = size.height / 2)

            var xOffset = 0f
            var xOffsetIntersection = 0f
            var doNotWrite = false
            var doNotWriteIntersect = false
            if (intersectionWords.size > 6) {
                doNotWrite = true
                xOffsetIntersection = size.width / 2 - circleDistance / 2
            } else if (intersectionWords.size > 4) {
                xOffset = codeCircleCenter.x + 80f
                xOffsetIntersection = size.width / 2 - circleDistance / 2
            } else if(intersectionWords.size > 1) {
                xOffset = codeCircleCenter.x -20f
                xOffsetIntersection = size.width / 2 - circleDistance / 2 + circleRadius / 1.5f
            } else {
                doNotWriteIntersect = true
                xOffset = codeCircleCenter.x - 80f
                xOffsetIntersection = size.width / 2 - circleDistance / 2 + circleRadius / 2
            }

            glossaryWordsSubset.forEachIndexed { index, word ->
                drawIntoCanvas { _ ->
                    if (!doNotWrite) {
                        drawText(
                            textMeasurer,
                            word,
                            Offset(
                                glossaryCircleCenter.x - circleRadius / 2,
                                glossaryCircleCenter.y - circleRadius / 2 + index * 30f
                            ),
                        )
                    }
                }
            }

            codeWordsSubset.forEachIndexed { index, word ->
                drawIntoCanvas { _ ->

                    if (!doNotWrite) {
                        drawText(
                            textMeasurer,
                            word,
                            Offset(
                                xOffset, // Subtract half the text width from the x-coordinate
                                codeCircleCenter.y - circleRadius / 2 + index * 30f
                            )
                        )
                    }
                }
            }

            intersectionWords.forEachIndexed { index, word ->
                drawIntoCanvas { _ ->
                    if (!doNotWriteIntersect) {
                        drawText(
                            textMeasurer,
                            word,
                            Offset(
                                xOffsetIntersection,
                                size.height / 2 - circleRadius / 2 + index * 30f
                            ),
                        )
                    }
                }
            }

        }

    }

}

@OptIn(ExperimentalTextApi::class)
@Composable
fun drawLegend(canvasWidth: Float, canvasHeight: Float) {
    val legendTextSize = 20f
    val legendItemHeight = 40f
    val legendStartOffset = Offset(x = canvasWidth, y = canvasHeight / 2)


    val legendItems = listOf(
        LegendItem("Mots du glossaire", Color(0xFFA1C084)),
        LegendItem("Mots du code", Color(0xFFE9C46A)),
        LegendItem("Mots du glossaire et du code", Color(0xFF6E7271))
    )

    val textMeasurer = rememberTextMeasurer()

    Canvas(modifier = Modifier.size(width = 50.dp, height = 500.dp)) {
        legendItems.forEachIndexed { index, legendItem ->
            drawRect(
                color = legendItem.color,
                topLeft = legendStartOffset + Offset(x=-50f, y = index * legendItemHeight),
                size = Size(20f, 20f)
            )
            drawIntoCanvas { _ ->
                drawText(
                    textMeasurer,
                    legendItem.label,
                    Offset(
                        -150f,
                        legendStartOffset.y + index * legendItemHeight
                    ),
                )
            }
        }
    }
}

data class LegendItem(val label: String, val color: Color)


