-- Blackout engine (Platynator-style simplification).
-- Clean implementation: hooksecurefunc (taint-free), only change foreground color to black,
-- never touch background, avoid conflicts, simple + maintainable.

-- This is kind of important I guess: don't check AC at load time — it may not exist yet.
-- Get AC reference when functions are called instead.
local function GetAC()
    return _G.ArenaCore
end

-- Blackout completely disabled — feature turned off everywhere.
-- No events, no functions, no classes will run.
local function IsBlackoutRestricted()
    return true  -- DISABLED: Don't run blackout anywhere
end

-- Midnight API constants.
-- In Midnight 12.0+, use Blizzard's new spell classification APIs instead of
-- combat log tracking and manual spell ID lists.
-- C_Spell.IsSpellImportant() identifies offensive cooldowns, defensives, etc.
-- C_UnitAuras.GetAuraDataByIndex() scans unit auras without combat log.

local MAX_AURAS_TO_SCAN = 40  -- Max auras to check per unit

-- Blackout tracking tables.
-- Track active blackout spells by unit string (can't use GUIDs in Midnight).
local activeBlackouts = {} -- [unit] = {auraIndex = X, expiresAt = time}

-- Anti-flicker: track blackout state per unit.
-- Only update color when state CHANGES (on→off or off→on), not on every buff tick.
-- Fixes MM Hunter Trueshot flicker (rapid UNIT_AURA events from focus regen/procs).
local lastBlackoutState = {} -- [unit] = true/false

-- Centralized unit validation.
-- Single source of truth for "is this unit valid for blackout?"
-- Prevents duplicate checks and ensures consistent filtering.

local function IsValidBlackoutTarget(unit, unitGUID)
    -- MIDNIGHT: No longer disabled - we use new C_Spell.IsSpellImportant API
    
    -- This is kind of important I guess: must have valid unit.
    if not unit or not UnitExists(unit) then return false end
    
    -- This is kind of important I guess: ONLY work on ENEMY PLAYERS (not NPCs, not friendlies, not pets, not totems).
    if not UnitIsPlayer(unit) then return false end  -- Must be a player
    if not UnitIsEnemy("player", unit) then return false end  -- Must be hostile to you
    if UnitIsUnit(unit, "player") then return false end  -- Never yourself
    
    -- This is kind of important I guess: exclude pets (hunter pets, warlock pets, etc.).
    -- Pets can sometimes pass UnitIsPlayer check but should NEVER get blackout.
    if UnitIsOtherPlayersPet(unit) then return false end
    
    -- MIDNIGHT: Skip GUID validation - GUIDs are "secret strings" that can't be parsed
    -- UnitIsPlayer + UnitIsEnemy + UnitIsOtherPlayersPet checks above are sufficient
    -- Attempting guid:match() on secret strings causes taint errors
    
    return true
end

-- Check if unit has blackout (Midnight API — no combat log).
-- Scans HELPFUL auras (BUFFS) on enemy nameplates for offensive cooldowns.
-- Uses FILTER-ONLY approach — NO secret value comparisons allowed.
-- Logic: Nameplate buffs that are NOT in BIG_DEFENSIVE filter = OFFENSIVE.

local function HasBlackoutAura(unit)
    -- CRITICAL FIX: Use centralized validation (eliminates duplicate checks)
    if not IsValidBlackoutTarget(unit, nil) then return false end
    
    local AC = GetAC()
    
    -- Midnight fix: filter-only approach (NO secret value comparisons).
    -- CANNOT compare ANY secret values (IsSpellImportant, AuraIsBigDefensive, etc.).
    -- Instead, use Blizzard's filter system to categorize spells:
    -- 1. Get all BIG_DEFENSIVE auraInstanceIDs (defensive CDs)
    -- 2. Get all INCLUDE_NAME_PLATE_ONLY auraInstanceIDs (important buffs)
    -- 3. If a nameplate buff is NOT defensive → it's likely offensive
    -- auraInstanceID is NOT secret and CAN be compared.
    
    -- Step 1: collect defensive auraInstanceIDs using filter.
    local defensiveAuras = {}
    for i = 1, MAX_AURAS_TO_SCAN do
        local defData = C_UnitAuras.GetAuraDataByIndex(unit, i, "HELPFUL|BIG_DEFENSIVE")
        if not defData then break end
        -- auraInstanceID is NOT secret — we can use it as a key.
        defensiveAuras[defData.auraInstanceID] = true
    end
    
    -- Step 2: check nameplate buffs against defensive list.
    for i = 1, MAX_AURAS_TO_SCAN do
        local auraData = C_UnitAuras.GetAuraDataByIndex(unit, i, "HELPFUL|INCLUDE_NAME_PLATE_ONLY")
        if not auraData then break end
        
        -- If this nameplate buff is NOT in defensive list → likely offensive CD.
        if not defensiveAuras[auraData.auraInstanceID] then
            if AC and AC.BLACKOUT_DEBUG then
                print(string.format("|cff00FF00[Blackout]|r %s has NON-DEFENSIVE nameplate buff (auraID: %d) - OFFENSIVE CD!", unit, auraData.auraInstanceID))
            end
            
            activeBlackouts[unit] = {
                auraIndex = i,
                auraInstanceID = auraData.auraInstanceID,
                expiresAt = GetTime() + 30
            }
            
            return true, nil
        elseif AC and AC.BLACKOUT_DEBUG then
            print(string.format("|cffFFAA00[Blackout]|r %s has DEFENSIVE buff (auraID: %d) - skipping", unit, auraData.auraInstanceID))
        end
    end
    
    -- No offensive CD buffs found - clear tracking
    if activeBlackouts[unit] then
        activeBlackouts[unit] = nil
    end
    
    return false, nil
end

-- Frame config initialization.

local function InitializeFrameConfig(frame)
    if not frame.ArenaCore then
        frame.ArenaCore = {}
    end
    if not frame.ArenaCore.config then
        frame.ArenaCore.config = {}
    end
    return frame.ArenaCore.config
end

-- Blackout color scanner.
-- Scans for blackout auras and stores the result in frame config.

local function ScanBlackoutAura(frame)
    if IsBlackoutRestricted() then return end -- MIDNIGHT: Disable in arena
    if not frame or not frame.unit then return end
    if frame:IsForbidden() or frame:IsProtected() then return end -- TAINT PREVENTION
    
    -- CRITICAL FIX: Use centralized validation (eliminates duplicate checks)
    -- MIDNIGHT: Don't use UnitGUID - it's a secret/tainted value
    if not IsValidBlackoutTarget(frame.unit, nil) then
        -- This is kind of important I guess: clear blackout state for non-player units (pets, totems, NPCs).
        -- Prevents recycled nameplate frames from showing old blackout textures.
        local config = frame.ArenaCore and frame.ArenaCore.config
        if config then
            config.blackoutColor = nil
            config.blackoutSpellID = nil
        end
        return
    end
    
    local AC = GetAC()
    if not AC then return end
    
    local db = AC.DB and AC.DB.profile and AC.DB.profile.blackout
    if not db or db.enabled == false then
        -- Clear any existing blackout state
        local config = frame.ArenaCore and frame.ArenaCore.config
        if config then
            config.blackoutColor = nil
        end
        return
    end
    
    -- Initialize config if needed
    local config = InitializeFrameConfig(frame)
    
    -- Check for blackout aura
    local hasBlackout, spellID = HasBlackoutAura(frame.unit)
    
    if hasBlackout then
        -- MIDNIGHT: No spell list check needed - C_Spell.IsSpellImportant handles filtering
        
        -- This is kind of important I guess: when using texture mode, DO NOT set any color at all.
        -- Only set a marker that blackout is active for texture application.
        local db = AC.DB and AC.DB.profile and AC.DB.profile.blackout
        if db and db.useTexture then
            -- Texture mode: ONLY set marker, NO color values
            config.blackoutColor = {textureMode = true}  -- Pure marker, no RGB values
        else
            -- Color mode: Set black color
            config.blackoutColor = {r = 0, g = 0, b = 0}  -- Default black only for color mode
        end
        config.blackoutSpellID = spellID
        
        if AC.BLACKOUT_DEBUG then
            print("|cff00FFFF[Blackout]|r Stored blackout for", frame.unit, (db and db.useTexture) and "(texture mode)" or "(color mode)")
        end
    else
        -- Clear blackout color
        config.blackoutColor = nil
        config.blackoutSpellID = nil
    end
end

-- ArenaCore's own health color update function.
-- Copy of Blizzard's CompactUnitFrame_UpdateHealthColor with blackout applied at end.
-- Allows us to bypass Blizzard's function entirely and prevent ping-pong.

function AC_CompactUnitFrame_UpdateHealthColor(frame, exitLoop)
    if not frame or not frame.unit then return end
    if frame:IsForbidden() or frame:IsProtected() then return end
    
    -- CRITICAL FIX: ONLY handle nameplates (not arena frames, not party frames)
    if not frame.unit:find("nameplate") then return end
    
    local config = frame.ArenaCore and frame.ArenaCore.config or InitializeFrameConfig(frame)
    
    -- Blizzard's original health color logic (exact copy).
    local r, g, b;
    local unitIsConnected = UnitIsConnected(frame.unit);
    local unitIsDead = unitIsConnected and UnitIsDead(frame.unit);
    local unitIsPlayer = UnitIsPlayer(frame.unit) or UnitIsPlayer(frame.displayedUnit);

    if ( not unitIsConnected or (unitIsDead and not unitIsPlayer) ) then
        --Color it gray
        r, g, b = 0.5, 0.5, 0.5;
    else
        if ( frame.optionTable.healthBarColorOverride ) then
            local healthBarColorOverride = frame.optionTable.healthBarColorOverride;
            r, g, b = healthBarColorOverride.r, healthBarColorOverride.g, healthBarColorOverride.b;
        else
            --Try to color it by class.
            local localizedClass, englishClass = UnitClass(frame.unit);
            local classColor = RAID_CLASS_COLORS[englishClass];
            local useClassColors = CompactUnitFrame_GetOptionUseClassColors(frame, frame.optionTable);
            if ( (frame.optionTable.allowClassColorsForNPCs or UnitIsPlayer(frame.unit) or UnitTreatAsPlayerForDisplay(frame.unit)) and classColor and useClassColors ) then
                -- Use class colors for players if class color option is turned on
                r, g, b = classColor.r, classColor.g, classColor.b;
            elseif ( CompactUnitFrame_IsTapDenied(frame) ) then
                -- Use grey if not a player and can't get tap on unit
                r, g, b = 0.9, 0.9, 0.9;
            elseif ( frame.optionTable.colorHealthBySelection ) then
                -- Use color based on the type of unit (neutral, etc.)
                if ( frame.optionTable.considerSelectionInCombatAsHostile and CompactUnitFrame_IsOnThreatListWithPlayer(frame.displayedUnit) and not UnitIsFriend("player", frame.unit) ) then
                    r, g, b = 1.0, 0.0, 0.0;
                elseif ( UnitIsPlayer(frame.displayedUnit) and UnitIsFriend("player", frame.displayedUnit) ) then
                    -- We don't want to use the selection color for friendly player nameplates because
                    -- it doesn't show player health clearly enough.
                    r, g, b = 0.667, 0.667, 1.0;
                else
                    r, g, b = UnitSelectionColor(frame.unit, frame.optionTable.colorHealthWithExtendedColors);
                end
            elseif ( UnitIsFriend("player", frame.unit) ) then
                r, g, b = 0.0, 1.0, 0.0;
            else
                r, g, b = 1.0, 0.0, 0.0;
            end
        end
    end

    -- Anti-flicker: only set color if it actually changed.
    local oldR, oldG, oldB = frame.healthBar:GetStatusBarColor();
    if ( r ~= oldR or g ~= oldG or b ~= oldB ) then
        frame.healthBar:SetStatusBarColor(r, g, b);

        if (frame.optionTable.colorHealthWithExtendedColors) then
            frame.selectionHighlight:SetVertexColor(r, g, b);
        else
            frame.selectionHighlight:SetVertexColor(1, 1, 1);
        end
    end
    
    -- ArenaCore blackout color application (Platynator-style).
    -- ONLY change foreground color, let Blizzard handle background.
    
    local AC = GetAC()
    if not AC then return end
    
    local db = AC.DB and AC.DB.profile and AC.DB.profile.blackout
    if not db or db.enabled == false then return end
    
    -- CRITICAL FIX: Skip validation AND clearing when in test mode
    local isInTestMode = db.healthBarTestMode or db.externalTestMode
    
    -- CRITICAL FIX: Use centralized validation (eliminates duplicate checks)
    -- MIDNIGHT: Don't use UnitGUID - it's a secret/tainted value
    if not IsValidBlackoutTarget(frame.unit, nil) then 
        -- CRITICAL FIX: Re-apply Effect Style color in test mode (Blizzard overwrites it)
        if isInTestMode and db.healthBarTestMode and not db.useTexture then
            local healthBar = frame.healthBar or (frame.HealthBarsContainer and frame.HealthBarsContainer.healthBar)
            if healthBar and AC.BlackoutCustomization then
                local effectType = db.effectType or "default"
                local testColor = AC.BlackoutCustomization:GetBlackoutColor(effectType, db.customColor)
                healthBar:SetStatusBarColor(testColor.r, testColor.g, testColor.b)
            end
        elseif not isInTestMode then
            -- Only clear if NOT in test mode
            if AC.BlackoutCustomization then
                AC.BlackoutCustomization:ClearCustomization(frame)
            end
        end
        return 
    end
    
    -- Apply blackout customization if stored in config
    if config and config.blackoutColor then
        -- Use BlackoutCustomization module for texture/color handling.
        if AC.BLACKOUT_DEBUG then
            print("|cff00FFFF[BlackoutEngine]|r About to call BlackoutCustomization for", frame.unit)
        end
        
        if AC.BlackoutCustomization then
            AC.BlackoutCustomization:ApplyCustomization(frame, config)
        else
            if AC.BLACKOUT_DEBUG then
                print("|cffFF0000[BlackoutEngine]|r ERROR: BlackoutCustomization module not loaded!")
            end
        end
    else
        -- Clear customization when blackout ends
        if AC.BlackoutCustomization then
            AC.BlackoutCustomization:ClearCustomization(frame)
        end
    end
end

-- Health color update hook.
-- This is kind of important I guess: this hook only handles when OTHER addons or Blizzard call the function.
-- Our own code uses AC_CompactUnitFrame_UpdateHealthColor() to bypass this entirely.

hooksecurefunc("CompactUnitFrame_UpdateHealthColor", function(frame)
    -- MIDNIGHT: Blackout now uses C_Spell.IsSpellImportant API - no longer disabled
    
    if not frame or not frame.unit then return end
    if frame:IsForbidden() or frame:IsProtected() then return end
    
    -- CRITICAL FIX: ONLY handle nameplates (not arena frames, not party frames)
    if not frame.unit:find("nameplate") then return end
    
    -- Blackout system (enemy players only) — Platynator-style.
    -- ONLY change foreground color, NEVER touch background.
    
    local AC = GetAC()
    if not AC then return end
    
    local db = AC.DB and AC.DB.profile and AC.DB.profile.blackout
    if not db or db.enabled == false then return end
    
    -- This is kind of important I guess: skip validation AND clearing when in test mode.
    -- Test mode needs to work on NPCs/dummies, not just players.
    local isInTestMode = db.healthBarTestMode or db.externalTestMode
    
    -- CRITICAL FIX: Use centralized validation (eliminates duplicate checks)
    -- MIDNIGHT: Don't use UnitGUID - it's a secret/tainted value
    if not IsValidBlackoutTarget(frame.unit, nil) then 
        -- CRITICAL FIX: Re-apply Effect Style color in test mode (Blizzard overwrites it)
        if isInTestMode and db.healthBarTestMode and not db.useTexture then
            local healthBar = frame.healthBar or (frame.HealthBarsContainer and frame.HealthBarsContainer.healthBar)
            if healthBar and AC.BlackoutCustomization then
                local effectType = db.effectType or "default"
                local testColor = AC.BlackoutCustomization:GetBlackoutColor(effectType, db.customColor)
                healthBar:SetStatusBarColor(testColor.r, testColor.g, testColor.b)
            end
        elseif not isInTestMode then
            -- Only clear if NOT in test mode
            if AC.BlackoutCustomization then
                AC.BlackoutCustomization:ClearCustomization(frame)
            end
        end
        return 
    end
    
    -- This is kind of important I guess: re-scan for blackout aura to ensure we have current state.
    -- Prevents untargeting from clearing blackout.
    ScanBlackoutAura(frame)
    
    -- Check if frame has blackout color stored in config
    local config = frame.ArenaCore and frame.ArenaCore.config
    if config and config.blackoutColor then
        -- Use BlackoutCustomization module for texture/color handling
        if AC.BLACKOUT_DEBUG then
            print("|cff00FFFF[BlackoutEngine HOOK]|r About to call BlackoutCustomization for", frame.unit)
        end
        
        if AC.BlackoutCustomization then
            AC.BlackoutCustomization:ApplyCustomization(frame, config)
        else
            if AC.BLACKOUT_DEBUG then
                print("|cffFF0000[BlackoutEngine HOOK]|r ERROR: BlackoutCustomization module not loaded!")
            end
        end
    else
        -- Clear customization when blackout ends
        if AC.BlackoutCustomization then
            AC.BlackoutCustomization:ClearCustomization(frame)
        end
    end
end)

-- External integration.
-- REMOVED: No longer needed since we don't touch backgrounds.
-- Other nameplate systems may manage their own background colors; this module only changes foreground color for blackout.

-- GROUP_ROSTER_UPDATE handler (Solo Shuffle cleanup — no combat log).
-- Handles Solo Shuffle round transitions to clean up blackout states.

local groupRosterFrame
local function InitializeGroupRosterFrame()
    if groupRosterFrame then return end
    
    groupRosterFrame = CreateFrame("Frame")
    groupRosterFrame:RegisterEvent("GROUP_ROSTER_UPDATE")
    
    groupRosterFrame:SetScript("OnEvent", function(self, event)
        local AC = GetAC()
        if not AC then return end
        
        -- Solo Shuffle round transition - clean up blackout states
        local _, instanceType = IsInInstance()
        if instanceType == "arena" then
            -- Clear all blackout tracking
            wipe(activeBlackouts)
            -- ANTI-FLICKER: Clear state tracking table (prevents stale states)
            wipe(lastBlackoutState)
            
            -- This is kind of important I guess: clear test mode flags (prevent test textures from persisting).
            local db = AC.DB and AC.DB.profile and AC.DB.profile.blackout
            if db then
                db.externalTestMode = false
                db.healthBarTestMode = false
            end
            
            -- Trigger health color update for all nameplates to restore colors
            C_Timer.After(0.3, function()
                for _, nameplate in ipairs(C_NamePlate.GetNamePlates()) do
                    local frame = nameplate.unitFrame or nameplate.UnitFrame
                    if frame and frame.unit and not frame:IsForbidden() and not frame:IsProtected() then
                        ScanBlackoutAura(frame)
                        AC_CompactUnitFrame_UpdateHealthColor(frame)
                    end
                end
            end)
            
            if AC.BLACKOUT_DEBUG then
                print("|cff00FFFF[Blackout]|r Solo Shuffle cleanup complete (state tracking + test modes cleared)")
            end
        end
    end)
end

-- NAME_PLATE_UNIT_ADDED handler.
-- Scan new nameplates immediately when they appear.

local nameplateFrame
local function InitializeNameplateFrame()
    if nameplateFrame then return end
    
    nameplateFrame = CreateFrame("Frame")
    nameplateFrame:RegisterEvent("NAME_PLATE_UNIT_ADDED")

nameplateFrame:SetScript("OnEvent", function(self, event, unit)
    -- MIDNIGHT: No longer disabled - we use new C_Spell.IsSpellImportant API
    
    if IsBlackoutRestricted() then return end
    
    local AC = GetAC()
    if not AC then return end
    
    local nameplate = C_NamePlate.GetNamePlateForUnit(unit)
    if not nameplate then return end
    
    -- Universal nameplate addon compatibility.
    -- Detect the correct frame for any nameplate addon:
    -- - Blizzard default: nameplate.UnitFrame (uppercase 'U')
    -- - Plater: nameplate.unitFrame (lowercase 'u')
    -- - Platynator: nameplate.unitFrame (lowercase 'u')
    -- - Other addons: Try both, prefer custom frame if it exists.
    local frame = nameplate.unitFrame or nameplate.UnitFrame
    
    if frame and not frame:IsForbidden() and not frame:IsProtected() then
            -- Visibility activation: touch the HealthBarsContainer background to ensure nameplate elements initialize.
            -- This MUST happen for ALL nameplates FIRST!
            -- Activates Blizzard's visibility system for ALL units.
            if frame.HealthBarsContainer and frame.HealthBarsContainer.background then
                -- Access the background to trigger Blizzard's visibility
                local r, g, b, a = frame.HealthBarsContainer.background:GetVertexColor()
                -- This simple access is enough to activate the frame
            end
            
            -- Blackout system: scan for blackout auras.
            -- Let Blizzard set colors naturally; hook will override.
            -- Only scan for blackout, don't manually trigger color updates.
            local db = AC.DB and AC.DB.profile and AC.DB.profile.blackout
            if db and db.enabled then
                -- Scan for blackout aura immediately
                -- Blizzard will call CompactUnitFrame_UpdateHealthColor naturally
                -- Our hook will apply blackout color if aura is present
                ScanBlackoutAura(frame)
            end
    end
    end)
end

-- UNIT_AURA handler (enemy nameplate buff tracking).
-- Monitors UNIT_AURA for enemy nameplates to detect offensive cooldowns
-- When enemy pops Combustion, Trueshot, Meta, etc. → trigger blackout

local auraFrame
local function InitializeAuraFrame()
    if auraFrame then return end
    
    auraFrame = CreateFrame("Frame")
    auraFrame:RegisterEvent("UNIT_AURA")

auraFrame:SetScript("OnEvent", function(self, event, unit)
    -- Only handle nameplate units
    if not unit or not unit:find("nameplate") then return end
    
    if IsBlackoutRestricted() then return end
    
    local AC = GetAC()
    if not AC then return end
    
    local db = AC.DB and AC.DB.profile and AC.DB.profile.blackout
    if not db or db.enabled == false then return end
    
    -- Get nameplate frame
    local nameplate = C_NamePlate.GetNamePlateForUnit(unit)
    if not nameplate then return end
    local frame = nameplate.unitFrame or nameplate.UnitFrame
    if not frame then return end
    
    if frame and not frame:IsForbidden() and not frame:IsProtected() then
        if AC.BLACKOUT_DEBUG then
            print(string.format("|cffFFFF00[UNIT_AURA]|r Event triggered for %s", unit))
        end
        
        -- Check current blackout state (scans HELPFUL auras for important buffs).
        local hasBlackout = HasBlackoutAura(unit)
        
        -- Anti-flicker: only update if state changed.
        if lastBlackoutState[unit] ~= hasBlackout then
            lastBlackoutState[unit] = hasBlackout
            
            if AC.BLACKOUT_DEBUG then
                print(string.format("|cff00FFFF[Blackout]|r %s state changed: %s", unit, hasBlackout and "ACTIVE" or "CLEARED"))
            end
            
            ScanBlackoutAura(frame)
            
            if frame.healthBar then
                AC_CompactUnitFrame_UpdateHealthColor(frame)
            end
        end
    end
    end)
end

-- Slash command for debug.

-- Continuous monitor (removed).
-- No longer needed — we don't touch backgrounds anymore.

SLASH_BLACKOUTDEBUG1 = "/blackoutdebug"
SLASH_BLACKOUTDEBUG2 = "/bodebug"
SlashCmdList["BLACKOUTDEBUG"] = function(msg)
    local AC = GetAC()
    if not AC then
        print("|cffFF0000[Blackout]|r ArenaCore not loaded yet!")
        return
    end
    
    -- Toggle debug mode
    AC.BLACKOUT_DEBUG = not AC.BLACKOUT_DEBUG
    if AC.BLACKOUT_DEBUG then
        print("|cff00FFFF[Blackout]|r Debug mode |cff00FF00ENABLED|r")
        print("|cff00FFFF[Blackout]|r You will now see debug messages for blackout aura detection")
        print("|cff00FFFF[Blackout]|r Use /testblackout to check current target")
    else
        print("|cff00FFFF[Blackout]|r Debug mode |cffFF0000DISABLED|r")
    end
end

-- Public API.

-- Public API function — needs to be added to AC when it exists.
local function RefreshBlackout()
    -- MIDNIGHT: No spell list to rebuild - API handles filtering
    
    -- Rescan all visible nameplates
    local nameplates = C_NamePlate.GetNamePlates()
    for _, nameplate in ipairs(nameplates) do
        local frame = nameplate.unitFrame or nameplate.UnitFrame
        if frame and frame.unit then
            if not frame:IsForbidden() and not frame:IsProtected() then
                ScanBlackoutAura(frame)
                if frame.healthBar then
                    AC_CompactUnitFrame_UpdateHealthColor(frame)  -- Use OUR function, not Blizzard's
                end
            end
        end
    end
end

-- Register the public API when AC is ready
C_Timer.After(0.1, function()
    local AC = GetAC()
    if AC then
        AC.RefreshBlackout = RefreshBlackout
    end
end)

-- Reload safety net.

local reloadFrame = CreateFrame("Frame")
reloadFrame:RegisterEvent("PLAYER_ENTERING_WORLD")
reloadFrame:RegisterEvent("ARENA_PREP_OPPONENT_SPECIALIZATIONS")  -- Solo Shuffle round start
reloadFrame:RegisterEvent("ARENA_OPPONENT_UPDATE")  -- Arena opponent changes

reloadFrame:SetScript("OnEvent", function(self, event)
    C_Timer.After(0.5, function()
        -- MIDNIGHT: No spell list to rebuild - API handles filtering
        
        local AC = GetAC()
        if not AC then return end
        
        local db = AC.DB and AC.DB.profile and AC.DB.profile.blackout
        
        -- This is kind of important I guess: clear test mode flags on zone change/reload.
        -- Prevents test textures from persisting outside of active testing.
        if event == "PLAYER_ENTERING_WORLD" then
            local _, instanceType = IsInInstance()
            -- Clear test modes when NOT in arena (prevents target dummy issue)
            if instanceType ~= "arena" then
                if db then
                    db.externalTestMode = false
                    db.healthBarTestMode = false
                end
                
                -- Clear all blackout states when leaving arena
                wipe(activeBlackouts)
                wipe(lastBlackoutState)
                
                if AC.BLACKOUT_DEBUG then
                    print("|cff00FFFF[Blackout]|r Left arena - test modes cleared, blackout states reset")
                end
            end
        end
        
        if not db or db.enabled == false then return end
        
        -- Scan all visible nameplates
        local nameplates = C_NamePlate.GetNamePlates()
        for _, nameplate in ipairs(nameplates) do
            local frame = nameplate.unitFrame or nameplate.UnitFrame
            if frame and frame.unit then
                if not frame:IsForbidden() and not frame:IsProtected() then
                    ScanBlackoutAura(frame)
                    if frame.healthBar then
                        AC_CompactUnitFrame_UpdateHealthColor(frame)  -- Use OUR function, not Blizzard's
                    end
                    
                    -- This is kind of important I guess: refresh party class indicators on round changes.
                    if AC.UpdatePartyClassIndicator then
                        AC.UpdatePartyClassIndicator(frame)
                    end
                end
            end
        end
        
        if AC.BLACKOUT_DEBUG then
            print("|cff00FFFF[Blackout]|r System initialized (event: " .. event .. ")")
        end
    end)
end)

-- Debug command.

local function TestBlackout()
    print("|cff00FFFF[Blackout Debug - MIDNIGHT API]|r ==================")
    
    local AC = GetAC()
    if not AC then
        print("|cffFF0000[Blackout]|r ArenaCore not loaded yet!")
        return
    end
    
    -- Check if enabled
    local db = AC.DB and AC.DB.profile and AC.DB.profile.blackout
    if not db then
        print("|cffFF0000[Blackout]|r Database not found!")
        return
    end
    
    print("|cff00FF00[Blackout]|r Enabled:", tostring(db.enabled))
    print("|cff00FF00[Blackout]|r Mode: Midnight API (C_Spell.IsSpellImportant)")
    
    -- Check target
    if UnitExists("target") then
        print("|cff00FF00[Blackout]|r Target:", UnitName("target"))
        
        -- Check blackout detection using new API
        if IsBlackoutRestricted() then
            print("|cffFF0000[Blackout]|r Blackout is disabled in arena and arena prep")
            print("|cffFF0000[Blackout]|r Test functionality is not available")
            return
        end
        
        local hasBlackout, spellID = HasBlackoutAura("target")
        print("|cff00FF00[Blackout]|r Has important harmful aura:", tostring(hasBlackout))
        if spellID then
            local spellName = C_Spell.GetSpellName(spellID)
            print("|cff00FF00[Blackout]|r Detected spell:", spellName, "(", spellID, ")")
        end
        
        -- Scan all harmful auras on target for debugging
        print("|cffFFAA00[Blackout]|r All HARMFUL auras on target:")
        for i = 1, MAX_AURAS_TO_SCAN do
            local auraData = C_UnitAuras.GetAuraDataByIndex("target", i, "HARMFUL")
            if not auraData then break end
            local isImportant = C_Spell.IsSpellImportant and C_Spell.IsSpellImportant(auraData.spellId)
            local importantTag = isImportant and "|cff00FF00[IMPORTANT]|r" or ""
            print(string.format("  %d: %s (%d) %s", i, auraData.name or "Unknown", auraData.spellId, importantTag))
        end
        
        -- Check active blackouts (offensive buffs on enemies)
        print("|cffFFAA00[Blackout]|r Active tracked blackouts (enemy buffs):")
        local activeCount = 0
        for unitKey, data in pairs(activeBlackouts) do
            activeCount = activeCount + 1
            print(string.format("  %s: aura index %d", unitKey, data.auraIndex or 0))
        end
        if activeCount == 0 then
            print("  |cffFFAA00No active enemy buff blackouts|r")
        end
    else
        print("|cffFFAA00[Blackout]|r No target selected")
    end
    
    -- BLACKOUT DISABLED - No testing functionality in arena
    if IsBlackoutRestricted() then
        print("|cffFF0000[Blackout]|r Blackout is disabled in arena and arena prep")
        print("|cffFF0000[Blackout]|r Test functionality is not available")
        return
    end
    
    -- Show active blackout tracking
    print("|cffFFAA00[Blackout]|r Active blackout tracking table:")
    local trackCount = 0
    for unitKey, data in pairs(activeBlackouts) do
        trackCount = trackCount + 1
        print(string.format("  %s: aura index %d", unitKey, data.auraIndex or 0))
    end
    if trackCount == 0 then
        print("  |cffFFAA00No units currently tracked|r")
    end
    
    print("|cff00FFFF[Blackout Debug]|r ==================")
end

-- Register dedicated slash command
SLASH_BLACKOUTTEST1 = "/testblackout"
SLASH_BLACKOUTTEST2 = "/blackouttest"
SlashCmdList["BLACKOUTTEST"] = TestBlackout
SLASH_BLACKOUTLIST1 = "/blackoutlist"
SLASH_BLACKOUTLIST2 = "/bolist"
SlashCmdList["BLACKOUTLIST"] = function(msg)
    local AC = GetAC()
    if not AC then
        print("|cffFF0000[Blackout]|r ArenaCore not loaded yet!")
        return
    end
    
    print("|cffFF0000[Blackout]|r ========== BLACKOUT COMPLETELY DISABLED ==========")
    print("|cffFF0000[Blackout]|r Status: FEATURE REMOVED FROM TOC FILE")
    print("|cffFF0000[Blackout]|r Reason: User requested complete removal")
    print("|cffFF0000[Blackout]|r Environment: All functionality disabled everywhere")
    print("|cffFF0000[Blackout]|r =================================================")
    print("|cffFFAA00[Blackout]|r What's disabled:")
    print("|cffFFAA00[Blackout]|r   • BlackoutEngine.lua (commented out in TOC)")
    print("|cffFFAA00[Blackout]|r   • BlackoutCustomization.lua (commented out in TOC)")
    print("|cffFFAA00[Blackout]|r   • Blackout.lua page (commented out in TOC)")
    print("|cffFFAA00[Blackout]|r   • UI_BlackoutEditor.lua (commented out in TOC)")
    print("|cffFFAA00[Blackout]|r Feature will not load until re-enabled in TOC")
end

-- ============================================================================
-- NAMEPLATE CLEANUP (Prevent Frame Recycling Issues)
-- ============================================================================
-- CRITICAL: Blizzard recycles nameplate frames for performance
-- When a nameplate is removed, we MUST clear all blackout state
-- Otherwise, a pet nameplate might inherit blackout textures from a previous enemy player

local function HandleNamePlateRemoved(unit)
    local AC = GetAC()
    if not AC then return end
    
    -- Clear tracking tables for this unit
    if lastBlackoutState[unit] then
        lastBlackoutState[unit] = nil
    end
    if activeBlackouts[unit] then
        activeBlackouts[unit] = nil
    end
    
    -- Get the nameplate frame for this unit
    local nameplate = C_NamePlate.GetNamePlateForUnit(unit)
    if not nameplate then return end
    
    local frame = nameplate.unitFrame or nameplate.UnitFrame
    if not frame then return end
    
    -- Clear blackout config to prevent recycled frames from inheriting old state
    if frame.ArenaCore and frame.ArenaCore.config then
        frame.ArenaCore.config.blackoutColor = nil
        frame.ArenaCore.config.blackoutSpellID = nil
    end
    
    -- Clear all blackout textures and indicators
    if AC.BlackoutCustomization then
        AC.BlackoutCustomization:ClearCustomization(frame)
    end
end

-- Register NAME_PLATE_UNIT_REMOVED event
local nameplateRemovedFrame = CreateFrame("Frame")
nameplateRemovedFrame:RegisterEvent("NAME_PLATE_UNIT_REMOVED")
nameplateRemovedFrame:SetScript("OnEvent", function(self, event, unit)
    -- MIDNIGHT: No longer disabled - we use new C_Spell.IsSpellImportant API
    HandleNamePlateRemoved(unit)
end)

-- ============================================================================
-- INITIALIZATION
-- ============================================================================
-- Load blackout spells and initialize event frames when addon loads

C_Timer.After(0.5, function()
    local AC = GetAC()
    
    -- MIDNIGHT: Initialize with new API-based system
    -- No combat log, no spell ID list - uses C_Spell.IsSpellImportant
    
    -- Initialize all event frames AFTER addon loads to avoid taint warnings
    InitializeGroupRosterFrame()  -- Solo Shuffle cleanup only
    InitializeNameplateFrame()    -- NAME_PLATE_UNIT_ADDED
    InitializeAuraFrame()         -- UNIT_AURA (primary detection)
    
    if AC and AC.BLACKOUT_DEBUG then
        print("|cff00FFFF[Blackout]|r MIDNIGHT API Mode initialized")
        print("|cff00FFFF[Blackout]|r Using C_Spell.IsSpellImportant() for detection")
        print("|cff00FFFF[Blackout]|r Use /testblackout to debug")
    end
end)
