//
//  CableCalculator.swift
//  Cable
//
//  Created by Stefan Lange-Hegermann on 11.09.25.
//

import Foundation
import SwiftData

class CableCalculator: ObservableObject {
    @Published var voltage: Double = 12.0
    @Published var current: Double = 5.0
    @Published var power: Double = 60.0
    @Published var length: Double = 10.0
    @Published var loadName: String = "My Load"
    
    var calculatedPower: Double {
        voltage * current
    }
    
    var calculatedCurrent: Double {
        voltage > 0 ? power / voltage : 0
    }
    
    func updateFromCurrent() {
        power = voltage * current
    }
    
    func updateFromPower() {
        current = voltage > 0 ? power / voltage : 0
    }
    
    func recommendedCrossSection(for unitSystem: UnitSystem) -> Double {
        let lengthInMeters = unitSystem == .metric ? length : length * 0.3048 // ft to m
        // Simplified calculation: minimum cross-section based on current and voltage drop
        let maxVoltageDrop = voltage * 0.05 // 5% voltage drop limit
        let resistivity = 0.017 // Copper resistivity at 20°C (Ω⋅mm²/m)
        let calculatedMinCrossSection = (2 * current * lengthInMeters * resistivity) / maxVoltageDrop
        
        if unitSystem == .imperial {
            // Standard AWG wire sizes
            let standardAWG = [20, 18, 16, 14, 12, 10, 8, 6, 4, 2, 1, 0, 00, 000, 0000]
            let awgCrossSections = [0.519, 0.823, 1.31, 2.08, 3.31, 5.26, 8.37, 13.3, 21.2, 33.6, 42.4, 53.5, 67.4, 85.0, 107.0]
            
            // Find the smallest AWG that meets the requirement
            for (index, crossSection) in awgCrossSections.enumerated() {
                if crossSection >= calculatedMinCrossSection {
                    return Double(standardAWG[index])
                }
            }
            return Double(standardAWG.last!) // Largest available
        } else {
            // Standard metric cable cross-sections in mm²
            let standardSizes = [0.75, 1.0, 1.5, 2.5, 4.0, 6.0, 10.0, 16.0, 25.0, 35.0, 50.0, 70.0, 95.0, 120.0, 150.0, 185.0, 240.0, 300.0, 400.0, 500.0, 630.0]
            
            // Find the smallest standard size that meets the requirement
            return standardSizes.first { $0 >= max(0.75, calculatedMinCrossSection) } ?? standardSizes.last!
        }
    }
    
    func crossSection(for unitSystem: UnitSystem) -> Double {
        recommendedCrossSection(for: unitSystem)
    }
    
    func voltageDrop(for unitSystem: UnitSystem) -> Double {
        let lengthInMeters = unitSystem == .metric ? length : length * 0.3048
        let crossSectionMM2 = unitSystem == .metric ? crossSection(for: unitSystem) : crossSectionFromAWG(crossSection(for: unitSystem))
        let resistivity = 0.017
        let effectiveCurrent = current // Always use the current property which gets updated
        return (2 * effectiveCurrent * lengthInMeters * resistivity) / crossSectionMM2
    }
    
    func voltageDropPercentage(for unitSystem: UnitSystem) -> Double {
        (voltageDrop(for: unitSystem) / voltage) * 100
    }
    
    func powerLoss(for unitSystem: UnitSystem) -> Double {
        let effectiveCurrent = current
        return effectiveCurrent * voltageDrop(for: unitSystem)
    }
    
    var recommendedFuse: Int {
        let targetFuse = current * 1.25 // 125% of load current for safety
        
        // Common fuse values in amperes
        let standardFuses = [1, 2, 3, 5, 7, 10, 15, 20, 25, 30, 35, 40, 50, 60, 70, 80, 100, 125, 150, 175, 200, 225, 250, 300, 350, 400, 450, 500, 600, 700, 800]
        
        // Find the smallest standard fuse that's >= target
        return standardFuses.first { $0 >= Int(targetFuse.rounded(.up)) } ?? standardFuses.last!
    }
    
    // AWG conversion helper for voltage drop calculations
    private func crossSectionFromAWG(_ awg: Double) -> Double {
        let awgSizes = [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, 0: 53.5]
        
        // Handle 00, 000, 0000 AWG (represented as negative values)
        if awg == 00 { return 67.4 }
        if awg == 000 { return 85.0 }  
        if awg == 0000 { return 107.0 }
        
        return awgSizes[Int(awg)] ?? 0.75
    }
}

@Model
class ElectricalSystem {
    var name: String = ""
    var location: String = ""
    var timestamp: Date = Date()
    var iconName: String = "building.2"
    var colorName: String = "blue"
    
    init(name: String, location: String = "", iconName: String = "building.2", colorName: String = "blue") {
        self.name = name
        self.location = location
        self.timestamp = Date()
        self.iconName = iconName
        self.colorName = colorName
    }
}

@Model
class SavedLoad {
    var name: String = ""
    var voltage: Double = 0.0
    var current: Double = 0.0
    var power: Double = 0.0
    var length: Double = 0.0
    var crossSection: Double = 0.0
    var timestamp: Date = Date()
    var iconName: String = "lightbulb"
    var colorName: String = "blue"
    var isWattMode: Bool = false
    var system: ElectricalSystem?
    var remoteIconURLString: String? = nil
    var affiliateURLString: String? = nil
    var affiliateCountryCode: String? = nil
    var bomCompletedItemIDs: [String] = []
    var identifier: String = UUID().uuidString
    
    init(name: String, voltage: Double, current: Double, power: Double, length: Double, crossSection: Double, iconName: String = "lightbulb", colorName: String = "blue", isWattMode: Bool = false, system: ElectricalSystem? = nil, remoteIconURLString: String? = nil, affiliateURLString: String? = nil, affiliateCountryCode: String? = nil, bomCompletedItemIDs: [String] = [], identifier: String = UUID().uuidString) {
        self.name = name
        self.voltage = voltage
        self.current = current
        self.power = power
        self.length = length
        self.crossSection = crossSection
        self.timestamp = Date()
        self.iconName = iconName
        self.colorName = colorName
        self.isWattMode = isWattMode
        self.system = system
        self.remoteIconURLString = remoteIconURLString
        self.affiliateURLString = affiliateURLString
        self.affiliateCountryCode = affiliateCountryCode
        self.bomCompletedItemIDs = bomCompletedItemIDs
        self.identifier = identifier
    }
}
