import SwiftUI

struct BatteryEditorView: View {
    @Environment(\.dismiss) private var dismiss
    @State private var configuration: BatteryConfiguration
    @State private var editingField: EditingField?

    let onSave: (BatteryConfiguration) -> Void
    let onCancel: () -> Void

    private enum EditingField {
        case voltage
        case capacity
    }
    
    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 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 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"
        )
    }

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

    var body: some View {
        ScrollView {
            VStack(spacing: 24) {
                headerCard
                slidersSection
            }
            .padding(.vertical, 24)
            .padding(.horizontal)
        }
        .background(Color(.systemGroupedBackground).ignoresSafeArea())
        .navigationTitle(
            NSLocalizedString(
                "battery.editor.title",
                bundle: .main,
                value: "Battery Setup",
                comment: "Title for the battery editor"
            )
        )
        .navigationBarTitleDisplayMode(.inline)
        .toolbar {
            ToolbarItem(placement: .cancellationAction) {
                Button(
                    NSLocalizedString(
                        "battery.editor.cancel",
                        bundle: .main,
                        value: "Cancel",
                        comment: "Cancel button title"
                    )
                ) {
                    cancel()
                }
            }
            ToolbarItem(placement: .confirmationAction) {
                Button(
                    NSLocalizedString(
                        "battery.editor.save",
                        bundle: .main,
                        value: "Save",
                        comment: "Save button title"
                    )
                ) {
                    save()
                }
                .disabled(configuration.name.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty)
            }
        }
        .alert(
            NSLocalizedString(
                "battery.editor.alert.voltage.title",
                bundle: .main,
                value: "Edit Nominal Voltage",
                comment: "Title for the voltage edit alert"
            ),
            isPresented: Binding(
                get: { editingField == .voltage },
                set: { if !$0 { editingField = nil } }
            )
        ) {
            TextField(
                NSLocalizedString(
                    "battery.editor.alert.voltage.placeholder",
                    bundle: .main,
                    value: "Voltage",
                    comment: "Placeholder for voltage text field"
                ),
                value: $configuration.nominalVoltage,
                format: .number
            )
            .keyboardType(.decimalPad)

            Button(
                NSLocalizedString(
                    "battery.editor.alert.cancel",
                    bundle: .main,
                    value: "Cancel",
                    comment: "Cancel button title for edit alerts"
                ),
                role: .cancel
            ) { editingField = nil }

            Button(
                NSLocalizedString(
                    "battery.editor.alert.save",
                    bundle: .main,
                    value: "Save",
                    comment: "Save button title for edit alerts"
                )
            ) {
                editingField = nil
                let normalized = normalizedVoltage(for: configuration.nominalVoltage)
                if abs(normalized - configuration.nominalVoltage) > 0.000001 {
                    configuration.nominalVoltage = normalized
                }
            }
        } message: {
            Text(
                NSLocalizedString(
                    "battery.editor.alert.voltage.message",
                    bundle: .main,
                    value: "Enter voltage in volts (V)",
                    comment: "Message for the voltage edit alert"
                )
            )
        }
        .alert(
            NSLocalizedString(
                "battery.editor.alert.capacity.title",
                bundle: .main,
                value: "Edit Capacity",
                comment: "Title for the capacity edit alert"
            ),
            isPresented: Binding(
                get: { editingField == .capacity },
                set: { if !$0 { editingField = nil } }
            )
        ) {
            TextField(
                NSLocalizedString(
                    "battery.editor.alert.capacity.placeholder",
                    bundle: .main,
                    value: "Capacity",
                    comment: "Placeholder for capacity text field"
                ),
                value: $configuration.capacityAmpHours,
                format: .number
            )
            .keyboardType(.decimalPad)

            Button(
                NSLocalizedString(
                    "battery.editor.alert.cancel",
                    bundle: .main,
                    value: "Cancel",
                    comment: "Cancel button title for edit alerts"
                ),
                role: .cancel
            ) { editingField = nil }

            Button(
                NSLocalizedString(
                    "battery.editor.alert.save",
                    bundle: .main,
                    value: "Save",
                    comment: "Save button title for edit alerts"
                )
            ) {
                editingField = nil
                let normalized = normalizedCapacity(for: configuration.capacityAmpHours)
                if abs(normalized - configuration.capacityAmpHours) > 0.000001 {
                    configuration.capacityAmpHours = normalized
                }
            }
        } message: {
            Text(
                NSLocalizedString(
                    "battery.editor.alert.capacity.message",
                    bundle: .main,
                    value: "Enter capacity in amp-hours (Ah)",
                    comment: "Message for the capacity edit alert"
                )
            )
        }
    }

    private var headerCard: some View {
        VStack(alignment: .leading, spacing: 16) {
            VStack(alignment: .leading, spacing: 8) {
                Text(nameFieldLabel)
                    .font(.caption)
                    .foregroundStyle(.secondary)
                TextField(namePlaceholder, text: $configuration.name)
                    .textInputAutocapitalization(.words)
                    .padding(.vertical, 10)
                    .padding(.horizontal, 12)
                    .background(
                        RoundedRectangle(cornerRadius: 12, style: .continuous)
                            .fill(Color(.secondarySystemBackground))
                    )
            }

            VStack(alignment: .leading, spacing: 8) {
                Text(chemistryLabel)
                    .font(.caption)
                    .foregroundStyle(.secondary)
                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(.body.weight(.semibold))
                        Spacer()
                        Image(systemName: "chevron.down")
                            .font(.footnote.weight(.bold))
                            .foregroundStyle(.secondary)
                    }
                    .padding(.vertical, 10)
                    .padding(.horizontal, 12)
                    .background(
                        RoundedRectangle(cornerRadius: 12, style: .continuous)
                            .fill(Color(.secondarySystemBackground))
                    )
                }
                .buttonStyle(.plain)
            }

            VStack(alignment: .leading, spacing: 6) {
                Text(summaryLabel)
                    .font(.caption)
                    .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(20)
        .background(
            RoundedRectangle(cornerRadius: 20, style: .continuous)
                .fill(Color(.tertiarySystemBackground))
        )
    }

    private var slidersSection: some View {
        VStack(spacing: 30) {
            SliderSection(
                title: sliderVoltageTitle,
                value: $configuration.nominalVoltage,
                range: 6...60,
                unit: "V",
                tapAction: { editingField = .voltage },
                snapValues: voltageSnapValues
            )
            .onChange(of: configuration.nominalVoltage) { _, newValue in
                let normalized = normalizedVoltage(for: newValue)
                if abs(normalized - newValue) > 0.000001 {
                    configuration.nominalVoltage = normalized
                }
            }

            SliderSection(
                title: sliderCapacityTitle,
                value: $configuration.capacityAmpHours,
                range: 5...1000,
                unit: "Ah",
                tapAction: { editingField = .capacity },
                snapValues: capacitySnapValues
            )
            .onChange(of: configuration.capacityAmpHours) { _, newValue in
                let normalized = normalizedCapacity(for: newValue)
                if abs(normalized - newValue) > 0.000001 {
                    configuration.capacityAmpHours = normalized
                }
            }
        }
        .padding()
        .background(
            RoundedRectangle(cornerRadius: 20, style: .continuous)
                .fill(Color(.secondarySystemBackground))
        )
    }

    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 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 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.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 save() {
        onSave(configuration)
        dismiss()
    }

    private func cancel() {
        onCancel()
        dismiss()
    }
}

#Preview {
    let previewSystem = ElectricalSystem(name: "Camper")
    return NavigationStack {
        BatteryEditorView(
            configuration: BatteryConfiguration(name: "House Bank", system: previewSystem),
            onSave: { _ in },
            onCancel: {}
        )
    }
}
