-- Class icon auras (Midnight).

-- Mirrors Blizzard's arena DebuffFrame CC icon + cooldown swipe onto our class portrait.



local AC = _G.ArenaCore

if not AC then return end



if not (AC.Midnight and AC.Midnight.isMidnight) then return end



-- Master debug flag for aura debugging - set to false to completely disable all debug output
local AURA_DEBUG_ENABLED = false



local ClassIconAuras = {}

AC.ClassIconAuras = ClassIconAuras



local MAX_ARENA_ENEMIES = 3



ClassIconAuras.initialized = false

ClassIconAuras.hookedFrames = {}

ClassIconAuras.ccActive = {}

ClassIconAuras.importantActive = {}

ClassIconAuras.importantAuraData = {}



-- Check if class icon auras are disabled.

local function IsDisabled()

    local db = AC.DB and AC.DB.profile

    return db and db.classIcons and db.classIcons.showAuras == false

end



local function IsSpiralGlowLineEnabled()

    local db = AC.DB and AC.DB.profile

    if not (db and db.classIcons) then return true end

    return db.classIcons.spiralGlowLine ~= false

end



local function IsImportantAurasEnabled()

    local db = AC.DB and AC.DB.profile

    if not (db and db.classIcons) then return true end

    return db.classIcons.showImportantAuras ~= false

end



local function IsImportantSpiralGlowLineEnabled()

    local db = AC.DB and AC.DB.profile

    if not (db and db.classIcons) then return true end

    return db.classIcons.importantSpiralGlowLine ~= false

end



local function GetFontSize()

    local db = AC.DB and AC.DB.profile

    if db and db.classIcons and db.classIcons.fontSize then

        return db.classIcons.fontSize

    end

    return 14  -- Default font size

end



-- Midnight fires UNIT_AURA constantly, so we bail early when the payload
-- doesn't actually carry any changes worth reacting to.
local function AuraPayloadHasChanges(updateInfo)
    if not updateInfo or updateInfo.isFullUpdate then return true end
    local added   = updateInfo.addedAuras
    local updated = updateInfo.updatedAuraInstanceIDs
    local removed = updateInfo.removedAuraInstanceIDs
    if added   and #added   > 0 then return true end
    if updated and #updated > 0 then return true end
    if removed and #removed > 0 then return true end
    return false
end



-- Restore class icon after CC ends.

local function RestoreClassIcon(arenaIndex, classIcon, acFrame)

    classIcon.ccActive = false

    ClassIconAuras.ccActive[arenaIndex] = false

    if classIcon.auraCooldown then

        classIcon.auraCooldown:Clear()

    end

    if classIcon.importantAuraCooldown then
        classIcon.importantAuraCooldown:Clear()
        classIcon.importantAuraCooldown.durationObj = nil
    end



    local db = AC.DB and AC.DB.profile

    local showSpecInstead = db and db.classIcons and db.classIcons.showSpecInstead == true

    if showSpecInstead and acFrame and acFrame.specID and GetSpecializationInfoByID then

        local _, _, _, specIcon = GetSpecializationInfoByID(acFrame.specID)

        if specIcon and classIcon.icon and classIcon.icon.SetTexture then

            classIcon.icon:SetTexture(specIcon)

            if classIcon.icon.SetTexCoord then

                classIcon.icon:SetTexCoord(0.1, 0.9, 0.1, 0.9)

            end

        end

        if classIcon.overlay and classIcon.overlay.SetTexture then

            classIcon.overlay:SetTexture("Interface\\AddOns\\ArenaCore\\Media\\Classicons\\Overlays\\orangeoverlay.tga")

        end

        return

    end



    local storedClass = acFrame.class

    if storedClass and classIcon.UpdateClassIcon then

        classIcon.UpdateClassIcon(storedClass)

        -- Make sure border matches the user's setting after restoring the icon
        if classIcon.ApplyBorderStyle then
            classIcon.ApplyBorderStyle()
        end

    end

end



function ClassIconAuras:HookDebuffFrame(arenaIndex)

    local _, instanceType = IsInInstance()

    if instanceType ~= "arena" then return end

    if IsActiveBattlefieldArena and not IsActiveBattlefieldArena() then return end

    if self.hookedFrames[arenaIndex] then return end



    local blizzArenaFrame = _G["CompactArenaFrameMember" .. arenaIndex]

    if not blizzArenaFrame then return end



    local debuffFrame = blizzArenaFrame.DebuffFrame

    if not debuffFrame then return end



    local MFM = AC.MasterFrameManager

    local acFrame = MFM and MFM.frames and MFM.frames[arenaIndex]

    if not acFrame then return end



    local classIcon = acFrame.classIcon

    if not classIcon then return end



    -- Cooldown overlay: swipe + numbers.

    local okCooldown, cooldownOrErr = pcall(function()

        local cd = CreateFrame("Cooldown", nil, classIcon, "CooldownFrameTemplate")

        if cd.SetHideCountdownNumbers then

            cd:SetHideCountdownNumbers(false)

        end

        local r = { cd:GetRegions() }

        for i = 1, #r do

            local region = r[i]

            if region and region.GetObjectType and region:GetObjectType() == "FontString" and region.SetFont then

                region:SetFont(AC.FONT_PATH or "Interface\\AddOns\\ArenaCore\\Media\\Fonts\\arenacore.ttf", GetFontSize(), "OUTLINE")

            end

        end

        local anchor = classIcon.icon or classIcon

        cd:ClearAllPoints()

        cd:SetAllPoints(anchor)

        cd:SetDrawEdge(IsSpiralGlowLineEnabled())

        cd:SetDrawBling(false)

        cd:SetReverse(false)

        if cd.SetUseCircularEdge then

            cd:SetUseCircularEdge(true)

        end

        if cd.SetSwipeColor then

            cd:SetSwipeColor(0, 0, 0, 0.75)

        end

        return cd

    end)

    classIcon.auraCooldown = okCooldown and cooldownOrErr or nil



    -- Important Auras cooldown overlay: separate layer for priority

    local okImportantCooldown, importantCooldownOrErr = pcall(function()

        local cd = CreateFrame("Cooldown", nil, classIcon, "CooldownFrameTemplate")

        if cd.SetHideCountdownNumbers then

            cd:SetHideCountdownNumbers(false)

        end

        local r = { cd:GetRegions() }

        for i = 1, #r do

            local region = r[i]

            if region and region.GetObjectType and region:GetObjectType() == "FontString" and region.SetFont then

                -- Use ArenaCore's font for consistency and better visibility
                region:SetFont(AC.FONT_PATH or "Interface\\AddOns\\ArenaCore\\Media\\Fonts\\arenacore.ttf", GetFontSize(), "OUTLINE")

            end

        end

        local anchor = classIcon.icon or classIcon

        cd:ClearAllPoints()

        cd:SetAllPoints(anchor)

        cd:SetDrawEdge(IsImportantSpiralGlowLineEnabled())

        cd:SetDrawBling(false)

        cd:SetReverse(false)

        if cd.SetUseCircularEdge then

            cd:SetUseCircularEdge(true)

        end

        if cd.SetSwipeColor then

            cd:SetSwipeColor(0, 0.5, 0, 0.75) -- Green tint for important auras

        end

        -- MEDIUM strata keeps the timer text from getting buried under other elements
        cd:SetFrameStrata("MEDIUM")
        
        -- White text keeps the countdown readable against any icon
        if cd.SetCooldownTextColor then
            cd:SetCooldownTextColor(1, 1, 1) -- White text for maximum visibility
        end

        return cd

    end)

    classIcon.importantAuraCooldown = okImportantCooldown and importantCooldownOrErr or nil



    -- Hook 1: mirror CC texture.

    -- Blizzard swaps the icon back to the question mark when CC ends.

    if debuffFrame.Icon then

        hooksecurefunc(debuffFrame.Icon, "SetTexture", function(_, tex)

            if IsDisabled() then

                if classIcon.ccActive then

                    RestoreClassIcon(arenaIndex, classIcon, acFrame)

                end

                return

            end

            -- Blizzard uses QUESTION_MARK_ICON = 134400 (numeric), not the string path.
            local isQuestionMark = not issecretvalue(tex) and
                (tex == 134400 or tex == "INTERFACE\\ICONS\\INV_MISC_QUESTIONMARK.BLP")

            if isQuestionMark then

                -- CC ended - clear the timer and check for important auras.
                classIcon.ccActive = false

                ClassIconAuras.ccActive[arenaIndex] = false

                if classIcon.auraCooldown then
                    classIcon.auraCooldown:Clear()
                end

                -- Restore the class icon to its base texture NOW, before scanning
                -- for important auras. If we skip this, ShowImportantAura grabs
                -- whatever is currently on the icon (the CC texture) as originalTexture,
                -- then restores it when the important aura ends - causing a CC flash.
                RestoreClassIcon(arenaIndex, classIcon, acFrame)

                ClassIconAuras:UpdateImportantAura(arenaIndex)

            else

                -- CC active (tex is the spell icon, may be secret in Midnight).
                classIcon.ccActive = true

                ClassIconAuras.ccActive[arenaIndex] = true

                ClassIconAuras:ClearImportantAura(arenaIndex)

                if classIcon.icon then

                    classIcon.icon:SetTexture(tex)

                end

            end

        end)

    end



    -- Hook 2: mirror cooldown swipe + a safety net when it finishes.

    if debuffFrame.Cooldown then

        hooksecurefunc(debuffFrame.Cooldown, "SetCooldown", function()

            if IsDisabled() or not classIcon.auraCooldown then return end

            -- Midnight 12.0+: SetCooldown args are secret, so we query C_LossOfControl

            -- directly. priority is NeverSecret so comparisons are safe. The duration

            -- object API is the approved path that bypasses secret number restrictions.

            local unitToken = "arena" .. arenaIndex

            local count = C_LossOfControl.GetActiveLossOfControlDataCountByUnit(unitToken)

            local bestPriority, bestIndex = -1, nil

            for i = 1, count do

                local data = C_LossOfControl.GetActiveLossOfControlDataByUnit(unitToken, i)

                if data and data.priority > bestPriority then

                    bestPriority = data.priority

                    bestIndex = i

                end

            end

            if bestIndex then

                local durationObj = C_LossOfControl.GetActiveLossOfControlDuration(unitToken, bestIndex)

                if durationObj then

                    -- Avoid IsZero() here: it can produce a secret boolean in Midnight.

                    -- SetCooldownFromDurationObject(clearIfZero=true) handles clearing.

                    pcall(classIcon.auraCooldown.SetCooldownFromDurationObject, classIcon.auraCooldown, durationObj, true)

                    if classIcon.auraCooldown.SetHideCountdownNumbers then

                        classIcon.auraCooldown:SetHideCountdownNumbers(false)

                    end

                end

            end

        end)

        debuffFrame.Cooldown:HookScript("OnCooldownDone", function()

            if classIcon.ccActive then

                RestoreClassIcon(arenaIndex, classIcon, acFrame)

            end

        end)

    end



    -- Safety net: on Retail, Blizzard doesn't always swap the icon back to question mark.

    -- Sometimes it just hides the DebuffFrame / Icon when CC ends.

    if debuffFrame.HookScript then

        debuffFrame:HookScript("OnHide", function()

            if classIcon.ccActive then

                RestoreClassIcon(arenaIndex, classIcon, acFrame)

            end

        end)

    end



    if debuffFrame.Icon then

        if debuffFrame.Icon.HookScript then

            debuffFrame.Icon:HookScript("OnHide", function()

                if classIcon.ccActive then

                    RestoreClassIcon(arenaIndex, classIcon, acFrame)

                end

            end)

        end



        if debuffFrame.Icon.SetShown then

            hooksecurefunc(debuffFrame.Icon, "SetShown", function(_, shown)

                if shown == false and classIcon.ccActive then

                    RestoreClassIcon(arenaIndex, classIcon, acFrame)

                end

            end)

        end



        if debuffFrame.Icon.SetAlpha then

            hooksecurefunc(debuffFrame.Icon, "SetAlpha", function(_, a)

                local alpha = tonumber(a)

                if alpha and alpha <= 0.01 and classIcon.ccActive then

                    RestoreClassIcon(arenaIndex, classIcon, acFrame)

                end

            end)

        end

    end



    self.hookedFrames[arenaIndex] = true

end



function ClassIconAuras:UpdateSpiralGlowLine()

    local enabled = IsSpiralGlowLineEnabled()

    local MFM = AC.MasterFrameManager

    if not MFM or not MFM.frames then return end



    for i = 1, MAX_ARENA_ENEMIES do

        local acFrame = MFM.frames[i]

        local classIcon = acFrame and acFrame.classIcon

        local cd = classIcon and classIcon.auraCooldown

        if cd and cd.SetDrawEdge then

            cd:SetDrawEdge(enabled)

        end

    end

end



function ClassIconAuras:UpdateImportantSpiralGlowLine()

    local enabled = IsImportantSpiralGlowLineEnabled()

    local MFM = AC.MasterFrameManager

    if not MFM or not MFM.frames then return end



    for i = 1, MAX_ARENA_ENEMIES do

        local acFrame = MFM.frames[i]

        local classIcon = acFrame and acFrame.classIcon

        local cd = classIcon and classIcon.importantAuraCooldown

        if cd and cd.SetDrawEdge then

            cd:SetDrawEdge(enabled)

        end

    end

end



function ClassIconAuras:UpdateFontSize()

    local fontSize = GetFontSize()

    local MFM = AC.MasterFrameManager

    if not MFM or not MFM.frames then return end



    for i = 1, MAX_ARENA_ENEMIES do

        local acFrame = MFM.frames[i]

        local classIcon = acFrame and acFrame.classIcon



        -- Update CC aura cooldown font size

        local ccCd = classIcon and classIcon.auraCooldown

        if ccCd then

            local r = { ccCd:GetRegions() }

            for j = 1, #r do

                local region = r[j]

                if region and region.GetObjectType and region:GetObjectType() == "FontString" and region.SetFont then

                    region:SetFont(AC.FONT_PATH or "Interface\\AddOns\\ArenaCore\\Media\\Fonts\\arenacore.ttf", fontSize, "OUTLINE")

                end

            end

        end



        -- Update important aura cooldown font size

        local importantCd = classIcon and classIcon.importantAuraCooldown

        if importantCd then

            local r = { importantCd:GetRegions() }

            for j = 1, #r do

                local region = r[j]

                if region and region.GetObjectType and region:GetObjectType() == "FontString" and region.SetFont then

                    region:SetFont(AC.FONT_PATH or "Interface\\AddOns\\ArenaCore\\Media\\Fonts\\arenacore.ttf", fontSize, "OUTLINE")

                end

            end

        end

    end

end



-- Priority-based aura detection system for Midnight
-- Scans auras by priority category, returning first valid match
local function ScanForPriorityAura(unit)
    local trackedInstanceIDs = {}
    
    -- Priority 1: Crowd Control effects (highest)
    local ccAuras = C_UnitAuras.GetUnitAuras(unit, "HARMFUL|CROWD_CONTROL")
    if ccAuras then
        for _, aura in ipairs(ccAuras) do
            local instanceID = aura.auraInstanceID
            if not trackedInstanceIDs[instanceID] then
                trackedInstanceIDs[instanceID] = true
                local isCC = C_Spell.IsSpellCrowdControl(aura.spellId)
                if issecretvalue(isCC) or isCC then
                    return aura.spellId, aura.icon, instanceID, aura.applications, aura
                end
            end
        end
    end
    
    -- Priority 2: Important buffs
    local importantAuras = C_UnitAuras.GetUnitAuras(unit, "HELPFUL|IMPORTANT")
    if importantAuras then
        for _, aura in ipairs(importantAuras) do
            local instanceID = aura.auraInstanceID
            if not trackedInstanceIDs[instanceID] then
                trackedInstanceIDs[instanceID] = true
                local isImportant = C_Spell.IsSpellImportant(aura.spellId)
                if issecretvalue(isImportant) or isImportant then
                    return aura.spellId, aura.icon, instanceID, aura.applications, aura
                end
            end
        end
    end
    
    -- Priority 3: Major defensives
    local bigDefensives = C_UnitAuras.GetUnitAuras(unit, "HELPFUL|BIG_DEFENSIVE")
    if bigDefensives then
        for _, aura in ipairs(bigDefensives) do
            local instanceID = aura.auraInstanceID
            if not trackedInstanceIDs[instanceID] then
                trackedInstanceIDs[instanceID] = true
                local isBigDefensive = C_UnitAuras.AuraIsBigDefensive(aura.spellId)
                if issecretvalue(isBigDefensive) or isBigDefensive then
                    return aura.spellId, aura.icon, instanceID, aura.applications, aura
                end
            end
        end
    end
    
    -- Priority 4: External defensives (lowest)
    local externalDefensives = C_UnitAuras.GetUnitAuras(unit, "HELPFUL|EXTERNAL_DEFENSIVE")
    if externalDefensives then
        for _, aura in ipairs(externalDefensives) do
            local instanceID = aura.auraInstanceID
            if not trackedInstanceIDs[instanceID] then
                trackedInstanceIDs[instanceID] = true
                return aura.spellId, aura.icon, instanceID, aura.applications, aura
            end
        end
    end
    
    return nil
end



-- Update important aura for a specific arena unit

function ClassIconAuras:UpdateImportantAura(arenaIndex)

    if not IsImportantAurasEnabled() then
        self:ClearImportantAura(arenaIndex)
        return
    end

    

    local MFM = AC.MasterFrameManager

    local acFrame = MFM and MFM.frames and MFM.frames[arenaIndex]

    if not acFrame then return end

    

    local classIcon = acFrame.classIcon

    if not classIcon then return end

    

    local unitToken = "arena" .. arenaIndex

    -- Skip entirely if the unit doesn't exist yet (prevents garbage data scans).
    if not UnitExists(unitToken) then
        self:ClearImportantAura(arenaIndex)
        return
    end

    -- Validate the ccActive flag against live C_LossOfControl data on every pass.
    -- The SetTexture hook can miss the "CC ended" transition in Midnight when
    -- the question mark texture comes back as a secret value, leaving ccActive
    -- stuck as true even though the CC is long gone. Catching it here means
    -- UNIT_AURA (which always fires on removal) self-corrects the stale state.
    if classIcon.ccActive then
        local activeCount = C_LossOfControl.GetActiveLossOfControlDataCountByUnit(unitToken)
        if not activeCount or activeCount == 0 then
            classIcon.ccActive = false
            ClassIconAuras.ccActive[arenaIndex] = false
            if classIcon.auraCooldown then
                classIcon.auraCooldown:Clear()
            end
            -- Same as above: restore base texture before scanning so originalTexture
            -- is the real class icon, not the stale CC icon still sitting on the frame.
            RestoreClassIcon(arenaIndex, classIcon, acFrame)
        else
            self:ClearImportantAura(arenaIndex)
            return
        end
    end

    

    -- Scan for priority aura by category (CC > Important > Big Defensives > External)
    local foundImportant = false
    local spellID, texture, auraInstanceID, applications, auraData = ScanForPriorityAura(unitToken)

    if spellID then
        -- Midnight exposes secret number values on timing fields, so we pull a duration
        -- object instead - it travels through Blizzard's API without being tainted.
        local durationObj = nil
        local duration = 0
        local expirationTime = 0

        if AC:IsMidnight() and auraInstanceID then
            durationObj = C_UnitAuras.GetAuraDuration(unitToken, auraInstanceID)
            if durationObj then
                if classIcon.importantAuraCooldown then
                    classIcon.importantAuraCooldown:SetCooldownFromDurationObject(durationObj)
                    classIcon.importantAuraCooldown.durationObj = durationObj
                end
                local ok1, dur = pcall(durationObj.GetDuration, durationObj)
                local ok2, exp = pcall(durationObj.GetExpirationTime, durationObj)
                if ok1 and dur then
                    duration = dur
                    expirationTime = exp or 0
                end
                if AURA_DEBUG_ENABLED then
                    print("|cff00FF00[AuraDebug]|r duration object found for " .. (auraData and auraData.name or spellID))
                end
            else
                duration = auraData and auraData.duration or 0
                expirationTime = auraData and auraData.expirationTime or 0
                if AURA_DEBUG_ENABLED then
                    print("|cffFFAA00[AuraDebug]|r GetAuraDuration returned nil for " .. (auraData and auraData.name or spellID))
                end
            end
        else
            duration = auraData and auraData.duration or 0
            expirationTime = auraData and auraData.expirationTime or 0
        end

        -- Bundle everything the show function needs into one tidy package.
        local auraInfo = {
            spellId       = spellID,
            icon          = texture,
            applications  = applications or 0,
            auraInstanceID = auraInstanceID,
            duration      = duration,
            expirationTime = expirationTime,
        }

        if AC:IsMidnight() and durationObj then
            auraInfo.durationObj = durationObj
        end
        
        self:ShowImportantAura(arenaIndex, auraInfo)
        foundImportant = true
    end

    

    -- If no important aura found, clear it
    if not foundImportant then
        self:ClearImportantAura(arenaIndex)
    end

end



-- Show important aura on class icon

function ClassIconAuras:ShowImportantAura(arenaIndex, auraInfo)

    local MFM = AC.MasterFrameManager

    local acFrame = MFM and MFM.frames and MFM.frames[arenaIndex]

    if not acFrame then return end

    

    local classIcon = acFrame.classIcon

    if not classIcon then return end

    

    -- Store important aura data

    self.importantActive[arenaIndex] = true

    self.importantAuraData[arenaIndex] = auraInfo

    

    -- save the original class icon texture before we overwrite it (so we can put it back later)

    if not classIcon.originalTexture then

        classIcon.originalTexture = classIcon.icon and classIcon.icon:GetTexture()

    end

    

    -- Swap the class icon out for the active aura's spell icon.

    if classIcon.icon and auraInfo.icon then

        classIcon.icon:SetTexture(auraInfo.icon)

    end

    

    -- hide the overlay when showing important aura because it looks cleaner that way

    if classIcon.overlay then

        classIcon.overlay:Hide()

    end

    

    -- Drive the cooldown swipe.  Midnight needs the duration object path to avoid
    -- touching secret number values; legacy builds use the plain SetCooldown call.
    if classIcon.importantAuraCooldown then
        if AC:IsMidnight() and auraInfo.durationObj then
            -- Midnight path: duration object is the only safe way to set timing
            if AURA_DEBUG_ENABLED then
                print("|cff00FFFF[AuraDebug]|r Setting Midnight cooldown for " .. (auraInfo.spellId or "Unknown") .. " via duration object")
            end
            classIcon.importantAuraCooldown:SetCooldownFromDurationObject(auraInfo.durationObj)
            classIcon.importantAuraCooldown.durationObj = auraInfo.durationObj
        elseif auraInfo.expirationTime and auraInfo.duration then
            -- handle secret duration comparison safely because Midnight is picky about these things
            local durationGTZero
            if issecretvalue(auraInfo.duration) then
                -- Secret duration - assume it's valid and let cooldown handle it
                durationGTZero = true
            else
                durationGTZero = auraInfo.duration > 0
            end
            
            if durationGTZero then
                -- Secret duration can't be passed to SetCooldown - clear instead
                if issecretvalue(auraInfo.duration) then
                    classIcon.importantAuraCooldown:Clear()
                    classIcon.importantAuraCooldown.durationObj = nil
                else
                    local startTime
                    if issecretvalue(auraInfo.expirationTime) then
                        startTime = 0
                    else
                        startTime = auraInfo.expirationTime - auraInfo.duration
                    end
                    if AURA_DEBUG_ENABLED then
                        print("|cff00FFFF[AuraDebug]|r Setting Legacy cooldown for " .. (auraInfo.spellId or "Unknown") .. ": " .. auraInfo.duration .. "s")
                    end
                    classIcon.importantAuraCooldown:SetCooldown(startTime, auraInfo.duration)
                end
            else
                if AURA_DEBUG_ENABLED then
                    print("|cffFF0000[AuraDebug]|r No duration data for spellID: " .. (auraInfo.spellId or "Unknown") .. " - clearing cooldown")
                end
                classIcon.importantAuraCooldown:Clear()
                classIcon.importantAuraCooldown.durationObj = nil
            end
        end
        
        if classIcon.importantAuraCooldown.SetHideCountdownNumbers then
            classIcon.importantAuraCooldown:SetHideCountdownNumbers(false)
        end
    end

end



-- Clear important aura from class icon

function ClassIconAuras:ClearImportantAura(arenaIndex)

    local MFM = AC.MasterFrameManager

    local acFrame = MFM and MFM.frames and MFM.frames[arenaIndex]

    if not acFrame then return end

    

    local classIcon = acFrame.classIcon

    if not classIcon then return end

    

    self.importantActive[arenaIndex] = false

    self.importantAuraData[arenaIndex] = nil

    

    -- Clear cooldown (matches ShowImportantAura cleanup)
    if classIcon.importantAuraCooldown then
        classIcon.importantAuraCooldown:Clear()
        classIcon.importantAuraCooldown.durationObj = nil
    end

    

    -- restore original texture directly WITHOUT calling UpdateClassIcon (that would mess up the theme)
    -- UpdateClassIcon can trigger border/theme re-application which swaps user settings
    -- Important auras should ONLY change the icon texture, never the border style or theme
    if classIcon.icon and classIcon.originalTexture then
        classIcon.icon:SetTexture(classIcon.originalTexture)
        classIcon.originalTexture = nil
    elseif acFrame and classIcon.UpdateClassIcon then
        -- Fallback: original texture wasn't captured; restore using class data
        classIcon.UpdateClassIcon(acFrame.class)
    end

    

    -- Restore border to whatever style the user has selected
    if not classIcon.ccActive then
        if classIcon.ApplyBorderStyle then
            classIcon.ApplyBorderStyle()
        elseif classIcon.overlay then
            classIcon.overlay:Show()
        end
    end

    

    -- IMPORTANT: Don't call RestoreClassIcon here - it causes theme flashing
    -- Important auras should restore original texture directly, not via theme system

end



-- Refresh all important auras

function ClassIconAuras:RefreshImportantAuras()

    if not IsImportantAurasEnabled() then

        -- Clear all important auras if disabled

        for i = 1, MAX_ARENA_ENEMIES do

            self:ClearImportantAura(i)

        end

        return

    end

    

    -- Update all arena units with error handling

    for i = 1, MAX_ARENA_ENEMIES do

        local success, err = pcall(function()

            self:UpdateImportantAura(i)

        end)

        if not success then

            -- Silently handle errors to prevent UI lockups

            -- Could add debug logging here if needed

        end

    end

end



function ClassIconAuras:Initialize()

    if self.initialized then return end

    local _, instanceType = IsInInstance()

    if instanceType ~= "arena" then return end

    if IsActiveBattlefieldArena and not IsActiveBattlefieldArena() then return end



    for i = 1, MAX_ARENA_ENEMIES do

        self:HookDebuffFrame(i)

    end

    self.initialized = true

end



function ClassIconAuras:RefreshHooks()

    for i = 1, MAX_ARENA_ENEMIES do

        self:HookDebuffFrame(i)

    end

end



function ClassIconAuras:RestoreAll()

    local MFM = AC.MasterFrameManager

    if not MFM or not MFM.frames then return end



    local db = AC.DB and AC.DB.profile

    local showSpecInstead = db and db.classIcons and db.classIcons.showSpecInstead == true



    for i = 1, MAX_ARENA_ENEMIES do

        local acFrame = MFM.frames[i]

        if acFrame and acFrame.classIcon then

            local classIcon = acFrame.classIcon

            if classIcon.auraCooldown then

                classIcon.auraCooldown:Clear()

            end

            if classIcon.importantAuraCooldown then

                classIcon.importantAuraCooldown:Clear()

            end

            classIcon.ccActive = false

            self.ccActive[i] = false

            self.importantActive[i] = false

            self.importantAuraData[i] = nil



            if showSpecInstead then

                local specID = acFrame.specID

                if (not specID or specID <= 0) and GetArenaOpponentSpec then

                    specID = GetArenaOpponentSpec(i)

                end



                if specID and specID > 0 and GetSpecializationInfoByID then

                    acFrame.specID = specID

                    local _, _, _, specIcon = GetSpecializationInfoByID(specID)
                    acFrame.specIconTexture = specIcon

                    if specIcon and classIcon.icon and classIcon.icon.SetTexture then

                        classIcon.icon:SetTexture(specIcon)

                        if classIcon.icon.SetTexCoord then

                            classIcon.icon:SetTexCoord(0.1, 0.9, 0.1, 0.9)

                        end

                    end

                    if classIcon.overlay and classIcon.overlay.SetTexture then

                        classIcon.overlay:SetTexture("Interface\\AddOns\\ArenaCore\\Media\\Classicons\\Overlays\\orangeoverlay.tga")

                    end

                    classIcon:Show()

                else

                    classIcon:Hide()

                end



                if acFrame.specIcon then

                    acFrame.specIcon:Hide()

                end

            else

                local storedClass = acFrame.class

                if storedClass and classIcon.UpdateClassIcon then

                    classIcon.UpdateClassIcon(storedClass)

                end

            end

        end

    end

end



-- EVENTS



local eventFrame = CreateFrame("Frame")

eventFrame:RegisterEvent("PLAYER_ENTERING_WORLD")

eventFrame:RegisterEvent("ARENA_PREP_OPPONENT_SPECIALIZATIONS")

eventFrame:RegisterEvent("ARENA_OPPONENT_UPDATE")

eventFrame:RegisterEvent("GROUP_ROSTER_UPDATE")

eventFrame:RegisterEvent("UNIT_AURA")



eventFrame:SetScript("OnEvent", function(self, event, ...)

    local _, instanceType = IsInInstance()



    if event == "PLAYER_ENTERING_WORLD" then

        if instanceType == "arena" then

            C_Timer.After(0.5, function()

                if IsActiveBattlefieldArena and IsActiveBattlefieldArena() then

                    ClassIconAuras:RefreshHooks()

                    ClassIconAuras:RefreshImportantAuras()

                end

            end)

        else

            ClassIconAuras:RestoreAll()

        end

    elseif event == "ARENA_PREP_OPPONENT_SPECIALIZATIONS" then

        ClassIconAuras:RestoreAll()

        C_Timer.After(0.1, function()

            if IsActiveBattlefieldArena and IsActiveBattlefieldArena() then

                ClassIconAuras:RefreshHooks()

                ClassIconAuras:RefreshImportantAuras()

            end

        end)

    elseif event == "GROUP_ROSTER_UPDATE" then

        if instanceType == "arena" then

            ClassIconAuras:RestoreAll()

        end

    elseif event == "ARENA_OPPONENT_UPDATE" then

        C_Timer.After(0.1, function()

            if IsActiveBattlefieldArena and IsActiveBattlefieldArena() then

                ClassIconAuras:RefreshHooks()

                ClassIconAuras:RefreshImportantAuras()

            end

        end)

    elseif event == "UNIT_AURA" then

        local unit, updateInfo = ...

        -- Skip if nothing actually changed (Midnight sends UNIT_AURA very frequently).
        if not AuraPayloadHasChanges(updateInfo) then return end

        if unit and unit:match("^arena%d") then

            local arenaIndex = tonumber(unit:match("arena(%d)"))

            if arenaIndex and arenaIndex >= 1 and arenaIndex <= MAX_ARENA_ENEMIES then

                ClassIconAuras:UpdateImportantAura(arenaIndex)

            end

        end

    end

end)




C_Timer.After(0.5, function()

    if AC.Midnight and AC.Midnight.isMidnight then

        local _, instanceType = IsInInstance()

        if instanceType == "arena" and (not IsActiveBattlefieldArena or IsActiveBattlefieldArena()) then

            ClassIconAuras:Initialize()

        end

    end

end)

