import Foundation
import SwiftUI
import SwiftData

struct SystemComponentsPersistence {
    static func createDefaultLoad(
        for system: ElectricalSystem,
        in context: ModelContext,
        existingLoads: [SavedLoad],
        existingBatteries: [SavedBattery],
        existingChargers: [SavedCharger]
    ) -> SavedLoad {
        let defaultName = String(
            localized: "default.load.new",
            comment: "Default name when creating a new load from system view"
        )
        let loadName = uniqueName(
            startingWith: defaultName,
            loads: existingLoads,
            batteries: existingBatteries,
            chargers: existingChargers
        )
        let newLoad = SavedLoad(
            name: loadName,
            voltage: 12.0,
            current: 5.0,
            power: 60.0,
            length: 10.0,
            crossSection: 1.0,
            iconName: "lightbulb",
            colorName: "blue",
            isWattMode: false,
            dutyCyclePercent: 100.0,
            dailyUsageHours: 24.0,
            system: system,
            remoteIconURLString: nil
        )
        context.insert(newLoad)
        return newLoad
    }

    static func createLoad(
        from item: ComponentLibraryItem,
        for system: ElectricalSystem,
        in context: ModelContext,
        existingLoads: [SavedLoad],
        existingBatteries: [SavedBattery],
        existingChargers: [SavedCharger]
    ) -> SavedLoad {
        let localizedName = item.localizedName
        let baseName = localizedName.isEmpty ? "Library Load" : localizedName
        let loadName = uniqueName(
            startingWith: baseName,
            loads: existingLoads,
            batteries: existingBatteries,
            chargers: existingChargers
        )
        let voltage = item.displayVoltage ?? 12.0
        let power = item.watt ?? (item.current != nil ? item.current! * voltage : 0)
        let current: Double
        if let explicitCurrent = item.current {
            current = explicitCurrent
        } else if voltage > 0 {
            current = power / voltage
        } else {
            current = 0
        }

        let dutyCyclePercent = item.normalizedDutyCyclePercent ?? 100
        let dailyUsageHours = item.defaultDailyUsageHours ?? 1

        let newLoad = SavedLoad(
            name: loadName,
            voltage: voltage,
            current: current,
            power: power,
            length: 10.0,
            crossSection: 1.0,
            iconName: "lightbulb",
            colorName: "blue",
            isWattMode: item.watt != nil,
            dutyCyclePercent: dutyCyclePercent,
            dailyUsageHours: dailyUsageHours,
            system: system,
            remoteIconURLString: item.iconURL?.absoluteString,
            componentID: item.id
        )

        context.insert(newLoad)
        return newLoad
    }

    static func makeBatteryDraft(
        for system: ElectricalSystem,
        existingLoads: [SavedLoad],
        existingBatteries: [SavedBattery],
        existingChargers: [SavedCharger]
    ) -> BatteryConfiguration {
        let defaultName = String(
            localized: "battery.editor.default_name",
            defaultValue: "New Battery"
        )
        let batteryName = uniqueName(
            startingWith: defaultName,
            loads: existingLoads,
            batteries: existingBatteries,
            chargers: existingChargers
        )
        return BatteryConfiguration(
            name: batteryName,
            iconName: "battery.100.bolt",
            colorName: system.colorName,
            system: system
        )
    }

    static func makeChargerDraft(
        for system: ElectricalSystem,
        existingLoads: [SavedLoad],
        existingBatteries: [SavedBattery],
        existingChargers: [SavedCharger]
    ) -> ChargerConfiguration {
        let defaultName = String(
            localized: "charger.editor.default_name",
            defaultValue: "New Charger"
        )
        let chargerName = uniqueName(
            startingWith: defaultName,
            loads: existingLoads,
            batteries: existingBatteries,
            chargers: existingChargers
        )
        return ChargerConfiguration(
            name: chargerName,
            iconName: "bolt.fill",
            colorName: system.colorName,
            system: system
        )
    }

    static func saveBattery(
        _ configuration: BatteryConfiguration,
        for system: ElectricalSystem,
        existingBatteries: [SavedBattery],
        in context: ModelContext
    ) {
        if let existing = existingBatteries.first(where: { $0.id == configuration.id }) {
            configuration.apply(to: existing)
        } else {
            let newBattery = SavedBattery(
                id: configuration.id,
                name: configuration.name,
                nominalVoltage: configuration.nominalVoltage,
                capacityAmpHours: configuration.capacityAmpHours,
                chemistry: configuration.chemistry,
                usableCapacityOverrideFraction: configuration.usableCapacityOverrideFraction,
                chargeVoltage: configuration.chargeVoltage,
                cutOffVoltage: configuration.cutOffVoltage,
                minimumTemperatureCelsius: configuration.minimumTemperatureCelsius,
                maximumTemperatureCelsius: configuration.maximumTemperatureCelsius,
                iconName: configuration.iconName,
                colorName: configuration.colorName,
                system: system
            )
            context.insert(newBattery)
        }
    }

    static func saveCharger(
        _ configuration: ChargerConfiguration,
        for system: ElectricalSystem,
        existingChargers: [SavedCharger],
        in context: ModelContext
    ) {
        if let existing = existingChargers.first(where: { $0.id == configuration.id }) {
            configuration.apply(to: existing)
        } else {
            let newCharger = SavedCharger(
                id: configuration.id,
                name: configuration.name,
                inputVoltage: configuration.inputVoltage,
                outputVoltage: configuration.outputVoltage,
                maxCurrentAmps: configuration.maxCurrentAmps,
                maxPowerWatts: configuration.maxPowerWatts,
                iconName: configuration.iconName,
                colorName: configuration.colorName,
                system: system
            )
            context.insert(newCharger)
        }
    }

    static func deleteBatteries(
        at offsets: IndexSet,
        from batteries: [SavedBattery],
        in context: ModelContext
    ) {
        for index in offsets {
            context.delete(batteries[index])
        }
    }

    static func deleteChargers(
        at offsets: IndexSet,
        from chargers: [SavedCharger],
        in context: ModelContext
    ) {
        for index in offsets {
            context.delete(chargers[index])
        }
    }

    static func uniqueName(
        startingWith baseName: String,
        loads: [SavedLoad],
        batteries: [SavedBattery],
        chargers: [SavedCharger]
    ) -> String {
        let existingNames = Set(
            loads.map { $0.name } +
            batteries.map { $0.name } +
            chargers.map { $0.name }
        )

        if !existingNames.contains(baseName) {
            return baseName
        }

        var counter = 2
        var candidate = "\(baseName) \(counter)"

        while existingNames.contains(candidate) {
            counter += 1
            candidate = "\(baseName) \(counter)"
        }

        return candidate
    }

    static func createDefaultCharger(
        for system: ElectricalSystem,
        in context: ModelContext,
        existingLoads: [SavedLoad],
        existingBatteries: [SavedBattery],
        existingChargers: [SavedCharger]
    ) -> SavedCharger {
        let defaultName = String(
            localized: "charger.default.new",
            bundle: .main,
            comment: "Default name when creating a new charger from system view"
        )
        let chargerName = uniqueName(
            startingWith: defaultName,
            loads: existingLoads,
            batteries: existingBatteries,
            chargers: existingChargers
        )
        let charger = SavedCharger(
            name: chargerName,
            inputVoltage: LocaleDefaults.mainsVoltage,
            outputVoltage: 14.4,
            maxCurrentAmps: 30,
            iconName: "bolt.fill",
            colorName: system.colorName,
            system: system
        )
        context.insert(charger)
        return charger
    }
}
