package com.laseroptek.raman.ui.screens.home.slider

import android.content.res.Configuration
import androidx.compose.foundation.BorderStroke
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
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.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.rememberUpdatedState
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.laseroptek.raman.R
import com.laseroptek.raman.const.UpDownState
import com.laseroptek.raman.utils.ext.dropShadow
import com.laseroptek.raman.utils.ext.innerShadow
import com.laseroptek.raman.utils.ext.px
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch


@Composable
fun UpDownButton(
    onClick: (UpDownState) -> Unit = {},
    modifier: Modifier = Modifier,
) {
    val updatedOnClick by rememberUpdatedState(onClick)
    val initialDelayMillis = 500L // Wait this long before starting to repeat
    val repeatIntervalMillis = 100L // Repeat every 100ms

    val scope = rememberCoroutineScope()

    Row(
        modifier = modifier.fillMaxSize(),
        verticalAlignment = Alignment.CenterVertically,
        horizontalArrangement = Arrangement.Center,
    ) {
        // Left Button
        Row(
            modifier = Modifier
                .graphicsLayer()
                .clip(RoundedCornerShape(52.px.dp))
                .size(80.px.dp, 42.px.dp)
                /*
                .noRippleClickable {
                    onClick(UpDownState.Down)
                }
                */
                .pointerInput(Unit) {
                    awaitEachGesture {
                        val down = awaitFirstDown(requireUnconsumed = false)

                        // 1. Fire the first click immediately on press down.
                        updatedOnClick(UpDownState.Down)

                        // 2. Start a repeating loop job using the scope from rememberCoroutineScope.
                        val pressJob: Job = scope.launch(Dispatchers.Default) {
                            // 3. Wait for the initial delay.
                            delay(initialDelayMillis)
                            // 4. Start the repeating loop.
                            while (true) {
                                updatedOnClick(UpDownState.Down)
                                delay(repeatIntervalMillis)
                            }
                        }

                        // 5. Wait for the user to release their finger.
                        waitForUpOrCancellation()

                        // 6. Cancel the repeating loop when the finger is released.
                        pressJob.cancel()
                    }
                }
                .border(
                    border = BorderStroke(
                        width = 3.dp,
                        brush = Brush.linearGradient(
                            colors = listOf(Color(81, 81, 81), Color(64, 64, 64)),
                            //start = Offset(0f, 0f), // Optional: Start at the top-left
                            //end = Offset(200f, 200f) // Optional: End at the bottom-right
                        )
                    ),
                    shape = RoundedCornerShape(52.dp)
                )

                .innerShadow(
                    shape = RoundedCornerShape(52.px.dp),
                    color = Color(0, 0, 0).copy(alpha = 0.14f),
                    blur = 7.px.dp,
                    offsetY = 4.px.dp,
                    offsetX = 0.px.dp,
                    spread = 0.px.dp
                )
                .background(
                    Color(225, 225, 225)
                    /*
                    brush = Brush.linearGradient(
                        colors = listOf(
                            Color(250, 250, 250),
                            Color(198, 198, 198),
                        )
                    )
                    */
                ),
            horizontalArrangement = Arrangement.Center,
            verticalAlignment = Alignment.CenterVertically
        ) {
            Image(
                painter = painterResource(id = R.drawable.ic_left),
                contentDescription = null,
                modifier = Modifier.size(32.px.dp, 32.px.dp),
                contentScale = ContentScale.FillBounds
            )
        }

        Spacer(Modifier.width(30.px.dp))

        // Right Button
        Row(
            modifier = Modifier
                .graphicsLayer()
                .clip(RoundedCornerShape(52.px.dp))
                .size(80.px.dp, 42.px.dp)
                /*
                .noRippleClickable {
                    onClick(UpDownState.Up)
                }
                */
                .pointerInput(Unit) {
                    awaitEachGesture {
                        // Remove the unnecessary 'awaitPointerEventScope' wrapper
                        // The 'awaitEachGesture' block provides the context we need.

                        // Wait for the initial press up
                        val up = awaitFirstDown(requireUnconsumed = false)

                        // 1. Fire the first click immediately on press down.
                        updatedOnClick(UpDownState.Up)

                        // 2. Start a repeating loop job using the scope from rememberCoroutineScope.
                        val pressJob: Job = scope.launch(Dispatchers.Default) {
                            // 3. Wait for the initial delay.
                            delay(initialDelayMillis)
                            // 4. Start the repeating loop.
                            while (true) {
                                updatedOnClick(UpDownState.Up)
                                delay(repeatIntervalMillis)
                            }
                        }

                        // 5. Wait for the user to release their finger.
                        waitForUpOrCancellation()

                        // 6. Cancel the repeating loop when the finger is released.
                        pressJob.cancel()
                    }
                }
                .border(
                    border = BorderStroke(
                        width = 3.dp,
                        brush = Brush.linearGradient(
                            colors = listOf(Color(81, 81, 81), Color(64, 64, 64)),
                            //start = Offset(0f, 0f), // Optional: Start at the top-left
                            //end = Offset(200f, 200f) // Optional: End at the bottom-right
                        )
                    ),
                    shape = RoundedCornerShape(52.dp)
                )
                .dropShadow(
                    shape = RoundedCornerShape(52.px.dp),
                    color = Color(0, 0, 0).copy(alpha = 0.14f),
                    blur = 7.px.dp,
                    offsetY = 5.px.dp,
                    offsetX = 0.px.dp,
                    spread = 0.px.dp
                )
                .innerShadow(
                    shape = RoundedCornerShape(52.px.dp),
                    color = Color(0, 0, 0).copy(alpha = 0.14f),
                    blur = 7.px.dp,
                    offsetY = 4.px.dp,
                    offsetX = 0.px.dp,
                    spread = 0.px.dp
                )
                .background(
                    Color(225, 225, 225)
                    /*
                    brush = Brush.linearGradient(
                        colors = listOf(
                            Color(198, 198, 198),
                            Color(250, 250, 250),
                        )
                    )
                    */
                ),
            horizontalArrangement = Arrangement.Center,
            verticalAlignment = Alignment.CenterVertically
        ) {
            Image(
                painter = painterResource(id = R.drawable.ic_right),
                contentDescription = null,
                modifier = Modifier.size(32.px.dp, 32.px.dp),
                contentScale = ContentScale.FillBounds
            )
        }
    }
}


@Preview(
    apiLevel = 34,
    uiMode = Configuration.UI_MODE_NIGHT_NO,
    showBackground = true,
    //device = "spec:width=1920dp,height=1080dp,dpi=150,isRound=false,chinSize=0dp,orientation=landscape"
)
@Composable
fun PreviewUpDownButton(
    /*
    mainViewModel:MainViewModel = MainViewModel(
        chartDataRepository = ChartDataRepository(),
        preferenceRepository = PreferenceRepository(LocalContext.current),
        serialPortRepository = SerialPortRepository.createWithFakeRepository(),
        databaseRepository = DatabaseRepository(RamanDatabaseService(RamanDatabase.getInstance(LocalContext.current))),
        dispatcherProvider = DefaultDispatcherProvider(),
        applicationContext = LocalContext.current
    )
    */
) {
    UpDownButton(
        //mainViewModel = mainViewModel,
    )
}
