if isClient() then return end

local TABAS_Utils = require("TABAS_Utils")
local TABAS_GT = require("TABAS_GameTimes")
local TFC_Utils = require("TABAS_TFCSystem_Utils")

local fillRate = 0.08
local drainRate = 0.2
local reheatRate = 0.01

local function tubWaterActivate()
    local gData = GetTFCSystemData()
    local activated = gData.Activated
    local world = getWorld()
    local water = Fluid.Water
    for k, v in pairs(activated) do
        if not v.tfc then
            v.tfc = TABAS_Utils.getTfcBase(v.x, v.y, v.z, v.f)
            if not v.bath and v.tfc then
                v.bath = v.tfc.bathObject
            end
        elseif not v.emitter then
            v.emitter = world:getFreeEmitter(v.x + 0.5, v.y + 0.5, v.z)
            world:setEmitterOwner(v.emitter, v.bath)
        end
    end
    for k, v in pairs(activated) do
        if not v.activate then
            if v.emitter then v.emitter:stopAll() end
            v.emitter = nil
            activated[k] = nil
            TFCSystemTransmit()
            TFC_Utils.noise("TFC Activate", "Finished! " .. tostring(k))
        elseif v.tfc and v.bath and v.emitter then
            if v.state == "fill" then
                local amount = fillRate * TABAS_GT.GameTime:getMultiplier()
                local endAmount = fillRate * 160 * (60 / TABAS_GT.GameTime:getMinutesPerDay())
                if v.bath:hasFluid () and not v.tfc:isFull() and v.tfc:canAddFluid(water) then
                    v.bath:useFluid(amount)
                    v.tfc:addWater(amount)
                    if not v.emitter:isPlaying("tabas_tubwater_runout") then
                        if v.bath:getFluidAmount() <= endAmount then
                            v.emitter:stopAll()
                            v.emitter:playSoundImpl("tabas_tubwater_runout", v.bath)
                        elseif v.emitter:isEmpty() then
                            v.emitter:playSoundImpl("tabas_tubwater_fill", v.bath)
                        elseif not v.emitter:isPlaying("tabas_tubwater_fill") and v.bath:getFluidAmount() > endAmount then
                            v.emitter:stopAll()
                            v.emitter:playSoundImpl("tabas_tubwater_fill", v.bath)
                        end
                    elseif v.bath:getFluidAmount() > endAmount then
                        v.emitter:stopAll()
                    end
                else
                    v.activate = false
                    TFC_Utils.noise("Fill Tub Water", "Finished! " .. tostring(k))
                end
            elseif v.state == "empty" then
                if not v.tfc:isEmpty() then
                    local ratio = v.tfc:getRatio()
                    local endAmount = drainRate * 200 * (60 / TABAS_GT.GameTime:getMinutesPerDay())
                    local amount = drainRate * TABAS_GT.GameTime:getMultiplier()
                    v.tfc:removeFluid(amount)
                    if v.emitter:isEmpty() then
                        v.emitter:playSoundImpl("tabas_tubwater_drain_loop", v.bath)
                    elseif v.tfc:getAmount() < endAmount and not v.emitter:isPlaying("tabas_tubwater_drain_finish") then
                        v.emitter:stopAll()
                        v.emitter:playSoundImpl("tabas_tubwater_drain_finish", v.bath)
                    end
                else
                    v.tfc:remove()
                    v.activate = false
                    TFC_Utils.noise("Empty Tub Water", "Finished! " .. tostring(k))
                end
            elseif v.state == "reheat" then
                if TABAS_Utils.canHot(v.bath) then
                    local currntTempe = v.tfc:getWaterData("temperature")
                    if currntTempe <= v.tfc:getBathData("idealTemperature") then
                        if not v.emitter:isPlaying("tabas_tubwater_reheat") then
                            v.emitter:playSoundLoopedImpl("tabas_tubwater_reheat")
                        end
                        v.tfc:setWaterTemperature(currntTempe + reheatRate * TABAS_GT.GameTime:getMultiplier())
                    else
                        v.activate = false
                        v.tfc:updateLastUpdate()
                        TFC_Utils.noise("Reheat Tub Water", "Finished! " .. tostring(k))
                    end
                else
                    v.activate = false
                    TFC_Utils.noise("Reheat Tub Water", "Not powered!" .. tostring(k))
                end
            else
                v.activate = false
            end
        end
    end
end

local function lowerWaterTemperature()
    if isClient() then return end
    if not SandboxVars.TakeABathAndShower.WaterTemperatureConcept then return end

    local decrease = SandboxVars.TakeABathAndShower.TubWaterTemperatureDecrease
    if decrease < 1 then return end
    local gData = GetTFCSystemData()
    local minTempe = 10
    for _, v in pairs(gData.Registered) do
        if v.temperature and v.temperature > minTempe then
            local lastUpdate = v.lastUpdate
            local m, h, d = TABAS_Utils.getDifferentialTime(lastUpdate)
            if h and h > 0 then
                v.temperature = v.temperature - decrease
                TFCSystemTransmit()
                if getCell():getGridSquare(v.x, v.y, v.z) then
                    local tfc_Base = TABAS_Utils.getTfcBase(v.x, v.y, v.z, v.f)
                    -- To sync data, simply call TFC_Base. Objects that are not loaded are deferred from sync.
                end
                TFC_Utils.noise("Lower Water Temperature", v.temperature + decrease .. " >> " .. v.temperature  .. ".")
            end
        end
    end
end

Events.OnTick.Add(tubWaterActivate)
Events.EveryHours.Add(lowerWaterTemperature)
