local DRTracker = {}

local AC = _G.ArenaCore

-- Ensure DR spell list is available
local DR_SPELL_CATEGORIES = AC and AC.DR_SPELL_LIST or {}
if not next(DR_SPELL_CATEGORIES) then
    DR_SPELL_CATEGORIES = {
        [108194] = "stun", [91800] = "stun", [853] = "stun", [408] = "stun", [1833] = "stun",
        [33786] = "disorient", [8122] = "disorient", [2094] = "disorient",
        [118] = "incapacitate", [51514] = "incapacitate",
        [15487] = "silence", [1330] = "silence",
    }
end

local MAX_ARENA_ENEMIES = MAX_ARENA_ENEMIES or 3

function DRTracker:IsSourceFriendly(sourceGUID, sourceFlags)
    -- DO NOT call AC:IsDRSourceFriendly - causes infinite recursion
    
    if sourceFlags and bit then
        local mine = bit.band(sourceFlags, COMBATLOG_OBJECT_AFFILIATION_MINE) > 0
        local party = bit.band(sourceFlags, COMBATLOG_OBJECT_AFFILIATION_PARTY) > 0
        local raid = bit.band(sourceFlags, COMBATLOG_OBJECT_AFFILIATION_RAID) > 0
        if mine or party or raid then
            return true
        end
    end

    if not sourceGUID then return false end

    if UnitGUID("player") == sourceGUID then return true end
    if UnitGUID("pet") == sourceGUID then return true end

    for i = 1, 4 do
        if UnitGUID("party" .. i) == sourceGUID then return true end
        if UnitGUID("partypet" .. i) == sourceGUID then return true end
    end

    return false
end

function DRTracker:GetUnitIDFromGUID(guid)
    if not guid then return nil end

    for i = 1, MAX_ARENA_ENEMIES do
        local unit = "arena" .. i
        if UnitGUID(unit) == guid then
            return unit
        end
    end

    return nil
end

function DRTracker:GetFrameForUnit(unitID)
    local manager = AC and AC.FrameManager
    if manager and manager.GetFrames then
        local frames = manager:GetFrames()
        if frames then
            local index = tonumber(unitID:match("arena(%d+)"))
            if index and frames[index] then
                return frames[index]
            end
        end
    end

    if AC and AC.arenaFrames then
        local index = tonumber(unitID:match("arena(%d+)"))
        if index and AC.arenaFrames[index] then
            return AC.arenaFrames[index]
        end
    end

    return nil
end

function DRTracker:EnsureDRModule()
    local manager = AC and AC.FrameManager
    if manager and manager.DR then
        return manager.DR
    end

    manager = AC and AC.MasterFrameManager
    if manager and manager.DR then
        return manager.DR
    end

    return nil
end

function DRTracker:UpdateDisplay(unitID, category, actualSpellID)
    local drModule = self:EnsureDRModule()
    if not drModule then return end

    drModule:UpdateLiveDisplay(unitID, category, actualSpellID)
end

function DRTracker:TrackApplication(unitGUID, spellID, category)
    local drModule = self:EnsureDRModule()
    if not drModule then return end

    drModule:TrackApplication(unitGUID, spellID, category)
end

function DRTracker:StartRealArenaTicker()
    local drModule = self:EnsureDRModule()
    if not drModule then return end

    drModule:StartRealArenaTicker()
end

function DRTracker:HandleCombatLog()
    if not AC then return end

    local timestamp, subevent, _, sourceGUID, sourceName, sourceFlags, _,
          destGUID, destName, destFlags, _, spellID, spellName, _, auraType = CombatLogGetCurrentEventInfo()

    if subevent == "SPELL_AURA_APPLIED" or subevent == "SPELL_AURA_REFRESH" then
        local friendly = self:IsSourceFriendly(sourceGUID, sourceFlags)
        if not friendly then
            return
        end

        local unitID = self:GetUnitIDFromGUID(destGUID)
        if not unitID then
            return
        end

        local drCategory = DR_SPELL_CATEGORIES[spellID]
        if not drCategory then
            return
        end

        if auraType ~= "DEBUFF" then
            return
        end

        self:TrackApplication(destGUID, spellID, drCategory)
        self:UpdateDisplay(unitID, drCategory, spellID)

    elseif subevent == "SPELL_AURA_REMOVED" then
        -- Optional future logic for removal
    end
end

function DRTracker:Initialize()
    if not AC then return end

    -- DO NOT register COMBAT_LOG here - it's called from main ArenaCore handler
    -- Registering here causes duplicate event processing and infinite loops
    
    self:StartRealArenaTicker()
end

AC.modules = AC.modules or {}
AC.modules.diminishingReturns = AC.modules.diminishingReturns or {}
AC.modules.diminishingReturns.tracker = DRTracker

return DRTracker
