--/run WeakAuras.ScanEvents("UPDATE_FRAME_GLOW")
--ID_UPDATED UPDATE_FRAME_GLOW PLAYER_REGEN_DISABLED PLAYER_REGEN_ENABLED GROUP_ROSTER_UPDATE
--ElvUF_Focus.Health
--ElvUF_TargetTarget.Health
function(e, id)
    if not aura_env.ticker then aura_env.ticker = C_Timer.NewTicker(0.1, function() WeakAuras.ScanEvents("UPDATE_FRAME_GLOW") end) end
    if e == "PLAYER_REGEN_DISABLED" or e == "PLAYER_REGEN_ENABLED" then
        WeakAuras.ScanEvents("UPDATE_FRAME_GLOW")
    elseif e == "UPDATE_FRAME_GLOW" then
        local hptable = {["hp"] = 1e21, ["id"] = 0, ["mhp"] = 0, ["php"] = 100}
        for i = 1, GetNumGroupMembers() do
            --if UnitHealthMax("raid" .. i) - UnitHealth("raid" .. i) > hptable.mhp then --Missing HP
            if UnitIsConnected("raid" .. i) == true then
                if UnitHealth("raid" .. i) / UnitHealthMax("raid" .. i) < hptable.php then --% HP
                    if UnitHealth("raid" .. i) / UnitHealthMax("raid" .. i) < 0.6 and UnitHealth("raid" .. i) / UnitHealthMax("raid" .. i) > 0 and UnitIsConnected("raid" .. i) then
                        hptable.hp = UnitHealth("raid" .. i)
                        hptable.mhp = UnitHealthMax("raid" .. i) - UnitHealth("raid" .. i)
                        hptable.php = UnitHealth("raid" .. i) / UnitHealthMax("raid" .. i)
                        hptable.id = i
                        hptable.name = UnitName("raid" .. i)
                    end
                end
            end
        end
        if hptable.id ~= aura_env.lastID then
            WeakAuras.ScanEvents("ID_UPDATED", hptable.id)
            aura_env.lastID = hptable.id
        end

        if UnitExists("focus") then
            local fhp = UnitHealth("focus") / UnitHealthMax("focus")
            if fhp < 0.4 then
                ActionButton_ShowOverlayGlow(ElvUF_Focus.Health)
            else
                ActionButton_HideOverlayGlow(ElvUF_Focus.Health)
            end
        end
        if UnitExists("targettarget") then
            local tthp = UnitHealth("targettarget") / UnitHealthMax("targettarget")
            if tthp < 0.4 then
                print("QUICK GLOW OMG OMGO GMO")
                ActionButton_ShowOverlayGlow(ElvUF_TargetTarget.Health)
            else
                ActionButton_HideOverlayGlow(ElvUF_TargetTarget.Health)
            end
        end

    elseif e == "ID_UPDATED" then
        if id ~= aura_env.glowingPlate and aura_env.glowingPlate > 0 then
            ActionButton_HideOverlayGlow(aura_env.GetFrame("raid" .. aura_env.glowingPlate))
        end
        if aura_env.GetFrame("raid" .. id) then
            ActionButton_ShowOverlayGlow(aura_env.GetFrame("raid" .. id))
            aura_env.glowingPlate = id
        end
    end
end

--INIT
if not aura_env.ticker then aura_env.ticker = C_Timer.NewTicker(0.1, function() WeakAuras.ScanEvents("UPDATE_FRAME_GLOW") end) end
aura_env.lastID = 0
aura_env.glowingPlate = 0

local frame_priority = {
    -- raid frames
    [1] = "^Vd1", -- vuhdo
    [2] = "^Healbot", -- healbot
    [3] = "^GridLayout", -- grid
    [4] = "^Grid2Layout", -- grid2
    [5] = "^ElvUF_RaidGroup", -- elv
    [6] = "^oUF_bdGrid", -- bdgrid
    [7] = "^oUF.*raid", -- generic oUF
    [8] = "^LimeGroup", -- lime
    [9] = "^SUFHeaderraid", -- suf
    [10] = "^CompactRaid", -- blizz
    -- party frames
    [11] = "^SUFHeaderparty", --suf
    [12] = "^ElvUF_PartyGroup", -- elv
    [13] = "^oUF.*party", -- generic oUF
    [14] = "^PitBull4_Groups_Party", -- pitbull4
    [15] = "^CompactParty", -- blizz
    -- player frame
    [16] = "^SUFUnitplayer",
    [17] = "^PitBull4_Frames_Player",
    [18] = "^ElvUF_Player",
    [19] = "^oUF.*player",
    [20] = "^PlayerFrame",
}

WA_GetFramesCache = WA_GetFramesCache or {}
if not WA_GetFramesCacheListener then
    WA_GetFramesCacheListener = CreateFrame("Frame")
    local f = WA_GetFramesCacheListener
    f:RegisterEvent("PLAYER_REGEN_DISABLED")
    f:RegisterEvent("PLAYER_REGEN_ENABLED")
    f:RegisterEvent("GROUP_ROSTER_UPDATE")
    f:SetScript("OnEvent", function(self, event, ...)
            WA_GetFramesCache = {}
    end)
end

local function GetFrames(target)
    local function FindButtonsForUnit(frame, target)
        local results = {}
        if type(frame) == "table" and not frame:IsForbidden() then
            local type = frame:GetObjectType()
            if type == "Frame" or type == "Button" then
                for _,child in ipairs({frame:GetChildren()}) do
                    for _,v in pairs(FindButtonsForUnit(child, target)) do
                        tinsert(results, v)
                    end
                end
            end
            if type == "Button" then
                local unit = frame:GetAttribute('unit')
                if unit and frame:IsVisible() and frame:GetName() then
                    WA_GetFramesCache[frame] = unit
                    if UnitIsUnit(unit, target) then
                        -- print("F:", frame:GetName())
                        tinsert(results, frame)
                    end
                end
            end
        end
        return results
    end

    if not UnitExists(target) then
        if type(target) == "string" and target:find("Player") then
            target = select(6,GetPlayerInfoByGUID(target))
        else
            return {}
        end
    end

    local results = {}
    for frame, unit in pairs(WA_GetFramesCache) do
        --print("from cache:", frame:GetName())
        if UnitIsUnit(unit, target) then
            if frame:GetAttribute('unit') == unit then
                tinsert(results, frame)
            else
                results = {}
                break
            end
        end
    end

    return #results > 0 and results or FindButtonsForUnit(UIParent, target)
end

local isElvUI = IsAddOnLoaded("ElvUI")
local function WhyElvWhy(frame)
    if isElvUI and frame and frame:GetName():find("^ElvUF_") and frame.Health then
        return frame.Health
    else
        return frame
    end
end


function aura_env.GetFrame(target)
    local frames = GetFrames(target)
    if not frames then return nil end
    for i=1,#frame_priority do
        for _,frame in pairs(frames) do
            if (frame:GetName()):find(frame_priority[i]) then
                return WhyElvWhy(frame)
            end
        end
    end
    return WhyElvWhy(frames[1])
end
