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

import android.annotation.SuppressLint
import android.content.res.Configuration
import android.widget.Toast
import androidx.compose.foundation.background
import androidx.compose.foundation.interaction.MutableInteractionSource
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.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.material3.ExperimentalMaterial3Api
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.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
import com.laseroptek.raman.const.LaserParameter
import com.laseroptek.raman.const.LaserStatusType
import com.laseroptek.raman.const.MAX_LASER_COUNT
import com.laseroptek.raman.const.PresetButtonType
import com.laseroptek.raman.data.datasource.db.RamanDatabase
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.screens.home.count.HpCountView
import com.laseroptek.raman.ui.screens.home.count.HpView
import com.laseroptek.raman.ui.screens.home.count.LaserCountView
import com.laseroptek.raman.ui.screens.home.dcd.DcdView
import com.laseroptek.raman.ui.screens.home.preset.PresetButton
import com.laseroptek.raman.ui.screens.home.preset.PresetIconButton
import com.laseroptek.raman.ui.screens.home.slider.LaserControlView
import com.laseroptek.raman.ui.screens.home.standby.StandByButton
import com.laseroptek.raman.ui.screens.main.MainViewModel
import com.laseroptek.raman.utils.DefaultDispatcherProvider
import com.laseroptek.raman.utils.ext.px
import timber.log.Timber

@SuppressLint("NewApi")
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun HomeScreen(
    paddingValues: PaddingValues = PaddingValues(),
    mainViewModel: MainViewModel = hiltViewModel<MainViewModel>(),
) {
    val scope = rememberCoroutineScope()

    val focusManager = LocalFocusManager.current
    val context = LocalContext.current

    val pulseAngle by mainViewModel.pulseAngle.collectAsState()
    val fluenceAngle by mainViewModel.fluenceAngle.collectAsState()
    val repetitionAngle by mainViewModel.repetitionAngle.collectAsState()

    val fluenceList by mainViewModel.fluenceList.collectAsState()
    val pulseType by mainViewModel.pulseType.collectAsState()
    val repetitionList by mainViewModel.repetitionList.collectAsState()

    // Used to disable the ripple effect on the background click
    val interactionSource = remember { MutableInteractionSource() }
    val laserStatus by mainViewModel.laserStatus.collectAsState()
    val handPiece by mainViewModel.handPiece.collectAsState()

    val laserCount by mainViewModel.laserCount.collectAsState()
    val lampCount by mainViewModel.lampCount.collectAsState()
    val hpCount by mainViewModel.hpCount.collectAsState()
    val lifeTime by mainViewModel.lifeTime.collectAsState()

    val hpCountForMainScreen by remember(hpCount, lifeTime, handPiece) {
        mutableStateOf(mainViewModel.getHPCountForMainScreen())
    }

    val presetList by mainViewModel.presetList.collectAsState()

    LaunchedEffect(Unit) {
        Timber.d("LaunchedEffect - HomeScreen")
        focusManager.clearFocus(force = true) // Hide the keyboard

        Timber.d("Attempted to hide keyboard on EngineerScreen launch")
    }

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

    Box(
        modifier = Modifier
            .fillMaxSize()
            .background(Color.Transparent)
    ) {
        ///////////////////////////////////////////////////////////////////////////////////////////
        // Home Screen Main

        Column(
            modifier = Modifier
                .fillMaxSize()
                .background(color = Color.Transparent)
                /* .clickable(
                    interactionSource = interactionSource,
                    indication = null // Disable ripple effect
                )
                */
                /*
                .detectBackgroundTap {
                    Timber.d("HomeScreen background clicked")
                    if (laserStatus.laserStatus != 0 && laserStatus.laserStatus != 0x53) {
                        focusManager.clearFocus()

                        scope.launch {
                            mainViewModel.playBeepSound()
                        }

                        mainViewModel.txPacket(
                            READ_WRITE.WRITE,
                            CMD.LASER_STATUS,
                            byteArrayOf(LASER_STATUS.STAND_BY.toByte())
                        )
                    }

                }
                */
                .padding(paddingValues)
                .padding(
                    start = 30.px.dp,
                    end = 30.px.dp,
                    top = 30.px.dp,
                    bottom = 30.px.dp
                ),
            verticalArrangement = Arrangement.Top,
            horizontalAlignment = Alignment.CenterHorizontally,
        ) {
            // top
            Row(
                modifier = Modifier
                    .fillMaxWidth() // Make the Row take up the full width
                    .height(50.px.dp)
                    .background(Color.Transparent),
                horizontalArrangement = Arrangement.Center, // Push content to the right
                verticalAlignment = Alignment.Top
            ) {
                HpView(
                    handPiece = handPiece,
                    onClick = {}
                )

                Spacer(Modifier.weight(1f))

                HpCountView(
                    hpCountForMainScreen,
                    onClick = {}
                )

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

                LaserCountView(
                    mainViewModel = mainViewModel,
                    onClick = {
                        /*
                        if (handPiece.type == 0) {
                            Toast.makeText(
                                context,
                                "Handpiece is not recognized",
                                Toast.LENGTH_SHORT
                            ).show()
                            return@LaserCountView
                        }
                        */

                        mainViewModel.showResetLaserCountPopup = true
                    }
                )
            }

            // middle
            Row(
                modifier = Modifier
                    .fillMaxWidth()
                    .height(420.px.dp)
                    .background(Color.Transparent)
                    .padding(start = 100.px.dp)
                , verticalAlignment = Alignment.Bottom
                , horizontalArrangement = Arrangement.Center
            ) {
                // 1. PULSE DURATION
                LaserControlView(
                    modifier = Modifier
                        .align(Alignment.Bottom)
                        .size(330.px.dp, 380.px.dp),
                    //mainViewModel = mainViewModel,
                    fluenceList = fluenceList,
                    repetitionList = repetitionList,
                    pulseType = pulseType,
                    handPieceType = handPiece.type,
                    type = LaserStatusType.PULSE_DURATION,
                    angle = pulseAngle,
                    onChange = { angle ->
                        if (handPiece.type == 0) {
                            Toast.makeText(
                                context,
                                "Handpiece is not recognized",
                                Toast.LENGTH_SHORT
                            ).show()
                            return@LaserControlView
                        }

                        Timber.d("A: onChangePulseDuration - 터치 드래그로 값 변경 / 하단 ▲▼ 로 값 변경 : ${angle}")
                        mainViewModel.onChangePulseDuration(angle)
                    },
                    onClick = { state ->
                        if (handPiece.type == 0) {
                            Toast.makeText(
                                context,
                                "Handpiece is not recognized",
                                Toast.LENGTH_SHORT
                            ).show()
                            return@LaserControlView
                        }

                        //mainViewModel.onClickPulseDuration(state)
                        mainViewModel.onUpDownButtonClicked(LaserParameter.PulseWidth, state)
                    }
                )

                Spacer(Modifier.weight(1f))

                // 2. FLUENCE
                LaserControlView(
                    modifier = Modifier
                        .size(370.px.dp, 420.px.dp),
                    //mainViewModel = mainViewModel,
                    fluenceList = fluenceList,
                    repetitionList = repetitionList,
                    pulseType = pulseType,
                    handPieceType = handPiece.type,
                    type = LaserStatusType.FLUENCE,
                    angle = fluenceAngle,
                    onChange = { angle ->
                        if (handPiece.type == 0) {
                            Toast.makeText(
                                context,
                                "Handpiece is not recognized",
                                Toast.LENGTH_SHORT
                            ).show()
                            return@LaserControlView
                        }

                        mainViewModel.onChangeFluence(angle)
                    },
                    onClick = { state ->
                        if (handPiece.type == 0) {
                            Toast.makeText(
                                context,
                                "Handpiece is not recognized",
                                Toast.LENGTH_SHORT
                            ).show()
                            return@LaserControlView
                        }

                        //mainViewModel.onClickFluence(state)
                        mainViewModel.onUpDownButtonClicked(LaserParameter.Fluence, state)
                    }
                )

                Spacer(Modifier.weight(1f))

                // 3. REPETITION - SKIN TEMP
                LaserControlView(
                    modifier = Modifier
                        .size(330.px.dp, 380.px.dp),
                    fluenceList = fluenceList,
                    repetitionList = repetitionList,
                    pulseType = pulseType,
                    handPieceType = handPiece.type,
                    type = LaserStatusType.REPETITION,
                    angle = if (pulseType == 0 || repetitionList.size < 2) 0f else repetitionAngle,
                    onChange = { angle ->
                        if (handPiece.type == 0) {
                            Toast.makeText(
                                context,
                                "Handpiece is not recognized",
                                Toast.LENGTH_SHORT
                            ).show()
                            return@LaserControlView
                        }

                        if (pulseType == 0 || repetitionList.size < 2) {
                            //Toast.makeText(context, "Single pulse type (0 Hz)", Toast.LENGTH_SHORT).show()
                        } else {
                            mainViewModel.onChangeRepetition(angle)
                        }

                    },
                    onClick = { state ->
                        if (handPiece.type == 0) {
                            Toast.makeText(
                                context,
                                "Handpiece is not recognized",
                                Toast.LENGTH_SHORT
                            ).show()
                            return@LaserControlView
                        }

                        if (pulseType == 0 || repetitionList.size < 2) {
                            //Toast.makeText(context, "Single pulse type (0 Hz)", Toast.LENGTH_SHORT).show()
                        } else {
                            //mainViewModel.onClickRepetition(state)
                            mainViewModel.onUpDownButtonClicked(LaserParameter.Repetition, state)
                        }
                    }
                )
            }

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

            // bottom
            Row(
                modifier = Modifier
                    .height(100.px.dp)
                    .fillMaxWidth()
                    .background(color = Color.Transparent),
                verticalAlignment = Alignment.CenterVertically,
                horizontalArrangement = Arrangement.Center
            ) {
                // DCD Cooler
                DcdView(
                    mainViewModel = mainViewModel,
                    onClick = {
                        if (handPiece.type == 0) {
                            Toast.makeText(
                                context,
                                "Handpiece is not recognized",
                                Toast.LENGTH_SHORT
                            ).show()
                            return@DcdView
                        }

                        mainViewModel.showDcdSettingPopup = true
                    }
                )

                Spacer(Modifier.weight(1f))

                // Preset Load
                PresetIconButton(
                    modifier = Modifier.size(50.px.dp),
                    type = PresetButtonType.LOAD,
                    selected = mainViewModel.showPresetLoadPopup,
                    onClick = {
                        if (handPiece.type == 0) {
                            Toast.makeText(
                                context,
                                "Handpiece is not recognized",
                                Toast.LENGTH_SHORT
                            ).show()
                            return@PresetIconButton
                        }

                        // reset selected preset index
                        //mainViewModel.setSelectedPresetIndex(0)

                        Timber.d("onClick - Preset Load")
                        mainViewModel.showPresetLoadPopup = true
                    }
                )

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

                // Preset Buttons
                for (i in 1..5) {
                    val selectedPresetIndex by mainViewModel.selectedPresetIndex.collectAsState()
                    PresetButton(
                        modifier = Modifier.size(50.px.dp),
                        fontSize = 28,
                        no = i,
                        selected = selectedPresetIndex,
                        //enabled = presetList.filter{ it.priority == i }.size > 0,
                        onLongClick = { no ->
                            Timber.d("onClick - Preset Button ${no}")
                            if (handPiece.type == 0) {
                                Toast.makeText(
                                    context,
                                    "Handpiece is not recognized",
                                    Toast.LENGTH_SHORT
                                ).show()
                                return@PresetButton
                            }

                            val preset = presetList.firstOrNull { it.handPieceType == handPiece.type && it.priority == no }
                            if (preset == null || preset.priority < 1) {
                                Toast.makeText(
                                    context,
                                    "This number is not defined",
                                    Toast.LENGTH_SHORT
                                ).show()
                                return@PresetButton
                            }

                            mainViewModel.setSelectedPresetIndex( no )
                            mainViewModel.applyPreset(no)
                        }
                    )
                    Spacer(Modifier.width(25.px.dp))
                }

                // Preset Save
                PresetIconButton(
                    modifier = Modifier.size(50.px.dp),
                    type = PresetButtonType.SAVE,
                    selected = mainViewModel.showPresetSavePopup,
                    onClick = {
                        Timber.d("onClick - showPresetSavePopup")
                        if (handPiece.type == 0) {
                            Toast.makeText(
                                context,
                                "Handpiece is not recognized",
                                Toast.LENGTH_SHORT
                            ).show()
                            return@PresetIconButton
                        }

                        // reset selected preset index
                        // mainViewModel.setSelectedPresetIndex(0)

                        mainViewModel.showPresetSavePopup = true
                    }
                )

                Spacer(Modifier.weight(1f))

                // StandBy (Button)
                StandByButton(
                    laserStatus = laserStatus.laserStatus,
                    onClick = {
                        Timber.d("WRITE request > LASER_STATUS (Ready: 0x52) Request")
                        if (handPiece.type == 0) {
                            Toast.makeText(
                                context,
                                "Handpiece is not recognized",
                                Toast.LENGTH_SHORT
                            ).show()
                            return@StandByButton
                        }

                        if (laserCount >= MAX_LASER_COUNT) {
                            Toast.makeText(
                                context,
                                "Max Laser Count reached",
                                Toast.LENGTH_SHORT
                            ).show()
                            return@StandByButton
                        }

                        if (lampCount >= MAX_LASER_COUNT) {
                            Toast.makeText(
                                context,
                                "Max Lamp Count reached",
                                Toast.LENGTH_SHORT
                            ).show()
                            return@StandByButton
                        }

                        val hpCount = mainViewModel.getHPCount()
                        if (hpCount < 1) {
                            Toast.makeText(
                                context,
                                "Max H/P Count reached",
                                Toast.LENGTH_SHORT
                            ).show()
                            return@StandByButton
                        }

                        mainViewModel.txLaserStatusEntry(0x52) // send ready

                        // StandBy Popup
                        mainViewModel.showStandByPopup = true
                    }
                )

                Spacer(Modifier.width(10.px.dp))
            }
        }

        ///////////////////////////////////////////////////////////////////////////////////////////
        // Popups --> move to MainView

    }
}

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