package solutions.tretter.githugandroid

import androidx.compose.animation.core.LinearEasing
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.Canvas
import androidx.compose.foundation.background
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.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.Checkbox
import androidx.compose.material3.CheckboxDefaults
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.geometry.Rect
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.Path
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import kotlin.math.roundToInt

@Composable
internal fun HelpCalloutOverlay(
    showHelpOnStart: Boolean,
    onShowHelpOnStartChange: (Boolean) -> Unit,
    onOk: () -> Unit,
    onClose: () -> Unit,
    exerciseBounds: Rect?,
    promptBounds: Rect?,
) {
    val density = LocalDensity.current
    val insetPx = with(density) { 14.dp.roundToPx() }
    Box(modifier = Modifier.fillMaxSize()) {
        HelpBubble(
            text = "Read the exercise description, then solve it by entering commands below.",
            modifier = exerciseBounds?.let { bounds ->
                Modifier.offset {
                    IntOffset(
                        x = insetPx,
                        y = (bounds.top - insetPx).roundToInt().coerceAtLeast(0),
                    )
                }
            } ?: Modifier
                .align(Alignment.TopStart)
                .padding(horizontal = 14.dp, vertical = 10.dp),
        )
        HelpBubbleWithControls(
            modifier = promptBounds?.let { bounds ->
                val bubbleHeight = with(density) { 190.dp.roundToPx() }
                Modifier.offset {
                    IntOffset(
                        x = insetPx,
                        y = (bounds.top - bubbleHeight).roundToInt().coerceAtLeast(0),
                    )
                }
            } ?: Modifier
                .align(Alignment.BottomStart)
                .padding(start = 14.dp, bottom = 96.dp),
            text = "Tap the prompt to enter a command or answer.",
            showHelpOnStart = showHelpOnStart,
            onShowHelpOnStartChange = onShowHelpOnStartChange,
            onOk = onOk,
            onClose = onClose,
        )
    }
}

@Composable
private fun HelpBubbleWithControls(
    text: String,
    showHelpOnStart: Boolean,
    onShowHelpOnStartChange: (Boolean) -> Unit,
    onOk: () -> Unit,
    onClose: () -> Unit,
    modifier: Modifier = Modifier,
) {
    val bubbleColor = Color(0xFFFFF1A8)
    Column(modifier = modifier.fillMaxWidth(0.9f)) {
        Box(
            modifier = Modifier
                .background(bubbleColor, RoundedCornerShape(18.dp))
                .padding(horizontal = 14.dp, vertical = 10.dp),
        ) {
            Column(verticalArrangement = Arrangement.spacedBy(8.dp)) {
                Text(
                    text = text,
                    color = Color(0xFF161000),
                    fontWeight = FontWeight.Bold,
                    fontSize = 14.sp,
                )
                Row(
                    verticalAlignment = Alignment.CenterVertically,
                    horizontalArrangement = Arrangement.spacedBy(8.dp),
                ) {
                    Checkbox(
                        checked = showHelpOnStart,
                        onCheckedChange = onShowHelpOnStartChange,
                        colors = CheckboxDefaults.colors(
                            checkedColor = Color(0xFF161000),
                            uncheckedColor = Color(0xFF6E5A00),
                            checkmarkColor = bubbleColor,
                        ),
                    )
                    Text("Show help on start", color = Color(0xFF161000))
                }
                Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) {
                    Button(
                        onClick = onOk,
                        colors = ButtonDefaults.buttonColors(
                            containerColor = Color(0xFF161000),
                            contentColor = bubbleColor,
                        ),
                    ) {
                        Text("OK")
                    }
                    TextButton(onClick = onClose) {
                        Text("Close", color = Color(0xFF161000))
                    }
                }
            }
        }
        BubbleTail(bubbleColor)
    }
}

@Composable
private fun HelpBubble(
    text: String,
    modifier: Modifier = Modifier,
) {
    val bubbleColor = Color(0xFFFFF1A8)
    Column(modifier = modifier.fillMaxWidth(0.86f)) {
        Box(
            modifier = Modifier
                .background(bubbleColor, RoundedCornerShape(18.dp))
                .padding(horizontal = 14.dp, vertical = 10.dp),
        ) {
            Text(
                text = text,
                color = Color(0xFF161000),
                fontWeight = FontWeight.Bold,
                fontSize = 14.sp,
            )
        }
        BubbleTail(bubbleColor)
    }
}

@Composable
private fun BubbleTail(color: Color) {
    Canvas(
        modifier = Modifier
            .padding(start = 28.dp)
            .size(width = 26.dp, height = 13.dp),
    ) {
        drawPath(
            path = Path().apply {
                moveTo(0f, 0f)
                lineTo(size.width, 0f)
                lineTo(size.width * 0.25f, size.height)
                close()
            },
            color = color,
        )
    }
}

@Composable
internal fun MissingNativeGitScreen(message: String) {
    Surface(
        modifier = Modifier
            .fillMaxSize()
            .background(AppBackground)
            .padding(24.dp),
        color = AppBackground,
    ) {
        Column(
            modifier = Modifier.fillMaxSize(),
            verticalArrangement = Arrangement.Center,
            horizontalAlignment = Alignment.Start,
        ) {
            Text(
                text = "Native Git unavailable",
                color = TextPrimary,
                fontWeight = FontWeight.Bold,
                fontSize = 22.sp,
            )
            Text(
                text = message,
                modifier = Modifier.padding(top = 12.dp),
                color = TextSecondary,
                fontSize = 15.sp,
            )
        }
    }
}

@Composable
internal fun SolvedCelebrationOverlay(title: String) {
    val transition = rememberInfiniteTransition(label = "solved-celebration")
    val progress by transition.animateFloat(
        initialValue = 0f,
        targetValue = 1f,
        animationSpec = infiniteRepeatable(
            animation = tween(durationMillis = 1_200, easing = LinearEasing),
            repeatMode = RepeatMode.Restart,
        ),
        label = "confetti-progress",
    )
    val colors = listOf(Accent, Success, Color(0xFFFFD166), Color(0xFFFF6B6B), Color(0xFF9BF6FF))

    Box(
        modifier = Modifier.fillMaxSize(),
        contentAlignment = Alignment.Center,
    ) {
        Canvas(modifier = Modifier.fillMaxSize()) {
            repeat(42) { index ->
                val x = ((index * 73) % 100) / 100f * size.width
                val baseY = ((index * 37) % 100) / 100f * size.height
                val y = (baseY + progress * size.height * 0.6f) % size.height
                val pieceSize = 6.dp.toPx() + (index % 4) * 2.dp.toPx()
                drawCircle(
                    color = colors[index % colors.size],
                    radius = pieceSize / 2f,
                    center = Offset(x, y),
                    alpha = 0.85f,
                )
            }
        }
        Column(
            modifier = Modifier
                .background(PanelPrimary.copy(alpha = 0.94f), RoundedCornerShape(24.dp))
                .padding(horizontal = 26.dp, vertical = 22.dp),
            horizontalAlignment = Alignment.CenterHorizontally,
            verticalArrangement = Arrangement.spacedBy(8.dp),
        ) {
            Text(text = "👍", fontSize = 56.sp)
            Text(text = "Level solved", color = Success, fontSize = 22.sp)
            Text(text = title, color = TextSecondary, fontSize = 14.sp)
        }
    }
}
