import Foundation
import SwiftUI
import SwiftData

struct SystemComponentsPersistence {
    static func createDefaultLoad(
        for system: ElectricalSystem,
        in context: ModelContext,
        existingLoads: [SavedLoad],
        existingBatteries: [SavedBattery]
    ) -> 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
        )
        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,
            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]
    ) -> SavedLoad {
        let localizedName = item.localizedName
        let baseName = localizedName.isEmpty ? "Library Load" : localizedName
        let loadName = uniqueName(
            startingWith: baseName,
            loads: existingLoads,
            batteries: existingBatteries
        )
        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 affiliateLink = item.primaryAffiliateLink

        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,
            system: system,
            remoteIconURLString: item.iconURL?.absoluteString,
            affiliateURLString: affiliateLink?.url.absoluteString,
            affiliateCountryCode: affiliateLink?.country
        )

        context.insert(newLoad)
        return newLoad
    }

    static func makeBatteryDraft(
        for system: ElectricalSystem,
        existingLoads: [SavedLoad],
        existingBatteries: [SavedBattery]
    ) -> BatteryConfiguration {
        let defaultName = NSLocalizedString(
            "battery.editor.default_name",
            bundle: .main,
            value: "New Battery",
            comment: "Default name when configuring a new battery"
        )
        let batteryName = uniqueName(
            startingWith: defaultName,
            loads: existingLoads,
            batteries: existingBatteries
        )
        return BatteryConfiguration(
            name: batteryName,
            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,
                system: system
            )
            context.insert(newBattery)
        }
    }

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

    static func uniqueName(
        startingWith baseName: String,
        loads: [SavedLoad],
        batteries: [SavedBattery]
    ) -> String {
        let existingNames = Set(loads.map { $0.name } + batteries.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
    }
}
