local LGS = LibStub("LibGroupSocket")
local type, version = LGS.MESSAGE_TYPE_DPS, 1
local handler = LGS:RegisterHandler(type, version) -- TODO return saveData
if(not handler) then return end
local SKIP_CREATE = true
local Log = LGS.Log
local ON_RECEIVE_DPS = "OnReceiveDps"

local lastSendTime = 0

local function OnData(unitTag, data, isSelf)
    local index = 1
    local dps, index = LGS:ReadUint16(data, index)
    local randomOne, index = LGS:ReadUint8(data, index)
    local time, index = LGS:ReadUint16(data, index)
    local randomTwo, index = LGS:ReadUint16(data, index)
--    Log("OnData %s (%d byte): dps: %s, time: %s, randomOne: %s, randomTwo: %s", GetUnitName(unitTag), #data, tostring(dps), tostring(time), tostring(randomOne), tostring(randomTwo))

    local expectedLength = 7
    if(#data < expectedLength) then Log("DpsHandler received only %d of %d byte", #data, expectedLength) return end

    LGS.cm:FireCallbacks(ON_RECEIVE_DPS, GetUnitName(unitTag), dps, time, isSelf)
end

local saveData = {
    enabled = true,
} -- TODO

local MIN_SEND_TIMEOUT = 2
local MIN_COMBAT_SEND_TIMEOUT = 1
function handler:Send(dps, time)
    if(not saveData.enabled or not IsUnitGrouped("player")) then return end
    local now = GetTimeStamp()
    local timeout = IsUnitInCombat("player") and MIN_COMBAT_SEND_TIMEOUT or MIN_SEND_TIMEOUT
    if(now - lastSendTime < timeout) then return end
    --only ping when in combat
    if not IsUnitInCombat("player") then return end

    if dps == nil or time == nil then return end

    local data = {}
    local index = 1
    index = LGS:WriteUint16(data, index, dps)
    index = LGS:WriteUint8(data, index, 123)
    index = LGS:WriteUint16(data, index, time)
    index = LGS:WriteUint16(data, index, 54321)
    index = index + 1

    lastSendTime = now
--    Log("Send %d byte: dps: %d / time: %d", #data, AdvancedDpsSharing.tempVars.dps, AdvancedDpsSharing.tempVars.time)
    LGS:Send(type, data)
end

function handler:RegisterForReceiveDps(callback)
    LGS.cm:RegisterCallback(ON_RECEIVE_DPS, callback)
end

function handler:UnregisterForReceiveDps(callback)
    LGS.cm:UnregisterCallback(ON_RECEIVE_DPS, callback)
end

local function OnUpdate()
    handler:Send()
end

local isActive = false

local function StartSending()
    if(not isActive and saveData.enabled and IsUnitGrouped("player")) then
        EVENT_MANAGER:RegisterForUpdate("LibGroupSocketDpsHandler", 1000, OnUpdate)
        isActive = true
    end
end

local function StopSending()
    if(isActive) then
        EVENT_MANAGER:UnregisterForUpdate("LibGroupSocketDpsHandler")
        isActive = false
    end
end

local function OnCombat(inCombat)
    if inCombat and IsUnitGrouped("player") then
        StartSending()
    else
        StopSending()
    end
end

local function Unload()
    LGS.cm:UnregisterCallback(type, handler.dataHandler)
--    EVENT_MANAGER:UnregisterForEvent("LibGroupSocketDpsHandler", EVENT_PLAYER_COMBAT_STATE)
    StopSending()
end

local function Load()
    handler.dataHandler = OnData
    LGS.cm:RegisterCallback(type, OnData)
--    EVENT_MANAGER:RegisterForEvent("LibGroupSocketDpsHandler", EVENT_PLAYER_COMBAT_STATE, OnCombat)
    handler.Unload = Unload

    StartSending()
end

if(handler.Unload) then handler.Unload() end
Load()