-- Portal Authority — options/bootstrap.lua
-- Late search index/render/scroll helpers and options refresh/bootstrap wiring.
--
-- Depends on: PortalAuthority.OptionsInternal shared helpers; PortalAuthority.OptionsInternal.SearchRuntime early slice
-- Exposes:    PortalAuthority.OptionsInternal SearchRuntime late slice; PortalAuthority search/refresh methods
-- DB keys:    none direct
-- Events:     none
-- Search key: none

PortalAuthority = PortalAuthority or {}

if PortalAuthority.IsSettingsBaselineGateEnabled and PortalAuthority:IsSettingsBaselineGateEnabled() then
    return
end

if not Settings or not Settings.RegisterCanvasLayoutCategory then
    return
end

PortalAuthority.OptionsInternal = PortalAuthority.OptionsInternal or {}
local OptionsInternal = PortalAuthority.OptionsInternal

local settingsSearchRuntime = OptionsInternal.SearchRuntime
local lowerSettingsSearchText = settingsSearchRuntime.lowerSettingsSearchText
local trim = OptionsInternal.trim
local rgba255 = OptionsInternal.rgba255
local unpackColor = OptionsInternal.unpackColor
local applyGlobalFontToObject = OptionsInternal.applyGlobalFontToObject
local getPortalMedia = OptionsInternal.getPortalMedia
local normalizeSoundChoiceValue = OptionsInternal.normalizeSoundChoiceValue
local compareChoiceLabels = OptionsInternal.compareChoiceLabels
local normalizeChoicePathKey = OptionsInternal.normalizeChoicePathKey
local resolveFontChoicePath = OptionsInternal.resolveFontChoicePath
local getSoundChoiceValueKey = OptionsInternal.getSoundChoiceValueKey
local buildFallbackSoundChoices = OptionsInternal.buildFallbackSoundChoices
local getSummonSoundChoices = OptionsInternal.getSummonSoundChoices
local getAvailableFontChoices = OptionsInternal.getAvailableFontChoices
local buildSharedFontPickerChoices = OptionsInternal.buildSharedFontPickerChoices
local SUMMON_SOUND_CHANNEL_CHOICES = OptionsInternal.SUMMON_SOUND_CHANNEL_CHOICES
local debugSettingsLog = OptionsInternal.debugSettingsLog or function() end
local FLAT_SETTINGS_BACKDROP = OptionsInternal.FLAT_SETTINGS_BACKDROP
local SETTINGS_WINDOW_HOSTED_TOP_RHYTHM_NUDGE = OptionsInternal.SETTINGS_WINDOW_HOSTED_TOP_RHYTHM_NUDGE
local SETTINGS_WINDOW_SCROLLBAR_WIDTH = OptionsInternal.SETTINGS_WINDOW_SCROLLBAR_WIDTH
local SETTINGS_WINDOW_SCROLLBAR_GAP = OptionsInternal.SETTINGS_WINDOW_SCROLLBAR_GAP
local SETTINGS_WINDOW_SCROLLBAR_MIN_THUMB_HEIGHT = OptionsInternal.SETTINGS_WINDOW_SCROLLBAR_MIN_THUMB_HEIGHT
local SETTINGS_WINDOW_HOST_COLORS = OptionsInternal.SETTINGS_WINDOW_HOST_COLORS
local SETTINGS_WINDOW_SCROLLBAR_TRACK = OptionsInternal.SETTINGS_WINDOW_SCROLLBAR_TRACK
local SETTINGS_WINDOW_SCROLLBAR_THUMB = OptionsInternal.SETTINGS_WINDOW_SCROLLBAR_THUMB
local SETTINGS_WINDOW_SCROLLBAR_THUMB_HOVER = OptionsInternal.SETTINGS_WINDOW_SCROLLBAR_THUMB_HOVER
local frameIsAlive = OptionsInternal.frameIsAlive
local isDescendedFromFrame = OptionsInternal.isDescendedFromFrame
local markSettingsWindowVisualOptIn = OptionsInternal.markSettingsWindowVisualOptIn
local isUsingCustomSettingsWindowVisualStyle = OptionsInternal.isUsingCustomSettingsWindowVisualStyle
local registerSettingsWindowVisualRefresh = OptionsInternal.registerSettingsWindowVisualRefresh
local setTextureSolidColor = OptionsInternal.setTextureSolidColor
local hideDefaultScrollBarPart = OptionsInternal.hideDefaultScrollBarPart
local getTemplateScrollBar = OptionsInternal.getTemplateScrollBar
local hideDefaultScrollBarChrome = OptionsInternal.hideDefaultScrollBarChrome
local refreshCustomSettingsScrollBarThumb = OptionsInternal.refreshCustomSettingsScrollBarThumb
local settingsScrollRuntime = PortalAuthority._settingsScrollRuntime or OptionsInternal.settingsScrollRuntime
local createStyledFontString = OptionsInternal.createStyledFontString
local createTopRightHeader = OptionsInternal.createTopRightHeader
local PA_SafeBool = OptionsInternal.PA_SafeBool
local getClassHex = OptionsInternal.getClassHex
local createCheckbox = OptionsInternal.createCheckbox
local createActionButton = OptionsInternal.createActionButton
local styleSecondaryActionButtonShared = OptionsInternal.styleSecondaryActionButtonShared
local createNumeric = OptionsInternal.createNumeric
local createDropdown = OptionsInternal.createDropdown
local createDynamicDropdown = OptionsInternal.createDynamicDropdown
local createPremiumSegmentedChoice = OptionsInternal.createPremiumSegmentedChoice
local CreatePicker = OptionsInternal.CreatePicker
local CreateStepperControl = OptionsInternal.CreateStepperControl
local createCanonicalDockFontSizeStepperControl = OptionsInternal.CreateStepperControl or OptionsInternal.createCanonicalDockFontSizeStepperControl
local createTextPlacement = OptionsInternal.createTextPlacement
local setSettingsControlEnabled = OptionsInternal.setSettingsControlEnabled
local setSettingsTextEnabled = OptionsInternal.setSettingsTextEnabled
local createScrollableChild = OptionsInternal.createScrollableChild
local updateScrollBehavior = OptionsInternal.updateScrollBehavior
local withPanelHydration = OptionsInternal.withPanelHydration
local panelHasSizedViewport = OptionsInternal.panelHasSizedViewport
local handleSettingsFirstOpenSizeReady = OptionsInternal.handleSettingsFirstOpenSizeReady
local handleSettingsFirstOpenPanelShow = OptionsInternal.handleSettingsFirstOpenPanelShow
local handleSettingsFirstOpenPanelHide = OptionsInternal.handleSettingsFirstOpenPanelHide
local shouldSuppressSettingsFirstOpenExternalRefresh = OptionsInternal.shouldSuppressSettingsFirstOpenExternalRefresh
local isPanelUsingCustomSettingsWindowHost = OptionsInternal.isPanelUsingCustomSettingsWindowHost
local refreshPanel = OptionsInternal.refreshPanel
local createScrollableTextArea = OptionsInternal.createScrollableTextArea
local createSettingsSectionDescriptor = OptionsInternal.createSettingsSectionDescriptor
local layoutSettingsSectionDescriptor = OptionsInternal.layoutSettingsSectionDescriptor
local registerRefreshCallback = OptionsInternal.registerRefreshCallback
local ensureDatabase = OptionsInternal.ensureDatabase
local IsPointerInsideActivePickerSafeZone = OptionsInternal.IsPointerInsideActivePickerSafeZone
local CloseActivePortalPicker = OptionsInternal.CloseActivePortalPicker
local settingsFirstOpenHost = OptionsInternal.settingsFirstOpenHost

local function PA_PerfBegin(scopeName, explicitState)
    if PortalAuthority and PortalAuthority.PerfBegin then
        return PortalAuthority:PerfBegin(scopeName, explicitState)
    end
    return nil, nil
end

local function PA_PerfEnd(scopeName, startedAt, stateLabel)
    if startedAt ~= nil and PortalAuthority and PortalAuthority.PerfEnd then
        PortalAuthority:PerfEnd(scopeName, startedAt, stateLabel)
    end
end

local function getSettingsSearchPanelByKey(sectionKey)
    local registry = PortalAuthority and PortalAuthority.settingsPanelRegistry or nil
    local entry = registry and registry[sectionKey] or nil
    return entry and entry.panel or nil
end

local function getSettingsSearchTextFromRef(ref)
    if not ref then
        return ""
    end
    if ref.GetText then
        local ok, value = pcall(ref.GetText, ref)
        if ok then
            local sanitized = settingsSearchRuntime.sanitizeVisibleText(value)
            if sanitized ~= "" and settingsSearchRuntime.shouldSuppressSearchTextRef(ref, value) then
                return ""
            end
            return sanitized
        end
    end
    return ""
end

local function safeSettingsSearchMetric(frame, methodName)
    if not frame then
        return nil
    end
    local method = frame[methodName]
    if type(method) ~= "function" then
        return nil
    end
    local ok, value = pcall(method, frame)
    if not ok then
        return nil
    end
    return tonumber(value) or nil
end

function settingsSearchRuntime.resolveScrollY(panel, targetRef)
    if not panel or not targetRef then
        return 0
    end
    local scrollChild = panel._paSearchScrollChild or panel._paSettingsScrollChild or nil
    local rootTop = safeSettingsSearchMetric(scrollChild, "GetTop")
    local targetTop = safeSettingsSearchMetric(targetRef, "GetTop")
    if rootTop and targetTop then
        local offset = rootTop - targetTop
        if offset >= 0 then
            return math.floor(offset + 0.5)
        end
    end
    local targetBottom = safeSettingsSearchMetric(targetRef, "GetBottom")
    if rootTop and targetBottom then
        local offset = rootTop - targetBottom
        if offset >= 0 then
            return math.floor(offset + 0.5)
        end
    end
    return 0
end

function settingsSearchRuntime.buildHaystack(searchRefs)
    local pieces = {}
    local seen = {}

    local function addPiece(raw)
        local normalized = lowerSettingsSearchText(raw)
        if normalized == "" or seen[normalized] then
            return
        end
        seen[normalized] = true
        pieces[#pieces + 1] = normalized
    end

    if type(searchRefs) == "table" then
        for i = 1, #searchRefs do
            addPiece(getSettingsSearchTextFromRef(searchRefs[i]))
        end
    end
    return table.concat(pieces, " ")
end

function settingsSearchRuntime.isControlDescriptorKind(kind)
    kind = lowerSettingsSearchText(kind)
    return kind ~= "" and kind ~= "text" and kind ~= "group_title" and kind ~= "section_name"
end

function settingsSearchRuntime.getRenderableStandaloneKind(panel, descriptor, labelText)
    if not descriptor then
        return nil
    end

    local kind = lowerSettingsSearchText(descriptor.kind)
    if kind == "group_title" or kind == "section_name" then
        return kind
    end
    if kind ~= "" and kind ~= "text" then
        return nil
    end

    local displayRef = descriptor.displayRef
    local controlRef = descriptor.controlRef or descriptor.anchorRef or displayRef
    local size = tonumber(descriptor.fontSize) or 0
    local matchesSectionTitle = lowerSettingsSearchText(labelText) == lowerSettingsSearchText(panel and (panel._paSearchSectionName or panel.name or "") or "")

    if matchesSectionTitle and displayRef == panel._paSearchTopTarget then
        return nil
    end

    if size >= 12 and displayRef == controlRef then
        return "group_title"
    end

    return nil
end

function settingsSearchRuntime.addEntryHaystackPiece(entry, rawText)
    if not entry then
        return
    end
    local normalized = lowerSettingsSearchText(rawText)
    if normalized == "" then
        return
    end
    entry._haystackSeen = entry._haystackSeen or {}
    if entry._haystackSeen[normalized] then
        return
    end
    entry._haystackSeen[normalized] = true
    entry._haystackParts = entry._haystackParts or {}
    entry._haystackParts[#entry._haystackParts + 1] = normalized
end

function settingsSearchRuntime.appendControlEntryHelperRef(entry, ref)
    if not entry or not frameIsAlive(ref) then
        return
    end
    entry._searchHelperRefs = entry._searchHelperRefs or {}
    settingsSearchRuntime.appendUniqueSearchRef(entry._searchHelperRefs, ref)
end

function settingsSearchRuntime.appendControlEntryNaturalCandidate(entry, ref)
    if not entry or not frameIsAlive(ref) then
        return
    end
    entry._searchNaturalRowCandidates = entry._searchNaturalRowCandidates or {}
    settingsSearchRuntime.appendUniqueSearchRef(entry._searchNaturalRowCandidates, ref)
end

function settingsSearchRuntime.setSearchTargetFramePassThrough(frame)
    if not frameIsAlive(frame) then
        return
    end
    if frame.EnableMouse then
        frame:EnableMouse(false)
    end
    if frame.EnableMouseWheel then
        frame:EnableMouseWheel(false)
    end
    if frame.SetMouseClickEnabled then
        frame:SetMouseClickEnabled(false)
    end
    if frame.SetMouseMotionEnabled then
        frame:SetMouseMotionEnabled(false)
    end
end

function settingsSearchRuntime.collectSearchTargetBounds(refs)
    if type(refs) ~= "table" then
        return nil
    end

    local left, right, top, bottom = nil, nil, nil, nil
    for i = 1, #refs do
        local ref = refs[i]
        if frameIsAlive(ref) then
            local refLeft = safeSettingsSearchMetric(ref, "GetLeft")
            local refRight = safeSettingsSearchMetric(ref, "GetRight")
            local refTop = safeSettingsSearchMetric(ref, "GetTop")
            local refBottom = safeSettingsSearchMetric(ref, "GetBottom")
            if refLeft and refRight and refTop and refBottom and refRight > refLeft and refTop > refBottom then
                if not left or refLeft < left then
                    left = refLeft
                end
                if not right or refRight > right then
                    right = refRight
                end
                if not top or refTop > top then
                    top = refTop
                end
                if not bottom or refBottom < bottom then
                    bottom = refBottom
                end
            end
        end
    end

    if left and right and top and bottom and right > left and top > bottom then
        return {
            left = left,
            right = right,
            top = top,
            bottom = bottom,
            width = right - left,
            height = top - bottom,
        }
    end
    return nil
end

function settingsSearchRuntime.buildSearchTargetBoundsNote(targetBounds, visibleBounds)
    if type(targetBounds) ~= "table" or type(visibleBounds) ~= "table" then
        return "missing-bounds"
    end

    local leftExtra = math.floor((visibleBounds.left - targetBounds.left) + 0.5)
    local rightExtra = math.floor((targetBounds.right - visibleBounds.right) + 0.5)
    local topExtra = math.floor((targetBounds.top - visibleBounds.top) + 0.5)
    local bottomExtra = math.floor((visibleBounds.bottom - targetBounds.bottom) + 0.5)
    return string.format(
        "target=%dx%d visible=%dx%d extra(L%d R%d T%d B%d)",
        math.floor(targetBounds.width + 0.5),
        math.floor(targetBounds.height + 0.5),
        math.floor(visibleBounds.width + 0.5),
        math.floor(visibleBounds.height + 0.5),
        leftExtra,
        rightExtra,
        topExtra,
        bottomExtra
    )
end

function settingsSearchRuntime.evaluateSearchTargetBounds(candidateRef, visibleBounds)
    if not frameIsAlive(candidateRef) then
        return false, nil, "invalid-frame"
    end

    local candidateBounds = settingsSearchRuntime.collectSearchTargetBounds({ candidateRef })
    if type(candidateBounds) ~= "table" then
        return false, nil, "missing-bounds"
    end
    if type(visibleBounds) ~= "table" then
        return false, candidateBounds, "missing-visible-bounds"
    end

    local maxExtraHorizontal = math.max(18, (tonumber(visibleBounds.width) or 0) * 0.35)
    local maxExtraVertical = math.max(10, (tonumber(visibleBounds.height) or 0) * 0.65)
    local tolerance = 2

    local leftDelta = visibleBounds.left - candidateBounds.left
    local rightDelta = candidateBounds.right - visibleBounds.right
    local topDelta = candidateBounds.top - visibleBounds.top
    local bottomDelta = visibleBounds.bottom - candidateBounds.bottom

    if leftDelta < -tolerance or rightDelta < -tolerance or topDelta < -tolerance or bottomDelta < -tolerance then
        return false, candidateBounds, settingsSearchRuntime.buildSearchTargetBoundsNote(candidateBounds, visibleBounds)
    end

    if leftDelta > maxExtraHorizontal or rightDelta > maxExtraHorizontal or topDelta > maxExtraVertical or bottomDelta > maxExtraVertical then
        return false, candidateBounds, settingsSearchRuntime.buildSearchTargetBoundsNote(candidateBounds, visibleBounds)
    end

    return true, candidateBounds, settingsSearchRuntime.buildSearchTargetBoundsNote(candidateBounds, visibleBounds)
end

function settingsSearchRuntime.collectControlEntryVisibleRefs(entry)
    local refs = {}
    if type(entry) ~= "table" then
        return refs
    end

    settingsSearchRuntime.appendUniqueSearchRef(refs, entry._searchLabelRef)
    local helperRefs = entry._searchHelperRefs or {}
    for i = 1, #helperRefs do
        settingsSearchRuntime.appendUniqueSearchRef(refs, helperRefs[i])
    end
    settingsSearchRuntime.appendUniqueSearchRef(refs, entry._searchWidgetRef)
    return refs
end

function settingsSearchRuntime.getSearchTargetSingleBounds(ref)
    return settingsSearchRuntime.collectSearchTargetBounds({ ref })
end

function settingsSearchRuntime.collectControlEntryVisibleBounds(panel, entry)
    local refs = settingsSearchRuntime.collectControlEntryVisibleRefs(entry)
    local filteredRefs = {}
    local rejectedCount = 0
    local scrollChild = panel and (panel._paSearchScrollChild or panel._paSettingsScrollChild) or nil
    local scrollChildBounds = settingsSearchRuntime.getSearchTargetSingleBounds(scrollChild)
    local widgetBounds = settingsSearchRuntime.getSearchTargetSingleBounds(type(entry) == "table" and entry._searchWidgetRef or nil)
    local widgetCenterY = widgetBounds and ((widgetBounds.top + widgetBounds.bottom) * 0.5) or nil
    local maxVerticalDistance = widgetBounds and math.max(160, (tonumber(widgetBounds.height) or 0) * 6) or nil

    for i = 1, #refs do
        local ref = refs[i]
        local refBounds = settingsSearchRuntime.getSearchTargetSingleBounds(ref)
        local keep = type(refBounds) == "table"

        if keep and type(scrollChildBounds) == "table" then
            local nearFullWidth = (tonumber(refBounds.width) or 0) >= ((tonumber(scrollChildBounds.width) or 0) * 0.92)
            local nearFullHeight = (tonumber(refBounds.height) or 0) >= math.max(140, (tonumber(scrollChildBounds.height) or 0) * 0.60)
            if nearFullWidth and nearFullHeight then
                keep = false
            end
        end

        if keep and widgetCenterY and maxVerticalDistance and ref ~= entry._searchWidgetRef then
            local refCenterY = ((tonumber(refBounds.top) or 0) + (tonumber(refBounds.bottom) or 0)) * 0.5
            if math.abs(refCenterY - widgetCenterY) > maxVerticalDistance then
                keep = false
            end
        end

        if keep then
            settingsSearchRuntime.appendUniqueSearchRef(filteredRefs, ref)
        else
            rejectedCount = rejectedCount + 1
        end
    end

    if #filteredRefs == 0 and frameIsAlive(entry and entry._searchWidgetRef or nil) then
        settingsSearchRuntime.appendUniqueSearchRef(filteredRefs, entry._searchWidgetRef)
    end

    return filteredRefs, settingsSearchRuntime.collectSearchTargetBounds(filteredRefs), rejectedCount
end

function settingsSearchRuntime.findSearchCommonAncestor(refs, stopRef)
    if type(refs) ~= "table" or #refs <= 0 then
        return nil
    end

    local ancestryOrder = {}
    local ancestrySeen = {}
    local current = refs[1]
    while current do
        ancestryOrder[#ancestryOrder + 1] = current
        ancestrySeen[current] = true
        if current == stopRef then
            break
        end
        current = current.GetParent and current:GetParent() or nil
    end

    for i = 2, #refs do
        local nextSeen = {}
        local probe = refs[i]
        while probe do
            nextSeen[probe] = true
            if probe == stopRef then
                break
            end
            probe = probe.GetParent and probe:GetParent() or nil
        end
        for j = #ancestryOrder, 1, -1 do
            local candidate = ancestryOrder[j]
            if not nextSeen[candidate] then
                ancestrySeen[candidate] = nil
                table.remove(ancestryOrder, j)
            end
        end
    end

    for i = 1, #ancestryOrder do
        local candidate = ancestryOrder[i]
        if candidate ~= stopRef then
            return candidate
        end
    end
    return nil
end

function settingsSearchRuntime.collectControlEntryNaturalCandidates(panel, entry, visibleRefs)
    local refs = {}
    local scrollChild = panel and (panel._paSearchScrollChild or panel._paSettingsScrollChild) or nil
    if type(entry) ~= "table" then
        return refs
    end

    settingsSearchRuntime.appendUniqueSearchRef(refs, entry._searchExplicitRowFrame)

    local commonAncestor = settingsSearchRuntime.findSearchCommonAncestor(visibleRefs, scrollChild)
    settingsSearchRuntime.appendUniqueSearchRef(refs, commonAncestor)

    local widgetParent = frameIsAlive(entry._searchWidgetRef) and entry._searchWidgetRef.GetParent and entry._searchWidgetRef:GetParent() or nil
    local labelParent = frameIsAlive(entry._searchLabelRef) and entry._searchLabelRef.GetParent and entry._searchLabelRef:GetParent() or nil
    settingsSearchRuntime.appendUniqueSearchRef(refs, widgetParent)
    settingsSearchRuntime.appendUniqueSearchRef(refs, labelParent)

    local helperRefs = entry._searchHelperRefs or {}
    for i = 1, #helperRefs do
        local helperParent = helperRefs[i].GetParent and helperRefs[i]:GetParent() or nil
        settingsSearchRuntime.appendUniqueSearchRef(refs, helperParent)
    end

    local explicitCandidates = entry._searchNaturalRowCandidates or {}
    for i = 1, #explicitCandidates do
        settingsSearchRuntime.appendUniqueSearchRef(refs, explicitCandidates[i])
    end

    return refs
end

function settingsSearchRuntime.acquireSyntheticSearchRowFrame(entry, parent)
    if type(entry) ~= "table" or not frameIsAlive(parent) then
        return nil
    end

    local rowFrame = entry._searchSyntheticRowFrame
    if not frameIsAlive(rowFrame) then
        rowFrame = CreateFrame("Frame", nil, parent)
        entry._searchSyntheticRowFrame = rowFrame
    end
    if rowFrame:GetParent() ~= parent then
        rowFrame:SetParent(parent)
    end
    settingsSearchRuntime.setSearchTargetFramePassThrough(rowFrame)
    return rowFrame
end

function settingsSearchRuntime.hideSyntheticSearchRowFrame(entry)
    local rowFrame = type(entry) == "table" and entry._searchSyntheticRowFrame or nil
    if frameIsAlive(rowFrame) then
        rowFrame:Hide()
    end
end

function settingsSearchRuntime.recordControlEntryTargetClass(entry, targetType, phase)
    if type(entry) ~= "table" or type(targetType) ~= "string" or targetType == "" then
        return
    end

    local history = entry._searchTargetHistory or {}
    if history[#history] ~= targetType then
        history[#history + 1] = targetType
    end
    entry._searchTargetHistory = history
    entry._searchTargetHistorySummary = table.concat(history, " -> ")

    if not entry._searchFirstResolvedPhase then
        entry._searchFirstResolvedPhase = phase
    end
    if phase == "hidden" and not entry._searchHiddenResolvedTargetType then
        entry._searchHiddenResolvedTargetType = targetType
    end
    if phase == "real" then
        entry._searchRealResolvedTargetType = targetType
    end
    entry._searchResolvedPhase = phase
end

function settingsSearchRuntime.buildControlRegistryKey(panel, descriptor, labelText, controlRef, fallbackRef, orderIndex)
    local sectionKey = lowerSettingsSearchText(panel and panel._paSearchSectionKey or "")
    local kindKey = lowerSettingsSearchText(descriptor and descriptor.kind or "control")
    local labelKey = lowerSettingsSearchText(labelText or "")
    local orderKey = math.floor(tonumber(orderIndex) or 0)

    if sectionKey ~= "" and (labelKey ~= "" or orderKey > 0) then
        return table.concat({
            "control",
            sectionKey,
            tostring(orderKey),
            kindKey,
            labelKey,
        }, "|")
    end

    return controlRef or fallbackRef or (descriptor and descriptor.displayRef) or tostring(orderKey)
end

function settingsSearchRuntime.resolveControlEntryTarget(panel, entry)
    if not panel or type(entry) ~= "table" or entry.kind ~= "control" then
        return nil
    end

    local scrollChild = panel._paSearchScrollChild or panel._paSettingsScrollChild or nil
    local visibleRefs, visibleBounds, rejectedVisibleRefs = settingsSearchRuntime.collectControlEntryVisibleBounds(panel, entry)
    local isRealLayout = panel._paSearchRealActivationComplete == true
    local resolvedTarget, resolvedType, resolvedBoundsNote = nil, nil, nil

    if not frameIsAlive(resolvedTarget) and type(visibleBounds) ~= "table" and frameIsAlive(entry._searchExplicitRowFrame) then
        resolvedTarget = entry._searchExplicitRowFrame
        resolvedType = "explicit_row"
        resolvedBoundsNote = "explicit row without visible comparison"
    end

    local naturalCandidates = settingsSearchRuntime.collectControlEntryNaturalCandidates(panel, entry, visibleRefs)
    for i = 1, #naturalCandidates do
        local candidate = naturalCandidates[i]
        local candidateType = candidate == entry._searchExplicitRowFrame and "explicit_row" or "natural_row"
        local ok, _, boundsNote = settingsSearchRuntime.evaluateSearchTargetBounds(candidate, visibleBounds)
        if ok then
            resolvedTarget = candidate
            resolvedType = candidateType
            resolvedBoundsNote = boundsNote
            break
        end
    end

    if not frameIsAlive(resolvedTarget) and frameIsAlive(scrollChild) and type(visibleBounds) == "table" then
        local rootLeft = safeSettingsSearchMetric(scrollChild, "GetLeft")
        local rootTop = safeSettingsSearchMetric(scrollChild, "GetTop")
        if rootLeft and rootTop then
            local rowFrame = settingsSearchRuntime.acquireSyntheticSearchRowFrame(entry, scrollChild)
            if frameIsAlive(rowFrame) then
                rowFrame:ClearAllPoints()
                rowFrame:SetPoint("TOPLEFT", scrollChild, "TOPLEFT", visibleBounds.left - rootLeft, visibleBounds.top - rootTop)
                rowFrame:SetPoint("BOTTOMRIGHT", scrollChild, "TOPLEFT", visibleBounds.right - rootLeft, visibleBounds.bottom - rootTop)
                rowFrame:Show()
                resolvedTarget = rowFrame
                resolvedType = "synthetic_row"
                resolvedBoundsNote = settingsSearchRuntime.buildSearchTargetBoundsNote(visibleBounds, visibleBounds)
            end
        end
    else
        settingsSearchRuntime.hideSyntheticSearchRowFrame(entry)
    end

    if not frameIsAlive(resolvedTarget) then
        settingsSearchRuntime.hideSyntheticSearchRowFrame(entry)
        resolvedTarget = frameIsAlive(entry._searchWidgetRef) and entry._searchWidgetRef
            or (frameIsAlive(entry.controlRef) and entry.controlRef or nil)
        resolvedType = "widget_fallback"
        resolvedBoundsNote = type(visibleBounds) == "table"
            and "widget fallback - no broader visible row target validated"
            or "widget fallback - visible row bounds unavailable"
    end

    local provisional = isRealLayout ~= true
    local currentPhase = isRealLayout and "real" or "hidden"
    local previousType = entry._searchTargetType
    local boundsValid = false
    if frameIsAlive(resolvedTarget) then
        if resolvedType == "synthetic_row" and type(visibleBounds) == "table" then
            boundsValid = true
        else
            boundsValid = select(1, settingsSearchRuntime.evaluateSearchTargetBounds(resolvedTarget, visibleBounds)) == true
        end
    end
    entry._searchRegistryTargetRef = resolvedTarget
    entry._searchRegistryAnchorRef = resolvedTarget
    entry._searchScrollSourceRef = resolvedTarget
    entry._searchTargetType = resolvedType
    entry._searchTargetProvisional = provisional and true or false
    entry._searchVisibleBounds = visibleBounds
    entry._searchVisibleRefCount = #visibleRefs
    entry._searchRejectedVisibleRefCount = rejectedVisibleRefs or 0
    entry._searchTargetBounds = settingsSearchRuntime.collectSearchTargetBounds({ resolvedTarget })
    entry._searchTargetBoundsNote = string.format(
        "%s refs=%d rejected=%d",
        tostring(resolvedBoundsNote or "missing-bounds"),
        tonumber(#visibleRefs) or 0,
        tonumber(rejectedVisibleRefs) or 0
    )
    entry._searchTargetBoundsValid = boundsValid and true or false
    entry._searchTargetSameObject = resolvedTarget == entry._searchRegistryTargetRef
    entry._searchWidgetFallbackReason = resolvedType == "widget_fallback" and resolvedBoundsNote or nil
    if previousType and previousType ~= resolvedType then
        entry._searchTargetChanged = true
    end
    settingsSearchRuntime.recordControlEntryTargetClass(entry, resolvedType, currentPhase)

    entry.controlRef = resolvedTarget
    entry.anchorRef = resolvedTarget
    entry.scrollY = settingsSearchRuntime.resolveScrollY(panel, resolvedTarget)
    entry.skipHighlight = not frameIsAlive(resolvedTarget)
    entry._searchRegistryScrollY = entry.scrollY
    entry._searchAlignedTarget = entry.controlRef == entry.anchorRef and entry.controlRef == entry._searchScrollSourceRef
    if provisional then
        panel._paSearchHasProvisionalControlTargets = true
    end
    return resolvedTarget
end

function settingsSearchRuntime.newControlRegistryEntry(panel, descriptor, labelText, controlRef, fallbackRef, orderIndex, sectionName, registryKey)
    if not panel then
        return nil
    end

    registryKey = registryKey or settingsSearchRuntime.buildControlRegistryKey(panel, descriptor, labelText, controlRef, fallbackRef, orderIndex)
    panel._paSearchLiveControlEntries = panel._paSearchLiveControlEntries or {}
    local entry = panel._paSearchLiveControlEntries[registryKey]
    if type(entry) ~= "table" then
        entry = {}
        panel._paSearchLiveControlEntries[registryKey] = entry
    end

    entry.kind = "control"
    entry.sectionKey = panel._paSearchSectionKey
    entry.sectionName = sectionName
    entry.displayLabel = trim(tostring(labelText or ""))
    entry.displayHelper = nil
    entry.labelText = trim(tostring(labelText or ""))
    entry.helperText = nil
    entry.orderIndex = orderIndex
    entry.searchHaystack = ""
    entry.haystack = ""
    entry.dedupeKey = nil
    entry.iconType = descriptor and descriptor.iconType or nil
    entry._haystackParts = {}
    entry._haystackSeen = {}
    entry._searchRegistryKey = registryKey
    entry._searchWidgetRef = frameIsAlive(descriptor and descriptor.searchWidgetRef or nil) and descriptor.searchWidgetRef
        or (frameIsAlive(controlRef) and controlRef or nil)
    entry._searchLabelRef = frameIsAlive(descriptor and descriptor.searchLabelRef or nil) and descriptor.searchLabelRef
        or (frameIsAlive(descriptor and descriptor.displayRef or nil) and descriptor.displayRef or nil)
    entry._searchHelperRefs = {}
    entry._searchNaturalRowCandidates = {}
    entry._searchExplicitRowFrame = frameIsAlive(descriptor and descriptor.searchRowFrame or nil) and descriptor.searchRowFrame or nil
    entry.controlRef = frameIsAlive(entry._searchWidgetRef) and entry._searchWidgetRef
        or (frameIsAlive(fallbackRef) and fallbackRef or nil)
    entry.anchorRef = entry.controlRef
    entry.scrollY = settingsSearchRuntime.resolveScrollY(panel, entry.controlRef)
    entry.skipHighlight = not frameIsAlive(entry.controlRef)
    entry._searchRegistryTargetRef = nil
    entry._searchRegistryAnchorRef = nil
    entry._searchScrollSourceRef = nil
    entry._searchRegistryScrollY = nil
    entry._searchVisibleBounds = nil
    entry._searchTargetBounds = nil
    entry._searchTargetBoundsNote = nil
    entry._searchTargetBoundsValid = false
    entry._searchTargetType = entry._searchTargetType or nil
    entry._searchTargetProvisional = false
    entry._searchAlignedTarget = false
    entry._searchTargetChanged = false
    entry._searchWidgetFallbackReason = nil
    entry._searchTargetHistory = entry._searchTargetHistory or {}
    return entry
end

function settingsSearchRuntime.absorbDescriptorIntoControlEntry(entry, descriptor, labelText)
    if not entry or not descriptor then
        return
    end

    local displayLabel = trim(tostring(labelText or ""))
    if trim(entry.displayLabel or "") == "" and displayLabel ~= "" then
        entry.displayLabel = displayLabel
        entry.labelText = displayLabel
    end
    if not entry.iconType and descriptor.iconType then
        entry.iconType = descriptor.iconType
    end
    if frameIsAlive(descriptor.searchWidgetRef) then
        entry._searchWidgetRef = descriptor.searchWidgetRef
    end
    if frameIsAlive(descriptor.searchLabelRef) then
        entry._searchLabelRef = descriptor.searchLabelRef
    elseif frameIsAlive(descriptor.displayRef) then
        entry._searchLabelRef = descriptor.displayRef
    end
    if frameIsAlive(descriptor.searchRowFrame) then
        entry._searchExplicitRowFrame = descriptor.searchRowFrame
    end
    settingsSearchRuntime.appendControlEntryNaturalCandidate(entry, descriptor.searchRowFrame)
    settingsSearchRuntime.appendControlEntryNaturalCandidate(entry, descriptor.parentRef)

    local searchRefs = descriptor.searchRefs or {}
    for i = 1, #searchRefs do
        local text = getSettingsSearchTextFromRef(searchRefs[i])
        if i == 1 then
            settingsSearchRuntime.addEntryHaystackPiece(entry, text)
        else
            settingsSearchRuntime.attachHelperTextToControlEntry(entry, text)
        end
    end
    local helperRefs = descriptor.searchHelperRefs or {}
    for i = 1, #helperRefs do
        settingsSearchRuntime.appendControlEntryHelperRef(entry, helperRefs[i])
        settingsSearchRuntime.appendControlEntryNaturalCandidate(entry, helperRefs[i].GetParent and helperRefs[i]:GetParent() or nil)
    end
    settingsSearchRuntime.addEntryHaystackPiece(entry, displayLabel)
end

function settingsSearchRuntime.attachHelperTextToControlEntry(entry, helperText)
    if not entry then
        return
    end
    local text = trim(tostring(helperText or ""))
    if text == "" then
        return
    end
    if lowerSettingsSearchText(text) == lowerSettingsSearchText(entry.displayLabel or entry.labelText or "") then
        return
    end
    if trim(entry.displayHelper or "") == "" then
        entry.displayHelper = text
        entry.helperText = text
    end
    settingsSearchRuntime.addEntryHaystackPiece(entry, text)
end

function settingsSearchRuntime.buildTargetIdentity(controlRef, scrollY, orderIndex)
    if controlRef ~= nil then
        return tostring(controlRef)
    end
    return string.format("scroll:%d:%d", math.floor(tonumber(scrollY) or 0), math.floor(tonumber(orderIndex) or 0))
end

function settingsSearchRuntime.getEntryDedupeKey(entry)
    if type(entry) ~= "table" then
        return nil
    end

    local kind = lowerSettingsSearchText(entry.kind)
    local sectionKey = lowerSettingsSearchText(entry.sectionKey)
    local labelKey = lowerSettingsSearchText(entry.displayLabel or entry.labelText or "")
    local targetKey = settingsSearchRuntime.buildTargetIdentity(entry._searchRegistryKey or entry.controlRef, entry.scrollY, entry.orderIndex)

    if kind == "control" then
        return table.concat({ "control", sectionKey, targetKey }, "|")
    end
    if kind == "group_title" then
        return table.concat({ "group_title", sectionKey, labelKey, targetKey }, "|")
    end
    if kind == "section_name" then
        return table.concat({ "section_name", sectionKey, labelKey }, "|")
    end
    return nil
end

function settingsSearchRuntime.finalizeRegistryEntry(entry)
    if type(entry) ~= "table" then
        return nil
    end

    entry.displayLabel = trim(tostring(entry.displayLabel or entry.labelText or ""))
    entry.displayHelper = trim(tostring(entry.displayHelper or entry.helperText or ""))
    local haystackParts = entry._haystackParts
    if type(haystackParts) == "table" and #haystackParts > 0 then
        entry.searchHaystack = table.concat(haystackParts, " ")
    else
        entry.searchHaystack = trim(tostring(entry.searchHaystack or entry.haystack or ""))
    end
    entry.dedupeKey = settingsSearchRuntime.getEntryDedupeKey(entry)
    entry.labelText = entry.displayLabel
    entry.helperText = entry.displayHelper
    entry.haystack = entry.searchHaystack
    entry.skipHighlight = entry.kind == "section_name" or not frameIsAlive(entry.controlRef)
    entry._haystackParts = nil
    entry._haystackSeen = nil
    return entry
end

function settingsSearchRuntime.attachHelperDescriptorToControlEntry(controlEntries, helperDescriptor)
    if type(controlEntries) ~= "table" or type(helperDescriptor) ~= "table" then
        return false
    end

    local helperText = trim(tostring(helperDescriptor.labelText or ""))
    if helperText == "" then
        return false
    end

    local helperY = tonumber(helperDescriptor.scrollY) or 0
    local helperOrderIndex = tonumber(helperDescriptor.orderIndex) or 0
    local bestEntry, bestScore = nil, nil

    for i = 1, #controlEntries do
        local entry = controlEntries[i]
        if entry then
            local entryY = tonumber(entry.scrollY) or 0
            local yDelta = math.abs(entryY - helperY)
            local orderDelta = math.abs((tonumber(entry.orderIndex) or 0) - helperOrderIndex)
            local score = yDelta + (orderDelta * 6)
            if yDelta <= 140 or orderDelta <= 4 then
                if not bestScore or score < bestScore then
                    bestEntry = entry
                    bestScore = score
                end
            end
        end
    end

    if not bestEntry then
        return false
    end

    settingsSearchRuntime.attachHelperTextToControlEntry(bestEntry, helperText)
    settingsSearchRuntime.appendControlEntryHelperRef(bestEntry, helperDescriptor.displayRef)
    settingsSearchRuntime.appendControlEntryNaturalCandidate(bestEntry, helperDescriptor.displayRef and helperDescriptor.displayRef.GetParent and helperDescriptor.displayRef:GetParent() or nil)
    return true
end

function settingsSearchRuntime.rebuildRegistry(panel)
    if not panel then
        return nil, false
    end

    local state = settingsSearchRuntime.ensureDescriptorState(panel)
    panel._paSearchHasProvisionalControlTargets = false
    panel._paSearchLiveControlEntries = panel._paSearchLiveControlEntries or {}
    local registry = {}
    local sectionName = panel._paSearchSectionName or panel.name or ""
    local syntheticControlRef = panel._paSearchTopTarget
    registry[#registry + 1] = {
        kind = "section_name",
        sectionKey = panel._paSearchSectionKey,
        sectionName = sectionName,
        displayLabel = sectionName,
        displayHelper = nil,
        labelText = sectionName,
        helperText = nil,
        controlRef = syntheticControlRef,
        scrollY = syntheticControlRef and settingsSearchRuntime.resolveScrollY(panel, syntheticControlRef) or 0,
        orderIndex = 0,
        searchHaystack = lowerSettingsSearchText(sectionName),
        haystack = lowerSettingsSearchText(sectionName),
        dedupeKey = nil,
        iconType = nil,
        skipHighlight = not frameIsAlive(syntheticControlRef),
    }

    local controlEntriesByRef = {}
    local orderedControlEntries = {}
    local orderedRenderableEntries = {}
    local orphanTextDescriptors = {}
    local ownedTextRefs = {}
    local seenLiveControlKeys = {}

    for i = 1, #(state.descriptors or {}) do
        local descriptor = state.descriptors[i]
        local displayRef = descriptor and descriptor.displayRef or nil
        local labelText = getSettingsSearchTextFromRef(displayRef)
        local controlRef = descriptor and (descriptor.searchWidgetRef or descriptor.controlRef or descriptor.anchorRef or displayRef) or nil
        local orderIndex = descriptor and (descriptor.orderIndex or i) or i
        local isDuplicateSectionHeader = labelText ~= ""
            and lowerSettingsSearchText(labelText) == lowerSettingsSearchText(sectionName)
            and displayRef == panel._paSearchTopTarget
        if descriptor and not isDuplicateSectionHeader and labelText ~= "" then
            if settingsSearchRuntime.isControlDescriptorKind(descriptor.kind) then
                local entryKey = settingsSearchRuntime.buildControlRegistryKey(
                    panel,
                    descriptor,
                    labelText,
                    controlRef,
                    displayRef,
                    orderIndex
                )
                local entry = controlEntriesByRef[entryKey]
                if not entry then
                    entry = settingsSearchRuntime.newControlRegistryEntry(
                        panel,
                        descriptor,
                        labelText,
                        controlRef,
                        displayRef,
                        orderIndex,
                        sectionName,
                        entryKey
                    )
                    controlEntriesByRef[entryKey] = entry
                    orderedControlEntries[#orderedControlEntries + 1] = entry
                    orderedRenderableEntries[#orderedRenderableEntries + 1] = entry
                end
                seenLiveControlKeys[entryKey] = true
                settingsSearchRuntime.absorbDescriptorIntoControlEntry(entry, descriptor, labelText)
                local searchRefs = descriptor.searchRefs or {}
                for j = 1, #searchRefs do
                    local ref = searchRefs[j]
                    if frameIsAlive(ref) then
                        ownedTextRefs[ref] = true
                    end
                end
            else
                local standaloneKind = settingsSearchRuntime.getRenderableStandaloneKind(panel, descriptor, labelText)
                if standaloneKind then
                    orderedRenderableEntries[#orderedRenderableEntries + 1] = {
                        kind = standaloneKind,
                        sectionKey = panel._paSearchSectionKey,
                        sectionName = sectionName,
                        displayLabel = labelText,
                        displayHelper = nil,
                        labelText = labelText,
                        helperText = nil,
                        controlRef = controlRef,
                        scrollY = settingsSearchRuntime.resolveScrollY(panel, controlRef or displayRef),
                        orderIndex = orderIndex,
                        searchHaystack = lowerSettingsSearchText(labelText),
                        haystack = lowerSettingsSearchText(labelText),
                        dedupeKey = nil,
                        iconType = nil,
                        skipHighlight = standaloneKind == "section_name" or not frameIsAlive(controlRef or displayRef),
                    }
                else
                    orphanTextDescriptors[#orphanTextDescriptors + 1] = {
                        displayRef = displayRef,
                        labelText = labelText,
                        scrollY = settingsSearchRuntime.resolveScrollY(panel, displayRef or controlRef),
                        orderIndex = orderIndex,
                    }
                end
            end
        end
    end

    for i = 1, #orphanTextDescriptors do
        local orphan = orphanTextDescriptors[i]
        local displayRef = orphan and orphan.displayRef or nil
        if not ownedTextRefs[displayRef] then
            settingsSearchRuntime.attachHelperDescriptorToControlEntry(orderedControlEntries, orphan)
        end
    end

    for i = 1, #orderedControlEntries do
        settingsSearchRuntime.resolveControlEntryTarget(panel, orderedControlEntries[i])
    end

    for key, liveEntry in pairs(panel._paSearchLiveControlEntries or {}) do
        if not seenLiveControlKeys[key] and type(liveEntry) == "table" then
            settingsSearchRuntime.hideSyntheticSearchRowFrame(liveEntry)
            panel._paSearchLiveControlEntries[key] = nil
        end
    end

    for i = 1, #orderedRenderableEntries do
        local entry = settingsSearchRuntime.finalizeRegistryEntry(orderedRenderableEntries[i])
        if entry and entry.labelText ~= "" and entry.haystack ~= "" then
            registry[#registry + 1] = entry
        end
    end

    local dedupedRegistry = {}
    local seenKeys = {}
    local seenSectionNames = {}
    for i = 1, #registry do
        local entry = settingsSearchRuntime.finalizeRegistryEntry(registry[i])
        if entry and entry.labelText ~= "" and entry.haystack ~= "" then
            local labelKey = lowerSettingsSearchText(entry.displayLabel or entry.labelText or "")
            local sectionLabelKey = table.concat({
                lowerSettingsSearchText(entry.sectionKey),
                labelKey,
            }, "|")

            if entry.kind == "section_name" then
                seenSectionNames[sectionLabelKey] = true
            end

            local shouldSkip = false
            if entry.kind == "group_title" and seenSectionNames[sectionLabelKey] == true then
                shouldSkip = true
            end

            local dedupeKey = entry.dedupeKey
            if not shouldSkip and dedupeKey and seenKeys[dedupeKey] then
                shouldSkip = true
            end

            if not shouldSkip then
                if dedupeKey then
                    seenKeys[dedupeKey] = true
                end
                dedupedRegistry[#dedupedRegistry + 1] = entry
            end
        end
    end

    panel._paSearchRegistry = dedupedRegistry
    panel._paSearchRegistryVersion = (tonumber(panel._paSearchRegistryVersion) or 0) + 1
    panel._paSearchRegistryDirty = false
    return dedupedRegistry, true
end

function settingsSearchRuntime.ensurePanelRegistry(panel)
    if not panel or not panel._paSearchSectionKey then
        return nil, false
    end

    local changed = false
    if not panel._initialized and type(panel.EnsureBuilt) == "function" then
        panel._paSearchHiddenBuildInProgress = true
        local ok, err = pcall(panel.EnsureBuilt, panel)
        panel._paSearchHiddenBuildInProgress = nil
        if not ok then
            error(err, 0)
        end
        panel._paSearchHiddenIndexBuilt = true
        if panel._paSearchRealActivationComplete ~= true then
            panel._paSearchRealActivationPending = true
        end
        changed = true
    end

    local needsProvisionalRefresh = panel._paSearchHasProvisionalControlTargets == true
        and panel._paSearchRealActivationComplete == true
    if panel._paSearchRegistryDirty or type(panel._paSearchRegistry) ~= "table" or needsProvisionalRefresh then
        settingsSearchRuntime.rebuildRegistry(panel)
        changed = true
    end

    return panel._paSearchRegistry or {}, changed
end

function settingsSearchRuntime.refreshResolvedTargets(panel)
    if not panel or type(panel._paSearchRegistry) ~= "table" then
        return nil, false
    end

    local changed = false
    for i = 1, #panel._paSearchRegistry do
        local entry = panel._paSearchRegistry[i]
        if type(entry) == "table" and entry.kind == "control" then
            local previousTarget = entry.controlRef
            local previousType = entry._searchTargetType
            local previousScrollY = tonumber(entry.scrollY) or 0
            settingsSearchRuntime.resolveControlEntryTarget(panel, entry)
            if entry.controlRef ~= previousTarget
                or entry._searchTargetType ~= previousType
                or math.abs((tonumber(entry.scrollY) or 0) - previousScrollY) > 0.5
            then
                changed = true
            end
        end
    end

    if changed then
        panel._paSearchRegistryVersion = (tonumber(panel._paSearchRegistryVersion) or 0) + 1
    end
    return panel._paSearchRegistry, changed
end

if PortalAuthority then
    function PortalAuthority:SettingsSearch_MarkPanelDirty(panelOrKey)
        local panel = panelOrKey
        if type(panelOrKey) == "string" then
            panel = getSettingsSearchPanelByKey(panelOrKey)
        end
        if panel then
            panel._paSearchRegistryDirty = true
        end
    end

    function PortalAuthority:SettingsSearch_MarkAllDirty()
        local registry = self.settingsPanelRegistry or {}
        for key, entry in pairs(registry) do
            local panel = entry and entry.panel or nil
            if panel and panel._paSearchSectionKey and key ~= "root" then
                panel._paSearchRegistryDirty = true
            end
        end
    end

    function PortalAuthority:SettingsSearch_EnsurePanelRegistry(sectionKey)
        local panel = getSettingsSearchPanelByKey(sectionKey)
        return settingsSearchRuntime.ensurePanelRegistry(panel)
    end

    function PortalAuthority:SettingsSearch_RefreshResolvedTargets(sectionKey)
        local panel = getSettingsSearchPanelByKey(sectionKey)
        return settingsSearchRuntime.refreshResolvedTargets(panel)
    end

    function PortalAuthority:SettingsSearch_GetScrollContext(sectionKey)
        local panel = getSettingsSearchPanelByKey(sectionKey)
        if not panel then
            return nil, nil, nil
        end
        return panel, panel._paSearchScrollFrame or panel._paSettingsScrollFrame, panel._paSearchScrollChild or panel._paSettingsScrollChild
    end

    function PortalAuthority:SettingsWindowRegisterSearchScrollFrame(scrollFrame, scrollChild)
        if not scrollFrame or not scrollChild then
            return
        end
        markSettingsWindowVisualOptIn(scrollFrame)
        markSettingsWindowVisualOptIn(scrollChild)
        registerSettingsWindowVisualRefresh(scrollFrame, function(selfScroll)
            local child = selfScroll.GetScrollChild and selfScroll:GetScrollChild() or scrollChild
            local viewportHeight = tonumber(selfScroll.GetHeight and selfScroll:GetHeight()) or 0
            local contentHeight = child and (tonumber(child.GetHeight and child:GetHeight()) or 0) or 0
            settingsScrollRuntime.sync(selfScroll, child, viewportHeight, contentHeight)
        end)
        settingsScrollRuntime.sync(scrollFrame, scrollChild, scrollFrame:GetHeight() or 0, scrollChild:GetHeight() or 0)
    end

    function PortalAuthority:SettingsWindowApplySearchScroll(scrollFrame, scrollChild, value)
        if not scrollFrame or not scrollChild then
            return 0
        end
        if scrollFrame.UpdateScrollChildRect then
            scrollFrame:UpdateScrollChildRect()
        end
        local viewportHeight = tonumber(scrollFrame:GetHeight()) or 0
        local contentHeight = tonumber(scrollChild:GetHeight()) or 0
        local maxScroll = math.max(0, contentHeight - viewportHeight)
        local nextValue = math.max(0, math.min(maxScroll, tonumber(value) or 0))
        scrollFrame._paSkipNextCustomScrollBarHookSync = true
        scrollFrame:SetVerticalScroll(nextValue)
        settingsScrollRuntime.sync(scrollFrame, scrollChild, viewportHeight, contentHeight)
        return nextValue
    end
end
local function isRefreshOwnerVisible(owner)
    return owner and owner.IsShown and owner:IsShown() and true or false
end

local refreshCallbacks = {}
local function registerRefreshCallback(fn, owner)
    if type(fn) ~= "function" then
        return
    end
    refreshCallbacks[#refreshCallbacks + 1] = {
        fn = fn,
        owner = owner,
    }
end

local function refreshAllPanels()
    local perfStart, perfState = PA_PerfBegin("options_refresh_all")
    for _, entry in ipairs(refreshCallbacks) do
        local fn = entry and entry.fn or nil
        local owner = entry and entry.owner or nil
        if fn and (not owner or isRefreshOwnerVisible(owner)) then
            fn()
        end
    end
    PA_PerfEnd("options_refresh_all", perfStart, perfState)
end

if PortalAuthority then
    function PortalAuthority:RefreshOptionsPanels()
        refreshAllPanels()
    end
end

local function ensureDatabase()
    if PortalAuthority and PortalAuthority.EnsureDB then
        PortalAuthority:EnsureDB()
    end
end
OptionsInternal.registerRefreshCallback = registerRefreshCallback
OptionsInternal.ensureDatabase = ensureDatabase
OptionsInternal.refreshAllPanels = refreshAllPanels
