import SwiftUI

struct BatteryEditorView: View {
    @EnvironmentObject private var unitSettings: UnitSystemSettings
    @State private var configuration: BatteryConfiguration
    @State private var temperatureEditingField: TemperatureEditingField?
    @State private var isAdvancedExpanded = false
    @State private var minimumTemperatureInput: String = ""
    @State private var maximumTemperatureInput: String = ""
    @State private var showingAppearanceEditor = false
    let onSave: (BatteryConfiguration) -> Void

    private enum TemperatureEditingField {
        case minimumTemperature
        case maximumTemperature
    }
    
    private let voltageSnapValues: [Double] = [6, 12, 12.8, 24, 25.6, 36, 48, 51.2]
    private let capacitySnapValues: [Double] = [10, 20, 50, 75, 100, 125, 150, 200, 300, 400, 600, 800, 1000]
    private let voltageSnapTolerance: Double = 0.5
    private let capacitySnapTolerance: Double = 10.0
    private let batteryIconOptions: [String] = [
        "battery.100",
        "battery.100.bolt",
        "battery.75",
        "battery.25",
        "battery.0",
        "bolt",
        "bolt.fill",
        "bolt.circle",
        "bolt.horizontal.circle",
        "powerplug",
        "car.battery",
        "bolt.square",
        "lightbulb"
    ]

    private var nameFieldLabel: String {
        String(
            localized: "battery.editor.field.name",
            bundle: .main,
            comment: "Label for the battery name text field"
        )
    }

    private var namePlaceholder: String {
        String(
            localized: "battery.editor.placeholder.name",
            bundle: .main,
            comment: "Placeholder example for the battery name field"
        )
    }

    private var chemistryLabel: String {
        String(
            localized: "battery.editor.field.chemistry",
            bundle: .main,
            comment: "Label describing the chemistry menu"
        )
    }

    private var summaryLabel: String {
        String(
            localized: "battery.editor.section.summary",
            bundle: .main,
            comment: "Label for the summary section in the editor"
        )
    }

    private var sliderVoltageTitle: String {
        String(
            localized: "battery.editor.slider.voltage",
            bundle: .main,
            comment: "Title for the nominal voltage slider"
        )
    }

    private var sliderCapacityTitle: String {
        String(
            localized: "battery.editor.slider.capacity",
            bundle: .main,
            comment: "Title for the capacity slider"
        )
    }

    private var advancedSectionTitle: String {
        String(
            localized: "battery.editor.section.advanced",
            bundle: .main,
            comment: "Title for the advanced settings section in the battery editor"
        )
    }

    private var usableCapacitySliderTitle: String {
        String(
            localized: "battery.editor.slider.usable_capacity",
            bundle: .main,
            comment: "Title for the usable capacity slider"
        )
    }

    private var resetButtonTitle: String {
        String(
            localized: "battery.editor.button.reset_default",
            bundle: .main,
            comment: "Title for the reset button in the advanced section"
        )
    }

    private var alertCancelTitle: String {
        String(
            localized: "battery.editor.alert.cancel",
            defaultValue: "Cancel"
        )
    }

    private var alertSaveTitle: String {
        String(
            localized: "battery.editor.alert.save",
            defaultValue: "Save"
        )
    }

    private var voltageAlertTitle: String {
        String(
            localized: "battery.editor.alert.voltage.title",
            defaultValue: "Edit Nominal Voltage"
        )
    }

    private var voltageAlertPlaceholder: String {
        String(
            localized: "battery.editor.alert.voltage.placeholder",
            defaultValue: "Voltage"
        )
    }

    private var voltageAlertMessage: String {
        String(
            localized: "battery.editor.alert.voltage.message",
            defaultValue: "Enter voltage in volts (V)"
        )
    }

    private var capacityAlertTitle: String {
        String(
            localized: "battery.editor.alert.capacity.title",
            defaultValue: "Edit Capacity"
        )
    }

    private var capacityAlertPlaceholder: String {
        String(
            localized: "battery.editor.alert.capacity.placeholder",
            defaultValue: "Capacity"
        )
    }

    private var capacityAlertMessage: String {
        String(
            localized: "battery.editor.alert.capacity.message",
            defaultValue: "Enter capacity in amp-hours (Ah)"
        )
    }

    private var usableCapacityAlertTitle: String {
        String(
            localized: "battery.editor.alert.usable_capacity.title",
            defaultValue: "Edit Usable Capacity"
        )
    }

    private var usableCapacityAlertPlaceholder: String {
        String(
            localized: "battery.editor.alert.usable_capacity.placeholder",
            defaultValue: "Usable Capacity (%)"
        )
    }

    private var usableCapacityAlertMessage: String {
        String(
            localized: "battery.editor.alert.usable_capacity.message",
            defaultValue: "Enter usable capacity percentage (%)"
        )
    }

    private var chargeVoltageAlertTitle: String {
        String(
            localized: "battery.editor.alert.charge_voltage.title",
            defaultValue: "Edit Charge Voltage"
        )
    }

    private var chargeVoltageAlertPlaceholder: String {
        String(
            localized: "battery.editor.alert.charge_voltage.placeholder",
            defaultValue: "Charge Voltage"
        )
    }

    private var chargeVoltageAlertMessage: String {
        String(
            localized: "battery.editor.alert.charge_voltage.message",
            defaultValue: "Enter charge voltage in volts (V)"
        )
    }

    private var cutOffVoltageAlertTitle: String {
        String(
            localized: "battery.editor.alert.cutoff_voltage.title",
            defaultValue: "Edit Cut-off Voltage"
        )
    }

    private var cutOffVoltageAlertPlaceholder: String {
        String(
            localized: "battery.editor.alert.cutoff_voltage.placeholder",
            defaultValue: "Cut-off Voltage"
        )
    }

    private var cutOffVoltageAlertMessage: String {
        String(
            localized: "battery.editor.alert.cutoff_voltage.message",
            defaultValue: "Enter cut-off voltage in volts (V)"
        )
    }

    private var chargeVoltageTitle: String {
        String(
            localized: "battery.editor.slider.charge_voltage",
            defaultValue: "Charge Voltage"
        )
    }

    private var cutOffVoltageTitle: String {
        String(
            localized: "battery.editor.slider.cutoff_voltage",
            defaultValue: "Cut-off Voltage"
        )
    }

    private var temperatureRangeTitle: String {
        String(
            localized: "battery.editor.slider.temperature_range",
            defaultValue: "Temperature Range"
        )
    }

    private var chargeVoltageHelperText: String {
        String(
            localized: "battery.editor.advanced.charge_voltage.helper",
            defaultValue: "Set the maximum recommended charging voltage."
        )
    }

    private var cutOffVoltageHelperText: String {
        String(
            localized: "battery.editor.advanced.cutoff_voltage.helper",
            defaultValue: "Set the minimum safe discharge voltage."
        )
    }

    private var temperatureRangeHelperText: String {
        String(
            localized: "battery.editor.advanced.temperature_range.helper",
            defaultValue: "Define the recommended operating temperature range."
        )
    }

    private var minimumTemperatureLabel: String {
        String(
            localized: "battery.editor.slider.temperature_range.min",
            defaultValue: "Minimum"
        )
    }

    private var maximumTemperatureLabel: String {
        String(
            localized: "battery.editor.slider.temperature_range.max",
            defaultValue: "Maximum"
        )
    }

    private var usableCapacityDefaultFooterFormat: String {
        String(
            localized: "battery.editor.advanced.usable_capacity.footer_default",
            defaultValue: "Defaults to %@ based on chemistry."
        )
    }

    private var usableCapacityOverrideFooterFormat: String {
        String(
            localized: "battery.editor.advanced.usable_capacity.footer_override",
            defaultValue: "Override active. Chemistry default remains %@."
        )
    }

    private var usableCapacityFooterText: String {
        let defaultPercentage = formattedPercentage(configuration.defaultUsableCapacityFraction)
        if configuration.usableCapacityOverrideFraction != nil {
            return String.localizedStringWithFormat(usableCapacityOverrideFooterFormat, defaultPercentage)
        } else {
            return String.localizedStringWithFormat(usableCapacityDefaultFooterFormat, defaultPercentage)
        }
    }

    private var hasUsableCapacityOverride: Bool {
        configuration.usableCapacityOverrideFraction != nil
    }

    private var summaryVoltageLabel: String {
        String(
            localized: "battery.bank.badge.voltage",
            bundle: .main,
            comment: "Label used for voltage values"
        )
    }

    private var summaryCapacityLabel: String {
        String(
            localized: "battery.bank.badge.capacity",
            bundle: .main,
            comment: "Label used for capacity values"
        )
    }

    private var summaryEnergyLabel: String {
        String(
            localized: "battery.bank.badge.energy",
            bundle: .main,
            comment: "Label used for energy values"
        )
    }

    private var appearanceEditorTitle: String {
        String(
            localized: "battery.editor.appearance.title",
            defaultValue: "Battery Appearance"
        )
    }

    private var appearanceEditorSubtitle: String {
        String(
            localized: "battery.editor.appearance.subtitle",
            defaultValue: "Customize how this battery shows up"
        )
    }

    private var appearanceAccessibilityLabel: String {
        String(
            localized: "battery.editor.appearance.accessibility",
            defaultValue: "Edit battery appearance"
        )
    }

    private var iconColor: Color {
        Color.componentColor(named: configuration.colorName)
    }

    private var displayName: String {
        configuration.name.isEmpty ? namePlaceholder : configuration.name
    }
    
    private var voltageSliderRange: ClosedRange<Double> {
        let lowerBound = max(0, min(6, configuration.nominalVoltage))
        let upperBound = max(60, configuration.nominalVoltage)
        return lowerBound...upperBound
    }

    private var capacitySliderRange: ClosedRange<Double> {
        let lowerBound = max(0, min(5, configuration.capacityAmpHours))
        let upperBound = max(1000, configuration.capacityAmpHours)
        return lowerBound...upperBound
    }

    private var usableCapacitySliderRange: ClosedRange<Double> {
        0...100
    }

    private var usableCapacitySnapValues: [Double] {
        [configuration.defaultUsableCapacityFraction * 100]
    }

    private var chargeVoltageSliderRange: ClosedRange<Double> {
        let lowerBound = max(0, min(10, configuration.chargeVoltage))
        let upperBound = max(60, configuration.chargeVoltage)
        return lowerBound...upperBound
    }

    private var cutOffVoltageSliderRange: ClosedRange<Double> {
        let upperReference = max(configuration.nominalVoltage, configuration.chargeVoltage, 60)
        let lowerBound = max(0, min(5, configuration.cutOffVoltage))
        let upperBound = max(lowerBound + 1, upperReference)
        return lowerBound...upperBound
    }

    private var minimumTemperatureSliderRange: ClosedRange<Double> {
        let upperBound = max(configuration.maximumTemperatureCelsius, -60)
        return -60...min(upperBound, 80)
    }

    private var maximumTemperatureSliderRange: ClosedRange<Double> {
        let lowerBound = min(configuration.minimumTemperatureCelsius, 80)
        return max(lowerBound, -60)...80
    }

    private var chargeVoltageSnapValues: [Double] {
        [13.8, 14.0, 14.2, 14.4, 14.6, 14.8, 15.0]
    }

    private var cutOffVoltageSnapValues: [Double] {
        [10.0, 10.5, 11.0, 11.5, 12.0]
    }

    private var temperatureSnapValues: [Double] {
        [-40, -20, -10, 0, 25, 40, 50, 60]
    }

    init(configuration: BatteryConfiguration, onSave: @escaping (BatteryConfiguration) -> Void) {
        _configuration = State(initialValue: configuration)
        self.onSave = onSave
    }

    var body: some View {
        VStack(spacing: 0) {
            headerInfoBar
            List {
                configurationSection
                sliderSection
                advancedSection
            }
            .listStyle(.plain)
            .scrollIndicators(.hidden)
            .scrollContentBackground(.hidden)
            .background(Color.clear)
        }
        .background(Color(.systemGroupedBackground).ignoresSafeArea())
        .navigationTitle("")
        .navigationBarTitleDisplayMode(.inline)
        .toolbar {
            ToolbarItem(placement: .principal) {
                navigationTitleView
            }
        }
        .onDisappear {
            onSave(configuration)
        }
        .sheet(isPresented: $showingAppearanceEditor) {
            ItemEditorView(
                title: appearanceEditorTitle,
                nameFieldLabel: nameFieldLabel,
                previewSubtitle: appearanceEditorSubtitle,
                icons: batteryIconOptions,
                name: Binding(
                    get: { configuration.name },
                    set: { configuration.name = $0 }
                ),
                iconName: Binding(
                    get: { configuration.iconName },
                    set: { configuration.iconName = $0 }
                ),
                colorName: Binding(
                    get: { configuration.colorName },
                    set: { configuration.colorName = $0 }
                )
            )
        }
        .alert(
            String(
                localized: "battery.editor.alert.minimum_temperature.title",
                defaultValue: "Edit Minimum Temperature"
            ),
            isPresented: Binding(
                get: { temperatureEditingField == .minimumTemperature },
                set: { isPresented in
                    if !isPresented {
                        temperatureEditingField = nil
                        minimumTemperatureInput = ""
                    }
                }
            )
        ) {
            TextField(
                String(
                    localized: "battery.editor.alert.minimum_temperature.placeholder",
                    defaultValue: "Minimum Temperature (\u{00B0}C)"
                ),
                text: $minimumTemperatureInput
            )
            .keyboardType(.decimalPad)
            .onAppear {
                if minimumTemperatureInput.isEmpty {
                    minimumTemperatureInput = formattedEditValue(configuration.minimumTemperatureCelsius)
                }
            }
            .onChange(of: minimumTemperatureInput) { _, newValue in
                guard temperatureEditingField == .minimumTemperature, let parsed = parseInput(newValue) else { return }
                applyMinimumTemperatureInput(parsed)
            }

            Button(
                String(
                    localized: "battery.editor.alert.cancel",
                    defaultValue: "Cancel"
                ),
                role: .cancel
            ) {
                temperatureEditingField = nil
                minimumTemperatureInput = ""
            }

            Button(
                String(
                    localized: "battery.editor.alert.save",
                    defaultValue: "Save"
                )
            ) {
                if let parsed = parseInput(minimumTemperatureInput) {
                    applyMinimumTemperatureInput(parsed)
                }
                temperatureEditingField = nil
                minimumTemperatureInput = ""
            }
        } message: {
            Text(
                String(
                    localized: "battery.editor.alert.minimum_temperature.message",
                    defaultValue: "Enter minimum temperature in degrees Celsius (\u{00B0}C)"
                )
            )
        }
        .alert(
            String(
                localized: "battery.editor.alert.maximum_temperature.title",
                defaultValue: "Edit Maximum Temperature"
            ),
            isPresented: Binding(
                get: { temperatureEditingField == .maximumTemperature },
                set: { isPresented in
                    if !isPresented {
                        temperatureEditingField = nil
                        maximumTemperatureInput = ""
                    }
                }
            )
        ) {
            TextField(
                String(
                    localized: "battery.editor.alert.maximum_temperature.placeholder",
                    defaultValue: "Maximum Temperature (\u{00B0}C)"
                ),
                text: $maximumTemperatureInput
            )
            .keyboardType(.decimalPad)
            .onAppear {
                if maximumTemperatureInput.isEmpty {
                    maximumTemperatureInput = formattedEditValue(configuration.maximumTemperatureCelsius)
                }
            }
            .onChange(of: maximumTemperatureInput) { _, newValue in
                guard temperatureEditingField == .maximumTemperature, let parsed = parseInput(newValue) else { return }
                applyMaximumTemperatureInput(parsed)
            }

            Button(
                String(
                    localized: "battery.editor.alert.cancel",
                    defaultValue: "Cancel"
                ),
                role: .cancel
            ) {
                temperatureEditingField = nil
                maximumTemperatureInput = ""
            }

            Button(
                String(
                    localized: "battery.editor.alert.save",
                    defaultValue: "Save"
                )
            ) {
                if let parsed = parseInput(maximumTemperatureInput) {
                    applyMaximumTemperatureInput(parsed)
                }
                temperatureEditingField = nil
                maximumTemperatureInput = ""
            }
        } message: {
            Text(
                String(
                    localized: "battery.editor.alert.maximum_temperature.message",
                    defaultValue: "Enter maximum temperature in degrees Celsius (\u{00B0}C)"
                )
            )
        }
    }

    private var navigationTitleView: some View {
        Button {
            showingAppearanceEditor = true
        } label: {
            HStack(spacing: 8) {
                LoadIconView(
                    remoteIconURLString: nil,
                    fallbackSystemName: configuration.iconName.isEmpty ? "battery.100.bolt" : configuration.iconName,
                    fallbackColor: iconColor,
                    size: 26
                )
                Text(displayName)
                    .font(.headline)
                    .fontWeight(.semibold)
                    .foregroundColor(.primary)
            }
        }
        .buttonStyle(.plain)
        .accessibilityLabel(appearanceAccessibilityLabel)
    }

    private var configurationSection: some View {
        Section {
            VStack(alignment: .leading, spacing: 8) {
                Text(chemistryLabel.uppercased())
                    .font(.headline)
                Menu {
                    ForEach(BatteryConfiguration.Chemistry.allCases) { chemistry in
                        Button {
                            configuration.chemistry = chemistry
                        } label: {
                            if chemistry == configuration.chemistry {
                                Label(chemistry.displayName, systemImage: "checkmark")
                            } else {
                                Text(chemistry.displayName)
                            }
                        }
                    }
                } label: {
                    HStack {
                        Text(configuration.chemistry.displayName)
                            .font(.title)
                            .fontWeight(.bold)
                        Spacer()
                        Image(systemName: "chevron.down")
                            .font(.footnote.weight(.bold))
                            .foregroundStyle(.secondary)
                    }
                }
                .buttonStyle(.plain)
            }
            .padding(.vertical, 6)
        }
        .listRowBackground(Color(.systemBackground))
        .listRowSeparator(.hidden)
        .listRowInsets(EdgeInsets(top: 12, leading: 18, bottom: 12, trailing: 18))
    }

    private var summarySection: some View {
        Section {
            VStack(alignment: .leading, spacing: 8) {
                Text(summaryLabel.uppercased())
                    .font(.caption2)
                    .fontWeight(.medium)
                    .foregroundStyle(.secondary)
                ViewThatFits(in: .horizontal) {
                    HStack(spacing: 16) {
                        summaryBadge(
                            title: summaryVoltageLabel,
                            value: formattedValue(configuration.nominalVoltage, unit: "V"),
                            symbol: "bolt"
                        )
                        summaryBadge(
                            title: summaryCapacityLabel,
                            value: formattedValue(configuration.capacityAmpHours, unit: "Ah"),
                            symbol: "gauge.medium"
                        )
                        summaryBadge(
                            title: summaryEnergyLabel,
                            value: formattedValue(configuration.energyWattHours, unit: "Wh"),
                            symbol: "battery.100.bolt"
                        )
                    }

                    VStack(spacing: 12) {
                        summaryBadge(
                            title: summaryVoltageLabel,
                            value: formattedValue(configuration.nominalVoltage, unit: "V"),
                            symbol: "bolt"
                        )
                        summaryBadge(
                            title: summaryCapacityLabel,
                            value: formattedValue(configuration.capacityAmpHours, unit: "Ah"),
                            symbol: "gauge.medium"
                        )
                        summaryBadge(
                            title: summaryEnergyLabel,
                            value: formattedValue(configuration.energyWattHours, unit: "Wh"),
                            symbol: "battery.100.bolt"
                        )
                    }
                }
            }
            .padding(.vertical, 6)
        }
        .listRowBackground(Color(.systemBackground))
        .listRowSeparator(.hidden)
        .listRowInsets(EdgeInsets(top: 12, leading: 18, bottom: 12, trailing: 18))
    }

    private var sliderSection: some View {
        Section {
            EditableSliderRow(
                title: sliderVoltageTitle,
                unit: "V",
                range: voltageSliderRange,
                value: Binding(
                    get: { configuration.nominalVoltage },
                    set: { configuration.nominalVoltage = $0 }
                ),
                snapValues: voltageSnapValues,
                sliderTransform: normalizedVoltage,
                alertTransform: roundToTenth,
                formatValue: formattedEditValue,
                parseInput: parseInput,
                alertCopy: EditableSliderRow.AlertCopy(
                    title: voltageAlertTitle,
                    placeholder: voltageAlertPlaceholder,
                    message: voltageAlertMessage,
                    cancelTitle: alertCancelTitle,
                    saveTitle: alertSaveTitle
                )
            )
            .listRowSeparator(.hidden)

            EditableSliderRow(
                title: sliderCapacityTitle,
                unit: "Ah",
                range: capacitySliderRange,
                value: Binding(
                    get: { configuration.capacityAmpHours },
                    set: { configuration.capacityAmpHours = $0 }
                ),
                snapValues: capacitySnapValues,
                sliderTransform: normalizedCapacity,
                alertTransform: roundToTenth,
                formatValue: formattedEditValue,
                parseInput: parseInput,
                alertCopy: EditableSliderRow.AlertCopy(
                    title: capacityAlertTitle,
                    placeholder: capacityAlertPlaceholder,
                    message: capacityAlertMessage,
                    cancelTitle: alertCancelTitle,
                    saveTitle: alertSaveTitle
                )
            )
            .listRowSeparator(.hidden)
        }
        .listRowBackground(Color(.systemBackground))
        .listRowInsets(EdgeInsets(top: 12, leading: 18, bottom: 12, trailing: 18))
    }

    private var advancedSection: some View {
        Section {
            Button {
                withAnimation(.easeInOut(duration: 0.2)) {
                    isAdvancedExpanded.toggle()
                }
            } label: {
                HStack(spacing: 8) {
                    Text(advancedSectionTitle.uppercased())
                        .font(.caption2)
                        .fontWeight(.medium)
                        .foregroundStyle(.secondary)
                    Spacer()
                    Image(systemName: isAdvancedExpanded ? "chevron.up" : "chevron.down")
                        .font(.footnote.weight(.semibold))
                        .foregroundStyle(.secondary)
                }
                .padding(.vertical, 10)
                .contentShape(Rectangle())
            }
            .buttonStyle(.plain)
            .listRowBackground(Color(.secondarySystemBackground))
            .listRowSeparator(.hidden)

            if isAdvancedExpanded {
                advancedControls
                    .transition(.opacity.combined(with: .move(edge: .top)))
                    .listRowSeparator(.hidden)
                    .listRowBackground(Color(.systemBackground))
            }
        }
        .listRowSeparator(.hidden)
        .listRowInsets(EdgeInsets(top: 12, leading: 18, bottom: 12, trailing: 18))
        .animation(.easeInOut(duration: 0.2), value: isAdvancedExpanded)
    }

    private var advancedControls: some View {
        VStack(spacing: 16) {
            VStack(alignment: .leading, spacing: 8) {
                EditableSliderRow(
                    title: usableCapacitySliderTitle,
                    unit: "%",
                    range: usableCapacitySliderRange,
                    value: Binding(
                        get: { configuration.usableCapacityFraction * 100 },
                        set: { newValue in
                            updateUsableCapacityPercent(newValue)
                        }
                    ),
                    buttonText: resetButtonTitle,
                    buttonAction: resetUsableCapacityToDefault,
                    isButtonVisible: hasUsableCapacityOverride,
                    snapValues: usableCapacitySnapValues,
                    sliderTransform: roundToTenth,
                    alertTransform: roundToTenth,
                    formatValue: formattedEditValue,
                    parseInput: parseInput,
                    alertCopy: EditableSliderRow.AlertCopy(
                        title: usableCapacityAlertTitle,
                        placeholder: usableCapacityAlertPlaceholder,
                        message: usableCapacityAlertMessage,
                        cancelTitle: alertCancelTitle,
                        saveTitle: alertSaveTitle
                    )
                )
                Text(usableCapacityFooterText)
                    .font(.caption)
                    .foregroundStyle(.secondary)
            }

            VStack(alignment: .leading, spacing: 8) {
                EditableSliderRow(
                    title: chargeVoltageTitle,
                    unit: "V",
                    range: chargeVoltageSliderRange,
                    value: Binding(
                        get: { configuration.chargeVoltage },
                        set: { newValue in
                            let clamped = max(newValue, configuration.cutOffVoltage)
                            configuration.chargeVoltage = clamped
                        }
                    ),
                    snapValues: chargeVoltageSnapValues,
                    sliderTransform: normalizedChargeVoltage,
                    alertTransform: roundToTenth,
                    formatValue: formattedEditValue,
                    parseInput: parseInput,
                    alertCopy: EditableSliderRow.AlertCopy(
                        title: chargeVoltageAlertTitle,
                        placeholder: chargeVoltageAlertPlaceholder,
                        message: chargeVoltageAlertMessage,
                        cancelTitle: alertCancelTitle,
                        saveTitle: alertSaveTitle
                    )
                )
                Text(chargeVoltageHelperText)
                    .font(.caption)
                    .foregroundStyle(.secondary)
            }

            VStack(alignment: .leading, spacing: 8) {
                EditableSliderRow(
                    title: cutOffVoltageTitle,
                    unit: "V",
                    range: cutOffVoltageSliderRange,
                    value: Binding(
                        get: { configuration.cutOffVoltage },
                        set: { newValue in
                            let clamped = min(newValue, configuration.chargeVoltage)
                            configuration.cutOffVoltage = clamped
                        }
                    ),
                    snapValues: cutOffVoltageSnapValues,
                    sliderTransform: normalizedCutOffVoltage,
                    alertTransform: roundToTenth,
                    formatValue: formattedEditValue,
                    parseInput: parseInput,
                    alertCopy: EditableSliderRow.AlertCopy(
                        title: cutOffVoltageAlertTitle,
                        placeholder: cutOffVoltageAlertPlaceholder,
                        message: cutOffVoltageAlertMessage,
                        cancelTitle: alertCancelTitle,
                        saveTitle: alertSaveTitle
                    )
                )
                Text(cutOffVoltageHelperText)
                    .font(.caption)
                    .foregroundStyle(.secondary)
            }

            VStack(alignment: .leading, spacing: 8) {
                temperatureRangeRow
                Text(temperatureRangeHelperText)
                    .font(.caption)
                    .foregroundStyle(.secondary)
            }
        }
        .padding(.top, 6)
    }

    private var temperatureRangeRow: some View {
        VStack(alignment: .leading, spacing: 10) {
            Text(temperatureRangeTitle)
                .font(.headline)

            HStack(spacing: 8) {
                Button(action: beginMinimumTemperatureEditing) {
                    Text(formattedTemperature(configuration.minimumTemperatureCelsius))
                        .font(.title)
                        .fontWeight(.bold)
                        .foregroundStyle(.primary)
                }
                .buttonStyle(.plain)

                Text("–")
                    .font(.title2.weight(.semibold))
                    .foregroundStyle(.secondary)

                Button(action: beginMaximumTemperatureEditing) {
                    Text(formattedTemperature(configuration.maximumTemperatureCelsius))
                        .font(.title)
                        .fontWeight(.bold)
                        .foregroundStyle(.primary)
                }
                .buttonStyle(.plain)
            }

            VStack(alignment: .leading, spacing: 12) {
                Text(minimumTemperatureLabel.uppercased())
                    .font(.caption2)
                    .fontWeight(.medium)
                    .foregroundStyle(.secondary)

                HStack {
                    Text(formattedTemperature(minimumTemperatureSliderRange.lowerBound))
                        .font(.caption)
                        .foregroundStyle(.secondary)
                    Slider(
                        value: Binding(
                            get: { configuration.minimumTemperatureCelsius },
                            set: { newValue in
                                let adjusted = normalizedTemperature(for: newValue)
                                configuration.minimumTemperatureCelsius = min(adjusted, configuration.maximumTemperatureCelsius)
                            }
                        ),
                        in: minimumTemperatureSliderRange
                    )
                    Text(formattedTemperature(minimumTemperatureSliderRange.upperBound))
                        .font(.caption)
                        .foregroundStyle(.secondary)
                }

                Text(maximumTemperatureLabel.uppercased())
                    .font(.caption2)
                    .fontWeight(.medium)
                    .foregroundStyle(.secondary)

                HStack {
                    Text(formattedTemperature(maximumTemperatureSliderRange.lowerBound))
                        .font(.caption)
                        .foregroundStyle(.secondary)
                    Slider(
                        value: Binding(
                            get: { configuration.maximumTemperatureCelsius },
                            set: { newValue in
                                let adjusted = normalizedTemperature(for: newValue)
                                configuration.maximumTemperatureCelsius = max(adjusted, configuration.minimumTemperatureCelsius)
                            }
                        ),
                        in: maximumTemperatureSliderRange
                    )
                    Text(formattedTemperature(maximumTemperatureSliderRange.upperBound))
                        .font(.caption)
                        .foregroundStyle(.secondary)
                }
            }
        }
    }

    private var headerInfoBar: some View {
        HStack(spacing: 12) {
            overviewChip(
                icon: "bolt.fill",
                title: summaryVoltageLabel.uppercased(),
                value: formattedValue(configuration.nominalVoltage, unit: "V"),
                tint: .orange
            )

            overviewChip(
                icon: "gauge.medium",
                title: summaryCapacityLabel.uppercased(),
                value: formattedValue(configuration.capacityAmpHours, unit: "Ah"),
                tint: .blue
            )

            overviewChip(
                icon: "battery.100.bolt",
                title: summaryEnergyLabel.uppercased(),
                value: formattedValue(configuration.energyWattHours, unit: "Wh"),
                tint: .purple
            )

            Spacer(minLength: 0)
        }
        .padding(.horizontal)
        .padding(.vertical, 8)
        .background(Color(.systemGroupedBackground))
    }

    private func overviewChip(icon: String, title: String, value: String, tint: Color) -> some View {
        VStack(alignment: .leading, spacing: 4) {
            HStack(spacing: 6) {
                Image(systemName: icon)
                    .font(.system(size: 14, weight: .semibold))
                    .foregroundStyle(tint)
                Text(value)
                    .font(.subheadline.weight(.semibold))
                    .foregroundStyle(.primary)
            }
            Text(title)
                .font(.caption2)
                .fontWeight(.medium)
                .foregroundStyle(.secondary)
        }
        .padding(.horizontal, 10)
        .padding(.vertical, 8)
        .background(
            RoundedRectangle(cornerRadius: 10, style: .continuous)
                .fill(tint.opacity(0.12))
        )
    }

    private func roundToTenth(_ value: Double) -> Double {
        max(0, (value * 10).rounded() / 10)
    }

    private func formattedEditValue(_ value: Double) -> String {
        Self.numberFormatter.string(from: NSNumber(value: roundToTenth(value))) ?? String(format: "%.1f", value)
    }

    private func parseInput(_ text: String) -> Double? {
        let trimmed = text.trimmingCharacters(in: .whitespacesAndNewlines)
        guard !trimmed.isEmpty else { return nil }
        if let number = Self.numberFormatter.number(from: trimmed)?.doubleValue {
            return number
        }
        let decimalSeparator = Locale.current.decimalSeparator ?? "."
        let altSeparator = decimalSeparator == "." ? "," : "."
        let normalized = trimmed.replacingOccurrences(of: altSeparator, with: decimalSeparator)
        return Self.numberFormatter.number(from: normalized)?.doubleValue
    }

    private func beginMinimumTemperatureEditing() {
        minimumTemperatureInput = formattedEditValue(configuration.minimumTemperatureCelsius)
        temperatureEditingField = .minimumTemperature
    }

    private func beginMaximumTemperatureEditing() {
        maximumTemperatureInput = formattedEditValue(configuration.maximumTemperatureCelsius)
        temperatureEditingField = .maximumTemperature
    }

    private func nearestValue(to value: Double, in options: [Double], tolerance: Double) -> Double? {
        guard let closest = options.min(by: { abs($0 - value) < abs($1 - value) }) else { return nil }
        return abs(closest - value) <= tolerance ? closest : nil
    }

    private func normalizedVoltage(for value: Double) -> Double {
        let rounded = (value * 10).rounded() / 10
        if let snapped = nearestValue(to: rounded, in: voltageSnapValues, tolerance: voltageSnapTolerance) {
            return snapped
        }
        return rounded
    }

    private func normalizedCapacity(for value: Double) -> Double {
        let rounded = (value * 10).rounded() / 10
        if let snapped = nearestValue(to: rounded, in: capacitySnapValues, tolerance: capacitySnapTolerance) {
            return snapped
        }
        return rounded
    }

    private func normalizedChargeVoltage(for value: Double) -> Double {
        let rounded = (value * 10).rounded() / 10
        if let snapped = nearestValue(to: rounded, in: chargeVoltageSnapValues, tolerance: 0.2) {
            return snapped
        }
        return rounded
    }

    private func normalizedCutOffVoltage(for value: Double) -> Double {
        let rounded = (value * 10).rounded() / 10
        if let snapped = nearestValue(to: rounded, in: cutOffVoltageSnapValues, tolerance: 0.2) {
            return snapped
        }
        return rounded
    }

    private func normalizedTemperature(for value: Double) -> Double {
        let rounded = (value * 10).rounded() / 10
        if let snapped = nearestValue(to: rounded, in: temperatureSnapValues, tolerance: 1.5) {
            return snapped
        }
        return rounded
    }

    private func updateUsableCapacityPercent(_ percent: Double) {
        let clamped = max(0, min(100, percent))
        let rounded = (clamped * 10).rounded() / 10
        let fraction = max(0, min(1, rounded / 100))
        let defaultFraction = configuration.defaultUsableCapacityFraction
        if abs(fraction - defaultFraction) < 0.001 {
            configuration.usableCapacityOverrideFraction = nil
        } else {
            configuration.usableCapacityOverrideFraction = fraction
        }
    }

    private func resetUsableCapacityToDefault() {
        configuration.usableCapacityOverrideFraction = nil
    }

    private func applyMinimumTemperatureInput(_ value: Double) {
        let normalized = normalizedTemperature(for: value)
        configuration.minimumTemperatureCelsius = min(normalized, configuration.maximumTemperatureCelsius)
    }

    private func applyMaximumTemperatureInput(_ value: Double) {
        let normalized = normalizedTemperature(for: value)
        configuration.maximumTemperatureCelsius = max(normalized, configuration.minimumTemperatureCelsius)
    }

    private func summaryBadge(title: String, value: String, symbol: String) -> some View {
        VStack(spacing: 4) {
            Image(systemName: symbol)
                .font(.title3)
                .foregroundStyle(Color.accentColor)
            Text(value)
                .font(.subheadline.weight(.semibold))
                .lineLimit(1)
                .minimumScaleFactor(0.8)
            Text(title)
                .font(.caption)
                .foregroundStyle(.secondary)
        }
        .frame(maxWidth: .infinity)
        .padding(12)
        .background(
            RoundedRectangle(cornerRadius: 16, style: .continuous)
                .fill(Color(.secondarySystemBackground))
        )
    }

    private static let numberFormatter: NumberFormatter = {
        let formatter = NumberFormatter()
        formatter.locale = .current
        formatter.numberStyle = .decimal
        formatter.minimumFractionDigits = 0
        formatter.maximumFractionDigits = 1
        return formatter
    }()

    private func formattedValue(_ value: Double, unit: String) -> String {
        let numberString = Self.numberFormatter.string(from: NSNumber(value: value)) ?? String(format: "%.1f", value)
        return "\(numberString) \(unit)"
    }

    private func formattedTemperature(_ value: Double) -> String {
        let numberString = Self.numberFormatter.string(from: NSNumber(value: value)) ?? String(format: "%.1f", value)
        return "\(numberString)°C"
    }

    private func formattedPercentage(_ fraction: Double) -> String {
        let clamped = max(0, min(1, fraction))
        return Self.percentFormatter.string(from: NSNumber(value: clamped)) ?? String(format: "%.0f%%", clamped * 100)
    }

    private static let percentFormatter: NumberFormatter = {
        let formatter = NumberFormatter()
        formatter.locale = .current
        formatter.numberStyle = .percent
        formatter.minimumFractionDigits = 0
        formatter.maximumFractionDigits = 0
        return formatter
    }()

}

#Preview {
    let previewSystem = ElectricalSystem(name: "Camper")
    return NavigationStack {
        BatteryEditorView(
            configuration: BatteryConfiguration(
                name: "House Bank",
                iconName: "battery.100.bolt",
                colorName: "green",
                system: previewSystem
            ),
            onSave: { _ in }
        )
    }
    .environmentObject(UnitSystemSettings())
}
