-- ============================================================================
-- MismatchHandler.lua
-- Handles ALL arena frame visibility for mismatched games (2v3, 1v2, etc.)
-- Uses Gladius's proven event-driven pattern - NO bracket size calculations
-- ============================================================================

local AddonName, AC = ...

-- Create module
local MismatchHandler = {}
AC.MismatchHandler = MismatchHandler

-- Local references for performance
local GetArenaOpponentSpec = GetArenaOpponentSpec
local GetNumArenaOpponentSpecs = GetNumArenaOpponentSpecs
local GetSpecializationInfoByID = GetSpecializationInfoByID
local UnitClass = UnitClass
local UnitExists = UnitExists
local IsActiveBattlefieldArena = IsActiveBattlefieldArena
local IsInInstance = IsInInstance
local InCombatLockdown = InCombatLockdown
local MAX_ARENA_ENEMIES = 3

-- Event frame
local eventFrame = CreateFrame("Frame")

-- ============================================================================
-- UNIT VALIDATION (Gladius pattern lines 955-962)
-- ============================================================================

local function IsValidUnit(unit)
    if not unit then
        return false
    end
    
    -- Validate it's an arena unit (arena1-arena5)
    local unitID = unit:match("arena(%d+)")
    return unitID and tonumber(unitID) <= 5
end

-- ============================================================================
-- CORE GLADIUS PATTERN: ARENA_OPPONENT_UPDATE
-- This is the EXACT pattern from Gladius.lua lines 468-509
-- ============================================================================

function MismatchHandler:ARENA_OPPONENT_UPDATE(event, unit, updateType)
    -- Validate we're in arena (Gladius pattern line 469)
    if not IsActiveBattlefieldArena() then
        return
    end
    
    -- Validate unit (Gladius pattern line 473)
    if not IsValidUnit(unit) then
        return
    end
    
    -- Get frame for this unit
    local frame = self:GetFrame(unit)
    if not frame then
        return
    end
    
    -- Extract arena index
    local arenaIndex = tonumber(unit:match("arena(%d)"))
    if not arenaIndex then
        return
    end
    
    -- Update spec/class data (Gladius pattern lines 481-493)
    local specID = GetArenaOpponentSpec and GetArenaOpponentSpec(arenaIndex)
    
    if specID and specID > 0 then
        -- We have spec data - use it
        local id, name, description, icon, role, class = GetSpecializationInfoByID(specID)
        
        if class then
            -- Store for later use
            frame.class = class
            frame.specID = id
            frame.specIcon = icon
            
            -- Update visual spec icon
            if frame.specIcon and frame.specIcon.icon and icon then
                local AC = _G.ArenaCore
                local db = AC and AC.DB and AC.DB.profile
                local specEnabled = db and db.specIcons and db.specIcons.enabled
                if specEnabled ~= false then
                    frame.specIcon.icon:SetTexture(icon)
                    frame.specIcon:Show()
                else
                    frame.specIcon:Hide()
                end
            end
            
            -- Update visual class icon
            if frame.classIcon and class then
                local AC = _G.ArenaCore
                local db = AC and AC.DB and AC.DB.profile
                local classEnabled = db and db.classIcons and db.classIcons.enabled
                if classEnabled ~= false then
                    if frame.classIcon.UpdateClassIcon then
                        frame.classIcon.UpdateClassIcon(class)
                    else
                        local iconPath = "Interface\\AddOns\\ArenaCore\\Media\\Classicons\\" .. class .. ".tga"
                        frame.classIcon.icon:SetTexture(iconPath)
                        if frame.classIcon.overlay then
                            local overlayPath = "Interface\\AddOns\\ArenaCore\\Media\\Classicons\\Overlays\\" .. class:lower() .. "overlay.tga"
                            frame.classIcon.overlay:SetTexture(overlayPath, true, true)
                        end
                    end
                    frame.classIcon:Show()
                end
            end
        end
    else
        -- No spec data - fallback to UnitClass (Gladius pattern lines 490-492)
        local _, classFile = UnitClass(unit)
        if classFile then
            frame.class = classFile
            
            -- Hide spec icon
            if frame.specIcon then
                frame.specIcon:Hide()
            end
            
            -- Update class icon with fallback
            if frame.classIcon then
                local AC = _G.ArenaCore
                local db = AC and AC.DB and AC.DB.profile
                local classEnabled = db and db.classIcons and db.classIcons.enabled
                if classEnabled ~= false then
                    if frame.classIcon.UpdateClassIcon then
                        frame.classIcon.UpdateClassIcon(classFile)
                    else
                        local iconPath = "Interface\\AddOns\\ArenaCore\\Media\\Classicons\\" .. classFile .. ".tga"
                        frame.classIcon.icon:SetTexture(iconPath)
                        if frame.classIcon.overlay then
                            local overlayPath = "Interface\\AddOns\\ArenaCore\\Media\\Classicons\\Overlays\\" .. classFile:lower() .. "overlay.tga"
                            frame.classIcon.overlay:SetTexture(overlayPath, true, true)
                        end
                    end
                    frame.classIcon:Show()
                end
            end
        end
    end
    
    -- Update frame elements (moved from old handler)
    local AC = _G.ArenaCore
    if AC then
        -- Update dispels
        if AC.UpdateDispelFrames then
            C_Timer.After(0.05, function()
                AC:UpdateDispelFrames()
            end)
        end
        
        -- Update trinkets and racials
        if AC.TrinketsRacials and AC.TrinketsRacials.RefreshFrame then
            AC.TrinketsRacials:RefreshFrame(frame, unit)
        end
        
        -- Update MFM elements if available
        local MFM = AC.MasterFrameManager
        if MFM then
            -- Update name (clear test mode names)
            if not AC.testModeEnabled and MFM.UpdateName then
                MFM:UpdateName(frame)
            end
            
            -- Update health and power
            if MFM.UpdateHealth then MFM:UpdateHealth(frame) end
            if MFM.UpdatePower then MFM:UpdatePower(frame) end
        end
    end
    
    -- CRITICAL: Show frame for all update types (Gladius pattern line 495)
    -- ArenaFrameStealth.lua handles alpha, but we MUST show the frame
    -- Gladius calls ShowUnit() for "seen" and UpdateAlpha() shows frame for other types
    self:ShowFrame(unit)
end

-- ============================================================================
-- CORE GLADIUS PATTERN: ARENA_PREP_OPPONENT_SPECIALIZATIONS
-- This is the EXACT pattern from Gladius.lua lines 511-527
-- ============================================================================

function MismatchHandler:ARENA_PREP_OPPONENT_SPECIALIZATIONS()
    -- Loop through all opponent specs (handles mismatched brackets automatically)
    -- This is the KEY to handling 2v3, 1v2, etc. - we loop based on ACTUAL opponent count
    local numOpponents = GetNumArenaOpponentSpecs and GetNumArenaOpponentSpecs() or 0
    
    -- print("|cff00FF00[PREP_ROOM]|r ARENA_PREP_OPPONENT_SPECIALIZATIONS fired - numOpponents:", numOpponents)
    
    for i = 1, numOpponents do
        local unit = "arena" .. i
        local specID = GetArenaOpponentSpec and GetArenaOpponentSpec(i)
        
        if specID and specID > 0 then
            -- Get frame
            local frame = self:GetFrame(unit)
            if frame then
                -- Update spec/class data
                local id, name, description, icon, role, class = GetSpecializationInfoByID(specID)
                if class then
                    frame.class = class
                    frame.specID = id
                    frame.specIcon = icon
                end
                
                -- Show frame (alpha handled by ArenaFrameStealth.lua)
                self:ShowFrame(unit)
                
                -- print("[PREP_ROOM] Updated spec/class for", unit, "- Frame shown:", frame:IsShown())
            end
        end
    end
    
    -- GLADIUS PATTERN: Do NOT explicitly hide extra frames
    -- Gladius only shows frames with data and ignores the rest
    -- This prevents any potential race conditions with WoW's events
end

-- ============================================================================
-- FRAME MANAGEMENT (Gladius pattern)
-- ============================================================================

function MismatchHandler:GetFrame(unit)
    -- Get frame from FrameManager
    if not AC.FrameManager then
        return nil
    end
    
    local frames = AC.FrameManager:GetFrames()
    if not frames then
        return nil
    end
    
    -- Extract arena index
    local arenaIndex = tonumber(unit:match("arena(%d)"))
    if not arenaIndex then
        return nil
    end
    
    local frame = frames[arenaIndex]
    return frame
end

function MismatchHandler:ShowFrame(unit)
    local frame = self:GetFrame(unit)
    if not frame then
        return
    end
    
    -- Don't interfere with combat lockdown
    if InCombatLockdown() then
        return
    end
    
    -- Show the frame
    frame:Show()
end

function MismatchHandler:HideFrame(unit)
    local frame = self:GetFrame(unit)
    if not frame then
        return
    end
    
    -- Don't interfere with combat lockdown
    if InCombatLockdown() then
        return
    end
    
    -- Hide the frame
    frame:Hide()
    frame:SetAlpha(0)
end

function MismatchHandler:UpdateAlpha(unit, alpha)
    local frame = self:GetFrame(unit)
    if not frame then
        print("|cffFF0000[ALPHA]|r UpdateAlpha failed - no frame for", unit)
        return
    end
    
    -- Set alpha (Gladius pattern - alpha controls visibility state)
    local oldAlpha = frame:GetAlpha()
    frame:SetAlpha(alpha)
    print("|cffFFFF00[ALPHA]|r", unit, "alpha changed:", oldAlpha, "→", alpha)
end

-- ============================================================================
-- EVENT REGISTRATION
-- ============================================================================

function MismatchHandler:RegisterEvents()
    -- Register arena events (Gladius pattern lines 397-403)
    eventFrame:RegisterEvent("ARENA_OPPONENT_UPDATE")
    eventFrame:RegisterEvent("ARENA_PREP_OPPONENT_SPECIALIZATIONS")
    eventFrame:RegisterEvent("UNIT_NAME_UPDATE")  -- CRITICAL: Gladius line 399
    
    -- Set event handler
    eventFrame:SetScript("OnEvent", function(self, event, ...)
        if event == "ARENA_OPPONENT_UPDATE" then
            MismatchHandler:ARENA_OPPONENT_UPDATE(event, ...)
        elseif event == "ARENA_PREP_OPPONENT_SPECIALIZATIONS" then
            MismatchHandler:ARENA_PREP_OPPONENT_SPECIALIZATIONS()
        elseif event == "UNIT_NAME_UPDATE" then
            MismatchHandler:UNIT_NAME_UPDATE(event, ...)
        end
    end)
end

function MismatchHandler:UnregisterEvents()
    eventFrame:UnregisterEvent("ARENA_OPPONENT_UPDATE")
    eventFrame:UnregisterEvent("ARENA_PREP_OPPONENT_SPECIALIZATIONS")
    eventFrame:UnregisterEvent("UNIT_NAME_UPDATE")
end

-- ============================================================================
-- UNIT_NAME_UPDATE (Gladius pattern lines 456-466)
-- CRITICAL: This ensures frames show even if ARENA_OPPONENT_UPDATE is delayed
-- ============================================================================

function MismatchHandler:UNIT_NAME_UPDATE(event, unit)
    -- Validate we're in arena
    if not IsActiveBattlefieldArena() then
        return
    end
    
    -- Validate unit
    if not IsValidUnit(unit) then
        return
    end
    
    -- Show the frame (Gladius pattern line 465)
    self:ShowFrame(unit)
end

-- ============================================================================
-- INITIALIZATION
-- ============================================================================

function MismatchHandler:Initialize()
    -- Register events when entering arena
    self:RegisterEvents()
end

-- Auto-initialize on load
C_Timer.After(0.1, function()
    if AC.MismatchHandler then
        AC.MismatchHandler:Initialize()
    end
end)

-- ============================================================================
-- DEBUG COMMANDS
-- ============================================================================

SLASH_ACMISMATCH1 = "/acmismatch"
SlashCmdList["ACMISMATCH"] = function(msg)
    if msg == "debug" then
        print("ArenaCore MismatchHandler Debug:")
        print("- Events registered: ARENA_OPPONENT_UPDATE, ARENA_PREP_OPPONENT_SPECIALIZATIONS")
        print("- Frame count: " .. (AC.FrameManager and #AC.FrameManager:GetFrames() or 0))
        print("- In arena: " .. tostring(IsActiveBattlefieldArena()))
        
        local numOpps = GetNumArenaOpponentSpecs and GetNumArenaOpponentSpecs() or 0
        print("- Opponent count: " .. numOpps)
        
        for i = 1, MAX_ARENA_ENEMIES do
            local unit = "arena" .. i
            local frame = MismatchHandler:GetFrame(unit)
            if frame then
                print(string.format("  - %s: visible=%s, alpha=%.1f", unit, tostring(frame:IsVisible()), frame:GetAlpha()))
            end
        end
    else
        print("ArenaCore MismatchHandler - Gladius Pattern")
        print("Usage: /acmismatch debug")
    end
end
