timer_manager = {
    timers = {},
    timer_names = {},
}

function timer_manager:CreateTimer(name, time, rep, func, ...)
    if self.timers[name] then return end

    self.timers[name] = {
        fullTime = time,
        time = time,
        rep = rep,
        func = func,
        func_args = arg
    }
    self.timer_names[#self.timer_names+1] = name
    -- if type(func) == "string" then
    --     RegisterListenerTo("timer-"..name, func)
    -- end
end

function timer_manager:ClearTimer(name)
    if not self.timers[name] then return end

    local func = self.timers[name].func
    -- if type(func) == "string" then
    --     UnregisterListener("timer-"..name, func)
    -- end
    self.timers[name] = nil
    for i = 1, #self.timer_names do
        if self.timer_names[i] == name then
            table.remove(self.timer_names, i)
            break
        end
    end
end

function timer_manager:GetTimerValue(name)
    if self.timers[name] ~= nil then return self.timers[name].time else return 0.0 end
end

function timer_manager:FullReset()
    -- for k, v in pairs(self.timers) do
    --     if v.func == "string" then
    --         UnregisterListener("timer-"..k, v.func)
    --     end
    -- end
    self.timers = {}
    self.timer_names = {}
end

function timer_manager:ResetTimer(name)
    if not self.timers[name] then return end

    self.timers[name].time = self.timers[name].fullTime
end

function timer_manager:ChangeTimerDuration(name, changeTime)
    if not self.timers[name] then return end

    self.timers[name].time = self.timers[name].time - changeTime
end

function timer_manager:Tick(dt)
    local timeScale = 1.0
    if HasKey("level.time-scale") then
        timeScale = GetFloat("level.time-scale")
    end

    local timersToRemove = {}
    -- for k,v in pairs(self.timers) do -- pairs is unpredictable
    for i = 1, #self.timer_names do
        local k = self.timer_names[i]
        local v = self.timers[k]
        if v then
            v.time = v.time - dt/timeScale
            if v.time < 0 then
                -- if type(v.func) == "string" then
                --     TriggerEvent("timer-"..k, table.concat(v.func_args, ";"))
                -- else
                    v.func(unpack(v.func_args))
                -- end

                if v.rep then
                    v.time = v.fullTime
                else
                    table.insert(timersToRemove, k)
                end
            end
        end
    end

    for i=1, #timersToRemove do
        self:ClearTimer(timersToRemove[i])
    end
end
