--core/event_counter.lua, counts how often every game event fires during an encounter (backend).
--a diagnostic: on ENCOUNTER_START, if the checkbox is enabled, the frame registers ALL events
--and tallies each one until ENCOUNTER_END. the per-event totals feed the event panel. counting
--every event is deliberately heavy (that is the point -- it shows which events are expensive),
--so it is opt-in and only runs for the duration of a boss encounter.

local _ = nil
local addonName, private = ...

private.Core = private.Core or {}

---@class FPSPP_EventCounter
local EventCounter = {}
private.Core.EventCounter = EventCounter

--[eventName] = number of times it fired during the current/last encounter.
EventCounter.counts = {}
--true while all events are registered and being tallied.
EventCounter.active = false

--frame that receives the events. it always listens for the encounter triggers, and registers
--every other event only while counting.
local counterFrame = CreateFrame("Frame")

--the event handler. hot path while active: RegisterAllEvents means this runs for every event
--the client fires (combat log included), so the tally is kept inline and minimal.
local onEvent = function(self, event)
	if EventCounter.active then
		if event == "ENCOUNTER_END" then
			EventCounter:Finish()
		else
			EventCounter.counts[event] = (EventCounter.counts[event] or 0) + 1
		end
	elseif event == "ENCOUNTER_START" then
		EventCounter:Begin()
	end
end

--returns true while events are being tallied.
---@return boolean
function EventCounter:IsActive()
	return self.active
end

--returns the live [eventName] = count table.
---@return table
function EventCounter:GetCounts()
	return self.counts
end

--starts a fresh tally and registers all events -- but only if the checkbox is enabled. called
--from ENCOUNTER_START.
function EventCounter:Begin()
	if not private.Core.Profile:GetBool("event_counter.enabled") then
		return
	end

	wipe(self.counts)
	self.active = true
	counterFrame:RegisterAllEvents()
end

--stops tallying (keeping the final counts on screen) and restores just the encounter triggers
--so the next encounter can start again. called from ENCOUNTER_END.
function EventCounter:Finish()
	if not self.active then
		return
	end

	self.active = false
	counterFrame:UnregisterAllEvents()
	counterFrame:RegisterEvent("ENCOUNTER_START")
	counterFrame:RegisterEvent("ENCOUNTER_END")
end

--registers the encounter triggers and the handler. called once from OnInit.
function EventCounter:Initialize()
	counterFrame:RegisterEvent("ENCOUNTER_START")
	counterFrame:RegisterEvent("ENCOUNTER_END")
	counterFrame:SetScript("OnEvent", onEvent)
end
