package app.voltplan.cable.ui.chargers

import androidx.compose.foundation.clickable
import androidx.compose.foundation.horizontalScroll
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.outlined.ArrowBack
import androidx.compose.material.icons.outlined.ArrowDropDown
import androidx.compose.material3.DropdownMenu
import androidx.compose.material3.DropdownMenuItem
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.material3.TopAppBar
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.lifecycle.viewmodel.initializer
import androidx.lifecycle.viewmodel.viewModelFactory
import app.voltplan.cable.CableApplication
import app.voltplan.cable.R
import app.voltplan.cable.data.model.PowerSourceType
import app.voltplan.cable.ui.chargerIconOptions
import app.voltplan.cable.ui.components.AppearanceEditorSheet
import app.voltplan.cable.ui.components.MetricBadge
import app.voltplan.cable.ui.components.SnapSlider
import app.voltplan.cable.ui.components.ValueEditDialog
import app.voltplan.cable.ui.sfSymbol
import app.voltplan.cable.ui.theme.SysGreen
import app.voltplan.cable.ui.theme.SysIndigo
import app.voltplan.cable.ui.theme.SysOrange
import app.voltplan.cable.ui.theme.SysPink
import app.voltplan.cable.util.Fmt
import java.util.Locale

private enum class CField { INPUT, OUTPUT, CURRENT, POWER }

private val INPUT_SNAPS = listOf(12.0, 24.0, 48.0, 120.0, 230.0, 240.0)
private val OUTPUT_SNAPS = listOf(12.0, 12.6, 12.8, 14.2, 24.0, 48.0)
private val CURRENT_SNAPS = listOf(5.0, 10.0, 15.0, 20.0, 25.0, 30.0, 40.0, 50.0, 60.0, 80.0, 100.0, 150.0, 200.0)
private val POWER_SNAPS = listOf(100.0, 150.0, 200.0, 250.0, 300.0, 400.0, 500.0, 600.0, 750.0, 1000.0, 1250.0, 1500.0, 2000.0, 2500.0, 3000.0)

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun ChargerEditorScreen(systemId: String, chargerId: String?, onBack: () -> Unit) {
    val context = LocalContext.current
    val app = context.applicationContext as CableApplication
    val vm: ChargerEditorViewModel = viewModel(
        key = "charger-${chargerId ?: "new"}",
        factory = viewModelFactory { initializer { ChargerEditorViewModel(app, systemId, chargerId) } },
    )
    val s by vm.state.collectAsStateWithLifecycle()
    var editing by remember { mutableStateOf<CField?>(null) }
    var showAppearance by remember { mutableStateOf(false) }
    var sourceMenu by remember { mutableStateOf(false) }

    Scaffold(
        topBar = {
            TopAppBar(
                navigationIcon = {
                    IconButton(onClick = onBack) { Icon(Icons.AutoMirrored.Outlined.ArrowBack, contentDescription = stringResource(R.string.action_back)) }
                },
                title = { Text(s.name, fontWeight = FontWeight.SemiBold, modifier = Modifier.clickable { showAppearance = true }) },
            )
        },
    ) { padding ->
        Column(
            Modifier.padding(padding).fillMaxWidth().verticalScroll(rememberScrollState()).padding(16.dp),
            verticalArrangement = Arrangement.spacedBy(12.dp),
        ) {
            // Header chips
            Row(Modifier.horizontalScroll(rememberScrollState()), horizontalArrangement = Arrangement.spacedBy(12.dp)) {
                MetricBadge(stringResource(R.string.chargers_badge_input), String.format(Locale.US, "%.0f V", s.inputVoltage), SysIndigo)
                MetricBadge(stringResource(R.string.chargers_badge_output), String.format(Locale.US, "%.1f V", s.outputVoltage), SysGreen)
                MetricBadge(stringResource(R.string.chargers_badge_current), String.format(Locale.US, "%.1f A", s.maxCurrentAmps), SysOrange)
                MetricBadge(stringResource(R.string.chargers_badge_power), String.format(Locale.US, "%.0f W", s.effectivePowerWatts), SysPink)
            }

            // Power source picker
            Column {
                Text(stringResource(R.string.charger_source_type).uppercase(), style = MaterialTheme.typography.labelMedium, color = MaterialTheme.colorScheme.onSurfaceVariant)
                Row(
                    Modifier.fillMaxWidth().clickable { sourceMenu = true }.padding(vertical = 8.dp),
                    verticalAlignment = Alignment.CenterVertically,
                    horizontalArrangement = Arrangement.spacedBy(8.dp),
                ) {
                    Icon(sfSymbol(s.sourceType.iconName), contentDescription = null)
                    Text(sourceLabel(s.sourceType), style = MaterialTheme.typography.titleMedium, fontWeight = FontWeight.SemiBold)
                    Icon(Icons.Outlined.ArrowDropDown, contentDescription = null)
                    DropdownMenu(expanded = sourceMenu, onDismissRequest = { sourceMenu = false }) {
                        PowerSourceType.entries.forEach { t ->
                            DropdownMenuItem(
                                text = { Text(sourceLabel(t)) },
                                leadingIcon = { Icon(sfSymbol(t.iconName), contentDescription = null) },
                                onClick = { vm.setSource(t); sourceMenu = false },
                            )
                        }
                    }
                }
            }

            SnapSlider(
                title = stringResource(R.string.charger_field_input_voltage),
                value = s.inputVoltage,
                range = maxOf(0.0, minOf(12.0, s.inputVoltage))..maxOf(300.0, s.inputVoltage),
                valueText = String.format(Locale.US, "%.0f V", s.inputVoltage),
                onValueChange = vm::setInputVoltage, snapValues = INPUT_SNAPS, snapTolerance = 2.0, round = Fmt::roundToTenth,
                onEditRequest = { editing = CField.INPUT },
            )
            SnapSlider(
                title = stringResource(R.string.charger_field_output_voltage),
                value = s.outputVoltage,
                range = maxOf(0.0, minOf(10.0, s.outputVoltage))..maxOf(80.0, s.outputVoltage),
                valueText = String.format(Locale.US, "%.1f V", s.outputVoltage),
                onValueChange = vm::setOutputVoltage, snapValues = OUTPUT_SNAPS, snapTolerance = 0.5, round = Fmt::roundToTenth,
                onEditRequest = { editing = CField.OUTPUT },
            )

            if (s.powerEntryMode == PowerEntryMode.POWER) {
                SnapSlider(
                    title = stringResource(R.string.charger_field_power),
                    value = s.displayedPower,
                    range = 0.0..maxOf(3000.0, maxOf(s.maxPowerWatts, s.effectivePowerWatts)),
                    valueText = String.format(Locale.US, "%.0f W", s.displayedPower),
                    onValueChange = vm::setPower, snapValues = POWER_SNAPS, snapTolerance = 25.0, round = Fmt::roundToNearestFive,
                    onEditRequest = { editing = CField.POWER },
                    trailing = { TextButton(onClick = { vm.switchToCurrentMode() }) { Text(stringResource(R.string.slider_button_ampere)) } },
                )
                Text(stringResource(R.string.charger_field_power_footer), style = MaterialTheme.typography.bodySmall, color = MaterialTheme.colorScheme.onSurfaceVariant)
            } else {
                SnapSlider(
                    title = stringResource(R.string.charger_field_current),
                    value = s.maxCurrentAmps,
                    range = maxOf(0.0, minOf(5.0, s.maxCurrentAmps))..maxOf(200.0, s.maxCurrentAmps),
                    valueText = String.format(Locale.US, "%.1f A", s.maxCurrentAmps),
                    onValueChange = vm::setCurrent, snapValues = CURRENT_SNAPS, snapTolerance = 2.0, round = Fmt::roundToTenth,
                    onEditRequest = { editing = CField.CURRENT },
                    trailing = { TextButton(onClick = { vm.switchToPowerMode() }) { Text(stringResource(R.string.slider_button_watt)) } },
                )
            }
        }
    }

    editing?.let { field ->
        val onConfirm: (Double) -> Unit = when (field) {
            CField.INPUT -> { v -> vm.setInputVoltage(Fmt.roundToTenth(v)) }
            CField.OUTPUT -> { v -> vm.setOutputVoltage(Fmt.roundToTenth(v)) }
            CField.CURRENT -> { v -> vm.setCurrent(Fmt.roundToTenth(v)) }
            CField.POWER -> { v -> vm.setPower(Fmt.roundToNearestFive(v)) }
        }
        val title = when (field) {
            CField.INPUT -> stringResource(R.string.charger_alert_input_voltage_title)
            CField.OUTPUT -> stringResource(R.string.charger_alert_output_voltage_title)
            CField.CURRENT -> stringResource(R.string.charger_alert_current_title)
            CField.POWER -> stringResource(R.string.charger_alert_power_title)
        }
        val initial = when (field) {
            CField.INPUT -> s.inputVoltage
            CField.OUTPUT -> s.outputVoltage
            CField.CURRENT -> s.maxCurrentAmps
            CField.POWER -> s.displayedPower
        }
        ValueEditDialog(title = title, message = null, initialValue = initial, onConfirm = onConfirm, onDismiss = { editing = null })
    }

    if (showAppearance) {
        AppearanceEditorSheet(
            title = stringResource(R.string.charger_appearance_title),
            nameLabel = stringResource(R.string.charger_field_name),
            previewSubtitle = stringResource(R.string.charger_appearance_subtitle),
            icons = chargerIconOptions,
            initialName = s.name,
            initialIcon = s.iconName,
            initialColor = s.colorName,
            onSave = { name, icon, color -> vm.setAppearance(name, icon, color) },
            onDismiss = { showAppearance = false },
        )
    }
}

@Composable
private fun sourceLabel(t: PowerSourceType): String = stringResource(
    when (t) {
        PowerSourceType.SHORE -> R.string.charger_source_shore
        PowerSourceType.SOLAR -> R.string.charger_source_solar
        PowerSourceType.WIND -> R.string.charger_source_wind
        PowerSourceType.GENERATOR -> R.string.charger_source_generator
        PowerSourceType.ALTERNATOR -> R.string.charger_source_alternator
    },
)
