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

import android.content.res.Configuration
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.compose.ui.zIndex
import com.laseroptek.raman.R
import com.laseroptek.raman.const.Fluences
import com.laseroptek.raman.const.LaserStatusType
import com.laseroptek.raman.const.PulseDurations
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.main.MainViewModel
import com.laseroptek.raman.ui.theme.RobotoTypography
import com.laseroptek.raman.utils.DefaultDispatcherProvider
import com.laseroptek.raman.utils.ext.degreeToStep
import com.laseroptek.raman.utils.ext.px
import timber.log.Timber


@Composable
fun SliderBox(
    modifier: Modifier = Modifier,
    fluenceList: List<Float> = Fluences,
    repetitionList: List<Float> = listOf(1f),
    pulseType: Int = 1,
    type : LaserStatusType = LaserStatusType.PULSE_DURATION,
    handPieceType: Int = 0,
    angle: Float = 0f,
    padding : Float = 10f,
    stroke : Float = 30f,
    touchStroke : Float = 60f,
    onChange: ((Float) -> Unit)? = null,
) {
    Timber.d("type: ${type}")
    Timber.d("fluenceList: ${fluenceList}")
    Timber.d("repetitionList: ${repetitionList}")

    // Center Text & Below
    //
    val txtValue = when(type) {
        LaserStatusType.PULSE_DURATION -> {
            val pulseDuration = PulseDurations[angle.degreeToStep(totalSteps = PulseDurations.size)]
            Timber.d("PULSE_DURATION -> angle: ${angle}")
            if (pulseDuration - pulseDuration.toInt() == 0f) {
                "%d".format(pulseDuration.toInt())
            } else {
                "%.1f".format(pulseDuration)
            }

        }
        LaserStatusType.FLUENCE -> {
            val fluence = fluenceList[angle.degreeToStep(totalSteps = fluenceList.size)]
            Timber.d("FLUENCE -> angle: ${angle}")
            if (fluence - fluence.toInt() == 0f) {
                "%d".format(fluence.toInt())
            } else {
                "%.1f".format(fluence)
            }
        }
        LaserStatusType.REPETITION -> {
            if (repetitionList.size < 1) {
                return
            }

            val repetion = if (pulseType == 0) {
                // Single
                0.0f
            } else if (repetitionList.size == 1) {
                repetitionList[0]
            } else {
                // Repeate
                repetitionList[angle.degreeToStep(totalSteps = repetitionList.size)]
            }

            Timber.d("REPETITION -> angle: ${angle}")
            if (repetion - repetion.toInt() == 0f) {
                "%d".format(repetion.toInt())
            } else {
                "%.1f".format(repetion)
            }
        }
        else -> { "" }
    }
    val txtUnit = when(type) {
        LaserStatusType.PULSE_DURATION -> {
            "ms"
        }
        LaserStatusType.FLUENCE -> {
            "J/cm²"
        }
        LaserStatusType.REPETITION -> {
            "Hz"
        }
        else -> { "" }
    }
    val txtTitle = when(type) {
        LaserStatusType.PULSE_DURATION -> {
            "Pulse Duration"
        }
        LaserStatusType.FLUENCE -> {
            "Fluence"
        }
        LaserStatusType.REPETITION -> {
            "Repetition"
        }
        else -> { "" }
    }

    Box(
        modifier = modifier
            .fillMaxSize()
            .background(Color.Transparent),
        contentAlignment = Alignment.TopCenter,
    ) {
        val controlImageId = when (type) {
            LaserStatusType.FLUENCE -> { R.drawable.ic_control_fluence }
            LaserStatusType.REPETITION -> { R.drawable.ic_control_repetition }
            else -> { R.drawable.ic_control_duration }
        }

        // Image 1
        Image(
            painter = painterResource(id = controlImageId),
            contentDescription = "Background Image - Indicator",
            modifier = Modifier
                .fillMaxSize()
                .padding(
                    top = (padding + 5 + stroke).toDouble().px.dp,
                    start = (padding + stroke).toDouble().px.dp,
                    end = (padding + stroke).toDouble().px.dp,
                    bottom = (padding - 5 + stroke).toDouble().px.dp
                )
                .zIndex(-1f),
            contentScale = ContentScale.Crop
        )

        // Slider
        CircularSlider(
            modifier = Modifier
                .fillMaxSize()
                .padding(
                    (padding).toDouble().px.dp
                )
                .zIndex(1f),
            angleNew = angle,
            padding = (padding),
            stroke = stroke,
            touchStroke = touchStroke,
            onChange = {
                Timber.d("onChange: Original VAL : ${it}")
                onChange?.invoke(it)
            }
        )

        // Value
        Box(
            Modifier
                .size(110.px.dp)
                .align(Alignment.Center)
                .padding(
                    top = if (type == LaserStatusType.FLUENCE) 5.px.dp else 12.px.dp,
                    bottom = if (type == LaserStatusType.FLUENCE) 13.px.dp else 15.px.dp
                )
                .zIndex(2f)
        ) {
            if (handPieceType == 0) {
                Text(
                    text = "-",
                    textAlign = TextAlign.Center,
                    modifier = Modifier
                        .fillMaxWidth()
                        .align(Alignment.Center),
                    style = RobotoTypography.bodySmall.copy(
                        color = Color.White,
                        letterSpacing = 1.px.sp,
                        fontSize = 58.px.sp,
                        fontWeight = FontWeight.Thin
                    )
                )
            } else if (pulseType == 0 && type == LaserStatusType.REPETITION) {
                Text(
                    text = "SIG",
                    textAlign = TextAlign.Center,
                    modifier = Modifier
                        .fillMaxWidth()
                        .align(Alignment.Center),
                    style = RobotoTypography.bodySmall.copy(
                        color = Color.White,
                        letterSpacing = 1.px.sp,
                        fontSize = 58.px.sp,
                        fontWeight = FontWeight.Thin
                    )
                )
            } else {
                Text(
                    text = txtValue,
                    textAlign = TextAlign.Center,
                    modifier = Modifier
                        .fillMaxWidth()
                        .align(Alignment.TopCenter),
                    style = RobotoTypography.bodySmall.copy(
                        color = Color.White,
                        letterSpacing = if (txtValue.length > 2) -5.px.sp else 2.px.sp,
                        fontSize = if (type == LaserStatusType.FLUENCE) 64.px.sp else 58.px.sp,
                        fontWeight = FontWeight.Thin
                    )
                )
                Text(
                    text = txtUnit,
                    textAlign = TextAlign.Center,
                    modifier = Modifier
                        .fillMaxWidth()
                        .align(Alignment.BottomCenter),
                    style = RobotoTypography.bodySmall.copy(
                        fontSize = 16.px.sp,
                        color = Color.White,
                        fontWeight = FontWeight.Thin
                    )
                )
            }
        }

        // Title
        Column(
            Modifier
                .size(200.px.dp, 40.px.dp)
                .align(Alignment.BottomCenter)
                .zIndex(3f)
        ) {
            Text(
                text = txtTitle,
                textAlign = TextAlign.Center,
                modifier = Modifier.fillMaxWidth(),
                style = RobotoTypography.bodyMedium.copy(
                    color = Color.Black,
                    fontWeight = FontWeight.Thin,
                    fontSize = 20.px.sp,
                    lineHeight = 24.px.sp
                )
            )
            Spacer(modifier = Modifier.weight(1f))
        }
    }
}


@Preview(
    apiLevel = 34,
    uiMode = Configuration.UI_MODE_NIGHT_NO,
    showBackground = false,
    device = "spec:width=460dp,height=460dp,dpi=150,isRound=false,chinSize=0dp,orientation=landscape"
)
@Composable
fun PreviewSliderBox(
    mainViewModel:MainViewModel = MainViewModel(
        preferenceRepository = PreferenceRepository(LocalContext.current),
        serialPortRepository = SerialPortRepository.createWithFakeRepository(),
        databaseRepository = DatabaseRepository(RamanDatabaseService(RamanDatabase.getInstance(LocalContext.current))),
        dispatcherProvider = DefaultDispatcherProvider(),
        applicationContext = LocalContext.current
    )
) {
    SliderBox(
        //mainViewModel = mainViewModel
        //type = LaserStatusType.FLUENCE,
        type = LaserStatusType.REPETITION,
        pulseType = 0,
    )
}