//
//  LoadsView.swift
//  Cable
//
//  Created by Stefan Lange-Hegermann on 09.10.25.
//


import SwiftUI
import SwiftData

struct LoadsView: View {
    @Environment(\.modelContext) private var modelContext
    @EnvironmentObject var unitSettings: UnitSystemSettings
    @Query(sort: \SavedLoad.timestamp, order: .reverse) private var allLoads: [SavedLoad]
    @Query(sort: \SavedBattery.timestamp, order: .reverse) private var allBatteries: [SavedBattery]
    @Query(sort: \SavedCharger.timestamp, order: .reverse) private var allChargers: [SavedCharger]
    @State private var newLoadToEdit: SavedLoad?
    @State private var showingSystemEditor = false
    @State private var hasPresentedSystemEditorOnAppear = false
    @State private var hasOpenedLoadOnAppear = false
    @State private var showingComponentLibrary = false
    @State private var showingSystemBOM = false
    @State private var selectedComponentTab: ComponentTab
    @State private var batteryDraft: BatteryConfiguration?
    @State private var chargerDraft: ChargerConfiguration?
    @State private var activeStatus: LoadConfigurationStatus?
    @State private var editMode: EditMode = .inactive
    @State private var overviewExportRequested = false
    @State private var diagramExportRequested = false
    @State private var isExportingOverview = false
    @State private var overviewShareItem: OverviewShareItem?
    @State private var overviewExportError: OverviewExportError?

    let system: ElectricalSystem
    private let presentSystemEditorOnAppear: Bool
    private let loadToOpenOnAppear: SavedLoad?
    
    init(system: ElectricalSystem, presentSystemEditorOnAppear: Bool = false, loadToOpenOnAppear: SavedLoad? = nil, initialTab: ComponentTab = .overview) {
        self.system = system
        self.presentSystemEditorOnAppear = presentSystemEditorOnAppear
        self.loadToOpenOnAppear = loadToOpenOnAppear
        self._selectedComponentTab = State(initialValue: initialTab)
    }
    
    private var savedLoads: [SavedLoad] {
        allLoads.filter { $0.system == system }
    }
    
    private var savedBatteries: [SavedBattery] {
        allBatteries.filter { $0.system == system }
    }

    private var savedChargers: [SavedCharger] {
        allChargers.filter { $0.system == system }
    }

    var body: some View {
        VStack(spacing: 0) {
            TabView(selection: $selectedComponentTab) {
                overviewTab
                    .tag(ComponentTab.overview)
                    .tabItem {
                        Label(
                            String(
                                localized: "tab.overview",
                                bundle: .main,
                                comment: "Tab title for system overview"
                            ),
                            systemImage: "rectangle.3.group"
                        )
                        .accessibilityIdentifier("overview-tab")
                    }

                componentsTab
                    .tag(ComponentTab.components)
                    .tabItem {
                        Label(
                            String(
                                localized: "tab.components",
                                bundle: .main,
                                comment: "Tab title for components list"
                            ),
                            systemImage: "square.stack.3d.up"
                        )
                        .accessibilityIdentifier("components-tab")
                    }

                Group {
                    if savedBatteries.isEmpty {
                        OnboardingInfoView(
                            configuration: .battery(),
                            onPrimaryAction: { startBatteryConfiguration() }
                        )
                    } else {
                        BatteriesView(
                            system: system,
                            batteries: savedBatteries,
                            editMode: $editMode,
                            onEdit: { editBattery($0) },
                            onDelete: deleteBatteries
                        )
                        .environment(\.editMode, $editMode)
                    }
                }
                .tag(ComponentTab.batteries)
                .tabItem {
                    Label(
                        String(
                            localized: "tab.batteries",
                            bundle: .main,
                            comment: "Tab title for battery configurations"
                        ),
                        systemImage: "battery.100"
                    )
                    .accessibilityIdentifier("batteries-tab")
                }
                .environment(\.editMode, $editMode)

                ChargersView(
                    system: system,
                    chargers: savedChargers,
                    editMode: $editMode,
                    onAdd: { startChargerConfiguration() },
                    onEdit: { editCharger($0) },
                    onDelete: deleteChargers
                )
                .tag(ComponentTab.chargers)
                .tabItem {
                    Label(
                        String(
                            localized: "tab.chargers",
                            bundle: .main,
                            comment: "Tab title for chargers view"
                        ),
                        systemImage: "bolt.fill"
                    )
                    .accessibilityIdentifier("chargers-tab")
                }
                .environment(\.editMode, $editMode)
            }
        }
        .navigationBarTitleDisplayMode(.inline)
        .toolbar {
            ToolbarItem(placement: .principal) {
                Button(action: {
                    presentSystemEditor(source: "toolbar")
                }) {
                    HStack(spacing: 8) {
                        ZStack {
                            RoundedRectangle(cornerRadius: 6)
                                .fill(Color.componentColor(named: system.colorName))
                                .frame(width: 24, height: 24)
                            
                            Image(systemName: system.iconName)
                                .font(.system(size: 12))
                                .foregroundColor(.white)
                        }
                        
                        Text(system.name)
                            .font(.headline)
                            .fontWeight(.semibold)
                            .foregroundColor(.primary)
                    }
                }
            }
            
            ToolbarItem(placement: .navigationBarTrailing) {
                let showPrimary = selectedComponentTab != .overview
                let showEditLoads = selectedComponentTab == .components && !savedLoads.isEmpty
                let showEditBatteries = selectedComponentTab == .batteries && !savedBatteries.isEmpty
                let showEditChargers = selectedComponentTab == .chargers && !savedChargers.isEmpty

                if selectedComponentTab == .overview {
                    if isExportingOverview {
                        ProgressView()
                            .progressViewStyle(.circular)
                    } else {
                        Menu {
                            Button {
                                diagramExportRequested = true
                            } label: {
                                Label(
                                    String(localized: "overview.share.diagram", defaultValue: "Wiring Diagram"),
                                    systemImage: "bolt.horizontal"
                                )
                            }
                            Button {
                                overviewExportRequested = true
                            } label: {
                                Label(
                                    String(localized: "overview.share.pdf", defaultValue: "Full Report (PDF)"),
                                    systemImage: "doc.richtext"
                                )
                            }
                        } label: {
                            Image(systemName: "square.and.arrow.up")
                        }
                        .accessibilityIdentifier("system-overview-share-button")
                    }
                } else if showPrimary || showEditLoads || showEditBatteries || showEditChargers {
                    HStack {
                        if showPrimary {
                            Button(action: {
                                handlePrimaryAction()
                            }) {
                                Image(systemName: "plus")
                            }
                        }
                        if showEditLoads {
                            EditButton()
                                .disabled(savedLoads.isEmpty)
                        } else if showEditBatteries {
                            EditButton()
                                .disabled(savedBatteries.isEmpty)
                        } else if showEditChargers {
                            EditButton()
                                .disabled(savedChargers.isEmpty)
                        }
                    }
                }
            }
        }
        .navigationDestination(item: $newLoadToEdit) { load in
            CalculatorView(savedLoad: load)
        }
        .navigationDestination(item: $batteryDraft) { draft in
            BatteryEditorView(
                configuration: draft,
                onSave: { configuration in
                    saveBattery(configuration)
                    batteryDraft = nil
                }
            )
        }
        .navigationDestination(item: $chargerDraft) { draft in
            ChargerEditorView(
                configuration: draft,
                onSave: { configuration in
                    saveCharger(configuration)
                    chargerDraft = nil
                }
            )
        }
        .sheet(item: $overviewShareItem, onDismiss: cleanupOverviewShareItem) { item in
            ShareSheet(items: item.shareItems)
        }
        .alert(
            String(localized: "overview.share.error.title", defaultValue: "Export Failed"),
            isPresented: Binding<Bool>(
                get: { overviewExportError != nil },
                set: { if !$0 { overviewExportError = nil } }
            )
        ) {
            Button(String(localized: "generic.ok", defaultValue: "OK")) {
                overviewExportError = nil
            }
        } message: {
            if let error = overviewExportError {
                Text(error.message)
            }
        }
        .onChange(of: overviewExportRequested) { _, requested in
            if requested {
                overviewExportRequested = false
                exportOverviewPDF()
            }
        }
        .onChange(of: diagramExportRequested) { _, requested in
            if requested {
                diagramExportRequested = false
                exportDiagramImage()
            }
        }
        .sheet(isPresented: $showingComponentLibrary) {
            ComponentLibraryView { item in
                addComponent(item)
            }
        }
        .sheet(isPresented: $showingSystemBOM) {
            SystemBillOfMaterialsView(
                systemName: system.name,
                loads: savedLoads,
                batteries: savedBatteries,
                chargers: savedChargers,
                unitSystem: unitSettings.unitSystem
            )
        }
        .sheet(isPresented: $showingSystemEditor) {
            SystemEditorView(
                systemName: Binding(
                    get: { system.name },
                    set: { system.name = $0 }
                ),
                location: Binding(
                    get: { system.location },
                    set: { system.location = $0 }
                ),
                iconName: Binding(
                    get: { system.iconName },
                    set: { system.iconName = $0 }
                ),
                colorName: Binding(
                    get: { system.colorName },
                    set: { system.colorName = $0 }
                )
            )
        }
        .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")
                    )
                )
            )
        }
        .onAppear {
            if presentSystemEditorOnAppear && !hasPresentedSystemEditorOnAppear {
                hasPresentedSystemEditorOnAppear = true
                DispatchQueue.main.async {
                    presentSystemEditor(source: "auto")
                }
            }

            if let loadToOpen = loadToOpenOnAppear, !hasOpenedLoadOnAppear {
                hasOpenedLoadOnAppear = true
                DispatchQueue.main.async {
                    AnalyticsTracker.log(
                        "Load Opened",
                        properties: [
                            "mode": loadToOpen.isWattMode ? "watt" : "amp",
                            "system": system.name
                        ]
                    )
                    newLoadToEdit = loadToOpen
                }
            }
        }
        .onChange(of: selectedComponentTab) { _, newValue in
            AnalyticsTracker.log("Tab Changed", properties: [
                "tab": "\(newValue)",
                "system": system.name,
            ])
            if newValue == .chargers || newValue == .overview {
                editMode = .inactive
            }
        }
        .environment(\.editMode, $editMode)
    }
    
    private var overviewTab: some View {
        SystemOverviewView(
            system: system,
            loads: savedLoads,
            batteries: savedBatteries,
            chargers: savedChargers,
            onSelectLoads: { selectedComponentTab = .components },
            onSelectBatteries: { selectedComponentTab = .batteries },
            onSelectChargers: { selectedComponentTab = .chargers },
            onCreateLoad: { createNewLoad() },
            onBrowseLibrary: { openComponentLibrary(source: "overview") },
            onShowBillOfMaterials: { openBillOfMaterials() },
            onCreateBattery: { startBatteryConfiguration() },
            onCreateCharger: { startChargerConfiguration() }
        )
        .accessibilityIdentifier("system-overview")
    }

    private var loadsStatsHeader: some View {
        StatsHeaderContainer {
            loadsSummaryContent
        }
    }

    private var loadsSummaryContent: some View {
        VStack(alignment: .leading, spacing: 10) {
            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: "\(savedLoads.count)",
                        tint: .blue
                    )
                    summaryMetric(
                        icon: "bolt.fill",
                        label: loadsCurrentLabel,
                        value: formattedCurrent(totalCurrent),
                        tint: .orange
                    )
                    summaryMetric(
                        icon: "gauge.medium",
                        label: loadsPowerLabel,
                        value: formattedPower(totalPower),
                        tint: .green
                    )
                }

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

            if let status = loadStatus {
                Button {
                    activeStatus = status
                } label: {
                    statusBanner(for: status)
                }
                .buttonStyle(.plain)
            }
        }
    }

    private var libraryButton: some View {
        Button {
            openComponentLibrary(source: "library-button")
        } label: {
            Group {
                if #available(iOS 26.0, *) {
                    libraryButtonLabel
                        .padding(.horizontal, 18)
                        .padding(.vertical, 12)
                        .glassEffect(.regular, in: .capsule)
                } else {
                    libraryButtonLabel
                        .padding(.horizontal, 14)
                        .padding(.vertical, 10)
                        .background(.ultraThinMaterial, in: Capsule(style: .continuous))
                        .shadow(color: Color.black.opacity(0.08), radius: 16, x: 0, y: 8)
                }
            }
        }
        .buttonStyle(.plain)
        .tint(.accentColor)
    }

    private var libraryButtonLabel: some View {
        Label(
            String(
                localized: "loads.library.button",
                bundle: .main,
                comment: "Button title to open component library"
            ),
            systemImage: "books.vertical"
        )
        .font(.footnote.weight(.semibold))
    }

    private var componentsTab: some View {
        VStack(spacing: 0) {
            if savedLoads.isEmpty {
                OnboardingInfoView(
                    configuration: .loads(),
                    onPrimaryAction: { createNewLoad() },
                    onSecondaryAction: { openComponentLibrary(source: "components-onboarding") }
                )
                .padding(.horizontal, 0)
            } else {
                loadsListWithHeader
            }
        }
        .background(Color(.systemGroupedBackground))
    }

    @ViewBuilder
    private var loadsListWithHeader: some View {
        Group {
            if #available(iOS 26.0, *) {
                baseLoadsList
                    .scrollEdgeEffectStyle(.soft, for: .top)
                    .safeAreaInset(edge: .top, spacing: 0) {
                        loadsStatsHeader
                    }
            } else {
                baseLoadsList
                    .safeAreaInset(edge: .top, spacing: 0) {
                        loadsStatsHeader
                    }
            }
        }
        .overlay(alignment: .bottomTrailing) {
            libraryButton
                .padding(.trailing, 24)
                .padding(.bottom, 24)
        }
    }

    private var baseLoadsList: some View {
        List {
            ForEach(savedLoads) { load in
                Button {
                    selectLoad(load)
                } label: {
                    loadRow(for: load)
                }
                .buttonStyle(.plain)
                .disabled(editMode == .active)
                .listRowInsets(.init(top: 12, leading: 16, bottom: 12, trailing: 16))
                .listRowSeparator(.hidden)
                .listRowBackground(Color.clear)
            }
            .onDelete(perform: deleteLoads)
        }
        .listStyle(.plain)
        .scrollContentBackground(.hidden)
        .accessibilityIdentifier("loads-list")
        .environment(\.editMode, $editMode)
    }

    private func selectLoad(_ load: SavedLoad) {
        AnalyticsTracker.log(
            "Load Opened",
            properties: [
                "mode": load.isWattMode ? "watt" : "amp",
                "system": system.name
            ]
        )
        newLoadToEdit = load
    }

    private func loadRow(for load: SavedLoad) -> some View {
        VStack(alignment: .leading, spacing: 14) {
            HStack(spacing: 12) {
                LoadIconView(
                    remoteIconURLString: load.remoteIconURLString,
                    fallbackSystemName: load.iconName,
                    fallbackColor: Color.componentColor(named: load.colorName),
                    size: 48
                )

                VStack(alignment: .leading, spacing: 4) {
                    Text(load.name)
                        .font(.body.weight(.medium))
                        .lineLimit(1)
                        .truncationMode(.tail)

                    Text(loadSummary(for: load))
                        .font(.caption.weight(.medium))
                        .foregroundStyle(.secondary)
                        .padding(.horizontal, 8)
                        .padding(.vertical, 4)
                        .background(
                            Capsule(style: .continuous)
                                .fill(Color(.tertiarySystemBackground))
                        )
                }
                Spacer()
                Image(systemName: "chevron.right")
                    .font(.system(size: 14, weight: .semibold))
                    .foregroundStyle(.secondary)
            }

            metricsSection(for: load)
        }
        .padding(.vertical, 16)
        .padding(.horizontal, 16)
        .background(
            RoundedRectangle(cornerRadius: 18, style: .continuous)
                .fill(Color(.systemBackground))
        )
    }

    private func loadSummary(for load: SavedLoad) -> String {
        let voltageText = String(format: "%.1fV", load.voltage)
        let lengthText: String
        if unitSettings.unitSystem == .metric {
            lengthText = String(format: "%.1f%@", load.length, unitSettings.unitSystem.lengthUnit)
        } else {
            let imperialLength = load.length * 3.28084
            lengthText = String(format: "%.1f%@", imperialLength, unitSettings.unitSystem.lengthUnit)
        }
        let powerOrCurrent = load.isWattMode
            ? String(format: "%.0fW", load.power)
            : String(format: "%.1fA", load.current)
        return [voltageText, powerOrCurrent, lengthText].joined(separator: " • ")
    }

    private func wireGaugeString(for load: SavedLoad) -> String {
        if unitSettings.unitSystem == .imperial {
            let awgValue = awgFromCrossSection(load.crossSection)
            return "\(ElectricalCalculations.formatAWG(awgValue)) AWG"
        } else {
            return String(format: "%.1f mm²", load.crossSection)
        }
    }

    private func lengthString(for load: SavedLoad) -> String {
        if unitSettings.unitSystem == .imperial {
            let imperialLength = load.length * 3.28084
            return String(format: "%.1f ft", imperialLength)
        } else {
            return String(format: "%.1f m", load.length)
        }
    }

    @ViewBuilder
    private func metricsSection(for load: SavedLoad) -> some View {
        if editMode == .active {
            horizontalMetrics(for: load)
        } else {
            ViewThatFits(in: .horizontal) {
                horizontalMetrics(for: load)
                verticalMetrics(for: load)
            }
        }
    }

    private func horizontalMetrics(for load: SavedLoad) -> some View {
        HStack(spacing: 12) {
            metricBadge(
                label: fuseMetricLabel,
                value: "\(recommendedFuse(for: load)) A",
                tint: .pink
            )
            metricBadge(
                label: cableMetricLabel,
                value: wireGaugeString(for: load),
                tint: .teal
            )
            metricBadge(
                label: lengthMetricLabel,
                value: lengthString(for: load),
                tint: .orange
            )
            Spacer(minLength: 0)
        }
    }

    private func verticalMetrics(for load: SavedLoad) -> some View {
        VStack(alignment: .leading, spacing: 8) {
            metricBadge(
                label: fuseMetricLabel,
                value: "\(recommendedFuse(for: load)) A",
                tint: .pink
            )
            metricBadge(
                label: cableMetricLabel,
                value: wireGaugeString(for: load),
                tint: .teal
            )
            metricBadge(
                label: lengthMetricLabel,
                value: lengthString(for: load),
                tint: .orange
            )
        }
    }

    private var fuseMetricLabel: String {
        String(localized: "loads.metric.fuse", defaultValue: "Fuse")
    }

    private var cableMetricLabel: String {
        String(localized: "loads.metric.cable", defaultValue: "Cable")
    }

    private var lengthMetricLabel: String {
        String(localized: "loads.metric.length", defaultValue: "Length")
    }

    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 totalCurrent: Double {
        savedLoads.reduce(0) { result, load in
            result + max(load.current, 0)
        }
    }

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

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

    private func summaryMetric(icon: String, label: String, value: String, tint: Color) -> some View {
        ComponentSummaryMetricView(
            icon: icon,
            label: label,
            value: value,
            tint: tint
        )
    }

    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 func formattedCurrent(_ value: Double) -> String {
        let numberString = LoadsView.numberFormatter.string(from: NSNumber(value: value)) ?? String(format: "%.1f", value)
        return "\(numberString) A"
    }

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

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

    private func metricBadge(label: String, value: String, tint: Color) -> some View {
        ComponentMetricBadgeView(
            label: label,
            value: value,
            tint: tint
        )
    }

    private func handlePrimaryAction() {
        switch selectedComponentTab {
        case .overview:
            createNewLoad()
        case .components:
            createNewLoad()
        case .batteries:
            startBatteryConfiguration()
        case .chargers:
            startChargerConfiguration()
        }
    }

    private func presentSystemEditor(source: String) {
        AnalyticsTracker.log(
            "System Editor Opened",
            properties: [
                "source": source,
                "system": system.name
            ]
        )
        showingSystemEditor = true
    }

    private func openComponentLibrary(source: String) {
        AnalyticsTracker.log(
            "Component Library Opened",
            properties: [
                "source": source,
                "system": system.name
            ]
        )
        showingComponentLibrary = true
    }

    private func openBillOfMaterials() {
        AnalyticsTracker.log(
            "Bill Of Materials Opened",
            properties: [
                "system": system.name
            ]
        )
        showingSystemBOM = true
    }

    private func deleteLoads(offsets: IndexSet) {
        let loadsToDelete = offsets.map { savedLoads[$0] }
        withAnimation {
            for load in loadsToDelete {
                AnalyticsTracker.log(
                    "Load Deleted",
                    properties: [
                        "name": load.name,
                        "system": system.name
                    ]
                )
                modelContext.delete(load)
            }
        }
    }
    
    private func createNewLoad() {
        let newLoad = SystemComponentsPersistence.createDefaultLoad(
            for: system,
            in: modelContext,
            existingLoads: savedLoads,
            existingBatteries: savedBatteries,
            existingChargers: savedChargers
        )
        AnalyticsTracker.log(
            "Load Created",
            properties: [
                "name": newLoad.name,
                "system": system.name
            ]
        )
        newLoadToEdit = newLoad
    }

    private func startBatteryConfiguration() {
        AnalyticsTracker.log(
            "Battery Editor Opened",
            properties: [
                "source": "create",
                "system": system.name
            ]
        )
        batteryDraft = SystemComponentsPersistence.makeBatteryDraft(
            for: system,
            existingLoads: savedLoads,
            existingBatteries: savedBatteries,
            existingChargers: savedChargers
        )
    }
    
    private func saveBattery(_ configuration: BatteryConfiguration) {
        let isExisting = savedBatteries.contains { $0.id == configuration.id }
        SystemComponentsPersistence.saveBattery(
            configuration,
            for: system,
            existingBatteries: savedBatteries,
            in: modelContext
        )
        let eventName = isExisting ? "Battery Updated" : "Battery Created"
        AnalyticsTracker.log(
            eventName,
            properties: [
                "name": configuration.name,
                "system": system.name
            ]
        )
    }
    
    private func editBattery(_ battery: SavedBattery) {
        AnalyticsTracker.log(
            "Battery Editor Opened",
            properties: [
                "source": "edit",
                "system": system.name
            ]
        )
        batteryDraft = BatteryConfiguration(savedBattery: battery, system: system)
    }

    private func deleteBatteries(_ offsets: IndexSet) {
        let batteriesToDelete = offsets.map { savedBatteries[$0] }
        withAnimation {
            for battery in batteriesToDelete {
                AnalyticsTracker.log(
                    "Battery Deleted",
                    properties: [
                        "name": battery.name,
                        "system": system.name
                    ]
                )
            }
            SystemComponentsPersistence.deleteBatteries(
                at: offsets,
                from: savedBatteries,
                in: modelContext
            )
        }
    }

    private func startChargerConfiguration() {
        AnalyticsTracker.log(
            "Charger Editor Opened",
            properties: [
                "source": "create",
                "system": system.name
            ]
        )
        chargerDraft = SystemComponentsPersistence.makeChargerDraft(
            for: system,
            existingLoads: savedLoads,
            existingBatteries: savedBatteries,
            existingChargers: savedChargers
        )
    }

    private func saveCharger(_ configuration: ChargerConfiguration) {
        let isExisting = savedChargers.contains { $0.id == configuration.id }
        SystemComponentsPersistence.saveCharger(
            configuration,
            for: system,
            existingChargers: savedChargers,
            in: modelContext
        )
        let eventName = isExisting ? "Charger Updated" : "Charger Created"
        AnalyticsTracker.log(
            eventName,
            properties: [
                "name": configuration.name,
                "system": system.name
            ]
        )
    }

    private func editCharger(_ charger: SavedCharger) {
        AnalyticsTracker.log(
            "Charger Editor Opened",
            properties: [
                "source": "edit",
                "system": system.name
            ]
        )
        chargerDraft = ChargerConfiguration(savedCharger: charger, system: system)
    }

    private func deleteChargers(_ offsets: IndexSet) {
        let chargersToDelete = offsets.map { savedChargers[$0] }
        withAnimation {
            for charger in chargersToDelete {
                AnalyticsTracker.log(
                    "Charger Deleted",
                    properties: [
                        "name": charger.name,
                        "system": system.name
                    ]
                )
            }
            SystemComponentsPersistence.deleteChargers(
                at: offsets,
                from: savedChargers,
                in: modelContext
            )
        }
    }

    private func addComponent(_ item: ComponentLibraryItem) {
        let newLoad = SystemComponentsPersistence.createLoad(
            from: item,
            for: system,
            in: modelContext,
            existingLoads: savedLoads,
            existingBatteries: savedBatteries,
            existingChargers: savedChargers
        )
        AnalyticsTracker.log(
            "Library Load Added",
            properties: [
                "id": item.id,
                "name": item.localizedName,
                "system": system.name
            ]
        )
        newLoadToEdit = newLoad
    }
    
    private func awgFromCrossSection(_ crossSectionMM2: Double) -> Double {
        let awgSizes: [(Int, Double)] = [(20, 0.519), (18, 0.823), (16, 1.31), (14, 2.08), (12, 3.31),
                       (10, 5.26), (8, 8.37), (6, 13.3), (4, 21.2), (2, 33.6),
                       (1, 42.4), (-1, 53.5), (-2, 67.4), (-3, 85.0), (-4, 107.0)]

        // Find the closest AWG size
        let closest = awgSizes.min { abs($0.1 - crossSectionMM2) < abs($1.1 - crossSectionMM2) }
        return Double(closest?.0 ?? 20)
    }

    private func recommendedFuse(for load: SavedLoad) -> String {
        let fuse = ElectricalCalculations.recommendedFuse(forCurrent: load.current)
        return fuse == fuse.rounded() ? String(format: "%.0f", fuse) : String(format: "%.1f", fuse)
    }

    enum ComponentTab: Hashable {
        case overview
        case components
        case batteries
        case chargers
    }

    // MARK: - PDF Export

    private struct OverviewShareItem: Identifiable {
        let id = UUID()
        let shareItems: [Any]
        let tempURL: URL?
    }

    private struct OverviewExportError: Identifiable {
        let message: String
        var id: String { message }
    }

    private func exportOverviewPDF() {
        guard !isExportingOverview else { return }
        isExportingOverview = true

        let snapshot = buildSnapshot()

        Task {
            do {
                // Fetch diagram image from VoltPlan API (falls back to Core Graphics if unavailable)
                let diagramImage = await SystemOverviewPDFExporter.fetchDiagramImage(snapshot: snapshot)

                let exporter = SystemOverviewPDFExporter()
                let url = try exporter.export(snapshot: snapshot, diagramImage: diagramImage)
                AnalyticsTracker.log("Overview PDF Shared", properties: [
                    "system": snapshot.systemName,
                ])
                await MainActor.run {
                    overviewShareItem = OverviewShareItem(shareItems: [url], tempURL: url)
                    isExportingOverview = false
                }
            } catch {
                await MainActor.run {
                    overviewExportError = OverviewExportError(message: error.localizedDescription)
                    isExportingOverview = false
                }
            }
        }
    }

    private func exportDiagramImage() {
        guard !isExportingOverview else { return }
        isExportingOverview = true

        let snapshot = buildSnapshot()

        Task {
            let diagramImage = await SystemOverviewPDFExporter.fetchDiagramImage(snapshot: snapshot)
            await MainActor.run {
                if let image = diagramImage,
                   let opaqueImage = Self.imageWithWhiteBackground(image),
                   let pngData = opaqueImage.pngData() {
                    let url = FileManager.default.temporaryDirectory
                        .appendingPathComponent("\(snapshot.systemName)-Diagram.png")
                    try? pngData.write(to: url, options: .atomic)
                    AnalyticsTracker.log("Diagram Image Shared", properties: [
                        "system": snapshot.systemName,
                    ])
                    overviewShareItem = OverviewShareItem(shareItems: [url], tempURL: url)
                } else {
                    overviewExportError = OverviewExportError(
                        message: String(localized: "overview.share.diagram.error", defaultValue: "Could not generate diagram. Check your internet connection.")
                    )
                }
                isExportingOverview = false
            }
        }
    }

    private static func imageWithWhiteBackground(_ image: UIImage) -> UIImage? {
        let size = image.size
        UIGraphicsBeginImageContextWithOptions(size, true, image.scale)
        defer { UIGraphicsEndImageContext() }
        UIColor.white.setFill()
        UIRectFill(CGRect(origin: .zero, size: size))
        image.draw(at: .zero)

        return UIGraphicsGetImageFromCurrentImageContext()
    }

    private func buildSnapshot() -> SystemOverviewPDFExporter.SystemSnapshot {
        let currentUnitSystem = unitSettings.unitSystem
        let loads = savedLoads
        let batteries = savedBatteries
        let chargers = savedChargers

        let loadSnapshots = loads.map { load in
            SystemOverviewPDFExporter.LoadSnapshot(
                name: load.name,
                voltage: load.voltage,
                current: load.current,
                power: load.power,
                length: load.length,
                crossSection: load.crossSection,
                dutyCyclePercent: load.dutyCyclePercent,
                dailyUsageHours: load.dailyUsageHours,
                recommendedCrossSection: ElectricalCalculations.recommendedCrossSection(
                    length: load.length, current: load.current, voltage: load.voltage, unitSystem: currentUnitSystem
                ),
                voltageDrop: ElectricalCalculations.voltageDrop(
                    length: load.length, current: load.current, voltage: load.voltage, unitSystem: currentUnitSystem
                ),
                voltageDropPercent: ElectricalCalculations.voltageDropPercentage(
                    length: load.length, current: load.current, voltage: load.voltage, unitSystem: currentUnitSystem
                ),
                powerLoss: ElectricalCalculations.powerLoss(
                    length: load.length, current: load.current, voltage: load.voltage, unitSystem: currentUnitSystem
                ),
                recommendedFuse: ElectricalCalculations.recommendedFuse(forCurrent: load.current),
                iconUrl: load.remoteIconURLString
            )
        }

        let batterySnapshots = batteries.map { battery in
            SystemOverviewPDFExporter.BatterySnapshot(
                name: battery.name,
                chemistry: battery.chemistry.rawValue,
                nominalVoltage: battery.nominalVoltage,
                capacityAmpHours: battery.capacityAmpHours,
                usableCapacityAmpHours: battery.usableCapacityAmpHours,
                energyWattHours: battery.energyWattHours,
                usableEnergyWattHours: battery.usableEnergyWattHours,
                iconUrl: nil
            )
        }

        let chargerSnapshots = chargers.map { charger in
            SystemOverviewPDFExporter.ChargerSnapshot(
                name: charger.name,
                inputVoltage: charger.inputVoltage,
                outputVoltage: charger.outputVoltage,
                maxCurrentAmps: charger.maxCurrentAmps,
                effectivePowerWatts: charger.effectivePowerWatts,
                sourceType: charger.sourceType.rawValue,
                iconUrl: charger.remoteIconURLString
            )
        }

        let totalPower = loads.reduce(0.0) { $0 + $1.power }
        let totalCurrent = loads.reduce(0.0) { $0 + $1.current }
        let totalCapacity = batteries.reduce(0.0) { $0 + $1.capacityAmpHours }
        let totalEnergy = batteries.reduce(0.0) { $0 + $1.energyWattHours }
        let totalUsableCapacity = batteries.reduce(0.0) { $0 + $1.usableCapacityAmpHours }
        let totalUsableEnergy = batteries.reduce(0.0) { $0 + $1.usableEnergyWattHours }
        let totalChargerPower = chargers.reduce(0.0) { $0 + $1.effectivePowerWatts }
        let totalChargerCurrent = chargers.reduce(0.0) { $0 + $1.maxCurrentAmps }

        var runtimeFormatted: String? = nil
        if totalPower > 0 && totalUsableEnergy > 0 {
            let hours = totalUsableEnergy / totalPower
            runtimeFormatted = String(format: "%.1f h", hours)
        }

        var chargeTimeFormatted: String? = nil
        if totalChargerPower > 0 && totalEnergy > 0 {
            let hours = totalEnergy / totalChargerPower
            chargeTimeFormatted = String(format: "%.1f h", hours)
        }

        return SystemOverviewPDFExporter.SystemSnapshot(
            systemName: system.name,
            unitSystem: currentUnitSystem,
            loads: loadSnapshots,
            batteries: batterySnapshots,
            chargers: chargerSnapshots,
            estimatedRuntimeFormatted: runtimeFormatted,
            estimatedChargeTimeFormatted: chargeTimeFormatted,
            totalPower: totalPower,
            totalCurrent: totalCurrent,
            totalBatteryCapacity: totalCapacity,
            totalBatteryEnergy: totalEnergy,
            totalUsableCapacity: totalUsableCapacity,
            totalUsableEnergy: totalUsableEnergy,
            totalChargerPower: totalChargerPower,
            totalChargerCurrent: totalChargerCurrent
        )
    }

    private func cleanupOverviewShareItem() {
        guard let item = overviewShareItem else { return }
        overviewShareItem = nil
        if let url = item.tempURL {
            try? FileManager.default.removeItem(at: url)
        }
    }
}

