local appName, app                             = ...
---@class AbilityTimeline
local private                                  = app
local AceGUI                                   = LibStub("AceGUI-3.0")

private.activeFrames                             = {}
private.ENCOUNTER_TIMELINE_EVENT_ADDED         = function(self, eventInfo, initialState)
   if not private.TIMELINE_FRAME.frame:IsVisible() then
      private.handleFrame(true)
   end
   private.Debug(eventInfo, "New event added to timeline")
   -- According to moores law we could also do not (bwdisabled or dbmdisabled) but this is easier to read
   if (not private.DisableBlizzTimersBW and not private.DisableBlizzTimersDBM) or eventInfo.source == Enum.EncounterTimelineEventSource.Script or eventInfo.source == Enum.EncounterTimelineEventSource.EditMode then
      private.addEvent(eventInfo)
   end
end

private.TIMELINE_TICKS                         = { 5 }
private.AT_THRESHHOLD                          = 0.8
private.AT_THRESHHOLD_TIME                     = 10

private.BIGICON_THRESHHOLD_TIME                = 5

private.createTimelineIcon                     = function(eventInfo)
   local frame = AceGUI:Create("AtAbilitySpellIcon")
   frame:SetEventInfo(eventInfo)
   private.activeFrames[eventInfo.id] = frame
   frame.frame:Show()

   private.Debug(frame, "AT_TIMELINE_ICON")
   local copyTable = CopyTable(private.activeFrames, true)
   private.Debug(copyTable, "Active frames after adding new icon")
end
local activeEvents                             = {}
private.addEvent                               = function(eventInfo)
   --local durationObject = C_EncounterTimeline.GetEventTimer(eventInfo.id)
   --activeEvents[eventInfo.id]=durationObject
   if GetCVar("encounterTimelineHideLongCountdowns") and GetCVar("encounterTimelineHideLongCountdowns") ~= "0" then
      local trackID = C_EncounterTimeline.GetEventTrack(eventInfo.id)
      local trackType = C_EncounterTimeline.GetTrackType(trackID)
      if trackType == Enum.EncounterTimelineTrackType.Hidden then
         private.Debug("Hidden track, not adding icon for eventID", eventInfo.id)
         return
      end
   end
   private.createTimelineIcon(eventInfo)
end

private.removeEvent                            = function(eventInfo)
   private.removeAtIconFrame(eventInfo.id)
end

private.ENCOUNTER_STATES                       = {
   Active = 0,
   Paused = 1,
   Finished = 2,
   Canceled = 3,
   Blocked = 4,
}

private.removeAtIconFrame                      = function(eventID)
   local frame = private.activeFrames[eventID]
   if frame then
      frame.frame:Hide()
      frame:Release()
      private.activeFrames[eventID] = nil
   end
end

private.ENCOUNTER_TIMELINE_EVENT_STATE_CHANGED = function(self, eventID)
   local newState = C_EncounterTimeline.GetEventState(eventID)
   if newState == private.ENCOUNTER_STATES.Finished then
      private.removeAtIconFrame(eventID)
      if not C_EncounterTimeline.HasAnyEvents() then
         private.handleFrame(false)
      end
   elseif newState == private.ENCOUNTER_STATES.Canceled then
      private.removeAtIconFrame(eventID)
      if not C_EncounterTimeline.HasAnyEvents() then
         private.handleFrame(false)
      end
   elseif newState == private.ENCOUNTER_STATES.Paused then
   elseif newState == private.ENCOUNTER_STATES.Active then
   end
end

private.ENCOUNTER_TIMELINE_EVENT_TRACK_CHANGED = function(self, eventID)
   if not GetCVar("encounterTimelineHideLongCountdowns") or GetCVar("encounterTimelineHideLongCountdowns") == "0" then
      return
   end
   local trackID = C_EncounterTimeline.GetEventTrack(eventID)
   local trackType = C_EncounterTimeline.GetTrackType(trackID)
   if trackType == Enum.EncounterTimelineTrackType.Hidden then
      private.Debug("Hidden track, removing icon if exists for eventID", eventID)
      private.removeAtIconFrame(eventID)
      if not C_EncounterTimeline.HasAnyEvents() then
         private.handleFrame(false)
      end
   elseif not activeEvents[eventID] then
      local remainingTime = C_EncounterTimeline.GetEventTimeRemaining(eventID)
      if remainingTime <= 1 then
         return
      end
      private.Debug("New event tracked, adding icon for eventID", eventID)
      private.addEvent(C_EncounterTimeline.GetEventInfo(eventID))
   end
end

private.HIGHLIGHT_EVENTS                       = {
   BigIcons = {},
   HighlightTexts = {}
}
local highlightsTriggered                      = {}
-- private.EventTicker = C_Timer.NewTicker(0.1, function ()
--    for eventID, durationObject in pairs(activeEvents) do
--       local timeLeft = durationObject:GetRemainingDuration()
--       if timeLeft <= private.BIGICON_THRESHHOLD_TIME and timeLeft > 0 and not highlightsTriggered[eventID] then
--          private.TRIGGER_HIGHLIGHT(C_EncounterTimeline.GetEventInfo(eventID))
--       end
--    end
-- end)


private.TRIGGER_HIGHLIGHT = function(eventInfo)
   highlightsTriggered[eventInfo.id] = true
   if private.db.global.bigicon_enabled[private.ACTIVE_EDITMODE_LAYOUT] and not private.HIGHLIGHT_EVENTS.BigIcons[eventInfo.id] then
      private.createBigIcon(eventInfo)
   end
   if private.db.global.text_highlight_enabled[private.ACTIVE_EDITMODE_LAYOUT] and not private.HIGHLIGHT_EVENTS.HighlightTexts[eventInfo.id] then
      private.createTextHighlight(eventInfo)
   end
   if private.db.profile.useAudioCountdowns then
      private.playAudioAlert(eventInfo)
   end
end
private.ENCOUNTER_TIMELINE_EVENT_REMOVED = function(self, eventID)
   if not C_EncounterTimeline.HasAnyEvents() then
      private.handleFrame(false)
   end
   if private.activeFrames[eventID] then
      private.removeEvent(eventID)
   end
end


private.createTimelineFrame = function()
   private.TIMELINE_FRAME = AceGUI:Create("AtTimelineFrame")

   private.BIGICON_FRAME = AceGUI:Create("AtBigIconFrame")


   private.TEXT_HIGHLIGHT_FRAME = AceGUI:Create("AtTextHighlightFrame")

   private.Debug(private.TEXT_HIGHLIGHT_FRAME, "AT_TEXT_HIGHLIGHT_FRAME")
   private.Debug(private.TIMELINE_FRAME, "AT_TIMELINE_FRAME")
end

private.handleFrame = function(show)
   if show then
      if not private.TIMELINE_FRAME.frame then
         private.createTimelineFrame()
      end
      private.TIMELINE_FRAME.frame:Show()
   else
      if private.TIMELINE_FRAME.frame then
         private.TIMELINE_FRAME.frame:Hide()
      end
      private.removeAllFrames()
   end
end

private.removeAllFrames = function()
   for eventID, frame in pairs(private.activeFrames) do
      private.removeAtIconFrame(eventID)
   end
end
