import SwiftUI

struct ChargerEditorView: View {
    @State private var configuration: ChargerConfiguration
    @State private var editingField: EditingField?
    @State private var inputVoltageInput: String = ""
    @State private var outputVoltageInput: String = ""
    @State private var currentInput: String = ""
    @State private var powerInput: String = ""
    @State private var powerEntryMode: PowerEntryMode
    @State private var lastManualPowerWatts: Double
    @State private var showingAppearanceEditor = false
    let onSave: (ChargerConfiguration) -> Void

    private enum EditingField {
        case inputVoltage
        case outputVoltage
        case current
        case power
    }

    private enum PowerEntryMode {
        case current
        case power
    }

    private let inputVoltageSnapValues: [Double] = [12, 24, 48, 120, 230, 240]
    private let outputVoltageSnapValues: [Double] = [12, 12.6, 12.8, 14.2, 24, 48]
    private let currentSnapValues: [Double] = [5, 10, 15, 20, 25, 30, 40, 50, 60, 80, 100, 150, 200]
    private let powerSnapValues: [Double] = [100, 150, 200, 250, 300, 400, 500, 600, 750, 1000, 1250, 1500, 2000, 2500, 3000]
    private let inputVoltageSnapTolerance: Double = 2.0
    private let outputVoltageSnapTolerance: Double = 0.5
    private let currentSnapTolerance: Double = 2.0
    private let powerSnapTolerance: Double = 25.0
    private let chargerIconOptions: [String] = [
        "bolt.fill",
        "bolt",
        "bolt.circle",
        "bolt.circle.fill",
        "bolt.horizontal.circle",
        "bolt.square",
        "bolt.square.fill",
        "bolt.badge.clock",
        "bolt.badge.a",
        "powerplug",
        "flashlight.on.fill",
        "battery.100.bolt"
    ]

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

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

    private var electricalSectionLabel: String {
        String(
            localized: "charger.editor.section.electrical",
            bundle: .main,
            comment: "Label for the electrical section"
        )
    }

    private var chargingSectionLabel: String {
        String(
            localized: "charger.editor.section.power",
            bundle: .main,
            comment: "Label for the charging output section"
        )
    }

    private var inputVoltageLabel: String {
        String(
            localized: "charger.editor.field.input_voltage",
            bundle: .main,
            comment: "Label for the input voltage slider"
        )
    }

    private var outputVoltageLabel: String {
        String(
            localized: "charger.editor.field.output_voltage",
            bundle: .main,
            comment: "Label for the output voltage slider"
        )
    }

    private var currentLabel: String {
        String(
            localized: "charger.editor.field.current",
            bundle: .main,
            comment: "Label for the charging current slider"
        )
    }

    private var powerLabel: String {
        String(
            localized: "charger.editor.field.power",
            bundle: .main,
            comment: "Label for the optional power field"
        )
    }

    private var powerFooter: String {
        String(
            localized: "charger.editor.field.power.footer",
            bundle: .main,
            comment: "Footer text describing how the optional power field works"
        )
    }

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

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

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

    private var inputBadgeLabel: String {
        String(
            localized: "chargers.badge.input",
            bundle: .main,
            comment: "Label for input voltage badges"
        )
    }

    private var outputBadgeLabel: String {
        String(
            localized: "chargers.badge.output",
            bundle: .main,
            comment: "Label for output voltage badges"
        )
    }

    private var currentBadgeLabel: String {
        String(
            localized: "chargers.badge.current",
            bundle: .main,
            comment: "Label for charging current badges"
        )
    }

    private var powerBadgeLabel: String {
        String(
            localized: "chargers.badge.power",
            bundle: .main,
            comment: "Label for charging power badges"
        )
    }

    private var wattButtonTitle: String {
        String(
            localized: "slider.button.watt",
            bundle: .main,
            comment: "Button label when switching to power entry mode"
        )
    }

    private var ampButtonTitle: String {
        String(
            localized: "slider.button.ampere",
            bundle: .main,
            comment: "Button label when switching to current entry mode"
        )
    }

    private var inputVoltageAlertTitle: String {
        String(
            localized: "charger.editor.alert.input_voltage.title",
            defaultValue: "Edit Input Voltage"
        )
    }

    private var outputVoltageAlertTitle: String {
        String(
            localized: "charger.editor.alert.output_voltage.title",
            defaultValue: "Edit Output Voltage"
        )
    }

    private var currentAlertTitle: String {
        String(
            localized: "charger.editor.alert.current.title",
            defaultValue: "Edit Charge Current"
        )
    }

    private var powerAlertTitle: String {
        String(
            localized: "charger.editor.alert.power.title",
            defaultValue: "Edit Charge Power"
        )
    }

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

    private var alertMessagePower: String {
        String(
            localized: "charger.editor.alert.power.message",
            defaultValue: "Enter power in watts (W)"
        )
    }

    private var alertMessageCurrent: String {
        String(
            localized: "charger.editor.alert.current.message",
            defaultValue: "Enter current in amps (A)"
        )
    }

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

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

    private var powerAlertPlaceholder: String {
        String(
            localized: "charger.editor.alert.power.placeholder",
            defaultValue: "Power"
        )
    }

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

    private var displayName: String {
        configuration.name.isEmpty ? namePlaceholder : configuration.name
    }

    private var inputVoltageSliderRange: ClosedRange<Double> {
        let lowerBound = max(0, min(12, configuration.inputVoltage))
        let upperBound = max(300, configuration.inputVoltage)
        return lowerBound...upperBound
    }

    private var outputVoltageSliderRange: ClosedRange<Double> {
        let lowerBound = max(0, min(10, configuration.outputVoltage))
        let upperBound = max(80, configuration.outputVoltage)
        return lowerBound...upperBound
    }

    private var currentSliderRange: ClosedRange<Double> {
        let lowerBound = max(0, min(5, configuration.maxCurrentAmps))
        let upperBound = max(200, configuration.maxCurrentAmps)
        return lowerBound...upperBound
    }

    private var powerSliderRange: ClosedRange<Double> {
        let effectivePower = configuration.effectivePowerWatts
        let upperBound = max(3000, max(configuration.maxPowerWatts, effectivePower))
        return 0...upperBound
    }

    init(configuration: ChargerConfiguration, onSave: @escaping (ChargerConfiguration) -> Void) {
        var adjustedConfiguration = configuration
        if configuration.maxPowerWatts > 0 {
            let voltage = max(configuration.outputVoltage, 0.1)
            let derivedCurrent = configuration.maxPowerWatts / voltage
            let roundedCurrent = max(0, (derivedCurrent * 10).rounded() / 10)
            adjustedConfiguration.maxCurrentAmps = roundedCurrent
        }
        _configuration = State(initialValue: adjustedConfiguration)
        _powerEntryMode = State(initialValue: adjustedConfiguration.maxPowerWatts > 0 ? .power : .current)
        let initialPowerCandidate = adjustedConfiguration.maxPowerWatts > 0
            ? adjustedConfiguration.maxPowerWatts
            : max(0, adjustedConfiguration.outputVoltage * adjustedConfiguration.maxCurrentAmps)
        let roundedInitialPower = max(0, (initialPowerCandidate / 5).rounded() * 5)
        let snapValues = [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]
        let closestSnap = snapValues.min { abs($0 - roundedInitialPower) < abs($1 - roundedInitialPower) }
        let normalizedInitialPower: Double
        if let closestSnap, abs(closestSnap - roundedInitialPower) <= 25.0 {
            normalizedInitialPower = closestSnap
        } else {
            normalizedInitialPower = roundedInitialPower
        }
        _lastManualPowerWatts = State(initialValue: normalizedInitialPower)
        self.onSave = onSave
    }

    var body: some View {
        VStack(spacing: 0) {
            headerInfoBar
            List {
                powerSourceSection
                electricalSection
                chargingSection
            }
            .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: chargerIconOptions,
                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(
            inputVoltageAlertTitle,
            isPresented: Binding(
                get: { editingField == .inputVoltage },
                set: { isPresented in
                    if !isPresented {
                        editingField = nil
                        inputVoltageInput = ""
                    }
                }
            )
        ) {
            TextField(
                inputVoltageLabel,
                text: $inputVoltageInput
            )
            .keyboardType(.decimalPad)
            .onAppear {
                if inputVoltageInput.isEmpty {
                    inputVoltageInput = formattedEditValue(configuration.inputVoltage)
                }
            }
            .onChange(of: inputVoltageInput) { _, newValue in
                guard editingField == .inputVoltage, let parsed = parseInput(newValue) else { return }
                configuration.inputVoltage = roundToTenth(parsed)
            }

            Button(alertCancelTitle, role: .cancel) {
                editingField = nil
                inputVoltageInput = ""
            }

            Button(alertSaveTitle) {
                if let parsed = parseInput(inputVoltageInput) {
                    configuration.inputVoltage = roundToTenth(parsed)
                }
                editingField = nil
                inputVoltageInput = ""
            }
        } message: {
            Text(alertMessageVoltage)
        }
        .alert(
            outputVoltageAlertTitle,
            isPresented: Binding(
                get: { editingField == .outputVoltage },
                set: { isPresented in
                    if !isPresented {
                        editingField = nil
                        outputVoltageInput = ""
                    }
                }
            )
        ) {
            TextField(
                outputVoltageLabel,
                text: $outputVoltageInput
            )
            .keyboardType(.decimalPad)
            .onAppear {
                if outputVoltageInput.isEmpty {
                    outputVoltageInput = formattedEditValue(configuration.outputVoltage)
                }
            }
            .onChange(of: outputVoltageInput) { _, newValue in
                guard editingField == .outputVoltage, let parsed = parseInput(newValue) else { return }
                configuration.outputVoltage = roundToTenth(parsed)
                if powerEntryMode == .power {
                    synchronizeCurrentWithPower()
                } else {
                    updatePowerFromCurrent()
                }
            }

            Button(alertCancelTitle, role: .cancel) {
                editingField = nil
                outputVoltageInput = ""
            }

            Button(alertSaveTitle) {
                if let parsed = parseInput(outputVoltageInput) {
                    configuration.outputVoltage = roundToTenth(parsed)
                    if powerEntryMode == .power {
                        synchronizeCurrentWithPower()
                    } else {
                        updatePowerFromCurrent()
                    }
                }
                editingField = nil
                outputVoltageInput = ""
            }
        } message: {
            Text(alertMessageVoltage)
        }
        .alert(
            currentAlertTitle,
            isPresented: Binding(
                get: { editingField == .current },
                set: { isPresented in
                    if !isPresented {
                        editingField = nil
                        currentInput = ""
                    }
                }
            )
        ) {
            TextField(
                currentLabel,
                text: $currentInput
            )
            .keyboardType(.decimalPad)
            .onAppear {
                if currentInput.isEmpty {
                    currentInput = formattedEditValue(configuration.maxCurrentAmps)
                }
            }
            .onChange(of: currentInput) { _, newValue in
                guard editingField == .current, let parsed = parseInput(newValue) else { return }
                configuration.maxCurrentAmps = roundToTenth(parsed)
                configuration.maxPowerWatts = 0
                updatePowerFromCurrent()
            }

            Button(alertCancelTitle, role: .cancel) {
                editingField = nil
                currentInput = ""
            }

            Button(alertSaveTitle) {
                if let parsed = parseInput(currentInput) {
                    configuration.maxCurrentAmps = roundToTenth(parsed)
                    configuration.maxPowerWatts = 0
                    updatePowerFromCurrent()
                }
                editingField = nil
                currentInput = ""
            }
        } message: {
            Text(alertMessageCurrent)
        }
        .alert(
            powerAlertTitle,
            isPresented: Binding(
                get: { editingField == .power },
                set: { isPresented in
                    if !isPresented {
                        editingField = nil
                        powerInput = ""
                    }
                }
            )
        ) {
            TextField(
                powerAlertPlaceholder,
                text: $powerInput
            )
            .keyboardType(.decimalPad)
            .onAppear {
                if powerInput.isEmpty {
                    powerInput = formattedPowerEditValue(displayedPowerValue)
                }
            }
            .onChange(of: powerInput) { _, newValue in
                guard editingField == .power, let parsed = parseInput(newValue) else { return }
                let normalized = normalizedPower(for: parsed)
                configuration.maxPowerWatts = normalized
                lastManualPowerWatts = normalized
                synchronizeCurrentWithPower()
            }

            Button(alertCancelTitle, role: .cancel) {
                editingField = nil
                powerInput = ""
            }

            Button(alertSaveTitle) {
                if let parsed = parseInput(powerInput) {
                    let normalized = normalizedPower(for: parsed)
                    configuration.maxPowerWatts = normalized
                    lastManualPowerWatts = normalized
                    powerEntryMode = .power
                    synchronizeCurrentWithPower()
                }
                editingField = nil
                powerInput = ""
            }
        } message: {
            Text(alertMessagePower)
        }
    }

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

    private var powerSourceSection: some View {
        Section {
            Picker(
                String(localized: "charger.editor.source.type", defaultValue: "Power Source"),
                selection: $configuration.powerSourceType
            ) {
                ForEach(SavedCharger.PowerSourceType.allCases) { type in
                    Label(type.displayName, systemImage: type.iconName)
                        .tag(type)
                }
            }
            .pickerStyle(.menu)
        }
    }

    private var electricalSection: some View {
        Section {
            SliderSection(
                title: inputVoltageLabel,
                value: Binding(
                    get: { configuration.inputVoltage },
                    set: { newValue in
                        if editingField == .inputVoltage {
                            configuration.inputVoltage = roundToTenth(newValue)
                        } else {
                            configuration.inputVoltage = normalizedInputVoltage(for: newValue)
                        }
                    }
                ),
                range: inputVoltageSliderRange,
                unit: "V",
                tapAction: beginInputVoltageEditing,
                snapValues: editingField == .inputVoltage ? nil : inputVoltageSnapValues
            )
            .listRowSeparator(.hidden)

            SliderSection(
                title: outputVoltageLabel,
                value: Binding(
                    get: { configuration.outputVoltage },
                    set: { newValue in
                        if editingField == .outputVoltage {
                            configuration.outputVoltage = roundToTenth(newValue)
                        } else {
                            configuration.outputVoltage = normalizedOutputVoltage(for: newValue)
                        }
                        if powerEntryMode == .power {
                            synchronizeCurrentWithPower()
                        } else {
                            updatePowerFromCurrent()
                        }
                    }
                ),
                range: outputVoltageSliderRange,
                unit: "V",
                tapAction: beginOutputVoltageEditing,
                snapValues: editingField == .outputVoltage ? nil : outputVoltageSnapValues
            )
            .listRowSeparator(.hidden)
        }
        .listRowBackground(Color(.systemBackground))
        .listRowInsets(EdgeInsets(top: 12, leading: 18, bottom: 12, trailing: 18))
    }

    private var chargingSection: some View {
        Section {
            if powerEntryMode == .power {
                VStack(alignment: .leading, spacing: 12) {
                    SliderSection(
                        title: powerLabel,
                        value: Binding(
                            get: { displayedPowerValue },
                            set: { newValue in
                                let normalized = editingField == .power ? roundToNearestFive(newValue) : normalizedPower(for: newValue)
                                configuration.maxPowerWatts = normalized
                                lastManualPowerWatts = normalized
                                synchronizeCurrentWithPower()
                            }
                        ),
                        range: powerSliderRange,
                        unit: "W",
                        buttonText: ampButtonTitle,
                        buttonAction: switchToCurrentMode,
                        tapAction: beginPowerEditing,
                        snapValues: editingField == .power ? nil : powerSnapValues
                    )

                }
                .listRowSeparator(.hidden)
            } else {
                SliderSection(
                    title: currentLabel,
                    value: Binding(
                        get: { configuration.maxCurrentAmps },
                        set: { newValue in
                            if editingField == .current {
                                configuration.maxCurrentAmps = roundToTenth(newValue)
                            } else {
                                configuration.maxCurrentAmps = normalizedCurrent(for: newValue)
                            }
                            configuration.maxPowerWatts = 0
                            updatePowerFromCurrent()
                        }
                    ),
                    range: currentSliderRange,
                    unit: "A",
                    buttonText: wattButtonTitle,
                    buttonAction: switchToPowerMode,
                    tapAction: beginCurrentEditing,
                    snapValues: editingField == .current ? nil : currentSnapValues
                )
                .listRowSeparator(.hidden)
            }
        }
        .listRowBackground(Color(.systemBackground))
        .listRowInsets(EdgeInsets(top: 12, leading: 18, bottom: 12, trailing: 18))
    }

    private var headerInfoBar: some View {
        VStack(spacing: 0) {
            ScrollView(.horizontal, showsIndicators: false) {
                HStack(spacing: 12) {
                    overviewChip(
                        icon: "powerplug",
                        title: inputBadgeLabel.uppercased(),
                        value: formattedVoltage(configuration.inputVoltage),
                        tint: .indigo
                    )

                    overviewChip(
                        icon: "bolt.fill",
                        title: outputBadgeLabel.uppercased(),
                        value: formattedVoltage(configuration.outputVoltage),
                        tint: .green
                    )

                    overviewChip(
                        icon: "gauge.medium",
                        title: currentBadgeLabel.uppercased(),
                        value: formattedCurrent(configuration.maxCurrentAmps),
                        tint: .orange
                    )

                    overviewChip(
                        icon: "bolt.circle",
                        title: powerBadgeLabel.uppercased(),
                        value: formattedPower(configuration.effectivePowerWatts),
                        tint: .pink
                    )
                }
                .padding(.horizontal, 18)
            }
            .scrollClipDisabled(true)
        }
        .padding(.vertical, 14)
        .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 var displayedPowerValue: Double {
        if configuration.maxPowerWatts > 0 {
            return configuration.maxPowerWatts
        }
        if lastManualPowerWatts > 0 {
            return lastManualPowerWatts
        }
        return max(0, configuration.outputVoltage * configuration.maxCurrentAmps)
    }

    private func switchToPowerMode() {
        if configuration.maxPowerWatts <= 0 {
            let candidate = lastManualPowerWatts > 0 ? lastManualPowerWatts : configuration.outputVoltage * configuration.maxCurrentAmps
            let normalized = normalizedPower(for: candidate)
            configuration.maxPowerWatts = normalized
            lastManualPowerWatts = normalized
        } else {
            lastManualPowerWatts = configuration.maxPowerWatts
        }
        powerEntryMode = .power
        synchronizeCurrentWithPower()
    }

    private func switchToCurrentMode() {
        if configuration.maxPowerWatts > 0 {
            lastManualPowerWatts = configuration.maxPowerWatts
        }
        configuration.maxPowerWatts = 0
        powerEntryMode = .current
        updatePowerFromCurrent()
    }

    private func synchronizeCurrentWithPower() {
        guard powerEntryMode == .power else { return }
        guard configuration.maxPowerWatts > 0 else {
            configuration.maxCurrentAmps = 0
            return
        }
        let voltage = max(configuration.outputVoltage, 0.1)
        let derivedCurrent = configuration.maxPowerWatts / voltage
        configuration.maxCurrentAmps = roundToTenth(derivedCurrent)
    }

    private func updatePowerFromCurrent() {
        let derivedPower = configuration.outputVoltage * configuration.maxCurrentAmps
        lastManualPowerWatts = normalizedPower(for: derivedPower)
    }

    private func normalizedInputVoltage(for value: Double) -> Double {
        let rounded = roundToTenth(value)
        if let snapped = nearestValue(to: rounded, in: inputVoltageSnapValues, tolerance: inputVoltageSnapTolerance) {
            return snapped
        }
        return rounded
    }

    private func normalizedOutputVoltage(for value: Double) -> Double {
        let rounded = roundToTenth(value)
        if let snapped = nearestValue(to: rounded, in: outputVoltageSnapValues, tolerance: outputVoltageSnapTolerance) {
            return snapped
        }
        return rounded
    }

    private func normalizedCurrent(for value: Double) -> Double {
        let rounded = roundToTenth(value)
        if let snapped = nearestValue(to: rounded, in: currentSnapValues, tolerance: currentSnapTolerance) {
            return snapped
        }
        return rounded
    }

    private func normalizedPower(for value: Double) -> Double {
        let rounded = roundToNearestFive(value)
        if let snapped = nearestValue(to: rounded, in: powerSnapValues, tolerance: powerSnapTolerance) {
            return snapped
        }
        return rounded
    }

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

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

    private func formattedEditValue(_ value: Double) -> String {
        Self.decimalFormatter.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.decimalFormatter.number(from: trimmed)?.doubleValue {
            return number
        }
        let decimalSeparator = Locale.current.decimalSeparator ?? "."
        let altSeparator = decimalSeparator == "." ? "," : "."
        let normalized = trimmed.replacingOccurrences(of: altSeparator, with: decimalSeparator)
        return Self.decimalFormatter.number(from: normalized)?.doubleValue
    }

    private func beginInputVoltageEditing() {
        inputVoltageInput = formattedEditValue(configuration.inputVoltage)
        editingField = .inputVoltage
    }

    private func beginOutputVoltageEditing() {
        outputVoltageInput = formattedEditValue(configuration.outputVoltage)
        editingField = .outputVoltage
    }

    private func beginCurrentEditing() {
        currentInput = formattedEditValue(configuration.maxCurrentAmps)
        editingField = .current
    }

    private func beginPowerEditing() {
        powerInput = formattedPowerEditValue(displayedPowerValue)
        editingField = .power
    }

    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 formattedVoltage(_ value: Double) -> String {
        let numberString = Self.decimalFormatter.string(from: NSNumber(value: value)) ?? String(format: "%.1f", value)
        return "\(numberString) V"
    }

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

    private func formattedPower(_ value: Double) -> String {
        guard value > 0 else { return "— W" }
        let numberString = Self.powerFormatter.string(from: NSNumber(value: value)) ?? String(format: "%.0f", value)
        return "\(numberString) W"
    }

    private func formattedPowerEditValue(_ value: Double) -> String {
        guard value > 0 else { return "" }
        return Self.powerFormatter.string(from: NSNumber(value: value)) ?? String(format: "%.0f", value)
    }

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

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

#Preview {
    let previewSystem = ElectricalSystem(name: "Camper")
    return NavigationStack {
        ChargerEditorView(
            configuration: ChargerConfiguration(
                name: "Workshop Charger",
                inputVoltage: 230,
                outputVoltage: 14.4,
                maxCurrentAmps: 40,
                maxPowerWatts: 580,
                iconName: "bolt.fill",
                colorName: "orange",
                system: previewSystem
            ),
            onSave: { _ in }
        )
    }
}
