-- Server-side vehicle functions for W900 Semi-Truck
-- Registers custom battery charging and freezer update functions

require "Vehicles/Vehicles"

-- Initialize VehicleUtils for custom battery charging
VehicleUtils = VehicleUtils or {}

local AUX_BATTERY_PART_IDS = { "Battery4", "Battery3", "Battery2", "Battery1" }

local function getBatteryItemCharge(invItem)
    if not invItem then
        return 0
    end

    if invItem.getCurrentUsesFloat then
        return invItem:getCurrentUsesFloat()
    end

    if invItem.getUsedDelta then
        return invItem:getUsedDelta()
    end

    return 0
end

local function setBatteryItemCharge(invItem, charge)
    if not invItem then
        return false, 0, 0
    end

    local oldCharge = getBatteryItemCharge(invItem)
    local newCharge = math.max(0.0, math.min(charge, 1.0))
    if math.abs(newCharge - oldCharge) < 0.0001 then
        return false, oldCharge, newCharge
    end

    if invItem.setUsedDelta then
        invItem:setUsedDelta(newCharge)
    elseif invItem.setCurrentUsesFloat then
        invItem:setCurrentUsesFloat(newCharge)
    else
        return false, oldCharge, oldCharge
    end

    return true, oldCharge, newCharge
end

local function syncBatteryPart(vehicle, part, oldCharge, newCharge, alwaysTransmit)
    if not vehicle or not part then
        return
    end

    if vehicle.updatePartStats then
        vehicle:updatePartStats()
    end

    if alwaysTransmit or not VehicleUtils.compareFloats or VehicleUtils.compareFloats(oldCharge, newCharge, 2) then
        vehicle:transmitPartUsedDelta(part)
    end
end

local function applyBatteryDelta(vehicle, part, delta, alwaysTransmit)
    if not part then
        return false, 0
    end

    local invItem = part:getInventoryItem()
    if not invItem then
        return false, 0
    end

    local changed, oldCharge, newCharge = setBatteryItemCharge(invItem, getBatteryItemCharge(invItem) + delta)
    if changed then
        syncBatteryPart(vehicle, part, oldCharge, newCharge, alwaysTransmit)
    end

    return changed, newCharge
end

function VehicleUtils.getBatteryReserveW900(vehicle)
    if not vehicle then
        return 0
    end

    local totalCharge = 0
    for _, partId in ipairs(AUX_BATTERY_PART_IDS) do
        local batteryPart = vehicle:getPartById(partId)
        if batteryPart and batteryPart:getInventoryItem() then
            totalCharge = totalCharge + getBatteryItemCharge(batteryPart:getInventoryItem())
        end
    end

    local mainBattery = vehicle:getBattery()
    if mainBattery and mainBattery:getInventoryItem() then
        totalCharge = totalCharge + getBatteryItemCharge(mainBattery:getInventoryItem())
    end

    return totalCharge
end

function VehicleUtils.hasBatteryPowerW900(vehicle, minimumCharge)
    return VehicleUtils.getBatteryReserveW900(vehicle) > (minimumCharge or 0.001)
end

function Vehicles.InstallTest.W900MutuallyExclusiveTank(vehicle, part, chr)
    local canDo = Vehicles.InstallTest.Default(vehicle, part, chr)
    if not canDo then
        return false
    end

    local keyvalues = part:getTable("install")
    if not keyvalues or not keyvalues.requireUninstalled or keyvalues.requireUninstalled == "" then
        return true
    end

    local split = keyvalues.requireUninstalled:split(";")
    for _, partId in ipairs(split) do
        local requiredPart = vehicle:getPartById(partId)
        if requiredPart and requiredPart:getInventoryItem() then
            return false
        end
    end

    return true
end

-- Custom battery charging function for W900 with multiple batteries
-- This handles charging priority: Battery4 -> Battery3 -> Battery2 -> Battery1 -> Main Battery
function VehicleUtils.chargeBatteryW900(vehicle, delta)
    local battery = vehicle:getBattery()
    local Battery1 = vehicle:getPartById("Battery1")
    local Battery2 = vehicle:getPartById("Battery2")
    local Battery3 = vehicle:getPartById("Battery3")
    local Battery4 = vehicle:getPartById("Battery4")
    
    -- Check if batteries exist
    if not Battery1 or not Battery2 or not Battery3 or not Battery4 then
        -- Fallback to standard battery if custom batteries don't exist
        if battery and battery:getInventoryItem() then
            applyBatteryDelta(vehicle, battery, delta, delta < 0)
        end
        return
    end
    
    -- Get initial charges
    local initcharge1 = Battery1:getInventoryItem() and getBatteryItemCharge(Battery1:getInventoryItem()) or 0
    local initcharge2 = Battery2:getInventoryItem() and getBatteryItemCharge(Battery2:getInventoryItem()) or 0
    local initcharge3 = Battery3:getInventoryItem() and getBatteryItemCharge(Battery3:getInventoryItem()) or 0
    local initcharge4 = Battery4:getInventoryItem() and getBatteryItemCharge(Battery4:getInventoryItem()) or 0
    
    -- Different logic for charging (positive delta) vs discharging (negative delta)
    if delta < 0 then
        -- DISCHARGING: Priority Battery4 -> Battery3 -> Battery2 -> Battery1 -> Main
        -- Use Battery4 first if it has charge
        if Battery4:getInventoryItem() and initcharge4 > 0.001 then
            applyBatteryDelta(vehicle, Battery4, delta, true)
        -- Battery4 empty, use Battery3
        elseif Battery3:getInventoryItem() and initcharge3 > 0.001 then
            applyBatteryDelta(vehicle, Battery3, delta, true)
        -- Battery3 empty, use Battery2
        elseif Battery2:getInventoryItem() and initcharge2 > 0.001 then
            applyBatteryDelta(vehicle, Battery2, delta, true)
        -- Battery2 empty, use Battery1
        elseif Battery1:getInventoryItem() and initcharge1 > 0.001 then
            applyBatteryDelta(vehicle, Battery1, delta, true)
        -- All aux batteries empty, use main battery
        else
            if battery and battery:getInventoryItem() then
                applyBatteryDelta(vehicle, battery, delta, true)
            end
        end
    else
        -- CHARGING: Priority Battery4 -> Battery3 -> Battery2 -> Battery1 -> Main
        -- Only charge next battery when previous is full or missing
        if Battery4:getInventoryItem() then
            applyBatteryDelta(vehicle, Battery4, delta, false)
        -- Priority 2: Charge Battery3 if Battery4 is empty or missing
        elseif Battery3:getInventoryItem() and initcharge4 <= 0.001 then
            applyBatteryDelta(vehicle, Battery3, delta, false)
        -- Priority 3: Charge Battery2 if Battery3 is empty or missing
        elseif Battery2:getInventoryItem() and initcharge3 <= 0.001 then
            applyBatteryDelta(vehicle, Battery2, delta, false)
        -- Priority 4: Charge Battery1 if Battery2 is empty or missing
        elseif Battery1:getInventoryItem() and initcharge2 <= 0.001 then
            applyBatteryDelta(vehicle, Battery1, delta, false)
        -- Priority 5: Use main battery as fallback
        else
            if battery and battery:getInventoryItem() then
                applyBatteryDelta(vehicle, battery, delta, false)
            end
        end
    end
end

require "Vehicles/W900_Freezer"

--print(("W900: Registered CommonTemplates functions")
--print(("W900: VehicleFreezer registered in Vehicles.Update table")
