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

import android.content.Intent
import android.content.res.Configuration
import android.provider.Settings
import android.widget.Toast
import androidx.compose.foundation.Image
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.PaddingValues
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxHeight
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.layout.width
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.IconButton
import androidx.compose.material3.IconButtonDefaults
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
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.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
import androidx.navigation.NavHostController
import androidx.navigation.compose.rememberNavController
import com.laseroptek.raman.R
import com.laseroptek.raman.const.CMD
import com.laseroptek.raman.const.DEFAULT_GUIDE_BEAM
import com.laseroptek.raman.const.Energies
import com.laseroptek.raman.const.MAX_LAMP_COUNT
import com.laseroptek.raman.const.MAX_LIFETIME_DETECTOR
import com.laseroptek.raman.const.MAX_LIFETIME_HP
import com.laseroptek.raman.const.MAX_LIFETIME_LAMP
import com.laseroptek.raman.const.MAX_LIFETIME_WATER
import com.laseroptek.raman.const.MAX_OP_TIME
import com.laseroptek.raman.const.MAX_REFER2_VALUE
import com.laseroptek.raman.const.MIN_GUIDE_BEAM
import com.laseroptek.raman.const.PulseDurations
import com.laseroptek.raman.const.READ_WRITE
import com.laseroptek.raman.const.Repetitions
import com.laseroptek.raman.const.engineerModeButtonLists
import com.laseroptek.raman.data.datasource.db.RamanDatabase
import com.laseroptek.raman.data.model.serial.EnergyControl
import com.laseroptek.raman.data.model.serial.EnergyHandpiece
import com.laseroptek.raman.data.model.serial.EnergyMeasured
import com.laseroptek.raman.data.model.serial.LaserStatus
import com.laseroptek.raman.data.model.serial.Oven
import com.laseroptek.raman.data.model.serial.QSwitch
import com.laseroptek.raman.data.model.serial.getLaserStatusString
import com.laseroptek.raman.data.source.db.RamanDatabaseService
import com.laseroptek.raman.navigation.Routes
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.engineer.count.CountPopup
import com.laseroptek.raman.ui.screens.engineer.count.FloatPopup
import com.laseroptek.raman.ui.screens.engineer.dcd.DcdConfigPopup
import com.laseroptek.raman.ui.screens.engineer.default.DefaultConfirmPopup
import com.laseroptek.raman.ui.screens.engineer.energy.Refer1Popup
import com.laseroptek.raman.ui.screens.engineer.energy.Refer2Popup
import com.laseroptek.raman.ui.screens.engineer.export.ExportConfirmPopup
import com.laseroptek.raman.ui.screens.engineer.import.ImportConfirmPopup
import com.laseroptek.raman.ui.screens.engineer.load.LoadConfirmPopup
import com.laseroptek.raman.ui.screens.engineer.log.LogPopup
import com.laseroptek.raman.ui.screens.engineer.qswitch.QSwitchView
import com.laseroptek.raman.ui.screens.engineer.save.SaveConfirmPopup
import com.laseroptek.raman.ui.screens.engineer.serial.SerialNumberPopup
import com.laseroptek.raman.ui.screens.engineer.set.SetConfirmPopup
import com.laseroptek.raman.ui.screens.engineer.standby.EMStandByPopup
import com.laseroptek.raman.ui.screens.engineer.update.UpdateConfirmPopup
import com.laseroptek.raman.ui.screens.engineer.version.ProgramVersionPopup
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.decreaseVoltageTableValue
import com.laseroptek.raman.utils.ext.getValueFromVoltageTable
import com.laseroptek.raman.utils.ext.increaseVoltageTableValue
import com.laseroptek.raman.utils.ext.px
import com.laseroptek.raman.utils.ext.setVoltageTable
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.launch
import timber.log.Timber

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun EngineerScreen(
    mainNavController: NavHostController = rememberNavController(),
    paddingValues: PaddingValues = PaddingValues(),
    mainViewModel: MainViewModel = hiltViewModel<MainViewModel>(),
    engineerViewModel: EngineerViewModel = hiltViewModel<EngineerViewModel>(),
    title: String = stringResource(R.string.engineer_mode)
    ) {
    val context = LocalContext.current  // context For open system setting
    val scope = rememberCoroutineScope()

    Timber.d("$$$ EngineerScreen $$$")

    // show Popups
    var showUpdateConfirmPopup  by remember { mutableStateOf(false) }
    var showEmStandByPopup by remember { mutableStateOf(false) }
    var showLogPopup by remember { mutableStateOf(false) }
    var showSerialNumberPopup by remember { mutableStateOf(false) }
    var showProgramVersionPopup by remember { mutableStateOf(false) }
    var showDcdConfigPopup by remember { mutableStateOf(false) }
    var showDefaultConfirmPopup  by remember { mutableStateOf(false) }
    var showSaveConfirmPopup by remember { mutableStateOf(false) }
    var showLoadConfirmPopup by remember { mutableStateOf(false) }
    var showLampTotalCountPopup by remember { mutableStateOf(false) }
    var showDeviceOpTimePopup by remember { mutableStateOf(false) }
    var showImportConfirmPopup by remember { mutableStateOf(false) }
    var showExportConfirmPopup by remember { mutableStateOf(false) }
    var showSetConfirmPopup by remember { mutableStateOf(false) }

    // show Popups - LifeTime (show)
    var showLifeTimeLampCountPopup by remember { mutableStateOf(false) }
    var showLifeTypeHP5x5Popup by remember { mutableStateOf(false) }
    var showLifeTimeHP7x7Popup by remember { mutableStateOf(false) }
    var showLifeTimeHP10x10Popup by remember { mutableStateOf(false) }
    var showLifeTimeHP12x12Popup by remember { mutableStateOf(false) }
    var showLifeTimeHP3x15Popup by remember { mutableStateOf(false) }
    var showLifeTimeDetectorPopup by remember { mutableStateOf(false) }
    var showLifeTimeWaterPopup by remember { mutableStateOf(false) }

    // show Popups - Temp (show)
    var showTempKTPPopup by remember { mutableStateOf(false) }
    var showTempChamber1Popup by remember { mutableStateOf(false) }
    var showTempChamber2Popup by remember { mutableStateOf(false) }
    var showTempBaseplatePopup by remember { mutableStateOf(false) }
    var showTempWaterPopup by remember { mutableStateOf(false) }

    // show Popups - Energy Detect
    var showRefer1Popup by remember { mutableStateOf(false) }
    var showRefer2Popup by remember { mutableStateOf(false) }

    // mainViewModel vars
    val handPiece by mainViewModel.handPiece.collectAsState()
    val laserCount by mainViewModel.laserCount.collectAsState()
    val lampCount by mainViewModel.lampCount.collectAsState()
    val dcdType by mainViewModel.dcdType.collectAsState()
    val opTimeHour by mainViewModel.opTimeHour.collectAsState()
    val temperatureRead by mainViewModel.temperature.collectAsState()
    val energyMeasured by mainViewModel.energyMeasured.collectAsState()
    val energyDetectRefer2 by mainViewModel.energyDetectRefer2.collectAsState()
    val version by mainViewModel.version.collectAsState()
    val productSerialList by mainViewModel.productSerialList.collectAsState()
    val laserHandSerialList by mainViewModel.laserHandSerialList.collectAsState()
    val powerSupplySerialList by mainViewModel.powerSupplySerialList.collectAsState()
    //val guideBeam by mainViewModel.guideBeam.collectAsState()
    val guideBeamMin by mainViewModel.guideBeamMin.collectAsState()
    val guideBeamMax by mainViewModel.guideBeamMax.collectAsState()
    val qSwitch by mainViewModel.qSwitch.collectAsState()
    val energyHandpiece by mainViewModel.energyHandpiece.collectAsState()

    // engineerViewModel vars (1)
    val isVoltageSelectedElseReptition by engineerViewModel.isVoltageSelectedElseReptition.collectAsState()
    val selectedCalibRepetitionIndex by engineerViewModel.selectedCalibRepetitionIndex.collectAsState()
    val selectedCalibVoltageIndex by engineerViewModel.selectedCalibVoltageIndex.collectAsState()
    val selectedCalibPulseWidthIndex by engineerViewModel.selectedCalibPulseWidthIndex.collectAsState()

    // engineerViewModel vars (2)
    val voltageTable by engineerViewModel.voltageTable.collectAsState()
    val laserStatus by engineerViewModel.laserStatus.collectAsState()
    val lifeTime by engineerViewModel.lifeTime.collectAsState()

    val temperatureWrite by engineerViewModel.temperature_write.collectAsState()
    val energyMeasuredWrite by engineerViewModel.energyMeasuredWrite.collectAsState()

    LaunchedEffect(Unit) {
        Timber.d("$$$ EngineerScreen LaunchedEffect $$$")
    }

    DisposableEffect(Unit) {
        onDispose {
            Timber.d("MyComposable is being disposed!")
        }
    }
    
    FullScreen(
        contentAlignment= Alignment.TopCenter,
        backgroundColor = Color.Transparent
    ) {

        Box(
            modifier = Modifier
                .fillMaxSize()
                .padding(paddingValues)
                .background(Color.Transparent),
        ) {
            Column(
                modifier = Modifier
                    .fillMaxSize()
                    .background(
                        brush = Brush.verticalGradient(
                            colorStops = arrayOf(
                                0.0f to Color(255, 255, 255),
                                0.5f to Color(235, 235, 235),
                                1.0f to Color(216, 216, 216)
                            )
                        )
                    )
                    .padding(
                        top = 20.px.dp, bottom = 20.px.dp, start = 40.px.dp, end = 40.px.dp
                    )
                , horizontalAlignment = Alignment.CenterHorizontally
                , verticalArrangement = Arrangement.Top
            ) {
                //titleBar
                EngineerTitltBarView(
                    title = title,
                    height = 36.px.dp,
                    onCloseClick = {
                        Timber.d("onCloseClick")

                        // update (load Voltage Table changed from Preference)
                        scope.launch {
                            mainViewModel.loadVoltageTableFromPreference()
                        }

                        mainNavController.navigate(Routes.Config.route)
                    },
                    onOSSetupClick = {
                        try {
                            context.startActivity(Intent(Settings.ACTION_SETTINGS))
                        } catch (e: Exception) {
                            Timber.e(e, "Could not open ACTION_SETTINGS")
                            // Fallback: Show a toast or other message if opening settings fails
                            Toast.makeText(
                                context,
                                "Could not open ACTION_SETTINGS. Please navigate manually.",
                                Toast.LENGTH_LONG
                            ).show()
                        }
                    }
                )

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

                // body
                Row(modifier = Modifier
                    .fillMaxSize(),
                    horizontalArrangement = Arrangement.SpaceBetween
                ) {
                    // left
                    Column(modifier = Modifier
                        .fillMaxSize()
                        .padding(end = 0.px.dp)
                        .weight(1f)
                    ) {
                        // left - left side
                        Row(modifier = Modifier
                            .fillMaxSize()
                            .weight(1f)
                        ) {
                            // left - left pannel
                            Column(modifier = Modifier
                                .width(388.px.dp)
                                .fillMaxHeight()
                                //.background(Color.Yellow)
                            ) {
                                // Repetion And Voltage
                                Row {
                                    // L: Repetion (Hz)
                                    RepetitionView(
                                        modifier = Modifier
                                            .fillMaxWidth()
                                            .weight(1f)
                                            .height(48.px.dp),
                                        selectedCalibRepetitionIndex = selectedCalibRepetitionIndex,
                                        isVoltageSelectedElseReptition = isVoltageSelectedElseReptition,
                                        title = stringResource(R.string.repetition_title),
                                        onClick = {
                                            engineerViewModel.setIsVoltageSelectedElseReptition(false)
                                        }
                                    )

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

                                    // R: Voltage (V)
                                    VoltageView(
                                        modifier = Modifier
                                            .fillMaxWidth()
                                            .weight(1f)
                                            .height(48.px.dp),
                                        laserStatus = laserStatus,
                                        title = stringResource(R.string.voltage_title)
                                    )
                                }
                                Spacer(modifier = Modifier.height(8.px.dp))

                                // left - pulse-width (ms)
                                PulseWidthView(
                                    selectedCalibPulseWidthIndex = selectedCalibPulseWidthIndex,
                                    onClick = { index ->
                                        Timber.d("onClickPulseWidth: $index")
                                        engineerViewModel.setSelectedCalibPulseWidthIndex(index)
                                    }
                                )
                                Spacer(modifier = Modifier.height(8.px.dp))

                                // left - reptition N voltage select
                                EnergyVoltageView(
                                    voltageTable = voltageTable,
                                    isVoltageSelectedElseReptition = isVoltageSelectedElseReptition,
                                    selectedCalibVoltageIndex = selectedCalibVoltageIndex,
                                    selectedCalibPulseWidthIndex = selectedCalibPulseWidthIndex,
                                    onClick = { index ->
                                        Timber.d("onClickVoltage: $index")

                                        engineerViewModel.setIsVoltageSelectedElseReptition(true)
                                        engineerViewModel.setSelectedCalibVoltageIndex(index)
                                    },
                                )
                                Spacer(modifier = Modifier.height(8.px.dp))

                                // left - // left - reptition N voltage change
                                RepetitionVoltageControlView(
                                    onClickUp = {
                                        Timber.d("[EM] onClickUp")
                                        Timber.d("[EM] selectedCalibPulseWidthIndex: ${selectedCalibPulseWidthIndex}")
                                        Timber.d("[EM] selectedCalibVoltageIndex: ${selectedCalibVoltageIndex}")
                                        // increase volume by 1
                                        if (isVoltageSelectedElseReptition) {
                                            val selectedPulseWidth = PulseDurations[selectedCalibPulseWidthIndex]
                                            increaseVoltageWithCascade(
                                                voltageTable = voltageTable,
                                                pulseWidth = selectedPulseWidth,
                                                selectedVoltageIndex = selectedCalibVoltageIndex,
                                                increament = 1
                                            )
                                        } else if (selectedCalibRepetitionIndex < Repetitions.size - 1) {
                                            engineerViewModel.setSelectedCalibRepetitionIndex(selectedCalibRepetitionIndex + 1)
                                            Timber.d("selectedCalibRepetitionIndex: ${selectedCalibRepetitionIndex}")
                                        } else {
                                            Timber.d("selectedCalibRepetitionIndex: ${selectedCalibRepetitionIndex}")
                                        }
                                    },
                                    onClickUpLongPress = {
                                        Timber.d("[EM] onClickUp")
                                        Timber.d("[EM] selectedCalibPulseWidthIndex: ${selectedCalibPulseWidthIndex}")
                                        Timber.d("[EM] selectedCalibVoltageIndex: ${selectedCalibVoltageIndex}")
                                        // increase volume by 10
                                        if (isVoltageSelectedElseReptition) {
                                            val selectedPulseWidth = PulseDurations[selectedCalibPulseWidthIndex]
                                            increaseVoltageWithCascade(
                                                voltageTable = voltageTable,
                                                pulseWidth = selectedPulseWidth,
                                                selectedVoltageIndex = selectedCalibVoltageIndex,
                                                increament = 10
                                            )
                                        } else if (selectedCalibRepetitionIndex < Repetitions.size - 1) {
                                            engineerViewModel.setSelectedCalibRepetitionIndex(selectedCalibRepetitionIndex + 1)
                                            Timber.d("selectedCalibRepetitionIndex: ${selectedCalibRepetitionIndex}")
                                        } else {
                                            Timber.d("selectedCalibRepetitionIndex: ${selectedCalibRepetitionIndex}")
                                        }
                                    },
                                    onClickDown = {
                                        Timber.d("[EM] onClickDown")
                                        Timber.d("[EM] selectedCalibPulseWidthIndex: ${selectedCalibPulseWidthIndex}")
                                        Timber.d("[EM] selectedCalibVoltageIndex: ${selectedCalibVoltageIndex}")
                                        if (isVoltageSelectedElseReptition) {
                                            val selectedPulseWidth = PulseDurations[selectedCalibPulseWidthIndex]
                                            decreaseVoltageWithCascade(
                                                voltageTable = voltageTable,
                                                pulseWidth = selectedPulseWidth,
                                                selectedVoltageIndex = selectedCalibVoltageIndex,
                                                decreament = 1
                                            )
                                        } else if (selectedCalibRepetitionIndex > 0) {
                                            engineerViewModel.setSelectedCalibRepetitionIndex(selectedCalibRepetitionIndex - 1)
                                            Timber.d("selectedCalibRepetitionIndex: ${selectedCalibRepetitionIndex}")
                                        } else {
                                            Timber.d("selectedCalibRepetitionIndex: ${selectedCalibRepetitionIndex}")
                                        }
                                    },
                                    onClickDownLongPress = {
                                        Timber.d("[EM] onClickDown")
                                        Timber.d("[EM] selectedCalibPulseWidthIndex: ${selectedCalibPulseWidthIndex}")
                                        Timber.d("[EM] selectedCalibVoltageIndex: ${selectedCalibVoltageIndex}")
                                        if (isVoltageSelectedElseReptition) {
                                            val selectedPulseWidth = PulseDurations[selectedCalibPulseWidthIndex]
                                            decreaseVoltageWithCascade(
                                                voltageTable = voltageTable,
                                                pulseWidth = selectedPulseWidth,
                                                selectedVoltageIndex = selectedCalibVoltageIndex,
                                                decreament = 10
                                            )
                                        } else if (selectedCalibRepetitionIndex > 0) {
                                            engineerViewModel.setSelectedCalibRepetitionIndex(selectedCalibRepetitionIndex - 1)
                                            Timber.d("selectedCalibRepetitionIndex: ${selectedCalibRepetitionIndex}")
                                        } else {
                                            Timber.d("selectedCalibRepetitionIndex: ${selectedCalibRepetitionIndex}")
                                        }
                                    },
                                    onClickDtoV = {
                                        Timber.d("onClickDtoV : emVoltageTable -> voltageTable")
                                        Timber.d("[EM] selectedCalibPulseWidthIndex: ${selectedCalibPulseWidthIndex}")
                                        Timber.d("[EM] selectedCalibVoltageIndex: ${selectedCalibVoltageIndex}")
                                        val key: Pair<Float, Float> = Pair(
                                            PulseDurations[selectedCalibPulseWidthIndex],
                                            Energies[selectedCalibVoltageIndex]
                                        )
                                        val v = laserStatus.voltage
                                        voltageTable.setVoltageTable(key, v)
                                    },
                                    onClickVtoD = {
                                        Timber.d("onClickVtoD : emVoltageTable -> voltageTable")
                                        Timber.d("[EM] selectedCalibPulseWidthIndex: ${selectedCalibPulseWidthIndex}")
                                        Timber.d("[EM] selectedCalibVoltageIndex: ${selectedCalibVoltageIndex}")
                                        val key: Pair<Float, Float> = Pair(
                                            PulseDurations[selectedCalibPulseWidthIndex],
                                            Energies[selectedCalibVoltageIndex]
                                        )
                                        val v = voltageTable.getValueFromVoltageTable(key) ?: 0
                                        engineerViewModel.setLaserStatus(
                                            LaserStatus(
                                                voltage = v,
                                                onTime = PulseDurations[selectedCalibPulseWidthIndex]
                                            )
                                        )
                                    },
                                )
                            }

                            // middle - os N temp
                            Column(modifier = Modifier
                                .fillMaxSize()
                                .padding(start = 20.px.dp)
                                .weight(1f)
                            ) {
                                Column(
                                    modifier = Modifier
                                        .fillMaxSize()
                                        .weight(1f)
                                        .clip(RoundedCornerShape(10.px.dp))
                                        .border(
                                            width = 1.px.dp,
                                            color = Color(209, 209, 209),
                                            shape = RoundedCornerShape(10.px.dp)
                                        )
                                        .background(Color.White),
                                    verticalArrangement = Arrangement.Center,
                                    horizontalAlignment = Alignment.CenterHorizontally
                                ) {
                                    Spacer(modifier = Modifier.height(10.px.dp))

                                    // Q Switch (main)
                                    QSwitchView(
                                        modifier = Modifier
                                            .fillMaxSize()
                                            .weight(1f)
                                            .padding(
                                                start = 20.px.dp,
                                                end = 20.px.dp,
                                                //bottom = 10.px.dp
                                            ),
                                        qSwitch = qSwitch,
                                        title = "Q-S/W (main)",
                                        onClick = { qSwitch ->
                                            Timber.d("onClick > Q-S/W (main)")
                                            mainViewModel.setQSwitch(qSwitch)
                                            scope.launch {
                                                mainViewModel.saveQSwitchToPreference()
                                            }
                                        }
                                    )

                                    HorizontalDivider(
                                        modifier = Modifier
                                            .padding(start = 18.px.dp, end=18.px.dp),
                                        thickness = 0.2.px.dp,
                                        color = Color.LightGray
                                    )

                                    // Q-S/W (sub)
                                    QSwitchView(
                                        modifier = Modifier
                                            .fillMaxSize()
                                            .weight(1f)
                                            .padding(
                                                start = 20.px.dp,
                                                end = 20.px.dp,
                                                //bottom = 10.px.dp
                                            ),
                                        qSwitch = qSwitch, //qSwitchSub,
                                        title = "Q-S/W (sub)",
                                        onClick = { qSwitch ->
                                            Timber.d("onClick > Q-S/W (sub)")
                                            //mainViewModel.setQSwitchSub(qSwitch)
                                            mainViewModel.setQSwitch(qSwitch)
                                            scope.launch {
                                                mainViewModel.saveQSwitchToPreference()
                                            }
                                        }
                                    )

                                    HorizontalDivider(
                                        modifier = Modifier
                                            .padding(start = 18.px.dp, end=18.px.dp),
                                        thickness = 0.2.px.dp,
                                        color = Color.LightGray
                                    )

                                    // Energy Detect
                                    EnergyDetectView(
                                        modifier = Modifier
                                            .fillMaxSize()
                                            .weight(1f)
                                            .padding(
                                                start = 20.px.dp,
                                                end = 20.px.dp,
                                                //bottom = 10.px.dp
                                            ),
                                        title = "ENERGY \nDETECT",
                                        onClick = { no ->
                                            Timber.d("onClick > Energy Detect")
                                            when (no) {
                                                1 -> showRefer1Popup = true
                                                2 -> showRefer2Popup = true
                                                else -> {}
                                            }
                                        }
                                    )

                                    HorizontalDivider(
                                        modifier = Modifier
                                            .padding(start = 18.px.dp, end=18.px.dp),
                                        thickness = 0.2.px.dp,
                                        color = Color.LightGray
                                    )

                                    // DCD
                                    DcdView(
                                        modifier = Modifier
                                            .fillMaxSize()
                                            .weight(1f)
                                            .padding(
                                                start = 20.px.dp,
                                                end = 20.px.dp,
                                                //bottom = 10.px.dp
                                            ),
                                        dcdType = dcdType,
                                        title = "DCD",
                                        onClick = {
                                            showDcdConfigPopup = true
                                        }
                                    )

                                    HorizontalDivider(
                                        modifier = Modifier
                                            .padding(start = 18.px.dp, end=18.px.dp),
                                        thickness = 0.2.px.dp,
                                        color = Color.LightGray
                                    )

                                    // Guide Beam
                                    GuideBeamView(
                                        modifier = Modifier
                                            .fillMaxSize()
                                            .weight(1f)
                                            .padding(
                                                start = 20.px.dp,
                                                end = 20.px.dp,
                                                //bottom = 10.px.dp
                                            ),
                                        title = "Guide Beam",
                                        minValue = guideBeamMin,
                                        maxValue = guideBeamMax,
                                        onClick = { state ->
                                            scope.launch {
                                                mainViewModel.onGuideBeamChanged(state)
                                            }
                                        }
                                    )

                                    HorizontalDivider(
                                        modifier = Modifier
                                            .padding(start = 18.px.dp, end=18.px.dp),
                                        thickness = 0.2.px.dp,
                                        color = Color.LightGray
                                    )

                                    // Lamp Total Count
                                    CountItemView(
                                        modifier = Modifier
                                            .fillMaxSize()
                                            .weight(1f)
                                            .padding(
                                                start = 20.px.dp,
                                                end = 20.px.dp,
                                                //bottom = 10.px.dp
                                            ),
                                        count = lampCount,
                                        title = "Lamp \nTotal Count",
                                        onClick = {
                                            showLampTotalCountPopup = true
                                        }
                                    )

                                    HorizontalDivider(
                                        modifier = Modifier
                                            .padding(start = 18.px.dp, end=18.px.dp),
                                        thickness = 0.2.px.dp,
                                        color = Color.LightGray
                                    )

                                    // Device Operation Time
                                    HourItemView(
                                        modifier = Modifier
                                            .fillMaxSize()
                                            .weight(1f)
                                            .padding(
                                                start = 20.px.dp,
                                                end = 20.px.dp,
                                                //bottom = 10.px.dp
                                            ),
                                        hour = opTimeHour.toInt(),
                                        title = "Device \nOperation Time",
                                        onClick = {
                                            showDeviceOpTimePopup = true
                                        }
                                    )

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

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

                                // LifeTime View
                                LifeTimeView(
                                    lifeTime = lifeTime,
                                    onClick = { index ->
                                        when (index) {
                                            0 -> {
                                                Timber.d("onClick > LifeTime")
                                                showLifeTimeLampCountPopup = true
                                            }
                                            1 -> {
                                                Timber.d("onClick > HP5x5")
                                                showLifeTypeHP5x5Popup = true
                                            }
                                            2 -> {
                                                Timber.d("onClick > HP7x7")
                                                showLifeTimeHP7x7Popup = true
                                            }
                                            3 -> {
                                                Timber.d("onClick > HP10x10")
                                                showLifeTimeHP10x10Popup = true
                                            }
                                            4 -> {
                                                Timber.d("onClick > HP12x12")
                                                showLifeTimeHP12x12Popup = true
                                            }
                                            5 -> {
                                                Timber.d("onClick > HP3x15")
                                                showLifeTimeHP3x15Popup = true
                                            }
                                            6 -> {
                                                Timber.d("onClick > HP3x15")
                                                showLifeTimeDetectorPopup = true
                                            }
                                            7 -> {
                                                Timber.d("onClick > HP3x15")
                                                showLifeTimeWaterPopup = true
                                            }
                                            else -> {}
                                        }

                                    }
                                )
                            }
                        }

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

                        // bottom Buttons
                        Row(modifier = Modifier
                            .fillMaxWidth()
                            .height(32.px.dp),
                            //.background(Color.Yellow),
                            horizontalArrangement = Arrangement.SpaceBetween,
                            verticalAlignment = Alignment.CenterVertically
                        ) {
                            engineerModeButtonLists.forEachIndexed { index, data ->
                                IconButton(
                                    onClick = {
                                        Timber.d("Perform action when button is clicked: %d", index)
                                        when(index) {
                                            0 -> {
                                                Timber.d("onUpdateClick")
                                                showUpdateConfirmPopup = true
                                            }
                                            1 -> {
                                                Timber.d("onDefaultClick")
                                                showDefaultConfirmPopup = true
                                            }
                                            2 -> {
                                                Timber.d("onSaveClick")
                                                showSaveConfirmPopup = true
                                            }
                                            3 -> {
                                                Timber.d("onLoadClick")
                                                showLoadConfirmPopup = true
                                            }
                                            4 -> {
                                                Timber.d("onImportClick")
                                                showImportConfirmPopup = true
                                            }
                                            5 -> {
                                                Timber.d("onExportClick")
                                                showExportConfirmPopup = true
                                            }
                                            6 -> {
                                                Timber.d("onLogClick")
                                                scope.launch {
                                                    mainViewModel.fetchSerialLog()
                                                }
                                                showLogPopup = true
                                            }
                                        }
                                    },
                                    modifier = Modifier
                                        .size(98.px.dp, 32.px.dp)
                                        .clip(RoundedCornerShape(percent = 50)),
                                    colors = IconButtonDefaults.iconButtonColors(
                                        contentColor = data.contentColor, // Icon and Text color
                                        containerColor = data.containerColor, // Background color
                                        disabledContentColor = data.contentColor, // Icon color when disabled
                                        disabledContainerColor = data.containerColor // Background color when disabled
                                    )
                                ) {
                                    Box(modifier = Modifier.fillMaxSize()) {
                                        Row(
                                            modifier = Modifier.align(Alignment.Center), // This now works correctly.
                                            verticalAlignment = Alignment.CenterVertically
                                        ) {
                                            Image(
                                                painter = painterResource(id = data.image),
                                                contentDescription = null,
                                                modifier = Modifier.size(14.px.dp),
                                                contentScale = ContentScale.Fit,
                                                colorFilter = ColorFilter.tint(data.contentColor)
                                            )

                                            // Spacer
                                            Spacer(modifier = Modifier.width(6.px.dp))

                                            // Text
                                            Text(
                                                text = stringResource(data.title),
                                                style = RobotoTypography.bodySmall,
                                                fontWeight = FontWeight.ExtraLight,
                                                fontSize = 14.px.sp,
                                                color = data.contentColor
                                            )

                                            Spacer(modifier = Modifier.width(6.px.dp))
                                        }
                                    }
                                }
                            }
                        }
                    }

                    // right
                    Column(modifier = Modifier
                        .width(408.px.dp)
                        .fillMaxHeight()
                        .padding(start = 20.px.dp)
                    ) {
                        // Temperature View
                        TemperatureView(
                            temperatureRead = temperatureRead,
                            temperatureWrite = temperatureWrite,
                            onClick = { index ->
                                when (index) {
                                    0 -> {
                                        Timber.d("onClick > showTempKTPPopup")
                                        showTempKTPPopup = true
                                    }
                                    1 -> {
                                        Timber.d("onClick > showTempChamber1Popup")
                                        showTempChamber1Popup = true
                                    }
                                    2 -> {
                                        Timber.d("onClick > showTempChamber2Popup")
                                        showTempChamber2Popup = true
                                    }
                                    3 -> {
                                        Timber.d("onClick > showTempBaseplatePopup")
                                        showTempBaseplatePopup = true
                                    }
                                    4 -> {
                                        Timber.d("onClick > showTempWaterPopup")
                                        showTempWaterPopup = true
                                    }
                                    else -> {}
                                }

                            },
                        )
                        Spacer(modifier = Modifier.height(8.px.dp))

                        VersionView(
                            version = version,
                            productSerialList = productSerialList,
                            laserHandSerialList = laserHandSerialList,
                            powerSupplySerialList = powerSupplySerialList,
                            onClick = { idx ->
                                when (idx) {
                                    0 -> {
                                        Timber.d("onClick > showSerialNumberPopup")
                                        showSerialNumberPopup = true
                                    }
                                    else -> {
                                        Timber.d("onClick > showProgramVersionPopup")
                                        showProgramVersionPopup = true
                                    }
                                }
                            }
                        )
                        Spacer(modifier = Modifier.height(8.px.dp))

                        // set Button
                        SetButton(
                            onClick = {
                                Timber.d("onSetClick")
                                //onSetClick.invoke()
                                showSetConfirmPopup = true

                                //mainViewModel.setVoltageTable()
                                //Voltage Table를 제외한 다른 설정 값 저장 (3.31)

                                // send qSwitch
                                //mainViewModel.txPacket(READ_WRITE.WRITE, CMD.Q_SWITCH, mainViewModel.qSwitch.value)
                            },
                            title = stringResource(R.string.set)
                        )
                        Spacer(modifier = Modifier.height(8.px.dp))

                        // StandBy Button
                        StandByButton(
                            onClick = {
                                Timber.d("onEmStandByClick: ${laserStatus}")

                                if (handPiece.type == 0) {
                                    Toast.makeText(
                                        context,
                                        "NO HAND-PIECE recognized",
                                        Toast.LENGTH_SHORT
                                    ).show()
                                    return@StandByButton
                                }

                                laserStatus.laserStatus = 0x52  // ready

                                // repetition
                                val repetition = Repetitions.get(
                                    selectedCalibRepetitionIndex
                                )
                                laserStatus.frequence = repetition

                                // pulseWith
                                val pulseWith = PulseDurations.get(
                                    selectedCalibPulseWidthIndex
                                )
                                laserStatus.onTime = pulseWith

                                mainViewModel.txPacket(READ_WRITE.WRITE, CMD.LASER_STATUS, laserStatus)

                                Toast.makeText(
                                    context,
                                    "[TX][onTime(ms): %f, frequence(Hz): %f) -> V(V): %d)]".format(
                                        laserStatus.onTime, laserStatus.frequence, laserStatus.voltage
                                    ),
                                    Toast.LENGTH_LONG
                                ).show()

                                showEmStandByPopup = true
                            },
                            title = getLaserStatusString(laserStatus.laserStatus)
                        )
                    }
                }
            }
        }

        ////////////////////////////////////////////////////////////////////////////////////////////
        // Popups
        if (showSerialNumberPopup) {
            SerialNumberPopup(
                title = stringResource(R.string.serial_number),
                productSerialList = productSerialList.toMutableList(),
                laserHandSerialList = laserHandSerialList.toMutableList(),
                powerSupplySerialList = powerSupplySerialList.toMutableList(),
                onClick = { ok, productSerialList, laserHandSerialList, powerSupplySerialList  ->
                    if (ok) {
                        Timber.d("onClick > productSerialList: $productSerialList")
                        Timber.d("onClick > laserHandSerialList: $laserHandSerialList")
                        Timber.d("onClick > powerSupplySerialList: $powerSupplySerialList")

                        mainViewModel.setProductSerialList(productSerialList)
                        mainViewModel.setLaserHandSerialList(laserHandSerialList)
                        mainViewModel.setPowerSupplySerialList(powerSupplySerialList)

                        // need to save to preference
                        scope.launch {
                            mainViewModel.saveProductSerialListToPreference()
                            mainViewModel.saveLaserHandSerialListToPreference()
                            mainViewModel.savePowerSupplySerialListToPreference()
                        }
                    }
                    showSerialNumberPopup = false
                }
            )
        }

        else if (showProgramVersionPopup) {
            ProgramVersionPopup(
                title = stringResource(R.string.program_version),
                version = mainViewModel.version,
                onClick = {
                    showProgramVersionPopup = false
                }
            )
        }

        else if (showDcdConfigPopup) {
            DcdConfigPopup(
                mainViewModel = mainViewModel,
                //showDcdConfigPopup = showDcdConfigPopup,
                //dcdType = mainViewModel.dcdType,
                onClick = {
                    showDcdConfigPopup = false
                }
            )
        }

        else if (showLampTotalCountPopup) {
            CountPopup(
                //mainViewModel = mainViewModel,
                title = stringResource(R.string.lamp_total_count_title),
                count = lampCount,
                maxValue = MAX_LAMP_COUNT,
                onClick = { ok, value ->
                    if (ok) {
                        mainViewModel.setLampCount( value )
                        scope.launch {
                            mainViewModel.saveLampCountToPreference()
                        }
                    }
                    showLampTotalCountPopup = false
                }
            )
        }

        else if (showDeviceOpTimePopup){
            CountPopup(
                title = stringResource(R.string.device_operation_time_title),
                count = opTimeHour.toInt(),
                maxValue = MAX_OP_TIME,
                onClick = { ok, value ->
                    if (ok) {
                        mainViewModel.setOpTimeHour( value.toLong() )
                        scope.launch {
                            mainViewModel.saveOpTimeHourToPreference()
                        }
                    }
                    showDeviceOpTimePopup = false
                }
            )
        }

        // Life Time {
        else if (showLifeTimeLampCountPopup){
            CountPopup(
                title = stringResource(R.string.lifetime_lamp_count_title),
                count = lifeTime.lamp,
                maxValue = MAX_LIFETIME_LAMP,
                onClick = { ok, value ->
                    if (ok) {
                        Timber.d("onClick > lampCount: $value")

                        mainViewModel.setLifeTime(
                            lifeTime.copy(
                                lamp = value
                            )
                        )

                        scope.launch {
                            mainViewModel.saveLifeTimeToPreference()
                        }
                    }
                    showLifeTimeLampCountPopup = false
                }
            )
        }

        else if (showLifeTypeHP5x5Popup){
            CountPopup(
                title = stringResource(R.string.lifetime_hp5x5_count_title),
                count = lifeTime.hp5x5,
                maxValue = MAX_LIFETIME_HP,
                onClick = { ok, value ->
                    if (ok) {
                        Timber.d("onClick > hp5x5: $value")
                        mainViewModel.setLifeTime(
                            lifeTime.copy(
                                hp5x5 = value
                            )
                        )
                        scope.launch {
                            mainViewModel.saveLifeTimeToPreference()
                        }
                    }
                    showLifeTypeHP5x5Popup = false
                }
            )
        }

        else if (showLifeTimeHP7x7Popup){
            CountPopup(
                title = stringResource(R.string.lifetime_hp7x7_count_title),
                count = lifeTime.hp7x7,
                maxValue = MAX_LIFETIME_HP,
                onClick = { ok, value ->
                    if (ok) {
                        Timber.d("onClick > hp7x7: $value")
                        mainViewModel.setLifeTime(
                            lifeTime.copy(
                                hp7x7 = value
                            )
                        )
                        scope.launch {
                            mainViewModel.saveLifeTimeToPreference()
                        }
                    }
                    showLifeTimeHP7x7Popup = false
                }
            )
        }

        else if (showLifeTimeHP10x10Popup){
            CountPopup(
                title = stringResource(R.string.lifetime_hp10x10_count_title),
                count = lifeTime.hp10x10,
                maxValue = MAX_LIFETIME_HP,
                onClick = { ok, value ->
                    if (ok) {
                        Timber.d("onClick > hp10x10: $value")
                        mainViewModel.setLifeTime(
                            lifeTime.copy(
                                hp10x10 = value
                            )
                        )
                        scope.launch {
                            mainViewModel.saveLifeTimeToPreference()
                        }
                    }
                    showLifeTimeHP10x10Popup = false
                }
            )
        }

        else if (showLifeTimeHP12x12Popup){
            CountPopup(
                title = stringResource(R.string.lifetime_hp12x12_count_title),
                count = lifeTime.hp12x12,
                maxValue = MAX_LIFETIME_HP,
                onClick = { ok, value ->
                    if (ok) {
                        Timber.d("onClick > hp12x12: $value")
                        mainViewModel.setLifeTime(
                            lifeTime.copy(
                                hp12x12 = value
                            )
                        )
                        scope.launch {
                            mainViewModel.saveLifeTimeToPreference()
                        }
                    }
                    showLifeTimeHP12x12Popup = false
                }
            )
        }

        else if (showLifeTimeHP3x15Popup){
            CountPopup(
                title = stringResource(R.string.lifetime_hp3x15_count_title),
                count = lifeTime.hp3x15,
                maxValue = MAX_LIFETIME_HP,
                onClick = { ok, value ->
                    if (ok) {
                        Timber.d("onClick > hp3x15: $value")
                        mainViewModel.setLifeTime(
                            lifeTime.copy(
                                hp3x15 = value
                            )
                        )
                        scope.launch {
                            mainViewModel.saveLifeTimeToPreference()
                        }
                    }
                    showLifeTimeHP3x15Popup = false
                }
            )
        }
        else if (showLifeTimeDetectorPopup){
            CountPopup(
                title = stringResource(R.string.lifetime_detector_count_title),
                count = lifeTime.detector,
                maxValue = MAX_LIFETIME_DETECTOR,
                onClick = { ok, value ->
                    if (ok) {
                        Timber.d("onClick > detector: $value")
                        mainViewModel.setLifeTime(
                            lifeTime.copy(
                                detector = value
                            )
                        )
                        scope.launch {
                            mainViewModel.saveLifeTimeToPreference()
                        }
                    }
                    showLifeTimeDetectorPopup = false
                }
            )
        }
        else if (showLifeTimeWaterPopup){
            CountPopup(
                title = stringResource(R.string.lifetime_water_count_title),
                count = lifeTime.water,
                maxValue = MAX_LIFETIME_WATER,
                onClick = { ok, value ->
                    if (ok) {
                        Timber.d("onClick > water: $value")
                        mainViewModel.setLifeTime(
                            lifeTime.copy(
                                water = value
                            )
                        )
                        scope.launch {
                            mainViewModel.saveLifeTimeToPreference()
                        }
                    }
                    showLifeTimeWaterPopup = false
                }
            )
        }
        // } Life Time

        // Temp {
        else if (showTempKTPPopup){
            FloatPopup(
                title = stringResource(R.string.ktp_count_title),
                count = temperatureWrite.ktp,
                onClick = { ok, value ->
                    if (ok) {
                        Timber.d("onClick > ktp: $value")
                        mainViewModel.setTemperatureWrite(
                            temperatureWrite.copy(
                                ktp = value.toFloat()
                            )
                        )

                        // send KTP (OVEN)
                        mainViewModel.txPacket(
                            READ_WRITE.WRITE,
                            CMD.OVEN,
                            Oven(
                                type = 0x41,
                                ktp = temperatureWrite.ktp
                            )
                        )

                        scope.launch {
                            mainViewModel.saveTemeratureWriteToPreference()
                        }
                    }
                    showTempKTPPopup = false
                }
            )
        }

        else if (showTempChamber1Popup){
            FloatPopup(
                title = stringResource(R.string.chamber1_count_title),
                count = temperatureWrite.chamber1,
                onClick = { ok, value ->
                    if (ok) {
                        Timber.d("onClick > chamber1: $value")

                        mainViewModel.setTemperatureWrite(
                            temperatureWrite.copy(
                                chamber1 = value.toFloat()
                            )
                        )
                        scope.launch {
                            mainViewModel.saveTemeratureWriteToPreference()
                        }
                    }
                    showTempChamber1Popup = false
                }
            )
        }

        else if (showTempChamber2Popup){
            FloatPopup(
                title = stringResource(R.string.chamber2_count_title),
                count = temperatureWrite.chamber2,
                onClick = { ok, value ->
                    if (ok) {
                        Timber.d("onClick > chamber2: $value")
                        mainViewModel.setTemperatureWrite(
                            temperatureWrite.copy(
                                chamber2 = value.toFloat()
                            )
                        )
                        scope.launch {
                            mainViewModel.saveTemeratureWriteToPreference()
                        }
                    }
                    showTempChamber2Popup = false
                }
            )
        }

        else if (showTempWaterPopup){
            FloatPopup(
                title = stringResource(R.string.water_count_title),
                count = temperatureWrite.water,
                onClick = { ok, value ->
                    if (ok) {
                        mainViewModel.setTemperatureWrite(
                            temperatureWrite.copy(
                                water = value.toFloat()
                            )
                        )
                        scope.launch {
                            mainViewModel.saveTemeratureWriteToPreference()
                        }
                    }
                    showTempWaterPopup = false
                }
            )
        }

        else if (showTempBaseplatePopup){
            FloatPopup(
                title = stringResource(R.string.baseplate_count_title),
                count = temperatureWrite.basePlate,
                onClick = { ok, value ->
                    if (ok) {
                        Timber.d("onClick > basePlate: $value")
                        mainViewModel.setTemperatureWrite(
                            temperatureWrite.copy(
                                basePlate = value.toFloat()
                            )
                        )
                        scope.launch {
                            mainViewModel.saveTemeratureWriteToPreference()
                        }
                    }
                    showTempBaseplatePopup = false
                }
            )
        }
        // } Temp

        else if (showDefaultConfirmPopup) {
            DefaultConfirmPopup(
                onClick = { ok ->
                    if (ok) {
                        engineerViewModel.factoryDefault()
                        mainViewModel.setGuideBeamMin(MIN_GUIDE_BEAM)
                        mainViewModel.setGuideBeamMax(DEFAULT_GUIDE_BEAM)
                        mainViewModel.setQSwitch(QSwitch())
                        mainViewModel.setQSwitchSub(QSwitch())
                    }
                    showDefaultConfirmPopup = false
                }
            )
        }

        else if (showUpdateConfirmPopup) {
            UpdateConfirmPopup(
                onClick = { ok ->
                    if (ok) {
                        Timber.d("onClick - UpdateConfirmPopup")
                        scope.launch {
                            mainViewModel.emitUpdateApkEvent()
                        }
                    }
                    showUpdateConfirmPopup = false
                }
            )
        }

        else if (showSaveConfirmPopup) {
            SaveConfirmPopup(
                onClick = { ok ->
                    if (ok) {
                        // save voltage to preference
                        Timber.d("onClick - SaveConfirmPopup")
                        scope.launch {
                            engineerViewModel.saveToPreference()

                            mainViewModel.saveGuideBeamMinToPreference()
                            mainViewModel.saveGuideBeamMaxToPreference()
                        }
                    }
                    showSaveConfirmPopup = false
                }
            )
        }

        else if (showLoadConfirmPopup) {
            LoadConfirmPopup(
                onClick = { ok ->
                    if (ok) {
                        Timber.d("onClick - LoadConfirmPopup")
                        scope.launch {
                            engineerViewModel.loadFromPreference()

                            mainViewModel.loadGuideBeamMinFromPreference()
                            mainViewModel.loadGuideBeamMaxFromPreference()
                            mainViewModel.loadQSwitchFromPreference()
                        }
                    }
                    showLoadConfirmPopup = false
                }
            )
        }

        else if (showImportConfirmPopup) {
            ImportConfirmPopup(
                onClick = { ok ->
                    if (ok) {
                        Timber.d("onClick - ImportConfirmPopup")
                        scope.launch {
                            engineerViewModel.loadFromPreference()
                        }
                    }
                    showImportConfirmPopup = false
                }
            )

        }

        else if (showExportConfirmPopup) {
            ExportConfirmPopup(
                onClick = { ok ->
                    Timber.d("onClick - ImportConfirmPopup $ok")

                    // save others
                    scope.launch {
                        engineerViewModel.saveToPreference()

                        mainViewModel.saveOpTimeHourToPreference()
                        mainViewModel.saveQSwitchToPreference()
                        mainViewModel.saveGuideBeamMinToPreference()
                        mainViewModel.saveGuideBeamMaxToPreference()
                        mainViewModel.saveLampCountToPreference()
                        mainViewModel.saveSprayDcdListToPreference()
                        mainViewModel.savePresetListToPreference()
                        mainViewModel.saveLifeTimeToPreference()
                        mainViewModel.saveTemeratureWriteToPreference()
                        mainViewModel.saveEnergyMeasuredWriteToPreference()
                        mainViewModel.saveEnergyRefer2ToPreference()
                        mainViewModel.saveProductSerialListToPreference()
                        mainViewModel.savePowerSupplySerialListToPreference()
                        mainViewModel.saveLaserHandSerialListToPreference()
                    }

                    showExportConfirmPopup = false
                }
            )
        }

        else if (showSetConfirmPopup) {
            SetConfirmPopup(
                onClick = { ok ->
                    if (ok) {
                        Timber.d("onClick - SetConfirmPopup $ok")
                        // 1. qSwitch send
                        mainViewModel.txPacket(
                            READ_WRITE.WRITE,
                            CMD.Q_SWITCH,
                            qSwitch
                        )

                        // 2. Oven (ktp write) send
                        mainViewModel.txPacket(
                            READ_WRITE.WRITE,
                            CMD.OVEN,
                            Oven(
                                type = 0x41,
                                ktp = temperatureWrite.ktp
                            )
                        )
                    }
                    showSetConfirmPopup = false
                }
            )
        }

        else if (showLogPopup) {
            LogPopup(
                //serialLogs = serialLogs,
                serialLogList = mainViewModel.serialLogList,
                onClick = {
                    showLogPopup = false
                }
            )
        }

        else if (showEmStandByPopup) {
            EMStandByPopup(
                title = stringResource(R.string.stand_by_title),
                description = stringResource(R.string.stand_by_message),
                laserStatus = engineerViewModel.laserStatus,
                laserCount = laserCount,
                onClick = {
                    laserStatus.laserStatus = 0x53  // standBy
                    Timber.d("onEmStandByClick: ${laserStatus}")

                    mainViewModel.txPacket(READ_WRITE.WRITE, CMD.LASER_STATUS, laserStatus)

                    Toast.makeText(
                        context,
                        "[TX][onTime(ms): %f, frequence(Hz): %f) -> V(V): %d)]".format(
                            laserStatus.onTime, laserStatus.frequence, laserStatus.voltage
                        ),
                        Toast.LENGTH_LONG
                    ).show()

                    showEmStandByPopup = false
                }
            )
        }

        else if (showRefer1Popup) {
            Timber.d("energyMeasured.measured: ${energyMeasured.measured}")

            // send hand piece mount
            mainViewModel.txPacket(
                READ_WRITE.READ,
                CMD.ENERGY_DETECT,
                EnergyHandpiece(type = 0x02, status = 0x41)
            )

            Refer1Popup(
                hpType = handPiece.type,
                measured = energyMeasured.measured,
                measuredWrite = energyMeasuredWrite.measured,
                onClickRead = {
                    // start detecting
                    //
                    // send start (energy control)
                    // ready: send start

                    if (handPiece.type == 0)  {
                        Toast.makeText(
                            context,
                            "Handpiece is not recognized",
                            Toast.LENGTH_SHORT
                        ).show()
                    } else if (energyHandpiece.status == 0x47) {
                        val voltage = mainViewModel.getVoltage(10f, 10f)
                        Timber.d("onClickRead voltage: $voltage")

                        mainViewModel.txPacket(
                            READ_WRITE.WRITE,
                            CMD.ENERGY_DETECT,
                            EnergyControl(
                                type = 0x03,
                                status = 0x41,  // 'A': Start
                                voltage = voltage
                            )
                        )
                    } else {
                        Toast.makeText(
                            context,
                            "Handpiece mount error. Try later",
                            Toast.LENGTH_LONG
                        ).show()
                    }
                },
                onClickCancel = {
                    showRefer1Popup = false
                },
                onClickSet = { v ->
                    // write measured value
                    mainViewModel.setEnergyMeasuredWrite(
                        EnergyMeasured(
                            measured = v
                        )
                    )

                    scope.launch {
                        mainViewModel.saveEnergyMeasuredWriteToPreference()
                    }

                    /*
                    Toast.makeText(
                        context,
                        "Set Measured Write",
                        Toast.LENGTH_SHORT
                    ).show()
                    */
                }
            )
        }

        else if (showRefer2Popup) {
            Refer2Popup(
                refer2 = energyDetectRefer2,
                maxValue = MAX_REFER2_VALUE, // 100% (=1)
                onClick = { ok, refer2 ->
                    if (ok) {
                        mainViewModel.setEnergyDetectRefer2(
                            refer2
                        )

                        scope.launch {
                            mainViewModel.saveEnergyRefer2ToPreference()
                        }

                        /*
                        Toast.makeText(
                            context,
                            "Refer2(good: ${refer2.good}, acceptable: ${refer2.acceptable}, bad: ${refer2.bad}) Set",
                            Toast.LENGTH_SHORT
                        ).show()
                        */
                    } else {
                        showRefer2Popup = false
                    }
                }
            )
        }
    }
}

private fun increaseVoltageWithCascade(
    voltageTable: MutableMap<Pair<Float, Float>, MutableStateFlow<Int>>,
    pulseWidth: Float,
    selectedVoltageIndex: Int,
    increament: Int = 1
) {
    //1. Get the current key and voltage
    val currentEnergy = Energies[selectedVoltageIndex]
    val currentKey = Pair(pulseWidth, currentEnergy)
    val currentVoltage = voltageTable[currentKey]?.value ?: 0

    // Ensure we don't try to increase past the system limit
    if (currentVoltage >= 990) {
        Timber.d("[EM] Cannot increase voltage for $currentKey, already at or above max (990).")
        return
    }

    // 2. Safely get the voltage of the next energy level
    val nextVoltage = if (selectedVoltageIndex < Energies.size - 1) {
        val nextEnergy = Energies[selectedVoltageIndex + 1]
        val nextKey = Pair(pulseWidth, nextEnergy)
        voltageTable[nextKey]?.value ?: 0
    } else {
        // If we are already at the last item, there is no "next" voltage to worry about.
        // We can use a value higher than any possible voltage to allow the increase.
        1000 // Effectively infinity
    }

    // 3. Simple Case: If we can increase the current voltage without equalling or exceeding the next one.
    if (currentVoltage + increament < nextVoltage) {
        Timber.d("[EM] Simple increase for $currentKey")
        voltageTable.increaseVoltageTableValue(currentKey, increament)
        return // We are done
    }

    // last key pair
    val lastSelectedCalibVoltageIndex = Energies[Energies.size -1]
    val lastKey = Pair(pulseWidth, lastSelectedCalibVoltageIndex)
    val lastVoltage = voltageTable[lastKey]?.value ?: 0

    if (lastVoltage + increament > 990) {
        Timber.d("[EM] Cannot increase voltage for $lastKey, already at or above max (990).")
        return
    }

    // 4. Cascade Case: If increasing the voltage would conflict.
    // We must increase the voltage for the current level and all subsequent levels by 1.
    Timber.d("[EM] Cascade increase starting from index $selectedVoltageIndex")

    for (i in selectedVoltageIndex until Energies.size) {
        val energyForIndex = Energies[i]
        val keyToUpdate = Pair(pulseWidth, energyForIndex)
        val voltageToUpdate = voltageTable[keyToUpdate]?.value ?: 0

        // Ensure we don't increase any value in the cascade beyond the max limit
        if (voltageToUpdate < 990) {
            voltageTable.increaseVoltageTableValue(keyToUpdate, increament)
        } else {
            // If any value in the chain is already at max, we can't push it further.
            // We should stop the entire operation to maintain the ascending order integrity.
            Timber.w("[EM] Cascade stopped at $keyToUpdate, value is already at max voltage (990).")
            // It might be better to revert the changes or show a toast here, but for now, we just stop.
            break
        }
    }
}

private fun decreaseVoltageWithCascade(
    voltageTable: MutableMap<Pair<Float, Float>, MutableStateFlow<Int>>,
    pulseWidth: Float,
    selectedVoltageIndex: Int,
    decreament: Int = 1
) {
    // 1. Get the current key and voltage
    val currentEnergy = Energies[selectedVoltageIndex]
    val currentKey = Pair(pulseWidth, currentEnergy)
    val currentVoltage = voltageTable[currentKey]?.value ?: 0

    // Ensure we don't decrease below a minimum (e.g., 0)
    if (currentVoltage <= 0) {
        Timber.d("[EM] Cannot decrease voltage for $currentKey, already at or below 0.")
        return
    }

    // 2. Safely get the voltage of the PREVIOUS energy level
    val previousVoltage = if (selectedVoltageIndex > 0) {
        val previousEnergy = Energies[selectedVoltageIndex - 1]
        val previousKey = Pair(pulseWidth, previousEnergy)
        voltageTable[previousKey]?.value ?: 0
    } else {
        // If we are already at the first item, there is no "previous" voltage to worry about.
        // We can use a value lower than any possible voltage to allow the decrease.
        -1 // Effectively negative infinity
    }

    // 3. Simple Case: If we can decrease the current voltage without it becoming equal to or less than the previous one.
    if (currentVoltage - decreament > previousVoltage) {
        Timber.d("[EM] Simple decrease for $currentKey")
        voltageTable.decreaseVoltageTableValue(currentKey, decreament)
        return // We are done
    }

    // first key pair
    val firstSelectedCalibVoltageIndex = Energies[0]
    val firstKey = Pair(pulseWidth, firstSelectedCalibVoltageIndex)
    val firstVoltage = voltageTable[firstKey]?.value ?: 0

    if (firstVoltage - decreament < 0) {
        Timber.d("[EM] Cannot decrease voltage for $firstVoltage, already at or below min (0).")
        return
    }

    // 4. Cascade Case: If decreasing the voltage would conflict with the previous one.
    // We must decrease the voltage for the current level and all PREVIOUS levels by 1.
    Timber.d("[EM] Cascade decrease starting from index $selectedVoltageIndex down to 0")
    for (i in selectedVoltageIndex downTo 0) {
        val energyForIndex = Energies[i]
        val keyToUpdate = Pair(pulseWidth, energyForIndex)
        val voltageToUpdate = voltageTable[keyToUpdate]?.value ?: 0

        // Ensure we don't decrease any value below the minimum limit
        if (voltageToUpdate > 0) {
            voltageTable.decreaseVoltageTableValue(keyToUpdate, decreament)
        } else {
            // If any value in the chain is already at min, we can't pull it further.
            // Stop the operation to maintain integrity.
            Timber.w("[EM] Cascade stopped at $keyToUpdate, value is already at min voltage (0).")
            break
        }
    }
}

@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 PreviewEngineerView(
    mainViewModel:MainViewModel = MainViewModel(
        preferenceRepository = PreferenceRepository(LocalContext.current),
        serialPortRepository = SerialPortRepository.createWithFakeRepository(),
        databaseRepository = DatabaseRepository(RamanDatabaseService(RamanDatabase.getInstance(LocalContext.current))),
        dispatcherProvider = DefaultDispatcherProvider(),
        applicationContext = LocalContext.current
    ),

    engineerViewModel:EngineerViewModel = EngineerViewModel(
        preferenceRepository = PreferenceRepository(LocalContext.current),
        serialPortRepository = SerialPortRepository.createWithFakeRepository(),
        databaseRepository = DatabaseRepository(RamanDatabaseService(RamanDatabase.getInstance(LocalContext.current))),
        dispatcherProvider = DefaultDispatcherProvider(),
        applicationContext = LocalContext.current
)
) {
    EngineerScreen(
        paddingValues = PaddingValues(top = 50.px.dp),
        mainViewModel = mainViewModel,
        engineerViewModel = engineerViewModel
    )
}