-- W900 Cistern - Vehicle to Vehicle Refueling
-- Real-time fuel transfer like vanilla, not end-of-action like TsarsLib

require "TimedActions/ISBaseTimedAction"
require "W900_CisternParts"

ISRefuelFromW900Cistern = ISBaseTimedAction:derive("ISRefuelFromW900Cistern")

function ISRefuelFromW900Cistern:isValid()
    return self.vehicle:isInArea(self.part:getArea(), self.character) and 
           W900CisternParts.isValidVehicleGasDestination(self.part) and
           W900CisternParts.isValidGasSourcePart(self.sourcePart) and
           self.sourcePart:getContainerContentAmount() > 0
end

function ISRefuelFromW900Cistern:waitToStart()
    self.character:faceThisObject(self.vehicle)
    return self.character:shouldBeTurning()
end

function ISRefuelFromW900Cistern:update()
    -- Real-time transfer like vanilla ISRefuelFromGasPump
    local litres = self.tankStart + (self.tankTarget - self.tankStart) * self:getJobDelta()
    litres = math.floor(litres)
    
    if litres ~= self.amountSent then
        if self.vehicle and self.part then
            -- Update destination tank
            self.part:setContainerContentAmount(litres)
            self.vehicle:transmitPartModData(self.part)
            
            -- Update source tank (cistern)
            local sourceAmount = self.sourceStart - (litres - self.tankStart)
            self.sourcePart:setContainerContentAmount(sourceAmount)
            self.sourceVehicle:transmitPartModData(self.sourcePart)
            
            self.amountSent = litres
        end
    end
    
    self.character:setMetabolicTarget(Metabolics.HeavyDomestic)
end

function ISRefuelFromW900Cistern:start()
    self:setActionAnim("fill_container_tap")
    self:setOverrideHandModels(nil, nil)
    self.character:reportEvent("EventTakeWater")
    self.sound = self.character:playSound("VehicleAddFuelFromGasPump")
end

function ISRefuelFromW900Cistern:stop()
    self.character:stopOrTriggerSound(self.sound)
    ISBaseTimedAction.stop(self)
end

function ISRefuelFromW900Cistern:serverStop()
    -- Sync final amounts on server stop
    local litres = self.tankStart + (self.tankTarget - self.tankStart) * self.netAction:getProgress()
    litres = math.floor(litres)
    
    self.part:setContainerContentAmount(litres)
    self.vehicle:transmitPartModData(self.part)
    
    local sourceAmount = self.sourceStart - (litres - self.tankStart)
    self.sourcePart:setContainerContentAmount(sourceAmount)
    self.sourceVehicle:transmitPartModData(self.sourcePart)
end

function ISRefuelFromW900Cistern:perform()
    self.character:stopOrTriggerSound(self.sound)
    ISBaseTimedAction.perform(self)
end

function ISRefuelFromW900Cistern:complete()
    if self.vehicle and self.part then
        self.part:setContainerContentAmount(self.tankTarget)
        self.vehicle:transmitPartModData(self.part)
        
        local sourceAmount = self.sourceStart - (self.tankTarget - self.tankStart)
        self.sourcePart:setContainerContentAmount(sourceAmount)
        self.sourceVehicle:transmitPartModData(self.sourcePart)
    end
    return true
end

function ISRefuelFromW900Cistern:getDuration()
    if not W900CisternParts.isValidVehicleGasDestination(self.part) or not W900CisternParts.isValidGasSourcePart(self.sourcePart) then
        self.tankStart = 0
        self.sourceStart = 0
        self.tankTarget = 0
        self.amountSent = 0
        return 0
    end

    self.tankStart = self.part:getContainerContentAmount()
    self.sourceStart = self.sourcePart:getContainerContentAmount()
    
    local tankLitresFree = self.part:getContainerCapacity() - self.tankStart
    local sourceLitresAvail = self.sourceStart
    
    -- Transfer the minimum of what's available and what fits
    local takeLitres = math.min(tankLitresFree, sourceLitresAvail)
    
    self.tankTarget = self.tankStart + takeLitres
    self.amountSent = self.tankStart
    
    -- 50 time units per litre (same as vanilla)
    return takeLitres * 50
end

function ISRefuelFromW900Cistern:new(character, part, sourcePart)
    local o = ISBaseTimedAction.new(self, character)
    o.vehicle = part:getVehicle()
    o.part = part
    o.sourcePart = sourcePart
    o.sourceVehicle = sourcePart:getVehicle()
    o.stopOnWalk = true
    o.stopOnRun = true
    o.maxTime = o:getDuration()
    return o
end
