import SwiftUI
import SwiftData

struct SystemOverviewView: View {
    @Environment(\.dismiss) private var dismiss
    @Environment(\.modelContext) private var modelContext
    @State private var activeStatus: LoadConfigurationStatus?
    @State private var suppressLoadNavigation = false
    @State private var showingRuntimeGoalEditor = false
    @State private var showingChargeGoalEditor = false
    @State private var runtimeGoalDraftHours: Double = 4
    @State private var chargeGoalDraftHours: Double = 4
    let system: ElectricalSystem
    let loads: [SavedLoad]
    let batteries: [SavedBattery]
    let chargers: [SavedCharger]
    let onSelectLoads: () -> Void
    let onSelectBatteries: () -> Void
    let onSelectChargers: () -> Void
    let onCreateLoad: () -> Void
    let onBrowseLibrary: () -> Void
    let onShowBillOfMaterials: () -> Void
    let onCreateBattery: () -> Void
    let onCreateCharger: () -> Void

    var body: some View {
        VStack(spacing: 0) {

                    if #available(iOS 26.0, *) {
                        ScrollView {
                            VStack(spacing: 16) {
                                loadsCard
                                batteriesCard
                                chargersCard
                            }
                            .padding(.horizontal, 16)
                            .padding(.bottom, 20)
                        }
                        // let the content slide under the top inset
                        // choose the Liquid Glass-friendly edge style
                        .scrollEdgeEffectStyle(.soft, for: .top)

                        // pin the Liquid Glass system card at the top safe area
                        .safeAreaInset(edge: .top, spacing: 0) {
                            systemCard
                                // Liquid Glass on custom view
                                .glassEffect(.regular, in: .rect(cornerRadius: 20))
                                .padding(.horizontal, 16)
                                .padding(.top, 12)
                                .padding(.bottom, 12)
                        }
                    } else {
                        ScrollView {
                            VStack(spacing: 16) {
                                loadsCard
                                batteriesCard
                                chargersCard
                            }
                            .padding(.horizontal, 16)
                            .padding(.bottom, 20)
                        }
                        // Don’t ignore the safe area — we want content to sit below the header
                        .safeAreaInset(edge: .top, spacing: 0) {
                            systemCard
                                .padding(.horizontal, 16)
                                .padding(.top, 20)
                                .padding(.bottom, 16)
                                .background(Color(.systemGroupedBackground)
                                )
                                .overlay(
                                    RoundedRectangle(cornerRadius: 20, style: .continuous)
                                        .strokeBorder(.white.opacity(0.15))
                                )
                        }
                    }

        }
        .frame(maxWidth: .infinity, maxHeight: .infinity)
        .background(Color(.systemGroupedBackground))
        .sheet(isPresented: $showingRuntimeGoalEditor) {
            GoalEditorSheet(
                title: runtimeGoalSheetTitle,
                tint: .orange,
                value: $runtimeGoalDraftHours,
                minimum: Self.minimumGoalHours,
                maximum: Self.maximumGoalHours,
                step: Self.goalStepHours,
                cancelTitle: goalCancelTitle,
                saveTitle: goalSaveTitle,
                clearTitle: goalClearTitle,
                showsClear: system.targetRuntimeHours != nil,
                formattedDurationProvider: { formattedDuration(hours: $0) },
                onSave: { saveRuntimeGoal(hours: $0) },
                onClear: system.targetRuntimeHours != nil ? { clearRuntimeGoal() } : nil
            )
        }
        .sheet(isPresented: $showingChargeGoalEditor) {
            GoalEditorSheet(
                title: chargeGoalSheetTitle,
                tint: .blue,
                value: $chargeGoalDraftHours,
                minimum: Self.minimumGoalHours,
                maximum: Self.maximumGoalHours,
                step: Self.goalStepHours,
                cancelTitle: goalCancelTitle,
                saveTitle: goalSaveTitle,
                clearTitle: goalClearTitle,
                showsClear: system.targetChargeTimeHours != nil,
                formattedDurationProvider: { formattedDuration(hours: $0) },
                onSave: { saveChargeGoal(hours: $0) },
                onClear: system.targetChargeTimeHours != nil ? { clearChargeGoal() } : nil
            )
        }
    }

    private var systemCard: some View {
        VStack(alignment: .leading, spacing: 18) {

            VStack(spacing: 14) {
                overviewMetricRow(
                    title: runtimeTitle,
                    subtitle: runtimeSubtitle,
                    icon: "clock.arrow.circlepath",
                    tint: .orange,
                    value: formattedRuntime,
                    placeholder: runtimePlaceholderSummary,
                    goal: runtimeGoalValueText,
                    actualHours: estimatedRuntimeHours,
                    goalHours: system.targetRuntimeHours,
                    progressFraction: nil,
                    hasValue: formattedRuntime != nil,
                    action: openRuntimeGoalEditor
                )

                overviewMetricRow(
                    title: chargeTimeTitle,
                    subtitle: chargeTimeSubtitle,
                    icon: "bolt.fill",
                    tint: .blue,
                    value: formattedChargeTime,
                    placeholder: chargeTimePlaceholderSummary,
                    goal: chargeGoalValueText,
                    actualHours: estimatedChargeHours,
                    goalHours: system.targetChargeTimeHours,
                    progressFraction: nil,
                    hasValue: formattedChargeTime != nil,
                    action: openChargeGoalEditor
                )
                
                overviewMetricRow(
                    title: bomTitle,
                    subtitle: bomSubtitle,
                    icon: "list.bullet.rectangle",
                    tint: .purple,
                    value: formattedBOMCompletedCount,
                    placeholder: bomPlaceholderSummary,
                    goal: formattedBOMTotalCount,
                    actualHours: nil,
                    goalHours: nil,
                    progressFraction: bomCompletionFraction,
                    hasValue: bomItemsCount > 0,
                    action: onShowBillOfMaterials,
                    accessibilityIdentifier: "system-bom-button"
                )


            }
            .padding(.top, 4)
        }
        .padding(.vertical, 18)
        .padding(.horizontal, 20)
        .frame(maxWidth: .infinity, alignment: .leading)
        .background(
            RoundedRectangle(cornerRadius: 20, style: .continuous)
                .stroke(Color(.separator).opacity(0.18), lineWidth: 1)
                .background(
                    RoundedRectangle(cornerRadius: 20, style: .continuous)
                        .fill(Color(red: 81/255, green: 144/255, blue: 152/255).opacity(0.12))
                )
        )
    }

    @ViewBuilder
    private func overviewMetricRow(
        title: String,
        subtitle: String?,
        icon: String,
        tint: Color,
        value: String?,
        placeholder: String?,
        goal: String?,
        actualHours: Double?,
        goalHours: Double?,
        progressFraction: Double?,
        hasValue: Bool,
        action: (() -> Void)? = nil,
        accessibilityIdentifier: String? = nil
    ) -> some View {
        let content = VStack(alignment: .leading, spacing: 10) {
            HStack(alignment: .center, spacing: 12) {
                RoundedRectangle(cornerRadius: 6, style: .continuous)
                    .fill(tint.opacity(0.18))
                    .frame(width: 24, height: 24)
                    .overlay {
                        Image(systemName: icon)
                            .font(.system(size: 11, weight: .semibold))
                            .foregroundStyle(tint)
                    }

                VStack(alignment: .leading, spacing: 2) {
                    Text(title)
                        .font(.subheadline.weight(.semibold))
                        .lineLimit(1)
                    if let subtitle {
                        Text(subtitle)
                            .font(.caption2)
                            .foregroundStyle(.secondary)
                            .lineLimit(1)
                    }
                }

                Spacer()

                VStack(alignment: .trailing, spacing: 2) {
                    Text(value ?? "—")
                        .font(.headline.weight(.semibold))
                        .foregroundStyle(hasValue ? Color.primary : Color.secondary)
                        .lineLimit(1)
                    if let goal {
                        Text("\(goalPrefix) \(goal)")
                            .font(.caption2)
                            .foregroundStyle(.secondary)
                            .lineLimit(1)
                    }
                }
            }

            progressBar(
                progress: adjustedProgress(for: progressFraction, actualHours: actualHours, goalHours: goalHours),
                tint: tint
            )
        }
        .padding(.vertical, 2)

        let paddedContent = content
            .padding(.horizontal, 4)
            .frame(maxWidth: .infinity, alignment: .leading)
            .contentShape(Rectangle())

        if let action {
            if let accessibilityIdentifier {
                Button(action: action) {
                    paddedContent
                }
                .buttonStyle(.plain)
                .accessibilityIdentifier(accessibilityIdentifier)
                .accessibilityLabel(title)
                .accessibilityAddTraits(.isButton)
                .contentShape(Rectangle())
            } else {
                Button(action: action) {
                    paddedContent
                }
                .buttonStyle(.plain)
                .accessibilityLabel(title)
                .accessibilityAddTraits(.isButton)
                .contentShape(Rectangle())
            }
        } else {
            paddedContent
        }
    }

    @ViewBuilder
    private var loadsCard: some View {
        if loads.isEmpty {
            VStack(alignment: .leading, spacing: 16) {
                HStack(alignment: .firstTextBaseline) {
                    Text(loadsSummaryTitle)
                        .font(.headline.weight(.semibold))
                    Spacer()
                }

                VStack(alignment: .leading, spacing: 8) {
                    Text(loadsEmptyTitle)
                        .font(.subheadline.weight(.semibold))
                    Text(loadsEmptyMessage)
                        .font(.footnote)
                        .foregroundStyle(.secondary)
                }

                VStack(alignment: .leading, spacing: 10) {
                    Button(action: onCreateLoad) {
                        Label(loadsEmptyCreateAction, systemImage: "plus")
                            .frame(maxWidth: .infinity)
                    }
                    .buttonStyle(.borderedProminent)
                    .controlSize(.large)

                    Button(action: onBrowseLibrary) {
                        Label(loadsEmptyBrowseAction, systemImage: "books.vertical")
                            .frame(maxWidth: .infinity)
                    }
                    .buttonStyle(.bordered)
                    .tint(.accentColor)
                    .controlSize(.large)
                }
            }
            .padding(.horizontal, 16)
            .padding(.vertical, 18)
            .frame(maxWidth: .infinity, alignment: .leading)
            .background(
                RoundedRectangle(cornerRadius: 20, style: .continuous)
                    .fill(Color(.tertiarySystemBackground))
            )
        } else {
            Button {
                if suppressLoadNavigation {
                    suppressLoadNavigation = false
                    return
                }
                onSelectLoads()
            } label: {
                VStack(alignment: .leading, spacing: 16) {
                    HStack(alignment: .firstTextBaseline) {
                        Text(loadsSummaryTitle)
                            .font(.headline.weight(.semibold))
                        Spacer()
                    }

                    ViewThatFits(in: .horizontal) {
                        HStack(spacing: 16) {
                            summaryMetric(
                                icon: "square.stack.3d.up",
                                label: loadsCountLabel,
                                value: "\(loads.count)",
                                tint: .blue
                            ).frame(maxWidth: .infinity, alignment: .leading)
                            summaryMetric(
                                icon: "bolt.fill",
                                label: loadsCurrentLabel,
                                value: formattedCurrent(totalCurrent),
                                tint: .orange
                            ).frame(maxWidth: .infinity, alignment: .leading)
                            summaryMetric(
                                icon: "gauge.medium",
                                label: loadsPowerLabel,
                                value: formattedPower(totalPower),
                                tint: .green
                            ).frame(maxWidth: .infinity, alignment: .leading)
                        }

                        VStack(alignment: .leading, spacing: 12) {
                            summaryMetric(
                                icon: "square.stack.3d.up",
                                label: loadsCountLabel,
                                value: "\(loads.count)",
                                tint: .blue
                            ).frame(maxWidth: .infinity, alignment: .leading)
                            summaryMetric(
                                icon: "bolt.fill",
                                label: loadsCurrentLabel,
                                value: formattedCurrent(totalCurrent),
                                tint: .orange
                            ).frame(maxWidth: .infinity, alignment: .leading)
                            summaryMetric(
                                icon: "gauge.medium",
                                label: loadsPowerLabel,
                                value: formattedPower(totalPower),
                                tint: .green
                            ).frame(maxWidth: .infinity, alignment: .leading)
                        }
                    }

                    if let status = loadStatus {
                        statusBanner(for: status)
                            .simultaneousGesture(
                                TapGesture().onEnded {
                                    suppressLoadNavigation = true
                                    activeStatus = status
                                }
                            )
                    }
                }
                .padding(.horizontal, 16)
                .padding(.vertical, 18)
                .frame(maxWidth: .infinity, alignment: .leading)
                .background(
                    RoundedRectangle(cornerRadius: 20, style: .continuous)
                        .fill(Color(.tertiarySystemBackground))
                )
            }
            .buttonStyle(.plain)
            .alert(item: $activeStatus) { status in
                let detail = status.detailInfo()
                return Alert(
                    title: Text(detail.title),
                    message: Text(detail.message),
                    dismissButton: .default(
                        Text(
                            String(
                                localized: "battery.bank.status.dismiss",
                                defaultValue: "Got it"
                            )
                        )
                    )
                )
            }
        }
    }

    private var batteriesCard: some View {
        Button(action: onSelectBatteries) {
            VStack(alignment: .leading, spacing: 16) {
                HStack(alignment: .center, spacing: 10) {
                    Text(batterySummaryTitle)
                        .font(.headline.weight(.semibold))
                    if let warning = batteryWarning {
                        HStack(spacing: 6) {
                            Image(systemName: warning.symbol)
                                .font(.system(size: 14, weight: .semibold))
                                .foregroundStyle(warning.tint)
                            Text(warning.shortLabel)
                                .font(.caption.weight(.semibold))
                                .foregroundStyle(warning.tint)
                        }
                        .padding(.horizontal, 10)
                        .padding(.vertical, 6)
                        .background(
                            RoundedRectangle(cornerRadius: 12, style: .continuous)
                                .fill(warning.tint.opacity(0.12))
                        )
                    }
                    Spacer()
                }

                if batteries.isEmpty {
                    VStack(alignment: .leading, spacing: 12) {
                        VStack(alignment: .leading, spacing: 4) {
                            Text(batteryEmptyTitle)
                                .font(.subheadline.weight(.semibold))
                            Text(batteryEmptySubtitle)
                                .font(.footnote)
                                .foregroundStyle(.secondary)
                                .fixedSize(horizontal: false, vertical: true)
                        }
                        Button(action: onCreateBattery) {
                            Label(batteryEmptyCreateAction, systemImage: "plus")
                                .frame(maxWidth: .infinity)
                        }
                        .buttonStyle(.borderedProminent)
                        .controlSize(.large)
                    }
                } else {
                    ViewThatFits(in: .horizontal) {
                        HStack(spacing: 16) {
                            batteryMetricsContent
                        }

                        LazyVGrid(
                            columns: Array(repeating: GridItem(.flexible(), spacing: 16), count: 2),
                            alignment: .leading,
                            spacing: 16
                        ) {
                            batteryMetricsContent
                        }

                        VStack(alignment: .leading, spacing: 12) {
                            batteryMetricsContent
                        }
                    }
                }
            }
            .padding(.horizontal, 16)
            .padding(.vertical, 18)
            .frame(maxWidth: .infinity, alignment: .leading)
            .background(
                RoundedRectangle(cornerRadius: 20, style: .continuous)
                    .fill(Color(.tertiarySystemBackground))
            )
        }
        .buttonStyle(.plain)
    }

    @ViewBuilder
    private var batteryMetricsContent: some View {
        summaryMetric(
            icon: "battery.100",
            label: batteryCountLabel,
            value: "\(batteries.count)",
            tint: .blue
        )
        summaryMetric(
            icon: "gauge.medium",
            label: batteryCapacityLabel,
            value: formattedValue(totalCapacity, unit: "Ah"),
            tint: .orange
        )
        summaryMetric(
            icon: "battery.100.bolt",
            label: batteryUsableCapacityLabel,
            value: formattedValue(totalUsableCapacity, unit: "Ah"),
            tint: .teal
        )
        summaryMetric(
            icon: "bolt.circle",
            label: batteryUsableEnergyLabel,
            value: formattedValue(totalUsableEnergy, unit: "Wh"),
            tint: .green
        )
    }

    private var chargersCard: some View {
        Button(action: onSelectChargers) {
            VStack(alignment: .leading, spacing: 16) {
                Text(chargerSummaryTitle)
                    .font(.headline.weight(.semibold))

                if chargers.isEmpty {
                    VStack(alignment: .leading, spacing: 12) {
                        VStack(alignment: .leading, spacing: 4) {
                            Text(chargerEmptyTitle)
                                .font(.subheadline.weight(.semibold))
                            Text(chargerEmptySubtitle)
                                .font(.footnote)
                                .foregroundStyle(.secondary)
                                .fixedSize(horizontal: false, vertical: true)
                        }

                        Button(action: onCreateCharger) {
                            Label(chargerEmptyCreateAction, systemImage: "plus")
                                .frame(maxWidth: .infinity)
                        }
                        .buttonStyle(.borderedProminent)
                        .controlSize(.large)
                    }
                } else {
                    ViewThatFits(in: .horizontal) {
                        HStack(spacing: 16) {
                            chargerMetricsContent
                        }

                        LazyVGrid(
                            columns: Array(repeating: GridItem(.flexible(), spacing: 16), count: 2),
                            alignment: .leading,
                            spacing: 16
                        ) {
                            chargerMetricsContent
                        }

                        VStack(alignment: .leading, spacing: 12) {
                            chargerMetricsContent
                        }
                    }
                }
            }
            .padding(.horizontal, 16)
            .padding(.vertical, 18)
            .frame(maxWidth: .infinity, alignment: .leading)
            .background(
                RoundedRectangle(cornerRadius: 20, style: .continuous)
                    .fill(Color(.tertiarySystemBackground))
            )
        }
        .buttonStyle(.plain)
    }

    @ViewBuilder
    private var chargerMetricsContent: some View {
        summaryMetric(
            icon: "bolt.fill",
            label: chargerCountLabel,
            value: "\(chargers.count)",
            tint: .blue
        ).frame(maxWidth: .infinity, alignment: .leading)
        summaryMetric(
            icon: "gauge.medium",
            label: chargerCurrentLabel,
            value: formattedCurrent(totalChargerCurrent),
            tint: .orange
        ).frame(maxWidth: .infinity, alignment: .leading)
        summaryMetric(
            icon: "bolt.circle",
            label: chargerPowerLabel,
            value: formattedPower(totalChargerPower),
            tint: .green
        ).frame(maxWidth: .infinity, alignment: .leading)
    }

    private var loadStatus: LoadConfigurationStatus? {
        guard !loads.isEmpty else { return nil }
        let incomplete = loads.filter { load in
            load.length <= 0 || load.crossSection <= 0
        }
        if !incomplete.isEmpty {
            return .missingDetails(count: incomplete.count)
        }
        return nil
    }

    private var totalCurrent: Double {
        loads.reduce(0) { result, load in
            result + max(load.current, 0)
        }
    }

    private var totalPower: Double {
        loads.reduce(0) { result, load in
            result + max(load.power, 0)
        }
    }

    private var totalAverageLoadPower: Double {
        loads.reduce(0) { result, load in
            let power = max(load.power, 0)
            guard power > 0 else { return result }
            let dutyCycleFraction = max(min(load.dutyCyclePercent, 100), 0) / 100
            let usageFraction = max(min(load.dailyUsageHours, 24), 0) / 24
            return result + power * dutyCycleFraction * usageFraction
        }
    }

    private var totalCapacity: Double {
        batteries.reduce(0) { result, battery in
            result + battery.capacityAmpHours
        }
    }

    private var totalEnergy: Double {
        batteries.reduce(0) { result, battery in
            result + battery.energyWattHours
        }
    }

    private var totalUsableCapacity: Double {
        batteries.reduce(0) { result, battery in
            result + battery.usableCapacityAmpHours
        }
    }

    private var totalUsableEnergy: Double {
        batteries.reduce(0) { result, battery in
            result + battery.usableEnergyWattHours
        }
    }

    private var totalChargerCurrent: Double {
        chargers.reduce(0) { result, charger in
            result + max(0, charger.maxCurrentAmps)
        }
    }

    private var totalChargerPower: Double {
        chargers.reduce(0) { result, charger in
            result + max(0, charger.effectivePowerWatts)
        }
    }

    private var representativeChargerOutput: Double? {
        let outputs = chargers.map { $0.outputVoltage }.filter { $0 > 0 }
        guard !outputs.isEmpty else { return nil }
        let total = outputs.reduce(0, +)
        return total / Double(outputs.count)
    }

    private var batteryWarning: BatteryWarning? {
        guard batteries.count > 1 else { return nil }

        if let targetVoltage = dominantValue(from: batteries.map { $0.nominalVoltage }, scale: 0.1) {
            let mismatched = batteries.filter { abs($0.nominalVoltage - targetVoltage) > 0.05 }
            if !mismatched.isEmpty {
                return .voltage(count: mismatched.count)
            }
        }

        if let targetCapacity = dominantValue(from: batteries.map { $0.capacityAmpHours }, scale: 1.0) {
            let mismatched = batteries.filter { abs($0.capacityAmpHours - targetCapacity) > 0.5 }
            if !mismatched.isEmpty {
                return .capacity(count: mismatched.count)
            }
        }

        return nil
    }

    private func dominantValue(from values: [Double], scale: Double) -> Double? {
        guard !values.isEmpty else { return nil }
        var counts: [Double: Int] = [:]
        var bestKey: Double?
        var bestCount = 0

        for value in values {
            let key = (value / scale).rounded() * scale
            let newCount = (counts[key] ?? 0) + 1
            counts[key] = newCount
            if newCount > bestCount {
                bestCount = newCount
                bestKey = key
            }
        }

        return bestKey
    }

    private func summaryMetric(icon: String, label: String, value: String, tint: Color) -> some View {
        VStack(alignment: .leading, spacing: 2) {
            HStack(spacing: 6) {
                Image(systemName: icon)
                    .font(.system(size: 14, weight: .semibold))
                    .foregroundStyle(tint)
                Text(value)
                    .font(.body.weight(.semibold))
            }
            Text(label.uppercased())
                .font(.caption2)
                .fontWeight(.medium)
                .foregroundStyle(.secondary)
        }
    }

    private func statusBanner(for status: LoadConfigurationStatus) -> some View {
        HStack(spacing: 10) {
            Image(systemName: status.symbol)
                .font(.system(size: 16, weight: .semibold))
                .foregroundStyle(status.tint)
            Text(status.bannerText)
                .font(.subheadline.weight(.semibold))
                .foregroundStyle(status.tint)
            Spacer()
        }
        .padding(.horizontal, 12)
        .padding(.vertical, 10)
        .background(
            RoundedRectangle(cornerRadius: 14, style: .continuous)
                .fill(status.tint.opacity(0.12))
        )
    }

    private var bomCompletionFraction: Double? {
        guard bomItemsCount > 0 else { return nil }
        return Double(completedBOMItemCount) / Double(bomItemsCount)
    }

    private var completedBOMItemCount: Int {
        let loadCount = settledLoads.reduce(0) { result, load in
            let uniqueItems = Set(load.bomCompletedItemIDs)
            let cappedCount = min(uniqueItems.count, Self.bomItemsPerLoad)
            return result + cappedCount
        }

        let batteryCount = settledBatteries.reduce(0) { result, battery in
            let uniqueItems = Set(battery.bomCompletedItemIDs)
            let cappedCount = min(uniqueItems.count, Self.bomItemsPerBattery)
            return result + cappedCount
        }

        let chargerCount = settledChargers.reduce(0) { result, charger in
            let uniqueItems = Set(charger.bomCompletedItemIDs)
            let cappedCount = min(uniqueItems.count, Self.bomItemsPerCharger)
            return result + cappedCount
        }

        return loadCount + batteryCount + chargerCount
    }

    private var bomItemsCount: Int {
        let loadItems = settledLoads.count * Self.bomItemsPerLoad
        let batteryItems = settledBatteries.count * Self.bomItemsPerBattery
        let chargerItems = settledChargers.count * Self.bomItemsPerCharger
        let total = loadItems + batteryItems + chargerItems
        return total
    }

    private var settledLoads: [SavedLoad] {
        loads.filter { $0.crossSection > 0 && $0.length > 0 }
    }

    private var settledBatteries: [SavedBattery] {
        batteries.filter { $0.system == system }
    }

    private var settledChargers: [SavedCharger] {
        chargers.filter { $0.system == system }
    }

    private func progressBar(progress: CGFloat?, tint: Color) -> some View {
        RoundedRectangle(cornerRadius: 3, style: .continuous)
            .fill(Color(.tertiarySystemFill))
            .frame(height: 4)
            .frame(maxWidth: .infinity)
            .overlay(alignment: .leading) {
                if let progress {
                    RoundedRectangle(cornerRadius: 3, style: .continuous)
                        .fill(tint)
                        .frame(maxWidth: .infinity)
                        .scaleEffect(x: max(min(progress, 1), 0), y: 1, anchor: .leading)
                        .animation(.easeInOut(duration: 0.25), value: progress)
                }
            }
    }

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

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

    private func numberString(for value: Double) -> String {
        Self.numberFormatter.string(from: NSNumber(value: value)) ?? String(format: "%.0f", value)
    }

    private func formattedChargerOutput(_ value: Double?) -> String {
        guard let value, value > 0 else { return "—" }
        return formattedValue(value, unit: "V")
    }

    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 progressFraction(actualHours: Double?, goalHours: Double?) -> CGFloat {
        guard let actualHours, let goalHours, goalHours > 0 else { return 0 }
        let ratio = actualHours / goalHours
        return CGFloat(max(min(ratio, 1), 0))
    }

    private func adjustedProgress(for explicit: Double?, actualHours: Double?, goalHours: Double?) -> CGFloat? {
        guard let ratio = progressRatio(explicitProgress: explicit, actualHours: actualHours, goalHours: goalHours) else { return nil }
        if explicit != nil { return ratio }
        guard let actual = actualHours, let goal = goalHours, goal > 0 else { return ratio }
        if goal == system.targetChargeTimeHours {
            let value = goal / max(actual, 0.0001)
            return CGFloat(max(min(value, 1), 0))
        }
        return ratio
    }

    private func progressRatio(explicitProgress: Double?, actualHours: Double?, goalHours: Double?) -> CGFloat? {
        if let explicitProgress {
            return CGFloat(max(min(explicitProgress, 1), 0))
        }

        guard goalHours != nil else { return nil }
        return progressFraction(actualHours: actualHours, goalHours: goalHours)
    }

    private var estimatedRuntimeHours: Double? {
        guard totalAverageLoadPower > 0, totalUsableEnergy > 0 else { return nil }
        let hours = totalUsableEnergy / totalAverageLoadPower
        return hours.isFinite && hours > 0 ? hours : nil
    }

    private var formattedRuntime: String? {
        guard let hours = estimatedRuntimeHours else { return nil }
        let seconds = hours * 3600
        if let formatted = Self.runtimeFormatter.string(from: seconds) {
            return formatted
        }
        let numberString = Self.numberFormatter.string(from: NSNumber(value: hours)) ?? String(format: "%.1f", hours)
        return "\(numberString) h"
    }
    
    private var formattedChargeTime: String? {
        guard let hours = estimatedChargeHours else { return nil }
        let seconds = hours * 3600
        if let formatted = Self.runtimeFormatter.string(from: seconds) {
            return formatted
        }
        let numberString = Self.numberFormatter.string(from: NSNumber(value: hours)) ?? String(format: "%.1f", hours)
        return "\(numberString) h"
    }

    private var estimatedChargeHours: Double? {
        guard totalUsableCapacity > 0, totalChargerCurrent > 0 else { return nil }
        let hours = totalUsableCapacity / totalChargerCurrent
        return hours.isFinite && hours > 0 ? hours : nil
    }

    private func openRuntimeGoalEditor() {
        runtimeGoalDraftHours = defaultGoalHours(current: system.targetRuntimeHours, fallback: estimatedRuntimeHours)
        showingRuntimeGoalEditor = true
    }

    private func openChargeGoalEditor() {
        chargeGoalDraftHours = defaultGoalHours(current: system.targetChargeTimeHours, fallback: estimatedChargeHours)
        showingChargeGoalEditor = true
    }

    private func saveRuntimeGoal(hours: Double) {
        let adjusted = clampedGoal(hours)
        system.targetRuntimeHours = adjusted
        runtimeGoalDraftHours = adjusted
        persistSystemChanges()
        showingRuntimeGoalEditor = false
    }

    private func saveChargeGoal(hours: Double) {
        let adjusted = clampedGoal(hours)
        system.targetChargeTimeHours = adjusted
        chargeGoalDraftHours = adjusted
        persistSystemChanges()
        showingChargeGoalEditor = false
    }

    private func clearRuntimeGoal() {
        system.targetRuntimeHours = nil
        persistSystemChanges()
        runtimeGoalDraftHours = defaultGoalHours(current: nil, fallback: estimatedRuntimeHours)
        showingRuntimeGoalEditor = false
    }

    private func clearChargeGoal() {
        system.targetChargeTimeHours = nil
        persistSystemChanges()
        chargeGoalDraftHours = defaultGoalHours(current: nil, fallback: estimatedChargeHours)
        showingChargeGoalEditor = false
    }

    private func persistSystemChanges() {
        guard modelContext.hasChanges else { return }

        do {
            try modelContext.save()
        } catch {
#if DEBUG
            print("Failed to save system goal: \(error.localizedDescription)")
#endif
        }
    }

    private func defaultGoalHours(current: Double?, fallback: Double?) -> Double {
        if let current, current >= Self.minimumGoalHours {
            return clampedGoal(current)
        }
        if let fallback, fallback >= Self.minimumGoalHours {
            return clampedGoal(fallback)
        }
        return Self.fallbackGoalHours
    }

    private func clampedGoal(_ hours: Double) -> Double {
        guard hours.isFinite else { return Self.fallbackGoalHours }
        let rounded = (hours / Self.goalStepHours).rounded() * Self.goalStepHours
        return min(max(rounded, Self.minimumGoalHours), Self.maximumGoalHours)
    }

    private func formattedDuration(hours: Double) -> String {
        let seconds = hours * 3600
        if let formatted = Self.runtimeFormatter.string(from: seconds) {
            return formatted
        }

        let numberString = Self.numberFormatter.string(from: NSNumber(value: hours)) ?? String(format: "%.1f", hours)
        return "\(numberString) h"
    }

    private var loadsSummaryTitle: String {
        String(localized: "loads.overview.header.title", defaultValue: "Load Overview")
    }

    private var loadsCountLabel: String {
        String(localized: "loads.overview.metric.count", defaultValue: "Loads")
    }

    private var loadsCurrentLabel: String {
        String(localized: "loads.overview.metric.current", defaultValue: "Total Current")
    }

    private var loadsPowerLabel: String {
        String(localized: "loads.overview.metric.power", defaultValue: "Total Power")
    }

    private var loadsEmptyTitle: String {
        String(localized: "overview.loads.empty.title", defaultValue: "No loads configured yet")
    }

    private var loadsEmptySubtitle: String {
        String(localized: "overview.loads.empty.subtitle", defaultValue: "Add components to get cable sizing and fuse recommendations tailored to this system.")
    }

    private var loadsEmptyMessage: String {
        String(localized: "loads.overview.empty.message", defaultValue: "Start by adding a load to see system insights.")
    }

    private var loadsEmptyCreateAction: String {
        String(localized: "loads.overview.empty.create", defaultValue: "Add Load")
    }

    private var loadsEmptyBrowseAction: String {
        String(localized: "loads.overview.empty.library", defaultValue: "Browse Library")
    }

    private var batterySummaryTitle: String {
        String(localized: "battery.bank.header.title", defaultValue: "Battery Bank")
    }

    private var batteryCountLabel: String {
        String(localized: "battery.bank.metric.count", defaultValue: "Batteries")
    }

    private var batteryCapacityLabel: String {
        String(localized: "battery.bank.metric.capacity", defaultValue: "Capacity")
    }

    private var batteryUsableCapacityLabel: String {
        String(localized: "battery.bank.metric.usable_capacity", defaultValue: "Usable Capacity")
    }

    private var batteryUsableEnergyLabel: String {
        String(localized: "battery.bank.metric.usable_energy", defaultValue: "Usable Energy")
    }

    private var batteryEmptyTitle: String {
        String(localized: "battery.bank.empty.title", defaultValue: "No Batteries Yet")
    }

    private var batteryEmptySubtitle: String {
        let format = String(
            localized: "battery.bank.empty.subtitle",
            defaultValue: "Tap the plus button to configure a battery for %@."
        )
        return String(format: format, system.name)
    }

    private var batteryEmptyCreateAction: String {
        String(localized: "battery.overview.empty.create", defaultValue: "Add Battery")
    }

    private var chargerSummaryTitle: String {
        String(localized: "overview.chargers.header.title", defaultValue: "Charger Overview")
    }

    private var chargerCountLabel: String {
        String(localized: "chargers.summary.metric.count", defaultValue: "Chargers")
    }

    private var chargerOutputLabel: String {
        String(localized: "chargers.summary.metric.output", defaultValue: "Output Voltage")
    }

    private var chargerCurrentLabel: String {
        String(localized: "chargers.summary.metric.current", defaultValue: "Charge Rate")
    }

    private var chargerPowerLabel: String {
        String(localized: "chargers.summary.metric.power", defaultValue: "Charge Power")
    }

    private var chargerEmptyTitle: String {
        String(localized: "overview.chargers.empty.title", defaultValue: "No chargers configured yet")
    }

    private var chargerEmptySubtitle: String {
        String(localized: "overview.chargers.empty.subtitle", defaultValue: "Add shore power, DC-DC, or solar chargers to understand your charging capacity.")
    }

    private var chargerEmptyCreateAction: String {
        String(localized: "overview.chargers.empty.create", defaultValue: "Add Charger")
    }

    private var systemOverviewTitle: String {
        String(localized: "overview.system.header.title", defaultValue: "System Overview")
    }

    private var bomTitle: String {
        String(localized: "overview.bom.title", defaultValue: "Bill of Materials")
    }

    private var bomSubtitle: String {
        String(localized: "overview.bom.subtitle", defaultValue: "Tap to review components")
    }

    private var bomPlaceholderSummary: String {
        String(localized: "overview.bom.placeholder.short", defaultValue: "Add loads")
    }

    private var formattedBOMCompletedCount: String? {
        guard bomItemsCount > 0 else { return nil }
        return numberString(for: Double(completedBOMItemCount))
    }

    private var formattedBOMTotalCount: String? {
        guard bomItemsCount > 0 else { return nil }
        return numberString(for: Double(bomItemsCount))
    }

    private var chargeTimeTitle: String {
        String(localized: "overview.chargetime.title", defaultValue: "Estimated charge time")
    }

    private var chargeTimeSubtitle: String {
        String(localized: "overview.chargetime.subtitle", defaultValue: "At combined charge rate")
    }

    private var chargeTimePlaceholderSummary: String {
        String(localized: "overview.chargetime.placeholder.short", defaultValue: "Add chargers")
    }

    private var chargeGoalValueText: String? {
        formattedGoalValue(for: system.targetChargeTimeHours)
    }

    private var goalPrefix: String {
        String(localized: "overview.goal.prefix", defaultValue: "Goal")
    }

    private var runtimeTitle: String {
        String(localized: "overview.runtime.title", defaultValue: "Estimated runtime")
    }

    private var runtimeSubtitle: String {
        String(localized: "overview.runtime.subtitle", defaultValue: "At maximum load draw")
    }

    private var runtimePlaceholderSummary: String {
        String(localized: "overview.runtime.placeholder.short", defaultValue: "Add capacity")
    }

    private var runtimeGoalValueText: String? {
        formattedGoalValue(for: system.targetRuntimeHours)
    }

    private func formattedGoalValue(for hours: Double?) -> String? {
        guard let hours else { return nil }
        return formattedDuration(hours: hours)
    }

    private var runtimeGoalSheetTitle: String {
        String(localized: "overview.runtime.goal.title", defaultValue: "Runtime Goal")
    }

    private var chargeGoalSheetTitle: String {
        String(localized: "overview.chargetime.goal.title", defaultValue: "Charge Goal")
    }

    private var goalClearTitle: String {
        String(localized: "overview.goal.clear", defaultValue: "Remove Goal")
    }

    private var goalCancelTitle: String {
        String(localized: "overview.goal.cancel", defaultValue: "Cancel")
    }

    private var goalSaveTitle: String {
        String(localized: "overview.goal.save", defaultValue: "Save")
    }

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

    private static let runtimeFormatter: DateComponentsFormatter = {
        let formatter = DateComponentsFormatter()
        formatter.allowedUnits = [.day, .hour, .minute]
        formatter.unitsStyle = .abbreviated
        formatter.maximumUnitCount = 2
        return formatter
    }()

    private static let minimumGoalHours: Double = 0.5
    private static let maximumGoalHours: Double = 240
    private static let goalStepHours: Double = 0.25
    private static let fallbackGoalHours: Double = 4

    private static let bomItemsPerLoad = 5
    private static let bomItemsPerBattery = 1
    private static let bomItemsPerCharger = 1

    private enum BatteryWarning {
        case voltage(count: Int)
        case capacity(count: Int)

        var symbol: String {
            switch self {
            case .voltage:
                return "exclamationmark.triangle.fill"
            case .capacity:
                return "exclamationmark.circle.fill"
            }
        }

        var tint: Color {
            switch self {
            case .voltage:
                return .red
            case .capacity:
                return .orange
            }
        }

        var shortLabel: String {
            switch self {
            case .voltage:
                return String(localized: "battery.bank.warning.voltage.short", defaultValue: "Voltage")
            case .capacity:
                return String(localized: "battery.bank.warning.capacity.short", defaultValue: "Capacity")
            }
        }
    }

}

private struct GoalEditorSheet: View {
    let title: String
    let tint: Color
    @Binding var value: Double
    let minimum: Double
    let maximum: Double
    let step: Double
    let cancelTitle: String
    let saveTitle: String
    let clearTitle: String
    let showsClear: Bool
    let formattedDurationProvider: (Double) -> String
    let onSave: (Double) -> Void
    let onClear: (() -> Void)?

    @State private var days: Int
    @State private var hours: Int
    @State private var minutes: Int
    private let minuteStepValues: [Int]

    @Environment(\.dismiss) private var dismiss

    init(
        title: String,
        tint: Color,
        value: Binding<Double>,
        minimum: Double,
        maximum: Double,
        step: Double,
        cancelTitle: String,
        saveTitle: String,
        clearTitle: String,
        showsClear: Bool,
        formattedDurationProvider: @escaping (Double) -> String,
        onSave: @escaping (Double) -> Void,
        onClear: (() -> Void)?
    ) {
        self.title = title
        self.tint = tint
        self._value = value
        self.minimum = minimum
        self.maximum = maximum
        self.step = step
        self.cancelTitle = cancelTitle
        self.saveTitle = saveTitle
        self.clearTitle = clearTitle
        self.showsClear = showsClear
        self.formattedDurationProvider = formattedDurationProvider
        self.onSave = onSave
        self.onClear = onClear
        self.minuteStepValues = GoalEditorSheet.minuteValues(forStep: step)

        let initialComponents = GoalEditorSheet.components(
            for: value.wrappedValue,
            minimum: minimum,
            maximum: maximum,
            minuteValues: self.minuteStepValues
        )
        _days = State(initialValue: initialComponents.days)
        _hours = State(initialValue: initialComponents.hours)
        _minutes = State(initialValue: initialComponents.minutes)
    }

    var body: some View {
        NavigationStack {
            Form {
                Section {
                    VStack(alignment: .leading, spacing: 16) {
                        Label {
                            Text(formattedDurationProvider(value))
                                .font(.title3.weight(.semibold))
                        } icon: {
                            Image(systemName: "flag.checkered")
                                .symbolRenderingMode(.hierarchical)
                                .foregroundStyle(tint)
                        }

                        HStack {
                            Picker("Days", selection: $days) {
                                ForEach(0...maxDays, id: \.self) { day in
                                    Text("\(day) day\(day == 1 ? "" : "s")")
                                        .tag(day)
                                }
                            }
                            .pickerStyle(.wheel)
                            .frame(maxWidth: .infinity)

                            Picker("Hours", selection: $hours) {
                                ForEach(hourRange, id: \.self) { hour in
                                    Text("\(hour) hr\(hour == 1 ? "" : "s")")
                                        .tag(hour)
                                }
                            }
                            .pickerStyle(.wheel)
                            .frame(maxWidth: .infinity)

                            Picker("Minutes", selection: $minutes) {
                                ForEach(minuteOptionsForSelection, id: \.self) { minute in
                                    Text("\(minute) min\(minute == 1 ? "" : "s")")
                                        .tag(minute)
                                }
                            }
                            .pickerStyle(.wheel)
                            .frame(maxWidth: .infinity)
                        }
                        .frame(height: 140)
                    }
                }

                if showsClear, let onClear {
                    Section {
                        Button(role: .destructive) {
                            onClear()
                            dismiss()
                        } label: {
                            Text(clearTitle)
                        }
                    }
                }
            }
            .tint(tint)
            .navigationTitle(title)
            .navigationBarTitleDisplayMode(.inline)
            .toolbar {
                ToolbarItem(placement: .cancellationAction) {
                    Button(cancelTitle) {
                        dismiss()
                    }
                }
                ToolbarItem(placement: .confirmationAction) {
                    Button(saveTitle) {
                        onSave(clampedValue)
                        dismiss()
                    }
                    .disabled(!value.isFinite || value < minimum)
                }
            }
        }
        .onChange(of: days) { _ in
            let cappedHours = min(hours, maxHours(for: days))
            if cappedHours != hours {
                hours = cappedHours
            }
            let allowedMinutes = minuteOptions(for: days, hours: hours)
            if !allowedMinutes.contains(minutes) {
                minutes = allowedMinutes.last ?? 0
            }
            updateValueFromSelection()
        }
        .onChange(of: hours) { _ in
            let allowedMinutes = minuteOptions(for: days, hours: hours)
            if !allowedMinutes.contains(minutes) {
                minutes = allowedMinutes.last ?? 0
            }
            updateValueFromSelection()
        }
        .onChange(of: minutes) { _ in
            updateValueFromSelection()
        }
        .onChange(of: value) { newValue in
            syncPickers(with: newValue)
        }
        .presentationDetents([.medium])
        .presentationDragIndicator(.visible)
    }

    private var maxDays: Int {
        max(0, Int(floor(maximum / 24)))
    }

    private var hourRange: ClosedRange<Int> {
        0...maxHours(for: days)
    }

    private var minuteOptionsForSelection: [Int] {
        minuteOptions(for: days, hours: hours)
    }

    private var clampedValue: Double {
        clamp(value)
    }

    private func maxHours(for days: Int) -> Int {
        GoalEditorSheet.maxHours(forDays: days, maximum: maximum)
    }

    private func minuteOptions(for days: Int, hours: Int) -> [Int] {
        GoalEditorSheet.allowedMinutes(
            forDays: days,
            hours: hours,
            maximum: maximum,
            minuteValues: minuteStepValues
        )
    }

    private func updateValueFromSelection() {
        let totalHours = Double(days * 24 + hours) + Double(minutes) / 60
        let clamped = clamp(totalHours)
        if abs(value - clamped) > .ulpOfOne {
            value = clamped
        }
    }

    private func syncPickers(with newValue: Double) {
        let clamped = clamp(newValue)
        let components = GoalEditorSheet.components(
            for: clamped,
            minimum: minimum,
            maximum: maximum,
            minuteValues: minuteStepValues
        )
        if components.days != days {
            days = components.days
        }
        if components.hours != hours {
            hours = components.hours
        }
        if components.minutes != minutes {
            minutes = components.minutes
        }
    }

    private func clamp(_ candidate: Double) -> Double {
        min(max(candidate, minimum), maximum)
    }

    private static func components(
        for value: Double,
        minimum: Double,
        maximum: Double,
        minuteValues: [Int]
    ) -> (days: Int, hours: Int, minutes: Int) {
        let clamped = min(max(value, minimum), maximum)
        let totalMinutes = Int((clamped * 60).rounded())
        let minutesPerDay = 24 * 60
        let maxDays = max(0, Int(floor(maximum / 24)))
        let rawDays = totalMinutes / minutesPerDay
        let days = min(rawDays, maxDays)
        let remainingAfterDays = totalMinutes - (days * minutesPerDay)
        let rawHours = remainingAfterDays / 60
        let maxHours = maxHours(forDays: days, maximum: maximum)
        let hours = min(rawHours, maxHours)
        let minuteRemainder = remainingAfterDays - hours * 60
        let allowedMinutes = allowedMinutes(
            forDays: days,
            hours: hours,
            maximum: maximum,
            minuteValues: minuteValues
        )
        let minutes = closestMinuteValue(
            target: minuteRemainder,
            allowedMinutes: allowedMinutes
        )
        return (days, hours, minutes)
    }

    private static func maxHours(forDays days: Int, maximum: Double) -> Int {
        let remaining = maximum - Double(days * 24)
        guard remaining > 0 else { return 0 }
        return min(23, max(0, Int(floor(remaining))))
    }

    private static func allowedMinutes(
        forDays days: Int,
        hours: Int,
        maximum: Double,
        minuteValues: [Int]
    ) -> [Int] {
        guard maximum > 0 else { return [0] }
        let usedHours = Double(days * 24 + hours)
        let remaining = maximum - usedHours
        guard remaining > 0 else { return [0] }

        let allowed = minuteValues.filter { minute in
            let additional = Double(minute) / 60
            return usedHours + additional <= maximum + 1e-6
        }
        return allowed.isEmpty ? [0] : allowed
    }

    private static func closestMinuteValue(target: Int, allowedMinutes: [Int]) -> Int {
        guard !allowedMinutes.isEmpty else { return 0 }
        let clampedTarget = max(0, min(59, target))
        return allowedMinutes.min(by: { abs($0 - clampedTarget) < abs($1 - clampedTarget) }) ?? 0
    }

    private static func minuteValues(forStep step: Double) -> [Int] {
        guard step > 0 else { return [0, 15, 30, 45] }
        let increment = max(1, Int(round(step * 60)))
        guard increment < 60 else { return [0] }

        var values: [Int] = []
        var current = 0
        while current < 60 {
            values.append(current)
            current += increment
        }
        return values.isEmpty ? [0] : values
    }
}

#Preview("SystemOverview – Populated") {
    let system = ElectricalSystem(
        name: "12V DC System",
        location: "Engine Room",
        iconName: "bolt.circle.fill",
        colorName: "blue",
        targetRuntimeHours: 24,
        targetChargeTimeHours: 3
    )
    //system.targetRuntimeHours = 8
    //system.targetChargeTimeHours = 6

    let loads: [SavedLoad] = [
        SavedLoad(
            name: "Navigation Lights",
            voltage: 12.8,
            current: 2.4,
            power: 28.8,
            length: 5.0,
            crossSection: 2.5
        ),
        SavedLoad(
            name: "Bilge Pump",
            voltage: 12.8,
            current: 8.0,
            power: 96.0,
            length: 3.0,
            crossSection: 4.0
        ),
        SavedLoad(
            name: "Chartplotter",
            voltage: 12.8,
            current: 1.5,
            power: 18.0,
            length: 2.0,
            crossSection: 1.5
        )
    ]

    let batteries: [SavedBattery] = [
        SavedBattery(
            name: "House AGM",
            nominalVoltage: 12.0,
            capacityAmpHours: 100.0
        ),
        SavedBattery(
            name: "Starter AGM",
            nominalVoltage: 12.0,
            capacityAmpHours: 100.0
        )
    ]

    let chargers: [SavedCharger] = [
        SavedCharger(
            name: "Shore Power",
            inputVoltage: 230,
            outputVoltage: 14.4,
            maxCurrentAmps: 40,
            maxPowerWatts: 580,
            iconName: "powerplug",
            colorName: "orange",
            system: system
        ),
        SavedCharger(
            name: "DC-DC Charger",
            inputVoltage: 12.8,
            outputVoltage: 14.2,
            maxCurrentAmps: 30,
            maxPowerWatts: 0,
            iconName: "bolt.circle",
            colorName: "blue",
            system: system
        )
    ]

    SystemOverviewView(
        system: system,
        loads: loads,
        batteries: batteries,
        chargers: chargers,
        onSelectLoads: {},
        onSelectBatteries: {},
        onSelectChargers: {},
        onCreateLoad: {},
        onBrowseLibrary: {},
        onShowBillOfMaterials: {},
        onCreateBattery: {},
        onCreateCharger: {}
    )
    .padding()
    .modelContainer(for: [ElectricalSystem.self, SavedLoad.self, SavedBattery.self, SavedCharger.self], inMemory: true)
}

#Preview("SystemOverview – Empty States") {
    let system = ElectricalSystem(
        name: "24V DC System",
        location: "Main Panel",
        iconName: "bolt.circle.fill",
        colorName: "green"
    )

    return SystemOverviewView(
        system: system,
        loads: [],
        batteries: [],
        chargers: [],
        onSelectLoads: {},
        onSelectBatteries: {},
        onSelectChargers: {},
        onCreateLoad: {},
        onBrowseLibrary: {},
        onShowBillOfMaterials: {},
        onCreateBattery: {},
        onCreateCharger: {}
    )
    .padding()
    .modelContainer(for: [ElectricalSystem.self, SavedLoad.self, SavedBattery.self, SavedCharger.self], inMemory: true)
}
