package com.laseroptek.raman.ui.screens.engineer

import android.content.res.Configuration
import androidx.compose.foundation.border
import androidx.compose.foundation.gestures.awaitEachGesture
import androidx.compose.foundation.gestures.awaitFirstDown
import androidx.compose.foundation.gestures.waitForUpOrCancellation
import androidx.compose.foundation.layout.Arrangement
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.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.laseroptek.raman.const.MinMaxUpDownState
import com.laseroptek.raman.ui.theme.RobotoTypography
import com.laseroptek.raman.utils.ext.px
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import timber.log.Timber


@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun GuideBeamView(
    modifier: Modifier = Modifier,
    onClick: (MinMaxUpDownState) -> Unit = {},
    minValue: Int = 0,
    maxValue: Int = 0,
    title:String = ""
) {
    val scope = rememberCoroutineScope()
    val customPressTimeout = 1000L

    // Guide Beam
    Row(modifier = modifier,
        horizontalArrangement = Arrangement.SpaceBetween,
        verticalAlignment = Alignment.CenterVertically
    ) {
        // Guide Beam - title
        Column(
            modifier = Modifier
                .fillMaxWidth()
                .weight(1f)
                .height(30.px.dp),
            verticalArrangement = Arrangement.Center,
            horizontalAlignment = Alignment.Start
        ) {
            Text(
                text = title,
                style = RobotoTypography.labelMedium,
                fontWeight = FontWeight.Normal,
                fontSize = 12.px.sp,
                color = Color.Black
            )
        }

        // Guide Beam - min
        Column(
            modifier = Modifier
                .fillMaxWidth()
                .weight(1.2f)
                .height(30.px.dp),
            verticalArrangement = Arrangement.Center,
            horizontalAlignment = Alignment.Start
        ) {
            Row(
                verticalAlignment = Alignment.CenterVertically
            ) {
                Text(
                    text = "Min: %4d".format(minValue),
                    style = RobotoTypography.bodyMedium,
                    fontWeight = FontWeight.Normal,
                    fontSize = 12.px.sp,
                    color = Color.Black,
                    textAlign = TextAlign.Start
                )
                Spacer(modifier = Modifier.width(5.px.dp))

                // Min Down (<)
                Column(
                    modifier = Modifier
                        /*
                        .noRippleClickable(
                            onClick = {
                                onClick.invoke(MinMaxUpDownState.MinDown)
                            }
                        )
                        */
                        .pointerInput(Unit) { // pass `Unit` or any key that, when changed, should reset the gesture detector
                            awaitEachGesture {
                                var longPressOccurred = false

                                awaitFirstDown()
                                val job = scope.launch(Dispatchers.Default) {
                                    delay(customPressTimeout)

                                    longPressOccurred = true

                                    // Long press detected
                                    while (true) {
                                        Timber.d("Long press detected, starting repeating timer...")
                                        onClick.invoke(MinMaxUpDownState.MinLongDown)
                                        delay(300) // A responsive 300ms interval
                                    }
                                }
                                waitForUpOrCancellation()
                                if (job.isActive) {
                                    job.cancel()

                                    if (!longPressOccurred) {
                                        // If the job is still active, it means it was a short press
                                        Timber.d("Short press detected.")
                                        onClick.invoke(MinMaxUpDownState.MinDown)
                                    } else {
                                        Timber.d("Up event after long press. Short press ignored.")
                                    }
                                }
                            }
                        }
                        .size(25.px.dp, 25.px.dp)
                        .border(width = 1.px.dp, color = Color.Gray, RoundedCornerShape(5.px.dp)),
                    verticalArrangement = Arrangement.Center,
                    horizontalAlignment = Alignment.CenterHorizontally
                ) {
                    Text(
                        text = "<",
                        style = RobotoTypography.bodyMedium,
                        fontWeight = FontWeight.Normal,
                        fontSize = 12.px.sp,
                        color = Color.Black,
                    )
                }
                Spacer(modifier = Modifier.width(5.px.dp))
                // Min Up (>)
                Column(
                    modifier = Modifier
                        /*
                        .noRippleClickable(
                            onClick = {
                                onClick.invoke(MinMaxUpDownState.MinUp)
                            }
                        )
                        */
                        .pointerInput(Unit) { // pass `Unit` or any key that, when changed, should reset the gesture detector
                            awaitEachGesture {
                                var longPressOccurred = false

                                awaitFirstDown()
                                val job = scope.launch(Dispatchers.Default) {
                                    delay(customPressTimeout)

                                    // Long press detected
                                    longPressOccurred = true

                                    while (true) {
                                        Timber.d("MinLongUp")
                                        onClick.invoke(MinMaxUpDownState.MinLongUp)
                                        delay(300) // A responsive 300ms interval
                                    }
                                }
                                waitForUpOrCancellation()
                                if (job.isActive) {
                                    job.cancel()
                                    if (!longPressOccurred) {
                                        // If the job is still active, it means it was a short press
                                        Timber.d("MinUp")
                                        onClick.invoke(MinMaxUpDownState.MinUp)
                                    } else {
                                        Timber.d("Up event after long press. Short press ignored.")
                                    }

                                }
                            }
                        }
                        .size(25.px.dp, 25.px.dp)
                        .border(width = 1.px.dp, color = Color.Gray, RoundedCornerShape(5.px.dp)),
                    verticalArrangement = Arrangement.Center,
                    horizontalAlignment = Alignment.CenterHorizontally
                ) {
                    Text(
                        text = ">",
                        style = RobotoTypography.bodyMedium,
                        fontWeight = FontWeight.Normal,
                        fontSize = 12.px.sp,
                        color = Color.Black
                    )
                }
            }
        }

        // Guide Beam - max
        Column(
            modifier = Modifier
                .fillMaxWidth()
                .weight(1.2f)
                .height(30.px.dp),
            verticalArrangement = Arrangement.Center,
            horizontalAlignment = Alignment.Start
        ) {
            Row(
                verticalAlignment = Alignment.CenterVertically
            ) {
                Text(
                    text = "Max: %4d".format(maxValue),
                    style = RobotoTypography.bodyMedium,
                    fontWeight = FontWeight.Normal,
                    fontSize = 12.px.sp,
                    color = Color.Black,
                    textAlign = TextAlign.Start
                )
                Spacer(modifier = Modifier.width(5.px.dp))
                // Max Down
                Column(
                    modifier = Modifier
                        /*
                        .noRippleClickable(
                            onClick = {
                                onClick.invoke(MinMaxUpDownState.MaxDown)
                            }
                        )
                        */
                        .pointerInput(Unit) { // pass `Unit` or any key that, when changed, should reset the gesture detector
                            awaitEachGesture {
                                var longPressOccurred = false

                                awaitFirstDown()
                                val job = scope.launch(Dispatchers.Default) {
                                    delay(customPressTimeout)

                                    longPressOccurred = true

                                    // Long press detected
                                    while (true) {
                                        Timber.d("MaxLongDown")
                                        onClick.invoke(MinMaxUpDownState.MaxLongDown)
                                        delay(300) // A responsive 300ms interval
                                    }
                                }
                                waitForUpOrCancellation()
                                if (job.isActive) {
                                    job.cancel()

                                    // If the job is still active, it means it was a short press
                                    if (!longPressOccurred) {
                                        Timber.d("MaxDown")
                                        onClick.invoke(MinMaxUpDownState.MaxDown)
                                    } else {
                                        Timber.d("Up event after long press. Short press ignored.")
                                    }
                                }
                            }
                        }
                        .size(25.px.dp, 25.px.dp)
                        .border(width = 1.px.dp, color = Color.Gray, RoundedCornerShape(5.px.dp)),
                    verticalArrangement = Arrangement.Center,
                    horizontalAlignment = Alignment.CenterHorizontally
                ) {
                    Text(
                        text = "<",
                        style = RobotoTypography.bodyMedium,
                        fontWeight = FontWeight.Normal,
                        fontSize = 12.px.sp,
                        color = Color.Black,
                    )
                }
                Spacer(modifier = Modifier.width(5.px.dp))
                // Max Up
                Column(
                    modifier = Modifier
                        /*
                        .noRippleClickable(
                            onClick = {
                                onClick.invoke(MinMaxUpDownState.MaxUp)
                            }
                        )
                        */
                        .pointerInput(Unit) {
                            awaitEachGesture {
                                var longPressOccurred = false

                                awaitFirstDown()
                                val job = scope.launch(Dispatchers.Default) {
                                    delay(customPressTimeout)

                                    longPressOccurred = true

                                    // Long press detected
                                    while (true) {
                                        Timber.d("MaxLongUp")
                                        onClick.invoke(MinMaxUpDownState.MaxLongUp)
                                        delay(300) // A responsive 300ms interval
                                    }
                                }
                                waitForUpOrCancellation()
                                if (job.isActive) {
                                    job.cancel()

                                    // If the job is still active, it means it was a short press
                                    if (!longPressOccurred) {
                                        Timber.d("MaxUp")
                                        onClick.invoke(MinMaxUpDownState.MaxUp)
                                    } else {
                                        Timber.d("Up event after long press. Short press ignored.")
                                    }
                                }
                            }
                        }
                        .size(25.px.dp, 25.px.dp)
                        .border(width = 1.px.dp, color = Color.Gray, RoundedCornerShape(5.px.dp)),
                    verticalArrangement = Arrangement.Center,
                    horizontalAlignment = Alignment.CenterHorizontally
                ) {
                    Text(
                        text = ">",
                        style = RobotoTypography.bodyMedium,
                        fontWeight = FontWeight.Normal,
                        fontSize = 12.px.sp,
                        color = Color.Black
                    )
                }
            }
        }
    }

}


@Preview(
    uiMode = Configuration.UI_MODE_NIGHT_NO,
    showBackground = false,
    device = "spec:width=640dp,height=60dp,dpi=150,isRound=false,chinSize=0dp,orientation=landscape"
)
@Composable
fun PreviewGuideBeamView() {
    Row {
        GuideBeamView(
            modifier = Modifier
                .size(640.px.dp, 80.px.dp),
            title = "Guide Beam",
            onClick = { v ->
                Timber.d("Clicked $v")
            },
        )
    }
}