package mg.dot.feufaro.ui

import androidx.compose.animation.*
import androidx.compose.animation.core.LinearEasing
import androidx.compose.animation.core.tween
import androidx.compose.foundation.Image
import androidx.compose.foundation.ScrollState
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.clickable
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.KeyboardArrowLeft
import androidx.compose.material.icons.automirrored.filled.KeyboardArrowRight
import androidx.compose.material.icons.filled.*
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.draw.paint
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.RectangleShape
import androidx.compose.ui.graphics.TransformOrigin
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import feufaro.composeapp.generated.resources.Res
import feufaro.composeapp.generated.resources.ic_mixer_satb
import feufaro.composeapp.generated.resources.ic_organ
import feufaro.composeapp.generated.resources.mixer_bg
import feufaro.composeapp.generated.resources.mixer_fader
import kotlinx.coroutines.delay
import mg.dot.feufaro.getPlatform
import mg.dot.feufaro.midi.FMediaPlayer
import org.jetbrains.compose.resources.painterResource

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun MidiControlPanel(
    isPause: Boolean,
    currentPos: Float,
    volume: Float,
    duration: Float,
    solfaScrollState: ScrollState,
    onPlayPauseClick: () -> Unit,
    onSeek: (Float) -> Unit,
    onVolumeChange: (Float) -> Unit,
    onVoiceVolumeChange: (voiceIndex: Int, newVolume: Float) -> Unit,
    mediaPlayer: FMediaPlayer,
    modifier: Modifier = Modifier
) {
    val momo = duration.toInt() - currentPos.toInt()

    val loopState by produceState(Triple(-1L, -1L, false), mediaPlayer) {
        while (true) {
            value = mediaPlayer.getLoopState()
            delay(200)
        }
    }

    val sliderVolumes = remember {
        mediaPlayer.getVoiceVolumes().map { mutableStateOf(it) }.toMutableStateList()
    }
    val labels = listOf("S", "A", "T", "B")
    listOf("Soprano", "Alto", "Ténor", "Basse")

    var tempo by remember { mutableStateOf(120.toFloat()) }
    var currentBpm by remember { mutableStateOf(mediaPlayer.getCurrentBPM()) }

    var isPianoSelected by remember { mutableStateOf(true) }

    var showSATBTools by remember { mutableStateOf(false) }
    var expandedCtl by remember { mutableStateOf(false) }
    val platform = getPlatform().name
    val coroutineScope = rememberCoroutineScope()

    LaunchedEffect(currentPos, duration, solfaScrollState.viewportSize, solfaScrollState.maxValue) {
        if (duration > 0f && solfaScrollState.maxValue > 0) {
            val progress = (currentPos / duration).coerceIn(0f, 1f)
            val viewportHeight = solfaScrollState.viewportSize.toFloat()
            val totalContentHeight = solfaScrollState.maxValue + viewportHeight

            val targetY = (progress * (totalContentHeight-200)) - (viewportHeight / 2)
            val finalTarget = targetY.coerceIn(0f, solfaScrollState.maxValue.toFloat())
            solfaScrollState.animateScrollTo(
                value = finalTarget.toInt(),
                animationSpec = tween (
                    durationMillis = 300,
                    easing = LinearEasing
                )
            )
        }
    }
    LaunchedEffect(tempo) {
        currentBpm = mediaPlayer.getCurrentBPM()
    }
    fun updateTempoToBpm(newBpm: Int) {
        tempo = newBpm.toFloat()
        mediaPlayer?.setTempo(tempo)
    }
    fun updateTempoByBpmStep(step: Int) {
        val currentBpm = mediaPlayer!!.getCurrentBPM()
        val nextBpm = currentBpm.toInt() + step
        updateTempoToBpm(nextBpm)
    }

    Column(
        modifier = Modifier.fillMaxWidth()
    ) {
        Row(
            modifier = Modifier.fillMaxWidth(),
            verticalAlignment = Alignment.Bottom,
            horizontalArrangement = Arrangement.Center
        ) {
            Column(
                modifier = modifier
                    .fillMaxWidth(if (platform.startsWith("Android")) 1f else 0.6f)
                    .background(color = Color.Gray.copy(alpha = 0.5f), shape = RoundedCornerShape(size = 5.dp)),
                horizontalAlignment = Alignment.CenterHorizontally
            ) {
                AnimatedVisibility(
                    visible = !expandedCtl
                ) {
                    Row(
                        verticalAlignment = Alignment.CenterVertically,
                        horizontalArrangement = Arrangement.spacedBy(8.dp)
                    ) {
                        Text("${currentPos.toInt() / 1000}s", color = Color.White)
                        Slider(
                            value = currentPos,
                            onValueChange = onSeek,
                            valueRange = 0f..(if (duration > 0) duration else 1f),
                            modifier = Modifier.weight(1f),
                            colors = SliderDefaults.colors(
                                thumbColor = Color.Red,
                                activeTrackColor = Color.Green,
                                inactiveTrackColor = Color.Gray,
                                inactiveTickColor = Color(0xffb0BEC5),
                                disabledThumbColor = Color(0xff78909C),
                                disabledActiveTickColor = Color(0xff757575),
                                disabledActiveTrackColor = Color(0xffBDBDBD),
                                disabledInactiveTickColor = Color(0xff616161),
                                disabledInactiveTrackColor = Color(0xffBCAAA4),
                            ),
                            thumb = {
                                Box(
                                    modifier = Modifier
                                        .size(15.dp)
                                        .background(Color.Gray, CircleShape)
                                )
                            },
                            track = { sliderState ->
                                SliderDefaults.Track(
                                    sliderState = sliderState,
                                    modifier = Modifier.height(5.dp)
                                )
                            }
                        )
                        Text("${momo / 1000}s", color = Color.White)
                    }
                }

                AnimatedVisibility(
                    visible = showSATBTools,
                    enter = fadeIn() + scaleIn() + slideInVertically { it / 2 },
                    exit = fadeOut() + scaleOut() + slideOutVertically { it / 2 }
                ) {
                    Row(
                        modifier = Modifier
                            .height(100.dp)
                            .widthIn(max = 250.dp)
                            .paint(
                                painter = painterResource(Res.drawable.mixer_bg),
                                contentScale = ContentScale.FillBounds
                            )
                            .padding(start = 0.dp, end = 0.dp)
                        ,
                        verticalAlignment = Alignment.CenterVertically,
                        horizontalArrangement = Arrangement.SpaceEvenly
                    ) {
                        for (i in 0 until 4) {
                            Box(
                                modifier = Modifier
                                    .fillMaxHeight()
                                    .weight(1f),
                                contentAlignment = Alignment.Center
                            ) {
                                Slider(
                                    value = sliderVolumes[i].value,
                                    onValueChange = { newValue ->
                                        sliderVolumes[i].value = newValue
                                        mediaPlayer.updateVoiceVolume(i, newValue)
                                    },
                                    valueRange = 0f..126f,
                                    modifier = Modifier
                                        .fillMaxHeight()
                                        .graphicsLayer {
                                            rotationZ = -90f
                                            transformOrigin = TransformOrigin.Center
                                        }
                                        .fillMaxWidth(),
                                    thumb = {
                                        Image(
                                            painter = painterResource(Res.drawable.mixer_fader),
                                            contentDescription = "Fader Thumb",
                                            modifier = Modifier
                                                .size(width = 20.dp, height = 20.dp)
                                                .graphicsLayer {
                                                    rotationZ = 90f
                                                },
                                            contentScale = ContentScale.Fit
                                        )
                                    },
                                    colors = SliderDefaults.colors(
                                        thumbColor = Color.Transparent,
                                        activeTrackColor = Color.Transparent,
                                        inactiveTrackColor = Color.Transparent
                                    ),
                                )
                            }
                        }
                    }
                }
                AnimatedVisibility(
                    visible = !expandedCtl,
                    enter = fadeIn() + scaleIn() + slideInVertically { it / 2 },
                    exit = fadeOut() + scaleOut() + slideOutVertically { it / 2 }
                ) {
                    Row {
                        Column(
                            horizontalAlignment = Alignment.CenterHorizontally
                        ) {
                            Row(
                                modifier = Modifier
                                    .height(45.dp)
                                    .clip(RoundedCornerShape(12.dp))
                                    .background(Color(0xFF2C3135))
                                    .padding(vertical = 6.dp),
                                verticalAlignment = Alignment.CenterVertically
                            ) {
                                if (tempo >= 40.0) { // limite 40BPM
                                    IconButton(
                                        modifier = Modifier.background(Color(0XFF2C3130)),
                                        onClick = { updateTempoByBpmStep(-10) }) {
                                        Icon(
                                            Icons.AutoMirrored.Filled.KeyboardArrowLeft,
                                            "gauche",
                                            tint = Color.White.copy(0.7f),
                                            modifier = Modifier.size(22.dp)
                                        )
                                    }
                                }

                                val currentBpmInt = (tempo).toInt()

                                Row(
                                    modifier = Modifier.padding(horizontal = 2.dp),
                                    verticalAlignment = Alignment.CenterVertically
                                ) {
                                    val values = listOf(currentBpmInt - 1, currentBpmInt, currentBpmInt + 1)

                                    values.forEach { bpmValue ->
                                        AnimatedContent(
                                            targetState = bpmValue,
                                            transitionSpec = {
                                                if (targetState > initialState) {
                                                    slideInHorizontally { it } + fadeIn() togetherWith slideOutHorizontally { -it } + fadeOut()
                                                } else {
                                                    slideInHorizontally { -it } + fadeIn() togetherWith slideOutHorizontally { it } + fadeOut()
                                                }
                                            },
                                            modifier = Modifier.padding(horizontal = 2.dp)
                                        ) { displayedBpm ->
                                            val isCenter = displayedBpm == currentBpmInt
                                            Text(
                                                text = "$displayedBpm",
                                                color = if (isCenter) Color.White else Color.Gray.copy(alpha = 0.4f),
                                                fontSize = if (isCenter) 22.sp else 14.sp,
                                                fontWeight = if (isCenter) FontWeight.Bold else FontWeight.Normal,
                                                modifier = Modifier
                                                    .clip(CircleShape)
                                                    .clickable(enabled = !isCenter) { updateTempoToBpm(displayedBpm) }
                                                    .padding(horizontal = 2.dp)
                                            )
                                        }
                                    }
                                }

                                if (tempo <= 160) { // limite 160BPM
                                    IconButton(
                                        modifier = Modifier.background(Color(0XFF2C3130)),
                                        onClick = { updateTempoByBpmStep(10) }) {
                                        Icon(
                                            Icons.AutoMirrored.Filled.KeyboardArrowRight,
                                            "droite",
                                            tint = Color.White.copy(0.7f),
                                            modifier = Modifier.size(22.dp)
                                        )
                                    }
                                }
                                Text(
                                    text = "bpm",
                                    color = Color.White.copy(0.6f),
                                    fontSize = 12.sp,
                                    modifier = Modifier.padding(end = 8.dp)
                                )
                            }
                        }
                    }
                }

                if (!expandedCtl) {
                    Spacer(modifier = Modifier.height(10.dp))
                }
                Row(
                    modifier = Modifier.fillMaxWidth().padding(horizontal = 5.dp),
                    verticalAlignment = Alignment.CenterVertically,
                ) {
                    Column {
                        val isAtStart = loopState.first == -1L
                        val isWaitingForB = loopState.first != -1L && !loopState.third
                        val isLooping = loopState.third

                        OutlinedButton(
                            onClick = {
                                when {
                                    isAtStart -> mediaPlayer.setPointA()
                                    isWaitingForB -> mediaPlayer.setPointB()
                                    isLooping -> {
                                        mediaPlayer.clearLoop()
                                    }
                                }
                            },
                            colors = ButtonDefaults.buttonColors(
                                containerColor = when {
                                    (isWaitingForB || isLooping) -> Color.Red
                                    else -> Color.LightGray
                                }
                            ),
                            contentPadding = PaddingValues(horizontal = 2.dp, vertical = 0.dp),
                            shape = RoundedCornerShape(5.dp),
                            modifier = Modifier
                                .height(34.dp)
                        ) {
                            Row(
                                verticalAlignment = Alignment.CenterVertically,
                                horizontalArrangement = Arrangement.spacedBy(4.dp)
                            ) {
                                Text(
                                    text = "A",
                                    color = if (isWaitingForB || isLooping) Color.White else Color.Black,
                                    fontSize = 16.sp
                                )

                                Icon(
                                    imageVector = Icons.Default.Loop,
                                    contentDescription = null,
                                    tint = if (isLooping) Color.White else Color.Black,
                                    modifier = Modifier.size(16.dp)
                                )

                                Text(
                                    text = "B",
                                    color = if (isLooping) Color.White else Color.Black,
                                    fontSize = 16.sp
                                )
                            }
                        }
                    }
                    Spacer(modifier = Modifier.weight(1f))

                    Column {
                        IconButton(
                            onClick = {
                                showSATBTools = !showSATBTools
                            }, modifier = Modifier
                                .size(40.dp)
                                .clip(CircleShape)
                                .background(if (showSATBTools) MaterialTheme.colorScheme.primary else Color.Transparent)
                        ) {
                            Icon(
                                painter = painterResource(Res.drawable.ic_mixer_satb),
                                contentDescription = "SATB",
                                tint = if (showSATBTools) Color.White else Color.Black,
                                modifier = Modifier.size(35.dp)
                            )
                        }
                    }
                    Spacer(modifier = Modifier.weight(1f))

                    if(platform.startsWith("Android")) {
                        Column(
                        modifier = Modifier.wrapContentWidth(),
                        horizontalAlignment = Alignment.CenterHorizontally
                    ) {
                            IconButton(
                                onClick = onPlayPauseClick,
                                modifier = Modifier.size(48.dp).background(MaterialTheme.colorScheme.primary, CircleShape)
                            ) {
                                Icon(
                                    imageVector = if (isPause) Icons.Filled.PlayArrow else Icons.Filled.Pause,
                                    contentDescription = "Pla",
                                    tint = Color.White
                                )
                            }
                        }

                        Spacer(modifier = Modifier.weight(1f))

                        Column {
                        IconButton(
                            onClick = {
                                isPianoSelected = !isPianoSelected
                                if (isPianoSelected) {
                                    mediaPlayer?.changeInstru(1)
                                } else {
                                    mediaPlayer?.changeInstru(20)
                                }

                            }
                        ) {
                            if (isPianoSelected) {
                                Icon(
                                    Icons.Default.Piano,
                                    contentDescription = "Piano",
                                    tint = Color.Black
                                )
                            } else {
                                Icon(
                                    painter = painterResource(Res.drawable.ic_organ),
                                    contentDescription = "Orgue",
                                    tint = Color.Black,
                                    modifier = Modifier.size(25.dp)
                                )
                            }
                        }
                    }
                    } else {
                        Column {
                            IconButton(
                                onClick = {
                                    isPianoSelected = !isPianoSelected
                                    if (isPianoSelected) {
                                        mediaPlayer?.changeInstru(1)
                                    } else {
                                        mediaPlayer?.changeInstru(20)
                                    }

                                }
                            ) {
                                if (isPianoSelected) {
                                    Icon(
                                        Icons.Default.Piano,
                                        contentDescription = "Piano",
                                        tint = Color.Black
                                    )
                                } else {
                                    Icon(
                                        painter = painterResource(Res.drawable.ic_organ),
                                        contentDescription = "Orgue",
                                        tint = Color.Black,
                                        modifier = Modifier.size(25.dp)
                                    )
                                }
                            }
                        }

                        Spacer(modifier = Modifier.weight(1f))
                        Column(
                            modifier = Modifier.wrapContentWidth(),
                            horizontalAlignment = Alignment.CenterHorizontally
                        ) {
                            IconButton(
                                onClick = onPlayPauseClick,
                                modifier = Modifier.size(48.dp).background(MaterialTheme.colorScheme.primary, CircleShape)
                            ) {
                                Icon(
                                    imageVector = if (isPause) Icons.Filled.PlayArrow else Icons.Filled.Pause,
                                    contentDescription = "Pla",
                                    tint = Color.White
                                )
                            }
                        }
                }


                    Spacer(modifier = Modifier.weight(1f))

                    if (platform.startsWith("Java")) {
                        ModernVolumeSlider(
                            volume, onVolumeChange = onVolumeChange
                        )
                    }

                    Spacer(modifier = Modifier.weight(1f))

                    Row(
                        modifier = Modifier.wrapContentWidth(),
                        horizontalArrangement = Arrangement.End,
                    ) {
                        IconButton(
                            onClick = { expandedCtl = !expandedCtl },
                            modifier = Modifier.size(48.dp)
                        ) {
                            Icon(
                                imageVector = if (expandedCtl) Icons.Default.MoreHoriz else Icons.Default.MoreVert,
                                contentDescription = "More",
                                tint = Color.White
                            )
                        }
                    }
                }
            }
        }
    }
}