local frame = CreateFrame("Frame", "RockyCoreWoWDeckHelperFrame")

-- Deliberately NOT registered: SPELL_UPDATE_COOLDOWN, SPELL_UPDATE_CHARGES,
-- BAG_UPDATE_DELAYED and ACTIONBAR_SHOWGRID. They fire constantly in combat but
-- never change which action sits in a slot, and the Stream Deck reads none of
-- the cooldown/charge/count data. SavedVariables only reach disk on /reload or
-- logout, so refreshing between those is work nothing ever reads.

-- Full refresh triggers — these change what's IN the slots
local FULL_REFRESH_EVENTS = {
    "PLAYER_LOGIN",
    "PLAYER_SPECIALIZATION_CHANGED",
    "ACTIVE_TALENT_GROUP_CHANGED",
    "UPDATE_SHAPESHIFT_FORM",
    "UPDATE_VEHICLE_ACTIONBAR",
    "UPDATE_OVERRIDE_ACTIONBAR",
    "UPDATE_POSSESS_BAR",
    "ACTIONBAR_PAGE_CHANGED",
    "UPDATE_BONUS_ACTIONBAR",
    "PLAYER_TALENT_UPDATE",
    "TRAIT_CONFIG_UPDATED",  -- Dragonflight+ talent system
}

-- Slot-specific update triggers
local SLOT_UPDATE_EVENTS = {
    "ACTIONBAR_SLOT_CHANGED",   -- payload: slot number (0 = all slots)
    "UPDATE_BINDINGS",          -- keybind changes
}

-- Only the player's own vehicle transitions matter; plain RegisterEvent would
-- fire these for every member of the group
local UNIT_EVENTS = {
    "UNIT_ENTERED_VEHICLE",
    "UNIT_EXITED_VEHICLE",
}

for _, event in ipairs(FULL_REFRESH_EVENTS) do
    frame:RegisterEvent(event)
end
for _, event in ipairs(SLOT_UPDATE_EVENTS) do
    frame:RegisterEvent(event)
end
for _, event in ipairs(UNIT_EVENTS) do
    frame:RegisterUnitEvent(event, "player")
end

-- Throttle bursts (a bar rearrange fires many slot-changed events). Generous,
-- because nothing reaches the Stream Deck until the next flush anyway.
local pendingRefresh = false
local THROTTLE_SECONDS = 2

local function ScheduleRefresh()
    if pendingRefresh then return end
    pendingRefresh = true
    C_Timer.After(THROTTLE_SECONDS, function()
        pendingRefresh = false
        RockyCoreWoWDeckHelper:RefreshAll()
        -- Bump timestamp so file watcher notices even if Lua table looks same
        RockyCoreWoWDeckHelper_State.timestamp = time()
    end)
end

frame:SetScript("OnEvent", function(self, event, ...)
    if event == "PLAYER_LOGIN" then
        RockyCoreWoWDeckHelper:Initialize()
        return
    end

    if event == "ACTIONBAR_SLOT_CHANGED" then
        local slot = ...
        if slot == 0 then
            -- 0 means ALL slots changed (page change, vehicle enter, etc.)
            ScheduleRefresh()
        else
            -- Update only the changed slot
            RockyCoreWoWDeckHelper_State.slots[slot] = RockyCoreWoWDeckHelper.ActionBar:GetSlotData(slot)
            RockyCoreWoWDeckHelper_State.timestamp = time()
        end
        return
    end

    -- All other events: full refresh
    ScheduleRefresh()
end)

-- Slash command: force a flush
SLASH_ROCKYCORE1 = "/rwd"
SLASH_ROCKYCORE2 = "/rockycore"
SlashCmdList["ROCKYCORE"] = function(msg)
    if msg == "refresh" then
        RockyCoreWoWDeckHelper:RefreshAll()
        print("RockyCore WoWDeck: state refreshed.")
    elseif msg == "reload" then
        ReloadUI()
    elseif msg == "debug" then
        RockyCoreWoWDeckHelper.debug = not RockyCoreWoWDeckHelper.debug
        print("RockyCore WoWDeck: capture logging " ..
            (RockyCoreWoWDeckHelper.debug and "on" or "off") .. ".")
    else
        print("RockyCore WoWDeck: /rwd refresh | reload | debug")
    end
end
