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

import androidx.compose.foundation.Image
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.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
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 androidx.compose.ui.window.Dialog
import androidx.compose.ui.window.DialogProperties
import com.airbnb.lottie.compose.LottieAnimation
import com.airbnb.lottie.compose.LottieCompositionSpec
import com.airbnb.lottie.compose.LottieConstants
import com.airbnb.lottie.compose.animateLottieCompositionAsState
import com.airbnb.lottie.compose.rememberLottieComposition
import com.laseroptek.raman.R
import com.laseroptek.raman.const.PURGE_STATUS
import com.laseroptek.raman.data.model.serial.PurgeBubble
import com.laseroptek.raman.ui.theme.RobotoTypography
import com.laseroptek.raman.utils.ext.dropShadow
import com.laseroptek.raman.utils.ext.px
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.MutableStateFlow

@Composable
fun PurgeProgressDialog(
    onDismissRequest: () -> Unit,
    modifier: Modifier = Modifier,
    dialogProperties: DialogProperties = DialogProperties(),
    purgeBubble: PurgeBubble = PurgeBubble(0)   // 0x41 (Accept), 0x42 (Complete), 0x44(Deny), 0x00(Initial)
) {
    /*
    var showFirstImage by remember { mutableStateOf(true) }
    val crossfadeDurationMillis: Int = 50
    val visibleDurationMillis: Long = 500
    val closeIcon: ImageVector = Icons.Filled.Close

    LaunchedEffect(Unit, visibleDurationMillis) { // Keyed to restart if visibleDurationMillis changes
        while (purgeBubble.value == 0x41) {
            delay(visibleDurationMillis)
            showFirstImage = !showFirstImage
        }
    }
    */
    val lottieJsonAssetName: String = "bubble.json"
    val iterations: Int = LottieConstants.IterateForever
    val speed: Float = 1.0f
    val composition by rememberLottieComposition(LottieCompositionSpec.Asset(lottieJsonAssetName))
    val progress by animateLottieCompositionAsState(
        composition = composition,
        iterations = iterations,
        speed = speed
    )

    Dialog(
        onDismissRequest = onDismissRequest,
        properties = dialogProperties
    ) {
        Column(
            modifier = Modifier
                .size(280.px.dp, 250.px.dp)
                .clip(RoundedCornerShape(28.px.dp))
                .background(color = Color.White)
                .dropShadow(
                    shape = RoundedCornerShape(28.px.dp),
                    color = Color(0,0,0).copy(alpha = 0.2f),
                    blur = 48.px.dp,
                    offsetX = 0.px.dp,
                    offsetY = 24.px.dp,
                    spread = 0.px.dp
                )
                .dropShadow(
                    shape = RoundedCornerShape(28.px.dp),
                    color = Color(0,0,0).copy(alpha = 0.1f),
                    blur = 6.px.dp,
                    offsetX = 0.px.dp,
                    offsetY = 3.px.dp,
                    spread = 0.px.dp
                )
                ,
            horizontalAlignment = Alignment.CenterHorizontally,
        ) {
            // Title
            Row(
                modifier = Modifier
                    .fillMaxWidth()
                    .height(56.px.dp)
                    .padding(start = 24.px.dp, top = 24.px.dp),
                horizontalArrangement = Arrangement.Start,
                verticalAlignment = Alignment.Top
            ) {
                Text(
                    text = "Purge",
                    style = RobotoTypography.bodySmall,
                    fontWeight = FontWeight.ExtraLight,
                    fontSize = 20.px.sp,
                    color = Color.Black
                )
            }

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

            when (purgeBubble.value) {
                PURGE_STATUS.INIT -> {
                    // requested (init)
                    Image(
                        painter = painterResource(id = R.drawable.ic_purge_off),
                        contentDescription = null,
                        modifier = Modifier
                            .size(42.px.dp),
                        contentScale = ContentScale.Fit
                    )
                }
                PURGE_STATUS.COMPLTE -> {
                    // completed
                    Image(
                        painter = painterResource(id = R.drawable.ic_completed),
                        contentDescription = null,
                        modifier = Modifier
                            .size(42.px.dp),
                        contentScale = ContentScale.Fit
                    )
                }
                PURGE_STATUS.FAIL -> {
                    // failed
                    Image(
                        painter = painterResource(id = R.drawable.ic_failed),
                        contentDescription = null,
                        modifier = Modifier
                            .size(42.px.dp),
                        contentScale = ContentScale.Fit
                    )
                }
                else -> {
                    // 0x41 or initial
                    Row(
                        modifier = Modifier
                            .fillMaxWidth()
                            .height(100.px.dp)
                    ) {
                        LottieAnimation(
                            composition = composition,
                            progress = { progress }, // Use a lambda that returns the progress
                            modifier = modifier,
                            contentScale = ContentScale.Fit
                        )
                    }

                    /*
                    Crossfade(
                        targetState = showFirstImage,
                        animationSpec = tween(durationMillis = crossfadeDurationMillis),
                        modifier = modifier.size(42.px.dp),
                        label = "ImageCrossfade"
                    ) { isFirstImage ->
                        val painter =
                            if (isFirstImage) painterResource(id = R.drawable.ic_purge_on)
                            else painterResource(id = R.drawable.ic_purge_off)
                        Image(
                            painter = painter,
                            contentDescription = null,
                            modifier = Modifier
                                .size(42.px.dp),
                            contentScale = ContentScale.Fit
                        )
                    }
                    */
                }
            }

            Spacer(modifier = Modifier.height(10.px.dp))

            // Body Text
            val bodyText = when (purgeBubble.value) {
                PURGE_STATUS.INIT -> "The purge is requested"
                PURGE_STATUS.COMPLTE -> "The purge is complete"
                PURGE_STATUS.FAIL -> "The operation failed.\nPlease try again."
                else -> "In progress"
            }

            Text(
                text = bodyText,
                textAlign = TextAlign.Center,
                style = RobotoTypography.bodySmall.copy(
                    lineHeight = 16.px.sp
                ),
                fontSize = 15.px.sp,
                color = Color.Black,
            )

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

            // Ok
            if (purgeBubble.value == PURGE_STATUS.COMPLTE || purgeBubble.value == PURGE_STATUS.FAIL) {
                Row(
                    modifier = Modifier
                        .fillMaxWidth()
                        .height(88.px.dp)
                        .padding(start = 10.px.dp, end = 10.px.dp),
                    horizontalArrangement = Arrangement.End,
                    verticalAlignment = Alignment.CenterVertically
                ) {
                    TextButton(
                        modifier = Modifier
                            .size(68.px.dp, 40.px.dp),
                        onClick = onDismissRequest
                    ) {
                        Text(
                            text = stringResource(R.string.close),
                            style = RobotoTypography.labelLarge,
                            fontWeight = FontWeight.Normal,
                            fontSize = 15.px.sp,
                            color = Color.Black
                        )
                    }
                }
            }
        }
    }
}

// Preview for the dialog with an image
@Preview(showBackground = true, device = "spec:width=1080px,height=1920px,dpi=420")
@Composable
private fun PurgeProgressDialogPreviewWithImage() {

    val _purgeBubble: MutableStateFlow<PurgeBubble> = MutableStateFlow(PurgeBubble())
    val purgeBubble: MutableStateFlow<PurgeBubble> = _purgeBubble
    fun setPurgeBubble(p: PurgeBubble) {
        _purgeBubble.value = p
    }

    val visibleDurationMillis: Long = 500
    LaunchedEffect(Unit, visibleDurationMillis) { // Keyed to restart if visibleDurationMillis changes
        for (i in 0..1000 ) {
            delay(visibleDurationMillis)
            when (i%4) {
                 0 -> setPurgeBubble(PurgeBubble(PURGE_STATUS.INIT)) // Init
                 1 -> setPurgeBubble(PurgeBubble(PURGE_STATUS.ACCEPT)) // Accept
                 2 -> {
                     setPurgeBubble(PurgeBubble(PURGE_STATUS.COMPLTE))
                 } // Complete
                 3 -> {
                     setPurgeBubble(PurgeBubble(PURGE_STATUS.FAIL))
                 } // Fail/Refuse
            }
        }
    }

    MaterialTheme { // Wrap with MaterialTheme for previews to apply colors and typography
        // Simulate a screen background for better preview context
        Box(
            modifier = Modifier
                .size(340.px.dp, 250.px.dp)
                .background(Color.Black), // Dimmed background like a typical dialog overlay
            contentAlignment = Alignment.Center
        ) {
            val purgeBubble by purgeBubble.collectAsState()
            PurgeProgressDialog(
                onDismissRequest = {
                    // Handle dismiss if needed
                },
                purgeBubble = purgeBubble
            )
        }

    }
}

