package pt.epvc.roleta.ui.components

import androidx.compose.animation.core.Animatable
import androidx.compose.animation.core.FastOutSlowInEasing
import androidx.compose.animation.core.tween
import androidx.compose.foundation.Canvas
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.aspectRatio
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material3.Surface
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
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.draw.rotate
import androidx.compose.ui.draw.shadow
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.geometry.Size
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.Path
import androidx.compose.ui.unit.dp
import androidx.compose.ui.text.ExperimentalTextApi
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.drawText
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.rememberTextMeasurer
import androidx.compose.ui.unit.sp
import pt.epvc.roleta.logic.PrizeLogic
import kotlin.math.cos
import kotlin.math.sin

@OptIn(ExperimentalTextApi::class)
@Composable
fun RouletteWheel(
    spinTrigger: Int,
    onSpinEnd: (pt.epvc.roleta.logic.Prize) -> Unit,
    modifier: Modifier = Modifier
) {
    val prizes = PrizeLogic.prizes
    val numSlices = prizes.size
    val anglePerSlice = 360f / numSlices

    // State for spinning
    val rotation = remember { Animatable(0f) }
    var resultPrize by remember { mutableStateOf<pt.epvc.roleta.logic.Prize?>(null) }
    val textMeasurer = rememberTextMeasurer()

    LaunchedEffect(spinTrigger) {
        if (spinTrigger > 0) {
            val prize = PrizeLogic.getRandomPrize()
            // To land on prize, we calculate its angle offset.
            // Slices are drawn starting from -90 degrees (top).
            // Index 0 starts at -18 degrees (since a slice is 36 deg, center is 0 deg from top).
            val sliceCenterAngle = prize.id * anglePerSlice - anglePerSlice
            
            // Current rotation modulo 360
            val currentRotMod = rotation.value % 360f
            
            // Calculate target - we want the center of the selected slice to be at the top (0 degrees).
            // This means we need to rotate backwards by the slice center angle.
            val targetRot = 360f - sliceCenterAngle + (360f * 5) // 5 extra full spins
            
            val totalTarget = rotation.value - currentRotMod + targetRot
            
            rotation.animateTo(
                targetValue = totalTarget,
                animationSpec = tween(durationMillis = 4000, easing = FastOutSlowInEasing)
            )
            onSpinEnd(prize)
        }
    }

    Box(
        modifier = modifier.aspectRatio(1f),
        contentAlignment = Alignment.Center
    ) {
        // Shadow and background
        Surface(
            modifier = Modifier
                .fillMaxSize()
                .padding(16.dp)
                .shadow(elevation = 16.dp, shape = CircleShape)
                .clip(CircleShape),
            color = Color.White
        ) {
            Canvas(
                modifier = Modifier
                    .fillMaxSize()
                    .rotate(rotation.value)
            ) {
                val radius = size.minDimension / 2
                val center = Offset(size.width / 2, size.height / 2)

                prizes.forEachIndexed { index, prize ->
                    // Android Canvas drawArc starts 0 at 3 o'clock. We want to start at top (-90 degrees),
                    // minus half a slice so index 0 is centered exactly at the top.
                    val startAngle = -90f - (anglePerSlice / 2) + (index * anglePerSlice)

                    // Draw slice shape
                    drawArc(
                        color = Color(android.graphics.Color.parseColor(prize.colorHex)),
                        startAngle = startAngle,
                        sweepAngle = anglePerSlice,
                        useCenter = true,
                        size = Size(size.minDimension, size.minDimension),
                        topLeft = Offset(center.x - radius, center.y - radius)
                    )

                    // Draw text inside each slice
                    // Calculate middle angle of the slice for text
                    val textAngle = startAngle + (anglePerSlice / 2)
                    val textAngleRad = Math.toRadians(textAngle.toDouble())
                    
                    // Distance from center to draw the text 
                    val textRadius = radius * 0.75f
                    
                    val textStr = prize.id.toString()
                    val textLayoutResult = textMeasurer.measure(
                        text = textStr,
                        style = TextStyle(
                            color = Color.White,
                            fontSize = (radius * 0.15f).sp,
                            fontWeight = FontWeight.Bold
                        )
                    )

                    val textSize = textLayoutResult.size
                    // Translate standard center to text position
                    val textX = center.x + textRadius * cos(textAngleRad).toFloat()
                    val textY = center.y + textRadius * sin(textAngleRad).toFloat()

                    drawContext.canvas.save()
                    drawContext.canvas.translate(textX, textY)
                    // Rotate canvas so text points outwards or towards center
                    drawContext.canvas.rotate(textAngle + 90f)
                    
                    drawText(
                        textLayoutResult = textLayoutResult,
                        topLeft = Offset(-textSize.width / 2f, -textSize.height / 2f)
                    )
                    drawContext.canvas.restore()
                }

                // Draw center white dot
                drawCircle(
                    color = Color.White,
                    radius = radius * 0.15f,
                    center = center
                )
                drawCircle(
                    color = Color.LightGray,
                    radius = radius * 0.15f,
                    center = center,
                    style = androidx.compose.ui.graphics.drawscope.Stroke(width = 8f)
                )
            }
        }

        // Fixed pointer at the top
        Canvas(modifier = Modifier
            .size(40.dp)
            .align(Alignment.TopCenter)
            .padding(top = 4.dp)
        ) {
            val path = Path().apply {
                moveTo(size.width / 2, size.height)
                lineTo(0f, 0f)
                lineTo(size.width, 0f)
                close()
            }
            drawPath(
                path = path,
                color = Color.Red
            )
        }
    }
}
