package theorycrafter.ui.settings

import androidx.compose.foundation.layout.*
import androidx.compose.material.Text
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.LastBaseline
import androidx.compose.ui.unit.dp
import compose.input.KeyShortcut
import compose.input.onKeyShortcut
import compose.utils.VerticallyCenteredRow
import compose.widgets.DropdownField
import compose.widgets.rememberAppendSuffixTransformation
import eve.data.NNBSP
import eve.data.toDecimalWithPrecisionAtMost
import theorycrafter.ColorThemeStyle
import theorycrafter.TheorycrafterContext
import theorycrafter.ui.OutlinedTextField
import theorycrafter.ui.RaisedButtonWithText
import theorycrafter.ui.TheorycrafterTheme
import theorycrafter.ui.widgets.DiscreteRangeSpinnerModel
import theorycrafter.ui.widgets.Spinner
import kotlin.math.roundToInt


/**
 * The settings pane for configuring Theorycrafter's appearance.
 */
@Composable
fun AppearanceSettingsPane() {
    Column(
        horizontalAlignment = Alignment.Start,
        verticalArrangement = Arrangement.spacedBy(TheorycrafterTheme.spacing.xlarge),
        modifier = Modifier.padding(TheorycrafterTheme.spacing.edgeMargins)
    ) {
        ColorThemeStyleSelector()
        UiScaleSelector()
    }

}


/**
 * A widget for selecting
 */
@Composable
private fun ColorThemeStyleSelector() {
    Column(
        verticalArrangement = Arrangement.spacedBy(TheorycrafterTheme.spacing.xsmall)
    ) {
        Text("Color Theme", style = TheorycrafterTheme.textStyles.caption)
        DropdownField(
            items = ColorThemeStyles,
            selectedItem = TheorycrafterContext.settings.colorThemeStyle,
            itemToString = {
                when (it) {
                    ColorThemeStyle.System -> "System Style"
                    ColorThemeStyle.Light -> "Light"
                    ColorThemeStyle.Dark -> "Dark"
                }
            },
            modifier = Modifier.width(200.dp),
            onItemSelected = { _, style ->
                TheorycrafterContext.settings.colorThemeStyle = style
            }
        )
    }
}


/**
 * The choices of the color theme style.
 */
private val ColorThemeStyles = listOf(
    ColorThemeStyle.System,
    ColorThemeStyle.Light,
    ColorThemeStyle.Dark
)


/**
 * Widget for selecting the UI scale.
 */
@Composable
private fun UiScaleSelector() {
    Column(
        verticalArrangement = Arrangement.spacedBy(TheorycrafterTheme.spacing.xsmall)
    ) {

        VerticallyCenteredRow(
            horizontalArrangement = Arrangement.spacedBy(TheorycrafterTheme.spacing.medium),
        ) {

            var scaleFactorText by remember {
                mutableStateOf(TheorycrafterContext.settings.uiScaleFactorPct.toDisplayedScaleFactor())
            }

            fun isScaleFactorTextValid(): Boolean {
                val scale = scaleFactorText.toFloatOrNull() ?: return false
                return scale in 0.5f .. 3f
            }

            fun applyScaleFactor() {
                if (!isScaleFactorTextValid())
                    return
                val scaleFactor = scaleFactorText.toFloat()
                val scaleFactorPct = (scaleFactor * 100).roundToInt()
                TheorycrafterContext.settings.uiScaleFactorPct = scaleFactorPct
            }

            val model = remember {
                DiscreteRangeSpinnerModel(
                    range = 50 .. 300,
                    step = 10,
                    add = Int::plus,
                    subtract = Int::minus,
                    parseValue = { toFloatOrNull()?.let { (it * 100).roundToInt() } },
                    displayValue = Int::toDisplayedScaleFactor
                )
            }

            Spinner(
                value = scaleFactorText,
                onValueChange = { scaleFactorText = it },
                textFieldProvider = {  value, onValueChange, arrows ->
                    TheorycrafterTheme.OutlinedTextField(
                        value = value,
                        onValueChange = onValueChange,
                        label = { Text("UI Scale") },
                        trailingIcon = {
                            Box(modifier = Modifier
                                .padding(end = TheorycrafterTheme.spacing.medium),
                                propagateMinConstraints = true
                            ) {
                                arrows()
                            }
                        } ,
                        visualTransformation = rememberAppendSuffixTransformation { "${NNBSP}x" },
                        singleLine = true,
                        isError = !isScaleFactorTextValid(),
                        modifier = Modifier
                            .width(120.dp)
                            .alignBy(LastBaseline)  // The label is FirstBaseline
                            .onKeyShortcut(KeyShortcut.anyEnter(), onPreview = true) {
                                applyScaleFactor()
                            },
                    )
                },
                model = model
            )

            TheorycrafterTheme.RaisedButtonWithText(
                text = "Apply",
                modifier = Modifier.alignBy(LastBaseline),
                enabled = isScaleFactorTextValid(),
                onClick = ::applyScaleFactor
            )
        }
        Text(
            text = "The UI will be scaled by this factor.\nValid values are between 0.5x and 3x.",
            style = TheorycrafterTheme.textStyles.detailedText()
        )
    }
}


/**
 * Returns the text to display for the given scale factor percentage.
 */
private fun Int.toDisplayedScaleFactor(): String = (this / 100.0).toDecimalWithPrecisionAtMost(2)
