-- ============================================================================
-- === FillUnitLowLevelFix.lua
-- === Mod by [LSMT] Modding Team 
-- === LS25 /FS25
-- === Script by [LSMT] BaTt3RiE @ 2025
-- === Ver 1.0.0.0
-- === Entfernt die 10%-Speicherbegrenzung für ALLE FillUnits
-- ============================================================================

FillUnitLowLevelFix = {}

local DEBUG = false
local function dprint(...) if DEBUG then print("[FillUnitLowLevelFix]", ...) end end

-- ============================================================================
-- PATCH 1: Motorized.onPostLoad - Verhindert automatisches Auffüllen auf 10%
-- ============================================================================
function Motorized.onPostLoad(self, savegame)
    local spec = self.spec_motorized
    
    -- WICHTIG: Die automatische 10%-Auffüllung wird KOMPLETT ÜBERSPRUNGEN!
    if self.isServer then
        -- Keine automatische Auffüllung mehr - weder für Diesel noch für andere Typen
        print("Automatische 10%%-Auffüllung für alle FillTypes übersprungen")
    end
    
    -- Rest der Original-Funktion
    spec.propellantFillUnitIndices = {}
    for _, fillType in pairs({FillType.DIESEL, FillType.DEF, FillType.ELECTRICCHARGE, FillType.METHANE}) do
        local fillTypeName = g_fillTypeManager:getFillTypeNameByIndex(fillType)
        if spec.consumersByFillTypeName[fillTypeName] ~= nil then
            table.insert(spec.propellantFillUnitIndices, spec.consumersByFillTypeName[fillTypeName].fillUnitIndex)
        end
    end
    
    if spec.motor ~= nil then
        spec.motor:postLoad(savegame)
    end
end

-- ============================================================================
-- PATCH 2: FillUnit.addFillUnitFillLevel - Entfernt 10%-Grenze für ALLE
-- ============================================================================
function FillUnit:addFillUnitFillLevel(farmId, fillUnitIndex, delta, fillTypeIndex, toolType, fillInfo)
    local spec = self.spec_fillUnit
    spec.isInfoDirty = true

    if delta < 0 and not (g_currentMission.accessHandler:canFarmAccess(farmId, self, true) or g_guidedTourManager:getIsTourRunning()) then
        return 0
    end

    if self.getMountObject ~= nil then
        local mountObject = self:getDynamicMountObject() or self:getMountObject()
        if mountObject ~= nil and not g_currentMission.accessHandler:canFarmAccess(mountObject:getActiveFarm(), self, true) then
            return 0
        end
    end

    local fillUnit = spec.fillUnits[fillUnitIndex]
    if fillUnit == nil then
        return 0
    end

    if delta > 0 and not fillUnit.ignoreFillLimit and g_currentMission.missionInfo.trailerFillLimit and self:getMaxComponentMassReached() then
        return 0
    end

    if not self:getFillUnitSupportsToolTypeAndFillType(fillUnitIndex, toolType, fillTypeIndex) then
        return 0
    end

    if self.isServer and delta > 0 and not fillUnit.ignoreFillLimit and g_currentMission.missionInfo.trailerFillLimit then
        local availableMass = self:getAvailableComponentMass()
        local fillType = g_fillTypeManager:getFillTypeByIndex(fillTypeIndex)
        if fillType ~= nil and fillType.massPerLiter ~= 0 then
            local maxDelta = availableMass / fillType.massPerLiter
            delta = math.min(delta, maxDelta)
        end
    end

    local oldFillLevel = fillUnit.fillLevel
    local capacity = fillUnit.capacity
    
    -- WICHTIG: Keine 10%-Begrenzung mehr - für ALLE FillTypes!
    local effectiveCapacity = capacity == 0 and math.huge or capacity
    
    local changedFillType = false

    if fillUnit.fillType == fillTypeIndex then
        local newFillLevel = oldFillLevel + delta
        fillUnit.fillLevel = math.max(0, math.min(effectiveCapacity, newFillLevel))
    elseif delta > 0 then
        if not self:getFillUnitAllowsFillType(fillUnitIndex, fillTypeIndex) then
            return 0
        end

        local previousFillType = fillUnit.fillType
        if oldFillLevel > 0 then
            local removeVehicleIfEmpty = spec.removeVehicleIfEmpty
            spec.removeVehicleIfEmpty = false
            self:addFillUnitFillLevel(farmId, fillUnitIndex, -math.huge, fillUnit.fillType, toolType, fillInfo)
            spec.removeVehicleIfEmpty = removeVehicleIfEmpty
        end

        fillUnit.fillLevel = math.max(0, math.min(effectiveCapacity, delta))
        fillUnit.fillType = fillTypeIndex
        self.rootVehicle:raiseStateChange(VehicleStateChange.FILLTYPE_CHANGE)
        SpecializationUtil.raiseEvent(self, "onChangedFillType", fillUnitIndex, fillTypeIndex, previousFillType)
        oldFillLevel = 0
        changedFillType = true
    end

    if fillUnit.fillLevel < 0.00001 then
        fillUnit.fillLevel = 0
    end

    -- Debug für ALLE FillTypes unter 10%
    if DEBUG and fillUnit.fillLevel < (capacity * 0.1) then
        local fillTypeName = g_fillTypeManager:getFillTypeNameByIndex(fillTypeIndex)
        dprint(string.format("%s unter 10%%: %.3f L / %.3f L (%.1f%%)", 
            fillTypeName or "UNKNOWN",
            fillUnit.fillLevel, capacity, (fillUnit.fillLevel / capacity) * 100))
    end

    if fillUnit.fillLevel > 0 then
        fillUnit.lastValidFillType = fillUnit.fillType
    else
        SpecializationUtil.raiseEvent(self, "onChangedFillType", fillUnitIndex, FillType.UNKNOWN, fillUnit.fillType)
        fillUnit.fillType = FillType.UNKNOWN
        if not fillUnit.fillTypeToDisplayIsPersistent then
            fillUnit.fillTypeToDisplay = FillType.UNKNOWN
        end
        if not fillUnit.fillLevelToDisplayIsPersistent then
            fillUnit.fillLevelToDisplay = nil
        end
    end

    local appliedDelta = fillUnit.fillLevel - oldFillLevel

    if self.isServer and fillUnit.synchronizeFillLevel then
        local changed = false
        if fillUnit.fillLevel ~= fillUnit.fillLevelSent then
            local numBits = 2^fillUnit.synchronizationNumBits - 1
            local precision = fillUnit.capacity / numBits
            local diff = fillUnit.fillLevel - fillUnit.fillLevelSent
            if precision < math.abs(diff) then
                fillUnit.fillLevelSent = fillUnit.fillLevel
                changed = true
            end
        end
        if fillUnit.fillType ~= fillUnit.fillTypeSent then
            fillUnit.fillTypeSent = fillUnit.fillType
            changed = true
        end
        if fillUnit.lastValidFillType ~= fillUnit.lastValidFillTypeSent then
            fillUnit.lastValidFillTypeSent = fillUnit.lastValidFillType
            changed = true
        end
        if changed then
            self:raiseDirtyFlags(spec.dirtyFlag)
        end
    end

    if fillUnit.updateMass then
        self:setMassDirty()
    end

    self:updateFillUnitAutoAimTarget(fillUnit)

    if self.isClient then
        self:updateAlarmTriggers(fillUnit.alarmTriggers)
        self:updateFillUnitFillPlane(fillUnit)
        self:updateMeasurementNodes(fillUnit, 0, true)
        if changedFillType then
            self:updateFillTypeMaterials(fillUnit.fillTypeMaterials, fillUnit.fillType)
        end
    end

    SpecializationUtil.raiseEvent(self, "onFillUnitFillLevelChanged", fillUnitIndex, delta, fillTypeIndex, toolType, fillInfo, appliedDelta)

    if self.isServer and spec.removeVehicleIfEmpty and fillUnit.fillLevel <= spec.removeVehicleThreshold and delta ~= 0 then
        if spec.removeVehicleDelay == 0 then
            self:delete()
            if spec.removeVehicleReward > 0 then
                g_currentMission:addMoney(spec.removeVehicleReward, self:getOwnerFarmId(), MoneyType.SOLD_PRODUCTS, true, true)
            end
        else
            Timer.createOneshot(spec.removeVehicleDelay, function()
                self:delete()
                if spec.removeVehicleReward > 0 then
                    g_currentMission:addMoney(spec.removeVehicleReward, self:getOwnerFarmId(), MoneyType.SOLD_PRODUCTS, true, true)
                end
            end)
        end
    end

    if appliedDelta > 0 then
        if #spec.fillEffects > 0 then
            g_effectManager:setEffectTypeInfo(spec.fillEffects, fillUnit.fillType)
            g_effectManager:startEffects(spec.fillEffects)
            spec.activeFillEffects[spec.fillEffects] = 500
        end
        if #fillUnit.fillEffects > 0 then
            g_effectManager:setEffectTypeInfo(fillUnit.fillEffects, fillUnit.fillType)
            g_effectManager:startEffects(fillUnit.fillEffects)
            spec.activeFillEffects[fillUnit.fillEffects] = 500
        end
        if #spec.animationNodes > 0 then
            g_animationManager:startAnimations(spec.animationNodes)
            spec.activeFillAnimations[spec.animationNodes] = 500
        end
        if #fillUnit.animationNodes > 0 then
            g_animationManager:startAnimations(fillUnit.animationNodes)
            spec.activeFillAnimations[fillUnit.animationNodes] = 500
        end
        if fillUnit.fillAnimation ~= nil and fillUnit.fillAnimationLoadTime ~= nil then
            local currentTime = self:getAnimationTime(fillUnit.fillAnimation)
            local timeDiff = fillUnit.fillAnimationLoadTime - currentTime
            local direction = math.sign(timeDiff)
            if direction ~= 0 then
                self:playAnimation(fillUnit.fillAnimation, direction, currentTime)
                self:setAnimationStopTime(fillUnit.fillAnimation, fillUnit.fillAnimationLoadTime)
            end
        end
    end

    if appliedDelta ~= 0 then
        for _, animation in ipairs(fillUnit.fillLevelAnimations) do
            if fillUnit.fillLevel > 0 or animation.resetOnEmpty then
                local currentTime = self:getAnimationTime(animation.name)
                local fillPct = fillUnit.fillLevel / fillUnit.capacity
                local targetTime = animation.useMaxStateIfEmpty and fillUnit.fillLevel == 0 and 1 or fillPct
                targetTime = not animation.updateWhileFilled and delta > 0 and 1 or targetTime
                self:setAnimationStopTime(animation.name, targetTime)
                local direction = math.sign(targetTime - currentTime)
                self:playAnimation(animation.name, direction, currentTime, true)
            end
        end
    end

    if fillUnit.fillLevel < 0.0001 and fillUnit.fillAnimation ~= nil and fillUnit.fillAnimationEmptyTime ~= nil then
        local currentTime = self:getAnimationTime(fillUnit.fillAnimation)
        local timeDiff = fillUnit.fillAnimationEmptyTime - currentTime
        local direction = math.sign(timeDiff)
        self:playAnimation(fillUnit.fillAnimation, direction, currentTime)
        self:setAnimationStopTime(fillUnit.fillAnimation, fillUnit.fillAnimationEmptyTime)
    end

    if self.setDashboardsDirty ~= nil then
        self:setDashboardsDirty()
    end

    FillUnit.updateUnloadActionDisplay(self)

    return appliedDelta
end

print("[FillUnitLowLevelFix] Aktiv – ALLE Tanks können nun unter 10% fallen.")