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

import android.content.res.Configuration
import android.widget.Toast
import androidx.compose.foundation.background
import androidx.compose.foundation.border
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.fillMaxSize
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.foundation.text.KeyboardActions
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
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.focus.FocusRequester
import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.TextRange
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.text.input.TextFieldValue
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.R
import com.laseroptek.raman.const.MAX_REFER2_VALUE
import com.laseroptek.raman.data.datasource.db.RamanDatabase
import com.laseroptek.raman.data.model.Refer2
import com.laseroptek.raman.data.source.db.RamanDatabaseService
import com.laseroptek.raman.repository.DatabaseRepository
import com.laseroptek.raman.repository.PreferenceRepository
import com.laseroptek.raman.repository.SerialPortRepository
import com.laseroptek.raman.ui.common.fullscreen.FullScreen
import com.laseroptek.raman.ui.screens.main.MainViewModel
import com.laseroptek.raman.ui.theme.RobotoTypography
import com.laseroptek.raman.utils.DefaultDispatcherProvider
import com.laseroptek.raman.utils.ext.dropShadow
import com.laseroptek.raman.utils.ext.px
import timber.log.Timber

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun Refer2Popup(
    title: String = stringResource(R.string.energy_detect_refer2_title),
    refer2: Refer2 = Refer2(),
    maxValue: Int = MAX_REFER2_VALUE,
    onClick: (Boolean, Refer2) -> Unit = { _, _ -> },
) {
    val context = LocalContext.current
    var goodFieldValue by remember {
        mutableStateOf(
            // Initialize TextFieldValue with the text and set the cursor to the end.
            TextFieldValue(
                text = "%d".format((refer2.good * 100).toInt()),
                selection = TextRange("%d".format((refer2.good * 100).toInt()).length) // This places the cursor at the end
            )
        )
    }
    var acceptableFieldValue by remember {
        mutableStateOf(
            // Initialize TextFieldValue with the text and set the cursor to the end.
            TextFieldValue(
                text = "%d".format((refer2.acceptable*100).toInt()),
                selection = TextRange("%d".format((refer2.acceptable*100).toInt()).length) // This places the cursor at the end
            )
        )
    }
    var badFieldValue by remember {
        mutableStateOf(
            // Initialize TextFieldValue with the text and set the cursor to the end.
            TextFieldValue(
                text = "%d".format((refer2.bad*100).toInt()),
                selection = TextRange("%d".format((refer2.bad*100).toInt()).length) // This places the cursor at the end
            )
        )
    }
    val focusManager = LocalFocusManager.current
    val focusRequester = remember { FocusRequester() }
    val performOkClick = {
        if (goodFieldValue.text.isEmpty() || acceptableFieldValue.text.isEmpty() || badFieldValue.text.isEmpty()) {
            Toast.makeText(
                context,
                "Input Number",
                Toast.LENGTH_SHORT
            ).show()
        } else {
            // don't Hide the keyboard first for a clean UI transition
            //focusManager.clearFocus()

            Timber.d("OK action performed ${goodFieldValue.text}, ${acceptableFieldValue.text}, ${badFieldValue.text}")

            onClick(
                true,
                Refer2(
                    good = goodFieldValue.text.toFloatOrNull() ?: 0f,
                    acceptable = acceptableFieldValue.text.toFloatOrNull() ?: 0f,
                    bad  = badFieldValue.text.toFloatOrNull() ?: 0f,
                )
            ) // This now closes the popup via the parent
        }
    }

    DisposableEffect(Unit) {
        onDispose {
            Timber.d("MyComposable is being disposed!")
            focusManager.clearFocus(force = true) // Hide the keyboard
        }
    }

    FullScreen {
        Box(
            modifier = Modifier
                .fillMaxSize()
                .padding(top = 50.px.dp),
            contentAlignment = Alignment.TopCenter
        ) {
            Column(
                modifier = Modifier
                    .size(420.px.dp, 360.px.dp)
                    .clip(RoundedCornerShape(28.px.dp))
                    .background(Color.White)
                    .dropShadow(
                        shape = RoundedCornerShape(16.px.dp),
                        color = Color.Black.copy(alpha = 0.2f),
                        blur = 48.px.dp,
                        offsetX = 0.px.dp,
                        offsetY = 24.px.dp,
                        spread = 0.px.dp
                    )
                    .dropShadow(
                        shape = RoundedCornerShape(16.px.dp),
                        color = Color.Black.copy(alpha = 0.1f),
                        blur = 6.px.dp,
                        offsetX = 0.px.dp,
                        offsetY = 3.px.dp,
                        spread = 0.px.dp
                    )
                    .padding(start = 24.px.dp, end = 24.px.dp, top = 10.px.dp),
                horizontalAlignment = Alignment.CenterHorizontally,
                verticalArrangement = Arrangement.Top
            ) {

                // Title
                Row(
                    modifier = Modifier
                        .fillMaxWidth()
                        .height(52.px.dp),
                    horizontalArrangement = Arrangement.Start,
                    verticalAlignment = Alignment.CenterVertically
                ){
                    Text(
                        text = title,
                        style = RobotoTypography.headlineLarge,
                        fontWeight = FontWeight.ExtraLight,
                        fontSize = 24.px.sp,
                        color = Color.Black,
                        textAlign = TextAlign.Center,
                    )
                }

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

                // Good
                Row(
                    modifier = Modifier
                        .size(372.px.dp, 56.px.dp),
                    horizontalArrangement = Arrangement.Start,
                    verticalAlignment = Alignment.CenterVertically
                ) {
                    // Text - Good
                    Row(
                        modifier = Modifier
                            .size(100.px.dp, 56.px.dp),
                        horizontalArrangement = Arrangement.Start,
                        verticalAlignment = Alignment.CenterVertically
                    ) {
                        Text(
                            text = "Good",
                            style = RobotoTypography.headlineLarge,
                            fontWeight = FontWeight.ExtraLight,
                            fontSize = 14.px.sp,
                            color = Color.Black,
                            textAlign = TextAlign.Center,
                        )

                    }

                    // Good (Set)
                    Row(
                        modifier = Modifier
                            .size(222.px.dp, 56.px.dp)
                            .background(Color(245,245,245))
                            .border(width = 1.px.dp, Color.LightGray,),
                        horizontalArrangement = Arrangement.Start,
                        verticalAlignment = Alignment.CenterVertically
                    ) {
                        OutlinedTextField(
                            value = goodFieldValue,
                            onValueChange = { newTextFieldValue ->
                                val newText = newTextFieldValue.text
                                if (newText.isEmpty()) {
                                    goodFieldValue = newTextFieldValue
                                } else if (newText.all { it.isDigit() }) {
                                    // Safely parse to Long to avoid NumberFormatException on large numbers
                                    val number = newText.toLongOrNull()
                                    if (number != null && number <= maxValue) {
                                        goodFieldValue = newTextFieldValue
                                    } else {
                                        // The number is too large or invalid, show a toast
                                        Toast.makeText(
                                            context,
                                            "Input Number exceeded max value of $maxValue",
                                            Toast.LENGTH_SHORT
                                        ).show()
                                    }
                                }
                            },
                            //label = { Text("Count") },
                            keyboardOptions = KeyboardOptions(
                                keyboardType = KeyboardType.NumberPassword, // KeyboardType.Number, //KeyboardType.Text
                                imeAction = ImeAction.Done,
                                //autoCorrect = false
                            ),
                            singleLine = true,
                            keyboardActions = KeyboardActions(onDone = {
                                performOkClick()
                            }),
                            modifier = Modifier
                                .fillMaxSize()
                                .focusRequester(focusRequester)
                        )

                        LaunchedEffect(Unit) {
                            Timber.d("focusRequester.requestFocus()")
                            focusRequester.requestFocus()
                        }
                    }

                    // Text - %
                    Row(
                        modifier = Modifier
                            .size(50.px.dp, 56.px.dp),
                        horizontalArrangement = Arrangement.Center,
                        verticalAlignment = Alignment.CenterVertically
                    ) {
                        Text(
                            text = "%",
                            style = RobotoTypography.headlineLarge,
                            fontWeight = FontWeight.ExtraLight,
                            fontSize = 16.px.sp,
                            color = Color.Black,
                            textAlign = TextAlign.Center,
                        )

                    }
                }

                Spacer(Modifier.height(5.px.dp))

                // Acceptable
                Row(
                    modifier = Modifier
                        .size(372.px.dp, 56.px.dp),
                    horizontalArrangement = Arrangement.Start,
                    verticalAlignment = Alignment.CenterVertically
                ) {
                    // Text - Acceptable
                    Row(
                        modifier = Modifier
                            .size(100.px.dp, 56.px.dp),
                        horizontalArrangement = Arrangement.Start,
                        verticalAlignment = Alignment.CenterVertically
                    ) {
                        Text(
                            text = "Acceptable",
                            style = RobotoTypography.headlineLarge,
                            fontWeight = FontWeight.ExtraLight,
                            fontSize = 14.px.sp,
                            color = Color.Black,
                            textAlign = TextAlign.Center,
                        )

                    }

                    // Acceptable (Set)
                    Row(
                        modifier = Modifier
                            .size(222.px.dp, 56.px.dp)
                            .background(Color(245,245,245))
                            .border(width = 1.px.dp, Color.LightGray,),
                        horizontalArrangement = Arrangement.Start,
                        verticalAlignment = Alignment.CenterVertically
                    ) {
                        OutlinedTextField(
                            value = acceptableFieldValue,
                            onValueChange = { newTextFieldValue ->
                                val newText = newTextFieldValue.text
                                if (newText.isEmpty()) {
                                    acceptableFieldValue = newTextFieldValue
                                } else if (newText.all { it.isDigit() }) {
                                    // Safely parse to Long to avoid NumberFormatException on large numbers
                                    val number = newText.toLongOrNull()
                                    if (number != null && number <= maxValue) {
                                        acceptableFieldValue = newTextFieldValue
                                    } else {
                                        // The number is too large or invalid, show a toast
                                        Toast.makeText(
                                            context,
                                            "Input Number exceeded max value of $maxValue",
                                            Toast.LENGTH_SHORT
                                        ).show()
                                    }
                                }
                            },
                            //label = { Text("Count") },
                            keyboardOptions = KeyboardOptions(
                                keyboardType = KeyboardType.NumberPassword, // KeyboardType.Number, //KeyboardType.Text
                                imeAction = ImeAction.Done,
                                //autoCorrect = false
                            ),
                            singleLine = true,
                            keyboardActions = KeyboardActions(onDone = {
                                performOkClick()
                            }),
                            modifier = Modifier
                                .fillMaxSize()
                                .focusRequester(focusRequester)
                        )

                        LaunchedEffect(Unit) {
                            Timber.d("focusRequester.requestFocus()")
                            focusRequester.requestFocus()
                        }
                    }

                    // Text - %
                    Row(
                        modifier = Modifier
                            .size(50.px.dp, 56.px.dp),
                        horizontalArrangement = Arrangement.Center,
                        verticalAlignment = Alignment.CenterVertically
                    ) {
                        Text(
                            text = "%",
                            style = RobotoTypography.headlineLarge,
                            fontWeight = FontWeight.ExtraLight,
                            fontSize = 16.px.sp,
                            color = Color.Black,
                            textAlign = TextAlign.Center,
                        )

                    }
                }

                Spacer(Modifier.height(5.px.dp))

                // Bad
                Row(
                    modifier = Modifier
                        .size(372.px.dp, 56.px.dp),
                    horizontalArrangement = Arrangement.Start,
                    verticalAlignment = Alignment.CenterVertically
                ) {
                    // Text - Bad
                    Row(
                        modifier = Modifier
                            .size(100.px.dp, 56.px.dp),
                        horizontalArrangement = Arrangement.Start,
                        verticalAlignment = Alignment.CenterVertically
                    ) {
                        Text(
                            text = "Bad",
                            style = RobotoTypography.headlineLarge,
                            fontWeight = FontWeight.ExtraLight,
                            fontSize = 14.px.sp,
                            color = Color.Black,
                            textAlign = TextAlign.Center,
                        )

                    }

                    // Bad (Set)
                    Row(
                        modifier = Modifier
                            .size(222.px.dp, 56.px.dp)
                            .background(Color(245,245,245))
                            .border(width = 1.px.dp, Color.LightGray,),
                        horizontalArrangement = Arrangement.Start,
                        verticalAlignment = Alignment.CenterVertically
                    ) {
                        OutlinedTextField(
                            value = badFieldValue,
                            onValueChange = { newTextFieldValue ->
                                val newText = newTextFieldValue.text
                                if (newText.isEmpty()) {
                                    badFieldValue = newTextFieldValue
                                } else if (newText.all { it.isDigit() }) {
                                    // Safely parse to Long to avoid NumberFormatException on large numbers
                                    val number = newText.toLongOrNull()
                                    if (number != null && number <= maxValue) {
                                        badFieldValue = newTextFieldValue
                                    } else {
                                        // The number is too large or invalid, show a toast
                                        Toast.makeText(
                                            context,
                                            "Input Number exceeded max value of $maxValue",
                                            Toast.LENGTH_SHORT
                                        ).show()
                                    }
                                }
                            },
                            //label = { Text("Count") },
                            keyboardOptions = KeyboardOptions(
                                keyboardType = KeyboardType.NumberPassword, // KeyboardType.Number, //KeyboardType.Text
                                imeAction = ImeAction.Done,
                                //autoCorrect = false
                            ),
                            singleLine = true,
                            keyboardActions = KeyboardActions(onDone = {
                                performOkClick()
                            }),
                            modifier = Modifier
                                .fillMaxSize()
                                .focusRequester(focusRequester)
                        )

                        LaunchedEffect(Unit) {
                            Timber.d("focusRequester.requestFocus()")
                            focusRequester.requestFocus()
                        }
                    }

                    // Text - %
                    Row(
                        modifier = Modifier
                            .size(50.px.dp, 56.px.dp),
                        horizontalArrangement = Arrangement.Center,
                        verticalAlignment = Alignment.CenterVertically
                    ) {
                        Text(
                            text = "%",
                            style = RobotoTypography.headlineLarge,
                            fontWeight = FontWeight.ExtraLight,
                            fontSize = 16.px.sp,
                            color = Color.Black,
                            textAlign = TextAlign.Center,
                        )

                    }
                }

                Spacer(Modifier.weight(1f))

                // Cancel & Set
                Row(
                    modifier = Modifier
                        .fillMaxWidth()
                        .height(68.px.dp)
                        .padding(start = 10.px.dp, end = 10.px.dp),
                    horizontalArrangement = Arrangement.End,
                    verticalAlignment = Alignment.CenterVertically
                ) {

                    // Cancel
                    TextButton(
                        modifier = Modifier
                            .size(68.px.dp, 40.px.dp),
                        onClick = {
                            Timber.d("onLoadClick")
                            onClick(
                                false,
                                Refer2(
                                    good = goodFieldValue.text.toFloat(),
                                    acceptable = acceptableFieldValue.text.toFloat(),
                                    bad  = badFieldValue.text.toFloat(),

                                    )
                            ) // This now closes the popup via the parent
                        }
                    ) {
                        Text(
                            text = stringResource(R.string.cancel),
                            style = RobotoTypography.labelLarge,
                            fontWeight = FontWeight.Normal,
                            fontSize = 14.px.sp,
                            color = Color.Black
                        )
                    }


                    // Set
                    TextButton(
                        modifier = Modifier
                            .size(68.px.dp, 40.px.dp),
                        onClick = {
                            Timber.d("Ok Clicked")
                            performOkClick()
                        }
                    ) {
                        Text(
                            text = stringResource(R.string.ok),
                            style = RobotoTypography.labelLarge,
                            fontWeight = FontWeight.Normal,
                            fontSize = 14.px.sp,
                            color = Color.Black
                        )
                    }
                }

            }
        }

    }
}

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