-- ============================================================================
-- MismatchHandler
-- Keeps frame visibility sane in weird brackets (2v3, 1v2, etc.)
-- ============================================================================

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
-- ============================================================================

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

-- ============================================================================
-- ARENA_OPPONENT_UPDATE
-- ============================================================================

function MismatchHandler:ARENA_OPPONENT_UPDATE(event, unit, updateType)
    -- Only care in arena.
    if not IsActiveBattlefieldArena() then
        return
    end
    
    -- Validate unit.
    if not IsValidUnit(unit) then
        return
    end
    
    -- This is kind of important I guess: create the frame if it doesn't exist yet.
    -- (Ex: stealth player finally shows up.)
    local frame = self:GetFrame(unit)
    if not frame then
        -- Try to get frame from FrameManager first.
        if AC.FrameManager then
            local frames = AC.FrameManager:GetFrames()
            if frames then
                local arenaIndex = tonumber(unit:match("arena(%d)"))
                if arenaIndex and not frames[arenaIndex] then
                    -- Frame doesn't exist, create it.
                    if AC.FrameManager.CreateFrame then
                        AC.FrameManager:CreateFrame(arenaIndex)
                        frame = self:GetFrame(unit)
                    end
                end
            end
        end
        
        -- Still no frame.
        if not frame then
            return
        end
    end
    
    -- Extract arena index.
    local arenaIndex = tonumber(unit:match("arena(%d)"))
    if not arenaIndex then
        return
    end
    
    -- Update spec/class data.
    local specID = GetArenaOpponentSpec and GetArenaOpponentSpec(arenaIndex)
    
    -- Store spec/class DATA only.
    -- Visual/icon updates are handled by MFM:HandleArenaOpponentUpdate().
    if specID and specID > 0 then
        local id, name, description, icon, role, class = GetSpecializationInfoByID(specID)
        if class then
            frame.class = class
            frame.specID = id
            frame.specIconTexture = icon
        end
    else
        -- No spec data, fallback to UnitClass.
        local _, classFile = UnitClass(unit)
        if classFile then
            frame.class = classFile
        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
    
    -- This is kind of important I guess: always show the frame.
    -- ArenaFrameStealth.lua handles alpha; we just make sure it's actually shown.
    self:ShowFrame(unit)
end

-- ============================================================================
-- ARENA_PREP_OPPONENT_SPECIALIZATIONS
-- ============================================================================

function MismatchHandler:ARENA_PREP_OPPONENT_SPECIALIZATIONS()
    -- Loop through 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.specIconTexture = icon
                end
                
                -- Show frame (alpha handled by ArenaFrameStealth.lua).
                self:ShowFrame(unit)
            end
        end
    end
    -- Don't explicitly hide extra frames.
    -- Only show frames with data and ignore the rest.
end

-- ============================================================================
-- FRAME MANAGEMENT
-- ============================================================================

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
        return
    end
    
    -- Set alpha.
    frame:SetAlpha(alpha)
end

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

function MismatchHandler:RegisterEvents()
    -- Register arena events.
    eventFrame:RegisterEvent("ARENA_OPPONENT_UPDATE")
    eventFrame:RegisterEvent("ARENA_PREP_OPPONENT_SPECIALIZATIONS")
    eventFrame:RegisterEvent("UNIT_NAME_UPDATE")  -- This is kind of important I guess: backup show if ARENA_OPPONENT_UPDATE lags.
    
    -- 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
-- ============================================================================

function MismatchHandler:UNIT_NAME_UPDATE(event, unit)
    -- Only care in arena.
    if not IsActiveBattlefieldArena() then
        return
    end
    
    -- Validate unit.
    if not IsValidUnit(unit) then
        return
    end
    
    -- Show the frame.
    self:ShowFrame(unit)
end

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

function MismatchHandler:Initialize()
    -- Register events.
    self:RegisterEvents()
end

-- Auto-initialize.
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")
        print("Usage: /acmismatch debug")
    end
end
