-- [ ORBIT FRAME SELECTION (CORE) ] ------------------------------------------------------------------
-- This is the refactored core module. Drag/Nudge/Tooltip/NativeHook
-- have been extracted into separate files in Selection/ subdirectory.

local _, Orbit = ...
local Engine = Orbit.Engine
local C = Orbit.Constants



Engine.FrameSelection = Engine.FrameSelection or {}
local Selection = Engine.FrameSelection

-- [ STATE ]------------------------------------------------------------------------------------------
Selection.selections = Selection.selections or {}
Selection.dragCallbacks = Selection.dragCallbacks or {}
Selection.selectionCallbacks = Selection.selectionCallbacks or {}
Selection.symmetricPairs = Selection.symmetricPairs or {}

Selection.selectedFrame = nil
Selection.selectedFrames = {}
Selection.isNativeFrame = false
Selection.keyboardHandler = nil
Selection.editModeHooked = false
Selection.combatDeferredCallback = nil

-- [ VISIBILITY HELPERS ] ----------------------------------------------------------------------------
local function ShouldShowOrbitFrames()
    return Orbit.db.GlobalSettings.ShowOrbitFrames ~= false
end

local function ShouldShowBlizzardFrames()
    return Orbit.db.GlobalSettings.ShowBlizzardFrames ~= false
end

local function GetOrbitEditModeColor()
    local curveData = Orbit.db.GlobalSettings and Orbit.db.GlobalSettings.EditModeColorCurve
    return (Orbit.Engine.ColorCurve:GetFirstColorFromCurve(curveData)) or C.Frame.EditModeColor
end

-- [ SYMMETRIC PAIR REGISTRATION ] -------------------------------------------------------------------
function Selection:RegisterSymmetricPair(frameNameA, frameNameB)
    self.symmetricPairs[frameNameA] = frameNameB
    self.symmetricPairs[frameNameB] = frameNameA
end

function Selection:GetSymmetricPartner(frameName)
    return self.symmetricPairs[frameName]
end

-- [ STATE MANAGEMENT ]-------------------------------------------------------------------------------
function Selection:SetSelectedFrame(frame, isNative)
    self.selectedFrame = frame
    self.selectedFrames = {}
    if frame then self.selectedFrames[frame] = true end
    self.isNativeFrame = isNative or false
end

function Selection:GetSelectedFrame()
    return self.selectedFrame
end

function Selection:AddSelectedFrame(frame)
    self.selectedFrames[frame] = true
    local sel = self.selections[frame]
    if sel then
        sel.isSelected = true
        self:UpdateVisuals(frame, sel)
        if Engine.SelectionResize then Engine.SelectionResize:Show(sel) end
    end
end

function Selection:RemoveSelectedFrame(frame)
    self.selectedFrames[frame] = nil
    local sel = self.selections[frame]
    if sel then
        sel.isSelected = false
        sel:ShowHighlighted()
        self:UpdateVisuals(frame, sel)
        if Engine.SelectionResize then Engine.SelectionResize:Hide(sel) end
    end
end

function Selection:GetSelectedFrames()
    return self.selectedFrames
end

function Selection:IsMultiSelected()
    local count = 0
    for _ in pairs(self.selectedFrames) do count = count + 1; if count > 1 then return true end end
    return false
end

-- [ HELPERS ]----------------------------------------------------------------------------------------
local function TintSelection(selection, r, g, b, desaturate)
    if not selection then
        return
    end
    for i = 1, select("#", selection:GetRegions()) do
        local region = select(i, selection:GetRegions())
        if region:IsObjectType("Texture") and not region.isAnchorLine then
            region:SetDesaturated(desaturate)
            region:SetVertexColor(r, g, b, 1)
        end
    end
end

local function ForEachRegion(selection, callback)
    if not selection then
        return
    end
    for i = 1, select("#", selection:GetRegions()) do
        local region = select(i, selection:GetRegions())
        callback(region)
    end
end

local OPPOSITE_EDGES = { TOP = "BOTTOM", BOTTOM = "TOP", LEFT = "RIGHT", RIGHT = "LEFT" }
local function GetOppositeEdge(edge)
    return OPPOSITE_EDGES[edge]
end

local ANCHOR_ALIGN_COLORS = {
    LEFT = { 1.0, 0.55, 0.15 },
    RIGHT = { 0.8, 0.4, 1.0 },
    TOP = { 1.0, 0.55, 0.15 },
    BOTTOM = { 0.8, 0.4, 1.0 },
    CENTER = { 0.2, 0.9, 0.85 },
}
local DEFAULT_ANCHOR_COLOR = { 0, 1, 0 }

local function DeferUntilOutOfCombat(callback)
    if not InCombatLockdown() then
        callback()
        return
    end
    Selection.combatDeferredCallback = callback
    Orbit.CombatManager:RegisterCombatCallback(nil, function()
        if Selection.combatDeferredCallback then
            Selection.combatDeferredCallback()
            Selection.combatDeferredCallback = nil
        end
    end)
end

-- [ MAIN API ]---------------------------------------------------------------------------------------
function Selection:GetSnapTargets(excludeFrame)
    local targets = {}

    -- Unified Dependency Check (BFS)
    -- Checks if target depends on root via ANY combination of Orbit Anchors or UI Parentage.
    -- This prevents circular dependencies even in complex interleaved chains.
    local function IsDependent(target, root)
        if not target or not root then
            return false
        end

        local visited = {}
        local queue = { target }
        local head = 1

        while head <= #queue do
            local current = queue[head]
            head = head + 1

            if current == root then
                return true
            end

            if not visited[current] then
                visited[current] = true

                -- Add Orbit Parent to check
                local orbitParent = Engine.FrameAnchor:GetAnchorParent(current)
                if orbitParent then
                    table.insert(queue, orbitParent)
                end

                -- Add UI Parent to check
                local uiParent = current:GetParent()
                if uiParent then
                    table.insert(queue, uiParent)
                end
            end
        end

        return false
    end

    -- Skip frames that are skipped in the AnchorGraph (virtual = content-empty,
    -- or disabled = off-spec / plugin off). Snapping to a skipped frame would
    -- create an anchor that ReconcileChain immediately promotes away, which
    -- is confusing UX (the visual drop point isn't where the frame ends up).
    -- Empty Tracked containers are the canonical case: they stay visible and
    -- selectable in edit mode but must not be valid anchor targets until they
    -- have content.
    local Graph = Engine.AnchorGraph
    for f in pairs(self.selections) do
        if f ~= excludeFrame and not f:IsForbidden() and f:IsVisible() and not Graph:IsSkipped(f) then
            -- Skip children/descendants of the dragged frame
            if not IsDependent(f, excludeFrame) then
                table.insert(targets, f)
            end
        end
    end

    if EditModeManagerFrame and EditModeManagerFrame.registeredSystemFrames then
        for _, systemFrame in ipairs(EditModeManagerFrame.registeredSystemFrames) do
            if systemFrame ~= excludeFrame and systemFrame:IsVisible() and not systemFrame:IsForbidden() and not systemFrame.orbitSnapExclude and not Graph:IsSkipped(systemFrame) then
                if not IsDependent(systemFrame, excludeFrame) then
                    table.insert(targets, systemFrame)
                end
            end
        end
    end

    return targets
end

function Selection:Attach(frame, dragCallback, selectionCallback)
    if self.selections[frame] then
        return
    end

    local selection = CreateFrame("Frame", nil, frame, "EditModeSystemSelectionTemplate")
    selection:SetAllPoints()
    selection:SetToplevel(false) -- template has toplevel=true; disable to prevent auto-Raise on Show()
    selection:SetFrameStrata(Orbit.Constants.Strata.Overlay)
    selection:SetFrameLevel(frame:GetFrameLevel() + Orbit.Constants.Levels.EditModeSelection)
    selection.isOrbitSelection = true

    -- Create anchor line gradient textures (two halves per edge for center-out fade)
    local lineThickness = C.Selection.AnchorLineThickness
    local lineContainer = CreateFrame("Frame", nil, selection)
    lineContainer:SetFrameLevel(selection:GetFrameLevel() + 10)
    lineContainer:SetAllPoints(selection)
    selection.AnchorLineFrame = lineContainer
    local function MakeHalf(p1, rp1, x1, y1, p2, rp2, x2, y2)
        local t = lineContainer:CreateTexture(nil, "OVERLAY")
        t:SetColorTexture(1, 1, 1, 1)
        t:SetPoint(p1, selection, rp1, x1, y1)
        t:SetPoint(p2, selection, rp2, x2, y2)
        t.isAnchorLine = true
        t:Hide()
        return t
    end
    selection.AnchorLines = {
        TOP    = { MakeHalf("TOPLEFT", "TOPLEFT", 0, lineThickness, "BOTTOMRIGHT", "TOP", 0, 0),
                   MakeHalf("TOPLEFT", "TOP", 0, lineThickness, "BOTTOMRIGHT", "TOPRIGHT", 0, 0) },
        BOTTOM = { MakeHalf("BOTTOMLEFT", "BOTTOMLEFT", 0, -lineThickness, "TOPRIGHT", "BOTTOM", 0, 0),
                   MakeHalf("TOPLEFT", "BOTTOM", 0, 0, "BOTTOMRIGHT", "BOTTOMRIGHT", 0, -lineThickness) },
        LEFT   = { MakeHalf("TOPLEFT", "TOPLEFT", -lineThickness, 0, "BOTTOMRIGHT", "LEFT", 0, 0),
                   MakeHalf("TOPLEFT", "LEFT", -lineThickness, 0, "BOTTOMRIGHT", "BOTTOMLEFT", 0, 0) },
        RIGHT  = { MakeHalf("TOPRIGHT", "TOPRIGHT", lineThickness, 0, "BOTTOMLEFT", "RIGHT", 0, 0),
                   MakeHalf("TOPRIGHT", "RIGHT", lineThickness, 0, "BOTTOMLEFT", "BOTTOMRIGHT", 0, 0) },
    }

    -- Wire up event handlers using extracted modules
    local Drag = Engine.SelectionDrag

    selection:SetScript("OnMouseDown", function(self)
        Drag:OnMouseDown(self)
    end)
    selection:SetScript("OnDragStart", function(self)
        Drag:OnDragStart(self)
    end)
    selection:SetScript("OnDragStop", function(self)
        Drag:OnDragStop(self)
    end)
    selection:EnableMouseWheel(true)
    selection:SetScript("OnMouseWheel", function(self, delta)
        Drag:OnMouseWheel(self, delta)
    end)

    selection:SetScript("OnMouseUp", function(self, button)
        if button == "RightButton" then
            Engine.CanvasMode:Toggle(self.parent, function(f)
                Selection:UpdateVisuals(f)
            end)
        end
    end)

    selection:SetScript("OnEnter", function(self)
        if not self.isSelected then
            self:ShowHighlighted()
        end
        self:ShowTooltip()
    end)

    selection:SetScript("OnLeave", function(self)
        if not self.isSelected then
            if EditModeManagerFrame and EditModeManagerFrame:IsShown() then
                self:ShowHighlighted()
            else
                self:Hide()
            end
        end
        GameTooltip:Hide()
    end)

    function selection:ShowTooltip()
        if not self.parent or self.parent.orbitIsDragging then
            return
        end

        GameTooltip:SetOwner(self, "ANCHOR_CURSOR_RIGHT")
        GameTooltip:AddLine(self.system.GetSystemName(), 1, 0.82, 0)
        GameTooltip:AddLine(EDIT_MODE_CLICK_TO_EDIT, 1, 1, 1)

        -- Show Canvas Mode hint if plugin supports it
        if self.parent and self.parent.orbitPlugin and self.parent.orbitPlugin.canvasMode then
            GameTooltip:AddLine("Right-click: Open Canvas Mode", 0.6, 0.9, 0.6)
        end

        if self.parent and self.parent.editModeTooltipLines then
            GameTooltip:AddLine(" ", 1, 1, 1)
            GameTooltip:AddLine("Exit edit mode and", 0.6, 0.6, 0.6)
            for _, line in ipairs(self.parent.editModeTooltipLines) do
                GameTooltip:AddLine(line, 0.6, 0.6, 0.6)
            end
            if self.parent.isTrackedBar then
                GameTooltip:AddLine("Shift-right click to delete icons", 0.6, 0.6, 0.6)
            elseif self.parent.isChargeBar then
                GameTooltip:AddLine("Shift-right click to delete bars", 0.6, 0.6, 0.6)
            end
        end
        GameTooltip:Show()
    end

    selection:Hide()

    if selection.Label then
        selection.Label:SetText(frame.editModeName or frame:GetName() or "Frame")
    end

    selection.parent = frame

    -- Copy editModeName and systemIndex from parent for dialog title support
    selection.editModeName = frame.editModeName
    selection.systemIndex = frame.systemIndex

    if not selection.system then
        selection.system = {
            GetSystemName = function()
                return frame.editModeName or frame:GetName() or "Frame"
            end,
        }
    end

    function selection:GetLabelText()
        if self.Label then
            return self.Label:GetText()
        end
        return self.system.GetSystemName()
    end

    self.selections[frame] = selection
    self.dragCallbacks[frame] = dragCallback
    self.selectionCallbacks[frame] = selectionCallback

    -- Attach resize handle for plugins with Width/Height settings
    if Engine.SelectionResize then Engine.SelectionResize:Attach(selection, frame) end

    if not self.editModeHooked then
        EditModeManagerFrame:HookScript("OnShow", function()
            self:OnEditModeEnter()
        end)
        EditModeManagerFrame:HookScript("OnHide", function()
            self:OnEditModeExit()
        end)

        -- Register combat callback to force visual cleanup and reuse
        Orbit.CombatManager:RegisterCombatCallback(function()
            -- On Combat Start: Force visual exit
            self:OnEditModeExit()
        end, function()
            -- On Combat End: Restore visual state if Edit Mode is still open
            if EditModeManagerFrame and EditModeManagerFrame:IsShown() then
                self:OnEditModeEnter()
            end
        end)

        self.editModeHooked = true
    end
end

-- [ EDIT MODE HANDLERS ]-----------------------------------------------------------------------------
function Selection:OnEditModeEnter()
    Engine.SelectionPeekHide:Enable(self)
    DeferUntilOutOfCombat(function()
        if not (EditModeManagerFrame and EditModeManagerFrame:IsShown()) then
            return
        end
        local showOrbit = ShouldShowOrbitFrames()
        for frame, selection in pairs(Selection.selections) do
            if frame.orbitDisabled then
                selection:Hide()
            elseif selection.isOrbitSelection and not showOrbit then
                selection:SetAlpha(0)
                selection:EnableMouse(false)
            else
                Selection:UpdateVisuals(frame, selection)
                if not frame.disableMovement then
                    frame:SetMovable(true)
                end
            end
        end

        -- Update native Blizzard frames
        if EditModeManagerFrame.registeredSystemFrames then
            local showNative = ShouldShowBlizzardFrames()
            for _, frame in ipairs(EditModeManagerFrame.registeredSystemFrames) do
                if frame.Selection then
                    frame.Selection:SetAlpha(showNative and 1 or 0)
                    frame.Selection:EnableMouse(showNative)
                end
            end
        end

        -- Auto-start Edit Mode tour for first-time users
        if Orbit.db and Orbit.db.AccountSettings and not Orbit.db.AccountSettings.TourComplete then
            if Engine.EditModeTour then Engine.EditModeTour:StartTour() end
        end

        -- Phase 3 implementation
        if Engine.FrameAnchor then
            Engine.FrameAnchor:ReconcileAll()
        end
    end)
end

function Selection:OnEditModeExit()
    Engine.SelectionPeekHide:Disable(self)
    -- End tour if active
    if Engine.EditModeTour then Engine.EditModeTour:EndTour() end
    -- Immediate Visual Cleanup (Safe in Combat)
    for frame, selection in pairs(Selection.selections) do
        selection:Hide()
        if selection.AnchorLineFrame then
            selection.AnchorLineFrame:Hide()
        end
        if Engine.SelectionResize then Engine.SelectionResize:Hide(selection) end
    end

    -- Deferred State/Logic Cleanup (Unsafe in Combat)
    DeferUntilOutOfCombat(function()
        if EditModeManagerFrame and EditModeManagerFrame:IsShown() then
            return
        end

        for frame, selection in pairs(Selection.selections) do
            -- Ensure hidden (redundant but safe)
            selection:Hide()
            selection.isSelected = false

            -- Protected calls
            if frame.SetMovable then
                frame:SetMovable(false)
            end
        end
        Selection:DisableKeyboardNudge()

        -- Phase 3 implementation
        if Engine.FrameAnchor then
            Engine.FrameAnchor:ReconcileAll()
        end
    end)
end

function Selection:DeselectAll()
    self.selectedFrame = nil
    self.selectedFrames = {}
    self.isNativeFrame = false
    self:DisableKeyboardNudge()

    for _, selection in pairs(self.selections) do
        if selection.isSelected then
            selection.isSelected = false
            selection:ShowSelected(false)
            selection:ShowHighlighted()
            if Engine.SelectionResize then Engine.SelectionResize:Hide(selection) end

            if EditModeManagerFrame:IsShown() then
                self:UpdateVisuals(nil, selection)
                if selection.parent then
                    selection.parent:SetMovable(true)
                end
            else
                selection:Hide()
                if selection.parent then
                    selection.parent:SetMovable(false)
                end
            end
        end
    end
end

-- [ KEYBOARD NUDGE (DELEGATES TO MODULE) ]-----------------------------------------------------------
function Selection:EnableKeyboardNudge()
    Engine.SelectionNudge:Enable(self)
end

function Selection:DisableKeyboardNudge()
    Engine.SelectionNudge:Disable(self)
end

-- [ ANCHOR LINE VISIBILITY ] ------------------------------------------------------------------------
local START_SOLID = { LEFT = true, TOP = true }
local END_SOLID = { RIGHT = true, BOTTOM = true }

function Selection:ShowAnchorLine(selection, side, align)
    if not selection or not selection.AnchorLines then return end
    for _, pair in pairs(selection.AnchorLines) do
        pair[1]:Hide()
        pair[2]:Hide()
    end
    if not side then
        if selection.AnchorLineFrame then selection.AnchorLineFrame:Hide() end
        return
    end
    local pair = selection.AnchorLines[side]
    if not pair then return end
    local c = (align and ANCHOR_ALIGN_COLORS[align]) or DEFAULT_ANCHOR_COLOR
    local orient = (side == "TOP" or side == "BOTTOM") and "HORIZONTAL" or "VERTICAL"
    local a1s, a1e, a2s, a2e
    if orient == "HORIZONTAL" then
        if align == "LEFT" then
            a1s, a1e, a2s, a2e = 1, 0.7, 0.7, 0.15
        elseif align == "RIGHT" then
            a1s, a1e, a2s, a2e = 0.15, 0.7, 0.7, 1
        else
            a1s, a1e, a2s, a2e = 0.15, 1, 1, 0.15
        end
    else
        if align == "TOP" then
            a1s, a1e, a2s, a2e = 0.7, 1, 0.15, 0.7
        elseif align == "BOTTOM" then
            a1s, a1e, a2s, a2e = 0.7, 0.15, 1, 0.7
        else
            a1s, a1e, a2s, a2e = 1, 0.15, 0.15, 1
        end
    end
    pair[1]:SetGradient(orient, CreateColor(c[1], c[2], c[3], a1s), CreateColor(c[1], c[2], c[3], a1e))
    pair[2]:SetGradient(orient, CreateColor(c[1], c[2], c[3], a2s), CreateColor(c[1], c[2], c[3], a2e))
    if selection.AnchorLineFrame then selection.AnchorLineFrame:Show() end
    pair[1]:Show()
    pair[2]:Show()
end

-- [ FORCE UPDATE ]-----------------------------------------------------------------------------------
function Selection:ForceUpdate(frame)
    local selection = self.selections[frame]
    if selection and selection:IsShown() then
        selection:ClearAllPoints()
        selection:SetAllPoints(frame)
        self:UpdateVisuals(frame, selection)
    end
end

function Selection:RefreshVisuals()
    -- 1. Update Orbit Selections
    local showOrbit = ShouldShowOrbitFrames()

    for frame, selection in pairs(self.selections) do
        if frame.orbitDisabled then
            selection:Hide()
        elseif selection.isOrbitSelection then
            if showOrbit then
                self:UpdateVisuals(frame, selection)
            else
                selection:SetAlpha(0)
                selection:EnableMouse(false)
            end
        else
            self:UpdateVisuals(frame, selection)
        end
    end

    -- 2. Update Native Blizzard Frames
    if EditModeManagerFrame and EditModeManagerFrame.registeredSystemFrames then
        local showNative = ShouldShowBlizzardFrames()

        for _, frame in ipairs(EditModeManagerFrame.registeredSystemFrames) do
            if frame.Selection then
                if showNative then
                    frame.Selection:SetAlpha(1)
                    frame.Selection:EnableMouse(true)
                else
                    frame.Selection:SetAlpha(0)
                    frame.Selection:EnableMouse(false)
                end
            end
        end
    end
end

-- [ UPDATE VISUALS ]---------------------------------------------------------------------------------
function Selection:UpdateVisuals(frame, selection)
    if not selection then
        if not frame then
            return
        end
        selection = self.selections[frame]
    end
    if not selection then
        return
    end

    -- Canvas Mode: Show green selection to indicate editable state
    local isComponentEdit = Engine.CanvasMode:IsActive(selection.parent)
    if isComponentEdit then
        -- Show selection with green tint for Canvas Mode
        selection:Show()
        selection:SetFrameStrata(Orbit.Constants.Strata.Overlay)

        -- Green tint for canvas mode
        ForEachRegion(selection, function(region)
            if region:IsObjectType("Texture") and region ~= selection.ComponentEditOverlay then
                region:SetDesaturated(false)
                region:SetVertexColor(0.3, 0.9, 0.3, 1)
                region:SetAlpha(1)
            end
        end)

        -- Hide label in canvas mode
        if selection.Label then
            selection.Label:Hide()
        end

        Selection:ShowAnchorLine(selection, nil)
        return
    end

    if selection.isSelected then
        -- Selected: Yellow
        if selection.ComponentEditOverlay then
            selection.ComponentEditOverlay:Hide()
        end
        if selection.CanvasBorderFrame then
            selection.CanvasBorderFrame:Hide()
        end

        -- Restore strata and mouse interaction
        selection:SetFrameStrata(Orbit.Constants.Strata.Overlay)
        selection:EnableMouse(true)

        ForEachRegion(selection, function(region)
            if region:IsObjectType("Texture") and region ~= selection.ComponentEditOverlay then
                region:SetDesaturated(false)
                region:SetVertexColor(1, 1, 1, 1)
                region:SetAlpha(1)
            end
        end)

        selection:ShowSelected(true)
        if selection.Label then selection.Label:SetText("") end
        if selection.Highlight then
            selection.Highlight:SetVertexColor(1, 1, 1, 1)
            selection.Highlight:SetAlpha(1)
        end

        if selection.orbitInset or selection.orbitCanvasInset then
            selection:ClearAllPoints()
            selection:SetAllPoints(selection.parent)
            selection.orbitInset = nil
            selection.orbitCanvasInset = nil
        end

        local isAnchored = Engine.FrameAnchor:GetAnchorParent(selection.parent) ~= nil
        if isAnchored then
            local anchor = Engine.FrameAnchor.anchors[selection.parent]
            if anchor and anchor.edge then
                Selection:ShowAnchorLine(selection, GetOppositeEdge(anchor.edge), anchor.align)
            end
        else
            Selection:ShowAnchorLine(selection, nil)
        end
    elseif EditModeManagerFrame and EditModeManagerFrame:IsShown() then
        -- Edit Mode Active (not selected)
        if selection.ComponentEditOverlay then
            selection.ComponentEditOverlay:Hide()
        end
        if selection.CanvasBorderFrame then
            selection.CanvasBorderFrame:Hide()
        end

        -- Restore strata and mouse interaction
        selection:SetFrameStrata(Orbit.Constants.Strata.Overlay)
        selection:EnableMouse(true)

        ForEachRegion(selection, function(region)
            if region:IsObjectType("Texture") and region ~= selection.ComponentEditOverlay then
                region:SetAlpha(1)
            end
        end)

        selection:ShowHighlighted()
        if selection.Label then selection.Label:SetText("") end

        if selection.orbitInset or selection.orbitCanvasInset then
            selection:ClearAllPoints()
            selection:SetAllPoints(selection.parent)
            selection.orbitInset = nil
            selection.orbitCanvasInset = nil
        end

        local isAnchored = Engine.FrameAnchor:GetAnchorParent(selection.parent) ~= nil

        if isAnchored then
            if selection.isOrbitSelection then
                if ShouldShowOrbitFrames() then
                    local c = GetOrbitEditModeColor()
                    TintSelection(selection, c.r, c.g, c.b, true)
                    selection:Show()
                    selection:SetAlpha(1)
                    selection:EnableMouse(true)
                else
                    selection:SetAlpha(0)
                    selection:EnableMouse(false)
                    return
                end
            else
                -- Always hide native selection to prevent z-fighting/persistence
                if frame.Selection then
                    frame.Selection:Hide()
                end

                if ShouldShowBlizzardFrames() then
                    TintSelection(selection, 1, 1, 1, false)
                    selection:Show()
                else
                    selection:Hide() -- Hide entirely if native frames disabled
                    return
                end
            end
            local anchor = Engine.FrameAnchor.anchors[selection.parent]
            if anchor and anchor.edge then
                Selection:ShowAnchorLine(selection, GetOppositeEdge(anchor.edge), anchor.align)
            end
        else
            if selection.isOrbitSelection then
                if ShouldShowOrbitFrames() then
                    local c = GetOrbitEditModeColor()
                    TintSelection(selection, c.r, c.g, c.b, true)
                    selection:Show()
                    selection:SetAlpha(1)
                    selection:EnableMouse(true)
                else
                    selection:SetAlpha(0)
                    selection:EnableMouse(false)
                    return
                end
            else
                -- Always hide native selection to prevent z-fighting/persistence
                if frame.Selection then
                    frame.Selection:Hide()
                end

                if ShouldShowBlizzardFrames() then
                    TintSelection(selection, 1, 1, 1, false)
                    selection:Show() -- Ensure Orbit's proxy is shown
                else
                    selection:Hide()
                    return
                end
            end
            Selection:ShowAnchorLine(selection, nil)
        end
    else
        selection:Hide()
    end
end
