-- ============================================================================
-- TARGET HIGHLIGHT
-- ============================================================================
-- Shows a border on arena frames when you actually target someone.
-- ============================================================================

local AC = _G.ArenaCore
if not AC then return end

local function GetTargetBorderColor()
    local defaultR, defaultG, defaultB, defaultA = 1, 0.6, 0, 1

    if AC.DB and AC.DB.profile and AC.DB.profile.arenaFrames and AC.DB.profile.arenaFrames.sizing then
        local c = AC.DB.profile.arenaFrames.sizing.targetBorderColor
        if type(c) == "table" then
            local r = c.r or c[1] or defaultR
            local g = c.g or c[2] or defaultG
            local b = c.b or c[3] or defaultB
            local a = c.a or c[4] or defaultA
            return r, g, b, a
        end
    end

    return defaultR, defaultG, defaultB, defaultA
end

local TargetHighlight = {}
AC.TargetHighlight = TargetHighlight

-- ============================================================================
-- CONFIGURATION
-- ============================================================================

local FADE_DURATION = 0.15  -- Fade in/out duration in seconds
local UPDATE_INTERVAL = 0.05  -- Animation update interval

-- ============================================================================
-- LOCAL VARIABLES
-- ============================================================================

local eventFrame = nil
local activeTarget = nil  -- Currently targeted arena unit
local animationTimers = {}  -- [unit] = {startTime, startAlpha, targetAlpha, duration}

-- ============================================================================
-- HELPER FUNCTIONS
-- ============================================================================

local function GetFrameForUnit(unit)
    -- Extract arena index from unit ("arena1" -> 1)
    local index = unit and tonumber(unit:match("arena(%d+)"))
    
    -- MasterFrameManager first.
    if index and AC.MasterFrameManager and AC.MasterFrameManager.frames then
        local frame = AC.MasterFrameManager.frames[index]
        if frame then
            return frame
        end
    end
    
    -- Fallback: match by `unit`.
    if AC.MasterFrameManager and AC.MasterFrameManager.frames then
        for i = 1, 3 do
            local frame = AC.MasterFrameManager.frames[i]
            if frame and frame.unit == unit then
                return frame
            end
        end
    end
    
    -- Fallback: old `arenaFrames`.
    if AC.arenaFrames then
        if index then
            local frame = AC.arenaFrames[index]
            if frame then
                return frame
            end
        end
        for i = 1, 3 do
            local frame = AC.arenaFrames[i]
            if frame and frame.unit == unit then
                return frame
            end
        end
    end
    
    return nil
end

local function GetSettings()
    -- Check new sizing-based settings first
    local sizingDB = AC.DB and AC.DB.profile and AC.DB.profile.arenaFrames and AC.DB.profile.arenaFrames.sizing
    
    local settings = {
        enabled = true,
        color = {r = 1, g = 0.7, b = 0, a = 1},
        fadeEnabled = true,
        fadeDuration = 0.15,
        disableTargetHighlight = false,
        targetHighlightOnClassIcon = false
    }
    
    -- Apply sizing settings if they exist
    if sizingDB then
        if sizingDB.disableTargetHighlight ~= nil then
            settings.disableTargetHighlight = sizingDB.disableTargetHighlight
        end
        if sizingDB.targetHighlightOnClassIcon ~= nil then
            settings.targetHighlightOnClassIcon = sizingDB.targetHighlightOnClassIcon
        end
    end
    
    -- Legacy targetHighlight settings
    if AC.DB and AC.DB.profile and AC.DB.profile.targetHighlight then
        local legacy = AC.DB.profile.targetHighlight
        if legacy.enabled ~= nil then settings.enabled = legacy.enabled end
        if legacy.color then settings.color = legacy.color end
        if legacy.fadeEnabled ~= nil then settings.fadeEnabled = legacy.fadeEnabled end
        if legacy.fadeDuration then settings.fadeDuration = legacy.fadeDuration end
    end

    if settings.disableTargetHighlight then
        settings.targetHighlightOnClassIcon = false
    end
    
    return settings
end

local function AnchorOutlineContainer(frame, container)
    if not frame or not container then return end

    container:ClearAllPoints()

    -- Check if Arena Core theme is active
    local isArenaCoreTheme = false
    if AC.ArenaFrameThemes and AC.ArenaFrameThemes.GetCurrentTheme then
        local currentTheme = AC.ArenaFrameThemes:GetCurrentTheme()
        isArenaCoreTheme = (currentTheme == "Arena Core")
    end

    -- For Arena Core theme, anchor to the theme background frame
    if isArenaCoreTheme and frame._themeBackground then
        container:SetPoint("TOPLEFT", frame._themeBackground, "TOPLEFT", 0, 0)
        container:SetPoint("BOTTOMRIGHT", frame._themeBackground, "BOTTOMRIGHT", 0, 0)
        return
    end

    -- For other themes, anchor to health/resource bars
    local healthBar = frame.healthBar or frame.HealthBar
    local resourceBar = frame.manaBar or frame.powerBar or frame.PowerBar

    if not healthBar then
        container:SetAllPoints(frame)
        return
    end

    -- Two-point anchor: stretches from healthBar top-left to resourceBar bottom-right.
    -- Mirrors the theme background approach -- always in sync, no manual size math needed.
    local bottomAnchor = resourceBar or healthBar
    container:SetPoint("TOPLEFT", healthBar, "TOPLEFT", 0, 0)
    container:SetPoint("BOTTOMRIGHT", bottomAnchor, "BOTTOMRIGHT", 0, 0)
end

-- ============================================================================
-- ANIMATION (smooth fade)
-- ============================================================================

local function StartFadeAnimation(unit, targetAlpha)
    local frame = GetFrameForUnit(unit)
    if not frame or not frame.targetOutline then return end
    
    local settings = GetSettings()
    local duration = settings.fadeEnabled and (settings.fadeDuration or FADE_DURATION) or 0
    
    -- Instant change if fade is disabled.
    if duration <= 0 then
        frame.targetOutline:SetAlpha(targetAlpha)
        animationTimers[unit] = nil
        return
    end
    
    -- Start animation.
    local currentAlpha = frame.targetOutline:GetAlpha()
    animationTimers[unit] = {
        startTime = GetTime(),
        startAlpha = currentAlpha,
        targetAlpha = targetAlpha,
        duration = duration
    }
end

local function UpdateAnimations()
    local currentTime = GetTime()
    
    for unit, anim in pairs(animationTimers) do
        local frame = GetFrameForUnit(unit)
        if frame and frame.targetOutline then
            local elapsed = currentTime - anim.startTime
            local progress = math.min(elapsed / anim.duration, 1.0)
            
            -- Smooth easing (ease-out).
            progress = 1 - math.pow(1 - progress, 3)
            
            local newAlpha = anim.startAlpha + (anim.targetAlpha - anim.startAlpha) * progress
            frame.targetOutline:SetAlpha(newAlpha)
            
            -- Animation complete.
            if progress >= 1.0 then
                animationTimers[unit] = nil
            end
        else
            -- Frame doesn't exist.
            animationTimers[unit] = nil
        end
    end
end

-- ============================================================================
-- TARGET TRACKING
-- ============================================================================

local function UpdateTargetHighlight()
    local settings = GetSettings()
    
    -- Check if target highlight is completely disabled
    if not settings.enabled or settings.disableTargetHighlight then 
        -- If disabled, hide everything (both frame and class icon outlines)
        for i = 1, 3 do
            local frame = GetFrameForUnit("arena" .. i)
            if frame then
                if frame.targetOutline then
                    frame.targetOutline:SetAlpha(0)
                end
                if frame.classIcon and frame.classIcon.targetOutline then
                    frame.classIcon.targetOutline:SetAlpha(0)
                end
            end
        end
        activeTarget = nil
        return 
    end
    
    -- No target, no highlight.
    if not UnitExists("target") then
        -- Clear any lingering highlight.
        if activeTarget then
            local frame = GetFrameForUnit(activeTarget)
            if frame then
                if frame.targetOutline then
                    frame.targetOutline:SetAlpha(0)
                end
                if frame.classIcon and frame.classIcon.targetOutline then
                    frame.classIcon.targetOutline:SetAlpha(0)
                end
            end
            activeTarget = nil
        end
        return
    end
    
    local newTarget = nil
    
    -- Find which arena unit is targeted.
    for i = 1, 3 do
        local arenaUnit = "arena" .. i
        if UnitExists(arenaUnit) and UnitIsUnit(arenaUnit, "target") then
            newTarget = arenaUnit
            break
        end
    end
    
    -- Target changed.
    if newTarget ~= activeTarget then
        -- Fade out old target (both frame and class icon).
        if activeTarget then
            local oldFrame = GetFrameForUnit(activeTarget)
            if oldFrame then
                if oldFrame.targetOutline then
                    oldFrame.targetOutline:SetAlpha(0)
                end
                if oldFrame.classIcon and oldFrame.classIcon.targetOutline then
                    oldFrame.classIcon.targetOutline:SetAlpha(0)
                end
            end
        end
        
        -- Fade in new target.
        if newTarget then
            local frame = GetFrameForUnit(newTarget)
            if frame then
                local r, g, b, a = GetTargetBorderColor()
                
                -- Determine which outline to show based on settings
                if settings.targetHighlightOnClassIcon then
                    -- Class icon mode: hide frame outline, show class icon outline
                    if frame.targetOutline then
                        frame.targetOutline:SetAlpha(0)
                    end
                    
                    -- Create class icon outline if it doesn't exist
                    if frame.classIcon and not frame.classIcon.targetOutline then
                        TargetHighlight:CreateClassIconOutline(frame)
                    end
                    
                    -- Show class icon outline
                    if frame.classIcon and frame.classIcon.targetOutline then
                        local outline = frame.classIcon.targetOutline
                        if outline.top then outline.top:SetVertexColor(r, g, b, a) end
                        if outline.bottom then outline.bottom:SetVertexColor(r, g, b, a) end
                        if outline.left then outline.left:SetVertexColor(r, g, b, a) end
                        if outline.right then outline.right:SetVertexColor(r, g, b, a) end
                        outline:SetAlpha(1.0)
                    end
                else
                    -- Frame mode: show frame outline, hide class icon outline
                    if frame.classIcon and frame.classIcon.targetOutline then
                        frame.classIcon.targetOutline:SetAlpha(0)
                    end

                    if not frame.targetOutline then
                        TargetHighlight:CreateOutline(frame)
                    end
                    
                    if frame.targetOutline then
                        if frame.targetOutline.top then frame.targetOutline.top:SetVertexColor(r, g, b, a) end
                        if frame.targetOutline.bottom then frame.targetOutline.bottom:SetVertexColor(r, g, b, a) end
                        if frame.targetOutline.left then frame.targetOutline.left:SetVertexColor(r, g, b, a) end
                        if frame.targetOutline.right then frame.targetOutline.right:SetVertexColor(r, g, b, a) end
                        StartFadeAnimation(newTarget, 1.0)
                    end
                end
            end
        end
        
        activeTarget = newTarget
    else
        -- DEBUG: Show why no change occurred (DISABLED)
        --[[
        if activeTarget then
            print("|cffFFA500[TargetHighlight]|r No change - still targeting:", activeTarget)
        else
            print("|cffFFA500[TargetHighlight]|r No change - no active target")
        end
        --]]
    end
end

-- ============================================================================
-- EVENT HANDLERS
-- ============================================================================

local function OnEvent(self, event, ...)
    if event == "PLAYER_TARGET_CHANGED" then
        UpdateTargetHighlight()
        
    elseif event == "PLAYER_REGEN_DISABLED" then
        -- Entering combat - continue tracking
        UpdateTargetHighlight()
        
    elseif event == "PLAYER_REGEN_ENABLED" then
        -- Leaving combat - continue tracking
        UpdateTargetHighlight()
        
    elseif event == "ARENA_PREP_OPPONENT_SPECIALIZATIONS" then
        -- Prep room: kill highlights immediately (no animation).
        activeTarget = nil
        animationTimers = {}  -- Clear all pending animations
        for i = 1, 3 do
            local frame = GetFrameForUnit("arena" .. i)
            if frame then
                if frame.targetOutline then
                    frame.targetOutline:SetAlpha(0)
                end
                if frame.classIcon and frame.classIcon.targetOutline then
                    frame.classIcon.targetOutline:SetAlpha(0)
                end
            end
        end
        
    elseif event == "ARENA_OPPONENT_UPDATE" then
        -- Arena state changed: clear first, then check target.
        -- This is kind of important I guess: don't auto-show highlights unless you're targeting.
        C_Timer.After(0.1, function()
            -- Only update if we have a valid target.
            if UnitExists("target") then
                UpdateTargetHighlight()
            else
                -- No target.
                activeTarget = nil
                for i = 1, 3 do
                    local frame = GetFrameForUnit("arena" .. i)
                    if frame then
                        if frame.targetOutline then
                            frame.targetOutline:SetAlpha(0)
                        end
                        if frame.classIcon and frame.classIcon.targetOutline then
                            frame.classIcon.targetOutline:SetAlpha(0)
                        end
                    end
                end
            end
        end)
        
    elseif event == "PLAYER_ENTERING_WORLD" then
        -- Reload/zone change: clear everything.
        activeTarget = nil
        animationTimers = {}
        for i = 1, 3 do
            local frame = GetFrameForUnit("arena" .. i)
            if frame then
                if frame.targetOutline then
                    frame.targetOutline:SetAlpha(0)
                end
                if frame.classIcon and frame.classIcon.targetOutline then
                    frame.classIcon.targetOutline:SetAlpha(0)
                end
            end
        end
    end
end

-- ============================================================================
-- FRAME CREATION
-- ============================================================================

function TargetHighlight:CreateOutline(frame)
    if frame.targetOutline then
        return frame.targetOutline
    end
    
    -- Container for border textures.
    local container = CreateFrame("Frame", nil, frame)
    container:SetFrameLevel(frame:GetFrameLevel() + 10)  -- Above everything

    -- Position container to cover the live health/resource bar stack.
    AnchorOutlineContainer(frame, container)
    
    -- Use 4 solid edges for a thick, obvious border.
    local borderThickness = 3  -- Default thickness
    if AC.DB and AC.DB.profile and AC.DB.profile.arenaFrames and AC.DB.profile.arenaFrames.sizing then
        borderThickness = AC.DB.profile.arenaFrames.sizing.targetBorderThickness or 3
    end
    local r, g, b, a = GetTargetBorderColor()
    
    -- Create 4 border edges (top, bottom, left, right).
    local top = container:CreateTexture(nil, "OVERLAY", nil, 7)
    top:SetColorTexture(r, g, b, a or 1)
    top:SetPoint("TOPLEFT", container, "TOPLEFT", 0, 0)
    top:SetPoint("TOPRIGHT", container, "TOPRIGHT", 0, 0)
    top:SetHeight(borderThickness)
    
    local bottom = container:CreateTexture(nil, "OVERLAY", nil, 7)
    bottom:SetColorTexture(r, g, b, a or 1)
    bottom:SetPoint("BOTTOMLEFT", container, "BOTTOMLEFT", 0, 0)
    bottom:SetPoint("BOTTOMRIGHT", container, "BOTTOMRIGHT", 0, 0)
    bottom:SetHeight(borderThickness)
    
    local left = container:CreateTexture(nil, "OVERLAY", nil, 7)
    left:SetColorTexture(r, g, b, a or 1)
    left:SetPoint("TOPLEFT", container, "TOPLEFT", 0, 0)
    left:SetPoint("BOTTOMLEFT", container, "BOTTOMLEFT", 0, 0)
    left:SetWidth(borderThickness)
    
    local right = container:CreateTexture(nil, "OVERLAY", nil, 7)
    right:SetColorTexture(r, g, b, a or 1)
    right:SetPoint("TOPRIGHT", container, "TOPRIGHT", 0, 0)
    right:SetPoint("BOTTOMRIGHT", container, "BOTTOMRIGHT", 0, 0)
    right:SetWidth(borderThickness)
    
    -- Store references.
    container.top = top
    container.bottom = bottom
    container.left = left
    container.right = right
    container:SetAlpha(0)  -- Hidden by default
    
    frame.targetOutline = container

    -- Keep outline synced even if layout applies after creation.
    if not frame._targetHighlightSyncHooked then
        frame._targetHighlightSyncHooked = true

        local function SyncOutline()
            if AC.TargetHighlight and AC.TargetHighlight.UpdateOutlineSize and frame.targetOutline then
                AC.TargetHighlight:UpdateOutlineSize(frame)
            end
        end

        frame:HookScript("OnShow", SyncOutline)
        SyncOutline()

        local hb = frame.healthBar or frame.HealthBar
        local rb = frame.manaBar or frame.powerBar or frame.PowerBar
        if hb and hb.HookScript then
            hb:HookScript("OnSizeChanged", SyncOutline)
            hb:HookScript("OnShow", SyncOutline)
        end
        if rb and rb.HookScript then
            rb:HookScript("OnSizeChanged", SyncOutline)
            rb:HookScript("OnShow", SyncOutline)
        end
    end
    
    return container
end

function TargetHighlight:UpdateOutlineSize(frame)
    if not frame or not frame.targetOutline then return end

    AnchorOutlineContainer(frame, frame.targetOutline)
end

function TargetHighlight:RefreshAll()
    -- Refresh all outlines (settings change).
    for i = 1, 3 do
        local frame = GetFrameForUnit("arena" .. i)
        if frame then
            self:UpdateOutlineSize(frame)
            if frame.targetOutline then
                frame.targetOutline:SetAlpha(0)
            end
            if frame.classIcon and frame.classIcon.targetOutline then
                frame.classIcon.targetOutline:SetAlpha(0)
            end
        end
    end
    
    -- Force re-evaluation so mode switches apply immediately without retargeting.
    activeTarget = nil

    -- Update current target.
    UpdateTargetHighlight()
end

function TargetHighlight:CreateClassIconOutline(frame)
    if not frame or not frame.classIcon then return end
    if frame.classIcon.targetOutline then return frame.classIcon.targetOutline end
    
    local classIcon = frame.classIcon
    
    -- Container for border textures
    local container = CreateFrame("Frame", nil, classIcon)
    container:SetFrameLevel(classIcon:GetFrameLevel() + 10)
    container:SetAllPoints(classIcon)
    
    -- Get border settings
    local borderThickness = 3
    if AC.DB and AC.DB.profile and AC.DB.profile.arenaFrames and AC.DB.profile.arenaFrames.sizing then
        borderThickness = AC.DB.profile.arenaFrames.sizing.targetBorderThickness or 3
    end
    local r, g, b, a = GetTargetBorderColor()
    
    -- Create 4 border edges
    local top = container:CreateTexture(nil, "OVERLAY", nil, 7)
    top:SetColorTexture(r, g, b, a or 1)
    top:SetPoint("TOPLEFT", container, "TOPLEFT", 0, 0)
    top:SetPoint("TOPRIGHT", container, "TOPRIGHT", 0, 0)
    top:SetHeight(borderThickness)
    
    local bottom = container:CreateTexture(nil, "OVERLAY", nil, 7)
    bottom:SetColorTexture(r, g, b, a or 1)
    bottom:SetPoint("BOTTOMLEFT", container, "BOTTOMLEFT", 0, 0)
    bottom:SetPoint("BOTTOMRIGHT", container, "BOTTOMRIGHT", 0, 0)
    bottom:SetHeight(borderThickness)
    
    local left = container:CreateTexture(nil, "OVERLAY", nil, 7)
    left:SetColorTexture(r, g, b, a or 1)
    left:SetPoint("TOPLEFT", container, "TOPLEFT", 0, 0)
    left:SetPoint("BOTTOMLEFT", container, "BOTTOMLEFT", 0, 0)
    left:SetWidth(borderThickness)
    
    local right = container:CreateTexture(nil, "OVERLAY", nil, 7)
    right:SetColorTexture(r, g, b, a or 1)
    right:SetPoint("TOPRIGHT", container, "TOPRIGHT", 0, 0)
    right:SetPoint("BOTTOMRIGHT", container, "BOTTOMRIGHT", 0, 0)
    right:SetWidth(borderThickness)
    
    -- Store references
    container.top = top
    container.bottom = bottom
    container.left = left
    container.right = right
    container:SetAlpha(0)
    
    classIcon.targetOutline = container
    
    return container
end

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

function TargetHighlight:Initialize()
    -- Create event frame.
    if not eventFrame then
        eventFrame = CreateFrame("Frame")
        eventFrame:SetScript("OnEvent", OnEvent)
        
        -- Register events.
        eventFrame:RegisterEvent("PLAYER_TARGET_CHANGED")
        eventFrame:RegisterEvent("PLAYER_REGEN_DISABLED")
        eventFrame:RegisterEvent("PLAYER_REGEN_ENABLED")
        eventFrame:RegisterEvent("ARENA_PREP_OPPONENT_SPECIALIZATIONS")
        eventFrame:RegisterEvent("ARENA_OPPONENT_UPDATE")
        eventFrame:RegisterEvent("PLAYER_ENTERING_WORLD")
    end
    
    -- Start animation ticker.
    if not self.animationTicker then
        self.animationTicker = C_Timer.NewTicker(UPDATE_INTERVAL, UpdateAnimations)
    end
    
    -- Create outlines for existing frames.
    for i = 1, 3 do
        local frame = GetFrameForUnit("arena" .. i)
        if frame and not frame.targetOutline then
            self:CreateOutline(frame)
        end
    end
    
    -- This is kind of important I guess: don't auto-highlight on init.
    -- Clear any lingering highlights from previous session.
    activeTarget = nil
    for i = 1, 3 do
        local frame = GetFrameForUnit("arena" .. i)
        if frame then
            if frame.targetOutline then
                frame.targetOutline:SetAlpha(0)
            end
            if frame.classIcon and frame.classIcon.targetOutline then
                frame.classIcon.targetOutline:SetAlpha(0)
            end
        end
    end
end

-- ============================================================================
-- PUBLIC API
-- ============================================================================

function TargetHighlight:Enable()
    local settings = GetSettings()
    settings.enabled = true
    self:RefreshAll()
end

function TargetHighlight:Disable()
    local settings = GetSettings()
    settings.enabled = false
    
    -- Hide all outlines
    for i = 1, 3 do
        StartFadeAnimation("arena" .. i, 0)
    end
    activeTarget = nil
end

function TargetHighlight:SetColor(r, g, b, a)
    local settings = GetSettings()
    settings.color = {r = r, g = g, b = b, a = a or 1}
    
    -- Update active target immediately
    if activeTarget then
        local frame = GetFrameForUnit(activeTarget)
        if frame and frame.targetOutline and frame.targetOutline.top then
            frame.targetOutline.top:SetVertexColor(r, g, b, a or 1)
            frame.targetOutline.bottom:SetVertexColor(r, g, b, a or 1)
            frame.targetOutline.left:SetVertexColor(r, g, b, a or 1)
            frame.targetOutline.right:SetVertexColor(r, g, b, a or 1)
        end
    end
end

function TargetHighlight:SetFadeDuration(duration)
    local settings = GetSettings()
    settings.fadeDuration = duration
end

function TargetHighlight:SetFadeEnabled(enabled)
    local settings = GetSettings()
    settings.fadeEnabled = enabled
end

function TargetHighlight:ClearAll()
    -- Clear all target highlights.
    activeTarget = nil
    for i = 1, 3 do
        local frame = GetFrameForUnit("arena" .. i)
        if frame and frame.targetOutline then
            frame.targetOutline:SetAlpha(0)
        end
        if frame and frame.classIcon and frame.classIcon.targetOutline then
            frame.classIcon.targetOutline:SetAlpha(0)
        end
        animationTimers["arena" .. i] = nil
    end
end

-- ============================================================================
-- AUTO-INITIALIZE
-- ============================================================================

-- Auto-initialize when ArenaCore is ready.
if AC.MasterFrameManager then
    C_Timer.After(0.5, function()
        TargetHighlight:Initialize()
    end)
else
    -- Wait for MasterFrameManager.
    local initFrame = CreateFrame("Frame")
    initFrame:RegisterEvent("ADDON_LOADED")
    initFrame:SetScript("OnEvent", function(self, event, addonName)
        if addonName == "ArenaCore" and AC.MasterFrameManager then
            C_Timer.After(0.5, function()
                TargetHighlight:Initialize()
            end)
            self:UnregisterAllEvents()
        end
    end)
end

-- Debug command removed for production
