local API = rawget(_G, "LIDCOUNCIL_API")
local INTERNAL_API = type(API) == "table" and type(API.__internal) == "table" and API.__internal or nil
if type(INTERNAL_API) ~= "table" then
  error("LidCouncil missing internal API registry.")
end

INTERNAL_API.LIDCOUNCIL_CreateLootProfileRefreshHelpers_Impl = function(deps)
  deps = type(deps) == "table" and deps or {}

  local editor = deps.editor
  local RootDB = deps.RootDB
  local GetSelectedProfileName = deps.GetSelectedProfileName
  local GetLootProfile = deps.GetLootProfile
  local GetLootProfileAccessInfo = deps.GetLootProfileAccessInfo
  local GetLootProfileAccessInfoForRole = deps.GetLootProfileAccessInfoForRole
  local GetLootProfilePermissionPolicyRoleState = deps.GetLootProfilePermissionPolicyRoleState
  local GetLootProfileRoleEntries = deps.GetLootProfileRoleEntries
  local SetLootProfilePermissionPolicyValue = deps.SetLootProfilePermissionPolicyValue
  local ResetLootProfilePermissionPolicy = deps.ResetLootProfilePermissionPolicy
  local PermissionPolicyRowDefs = deps.PermissionPolicyRowDefs or {}
  local SetPermissionPolicyCellState = deps.SetPermissionPolicyCellState
  local BuildLootProfileNavRows = deps.BuildLootProfileNavRows
  local EnsureTextListButtons = deps.EnsureTextListButtons
  local ToggleLootProfileGroupCollapsed = deps.ToggleLootProfileGroupCollapsed
  local SetListButtonSelected = deps.SetListButtonSelected
  local SetTextListButtonTextColor = deps.SetTextListButtonTextColor
  local TrimText = deps.TrimText
  local GetActiveLootSession = deps.GetActiveLootSession
  local GetEnabledLootProfileName = deps.GetEnabledLootProfileName
  local GetPrimaryLootProfileName = deps.GetPrimaryLootProfileName
  local FormatLootProfileRoleLabel = deps.FormatLootProfileRoleLabel
  local BuildLootProfileRoleListText = deps.BuildLootProfileRoleListText
  local BuildLootProfileRoleBuckets = deps.BuildLootProfileRoleBuckets
  local ResolveProfileMemberDisplay = deps.ResolveProfileMemberDisplay
  local ResolveProfileIconData = deps.ResolveProfileIconData
  local GetProfileClassColor = deps.GetProfileClassColor
  local ApplyProfileIcon = deps.ApplyProfileIcon
  local BuildProfileClassSummary = deps.BuildProfileClassSummary
  local BuildProfileMemberDropdownText = deps.BuildProfileMemberDropdownText
  local RefreshProfileMemberRows = deps.RefreshProfileMemberRows
  local ApplyProfileActionButtonStyle = deps.ApplyProfileActionButtonStyle
  local CollectSeasonLootEntries = deps.CollectSeasonLootEntries
  local FindRaidEntryByProfile = deps.FindRaidEntryByProfile
  local BuildSeasonRaidNamesText = deps.BuildSeasonRaidNamesText
  local ResolvePointMode = deps.ResolvePointMode
  local ResolveRollTemplate = deps.ResolveRollTemplate
  local GetRollTemplateText = deps.GetRollTemplateText
  local ResolveRaidPreviewTexture = deps.ResolveRaidPreviewTexture
  local ClearItemRuleSelection = deps.ClearItemRuleSelection
  local SetDropdownValue = deps.SetDropdownValue
  local FindSeasonLootEntry = deps.FindSeasonLootEntry
  local FormatRaidLootItemLabel = deps.FormatRaidLootItemLabel
  local RefreshRollOptionRows = deps.RefreshRollOptionRows
  local RefreshLidTableRows = deps.RefreshLidTableRows
  local BuildRollOptionsText = deps.BuildRollOptionsText
  local BuildPointRulesText = deps.BuildPointRulesText
  local BuildLidTableSummaryText = deps.BuildLidTableSummaryText
  local LayoutProfileContent = deps.LayoutProfileContent
  local CreatePurpleOutline = deps.CreatePurpleOutline
  local ClampListPage = deps.ClampListPage
  local GetListPageForValue = deps.GetListPageForValue
  local UpdatePagerControls = deps.UpdatePagerControls
  local AssignProfileToGroup = deps.AssignProfileToGroup
  local GetLootProfileIdentityInfo = type(API) == "table" and API.LIDCOUNCIL_GetLootProfileIdentityInfo or rawget(_G, "LIDCOUNCIL_GetLootProfileIdentityInfo")
  local ExportLootProfileSnapshot = type(API) == "table" and API.LIDCOUNCIL_ExportLootProfileSnapshot or rawget(_G, "LIDCOUNCIL_ExportLootProfileSnapshot")
  local GetProfileSyncEstimate = type(API) == "table" and API.LIDCOUNCIL_GetProfileSyncEstimate or rawget(_G, "LIDCOUNCIL_GetProfileSyncEstimate")
  local PROFILE_NAV_PAGE_SIZE = 25
  local LOCKED_ROLE_PERMISSION_POLICY = {
    COUNCIL = {
      canDeleteProfile = true,
      canOpenLiveBoard = true,
      canVote = true,
    },
    SESSION_HOST = {
      canDeleteProfile = true,
      canManageSession = true,
      canOpenLiveBoard = true,
      canVote = true,
      canAssignLoot = true,
    },
    RAIDER = {
      canDeleteProfile = true,
      canManageRights = false,
    },
  }

  local function IsPermissionPolicyLocked(role, permissionKey)
    local resolvedRole = string.upper(TrimText(role))
    local locks = LOCKED_ROLE_PERMISSION_POLICY[resolvedRole]
    return type(locks) == "table" and locks[permissionKey] ~= nil
  end

  local function GetLockedPermissionPolicyMessage(permissionKey)
    if permissionKey == "canManageRights" then
      return "Denied. Manage Rights can only be granted to Session Host or Council."
    end
    if permissionKey == "canDeleteProfile" then
      return "Delete Local Profile Copy is fixed for every role. It only removes your local copy and is blocked while a session is active."
    end
    return "Denied. Revoking this right would eliminate the purpose of this role."
  end

  local function FormatProfileSizeBytes(byteCount)
    local bytes = math.max(0, tonumber(byteCount) or 0)
    local kb = bytes / 1024
    if kb >= 10 then
      return string.format("%.0f KB (%d bytes)", kb, bytes)
    end
    return string.format("%.1f KB (%d bytes)", kb, bytes)
  end

  local function FormatProfileSizeShort(byteCount)
    local bytes = math.max(0, tonumber(byteCount) or 0)
    local kb = bytes / 1024
    if kb >= 10 then
      return string.format("%.0f KB", kb)
    end
    return string.format("%.1f KB", kb)
  end

  local function BuildProfileSyncEstimate(byteCount)
    if type(GetProfileSyncEstimate) == "function" then
      local ok, result = pcall(GetProfileSyncEstimate, byteCount)
      if ok and type(result) == "table" then
        return result
      end
    end

    local bytes = math.max(0, tonumber(byteCount) or 0)
    local chunkSize = 120
    local chunks = math.max(1, math.ceil(bytes / chunkSize))
    local messages = chunks + 2
    local intervalSeconds = 0.12
    return {
      bytes = bytes,
      chunkSize = chunkSize,
      chunks = chunks,
      messages = messages,
      intervalSeconds = intervalSeconds,
      seconds = messages * intervalSeconds,
    }
  end

  local function FormatProfileSyncExample(kb)
    local bytes = math.max(0, (tonumber(kb) or 0) * 1024)
    local estimate = BuildProfileSyncEstimate(bytes)
    return string.format("%d KB: ~%.1fs per target", kb, tonumber(estimate.seconds) or 0)
  end

  local function BuildProfileSizeDisplay(profileName)
    local resolvedName = TrimText(profileName)
    if resolvedName == "" then
      return nil
    end
    if type(ExportLootProfileSnapshot) ~= "function" then
      return {
        text = "Profile Size: unavailable",
        lines = {
          "The profile export helper is not loaded yet.",
        },
      }
    end

    local ok, snapshot = pcall(ExportLootProfileSnapshot, resolvedName)
    if not ok or type(snapshot) ~= "string" or snapshot == "" then
      return {
        text = "Profile Size: unavailable",
        lines = {
          "The profile snapshot could not be serialized right now.",
        },
      }
    end

    local bytes = #snapshot
    local estimate = BuildProfileSyncEstimate(bytes)
    local seconds = tonumber(estimate.seconds) or 0
    local chunks = tonumber(estimate.chunks) or 0
    local messages = tonumber(estimate.messages) or 0
    local chunkSize = tonumber(estimate.chunkSize) or 0
    local intervalSeconds = tonumber(estimate.intervalSeconds) or 0
    return {
      text = string.format("Profile Size: %s | ~%.1fs/player", FormatProfileSizeShort(bytes), seconds),
      lines = {
        "Serialized snapshot: " .. FormatProfileSizeBytes(bytes),
        string.format("Current sync estimate: %d chunks, %d queued addon messages.", chunks, messages),
        string.format("Current chunk size: %d bytes | queue delay: %.2fs/message.", chunkSize, intervalSeconds),
        "Rough examples with the current queue settings:",
        FormatProfileSyncExample(10),
        FormatProfileSyncExample(25),
        FormatProfileSyncExample(50),
        "For a full raid push, multiply the per-target estimate by the number of players receiving the profile.",
      },
    }
  end

  local function SetProfilesFeedback(owner, text, r, g, b, a)
    if not owner or not owner.lootProfilesFeedback then
      return
    end
    if owner.lootProfilesFeedback.SetText then
      owner.lootProfilesFeedback:SetText(tostring(text or ""))
    end
    if owner.lootProfilesFeedback.SetTextColor then
      owner.lootProfilesFeedback:SetTextColor(
        tonumber(r) or 0.82,
        tonumber(g) or 0.82,
        tonumber(b) or 0.86,
        tonumber(a) or 1.00
      )
    end
  end

  local function SetProfileNavButtonVariant(button, variantKey, selected)
    if not button then
      return
    end
    if not button.__profileVariantBg then
      local bg = button:CreateTexture(nil, "BORDER", nil, 0)
      bg:SetTexture("Interface\\Buttons\\WHITE8x8")
      bg:SetPoint("TOPLEFT", 1, -1)
      bg:SetPoint("BOTTOMRIGHT", -1, 1)
      bg:SetVertexColor(0, 0, 0, 0)
      button.__profileVariantBg = bg
    end
    if not button.__profileVariantAccent then
      local accent = button:CreateTexture(nil, "ARTWORK", nil, 0)
      accent:SetTexture("Interface\\Buttons\\WHITE8x8")
      accent:SetPoint("TOPLEFT", 1, -1)
      accent:SetPoint("BOTTOMLEFT", 1, 1)
      accent:SetWidth(3)
      accent:SetVertexColor(0, 0, 0, 0)
      button.__profileVariantAccent = accent
    end

    if variantKey == "SIMULATION" then
      local bgColor = selected and { 0.46, 0.10, 0.10, 0.52 } or { 0.32, 0.07, 0.07, 0.38 }
      local accentColor = selected and { 1.00, 0.56, 0.56, 0.96 } or { 0.92, 0.24, 0.24, 0.92 }
      button.__profileVariantBg:SetVertexColor(bgColor[1], bgColor[2], bgColor[3], bgColor[4])
      button.__profileVariantAccent:SetVertexColor(accentColor[1], accentColor[2], accentColor[3], accentColor[4])
    else
      button.__profileVariantBg:SetVertexColor(0, 0, 0, 0)
      button.__profileVariantAccent:SetVertexColor(0, 0, 0, 0)
    end
  end

  local function SetLockedPermissionPolicyFeedbackCell(owner, cell, permissionKey)
    if not cell then
      return
    end
    cell.__interactive = false
    cell:EnableMouse(true)
    if cell.Enable then
      cell:Enable()
    end
    cell:SetScript("OnClick", function()
      SetProfilesFeedback(owner, GetLockedPermissionPolicyMessage(permissionKey), 1.00, 0.32, 0.32, 1.00)
    end)
  end

  local function FinishPermissionPolicyUpdate(owner, profileName, roleKey, roleLabel, permissionLabel, permissionKey, desiredEnabled, ok, result, fallbackError)
    if ok then
      if owner.RefreshLootProfilePage then
        owner:RefreshLootProfilePage()
      end
      local actualEnabled = desiredEnabled and true or false
      if type(GetLootProfilePermissionPolicyRoleState) == "function" then
        local refreshedRoleState = GetLootProfilePermissionPolicyRoleState(profileName, roleKey)
        if type(refreshedRoleState) == "table" and refreshedRoleState[permissionKey] ~= nil then
          actualEnabled = refreshedRoleState[permissionKey] and true or false
        end
      elseif type(result) == "table" and result[permissionKey] ~= nil then
        actualEnabled = result[permissionKey] and true or false
      end
      if actualEnabled ~= (desiredEnabled and true or false) then
        SetProfilesFeedback(owner, string.format(
          "Could not verify %s permission: %s.",
          tostring(roleLabel or "role"),
          tostring(permissionLabel or permissionKey or "?")
        ), 1.00, 0.82, 0.24, 1.00)
        return
      end
      local suffix = actualEnabled and "granted" or "revoked"
      if actualEnabled then
        SetProfilesFeedback(owner, string.format(
          "Updated %s permission: %s %s.",
          tostring(roleLabel or "role"),
          tostring(permissionLabel or permissionKey or "?"),
          suffix
        ), 0.30, 0.90, 0.36, 1.00)
      else
        SetProfilesFeedback(owner, string.format(
          "Updated %s permission: %s %s.",
          tostring(roleLabel or "role"),
          tostring(permissionLabel or permissionKey or "?"),
          suffix
        ), 1.00, 0.32, 0.32, 1.00)
      end
    else
      SetProfilesFeedback(owner, tostring(result or fallbackError or "Could not update the permission."), 1.00, 0.32, 0.32, 1.00)
    end
  end
  local EnsureLootProfileGroupDragBadge

  local function BuildLootProfileIdentitySummary(identity, includeInternalDetails)
    identity = type(identity) == "table" and identity or {}
    local syncMode = string.upper(TrimText(identity.syncMode or ""))
    local origin = string.upper(TrimText(identity.origin or ""))
    local profileId = TrimText(identity.profileId)

    local kindLabel = "Local Profile"
    if syncMode == "SHARED" then
      kindLabel = "Shared Session Copy"
    elseif origin == "COPY" or origin == "IMPORT" then
      kindLabel = "Independent Local Clone"
    end

    local sourceLabel = ""
    if syncMode == "SHARED" then
      local sourceName = TrimText(identity.sharedSourceProfileName)
      local sourceCharacter = TrimText(identity.sharedSourceCharacter)
      if sourceName ~= "" and sourceCharacter ~= "" then
        sourceLabel = " | Source: " .. sourceName .. " from " .. sourceCharacter
      elseif sourceName ~= "" then
        sourceLabel = " | Source: " .. sourceName
      elseif sourceCharacter ~= "" then
        sourceLabel = " | Source: " .. sourceCharacter
      end
    else
      local cloneSource = TrimText(identity.cloneSourceProfileName)
      if cloneSource ~= "" then
        sourceLabel = " | Based on: " .. cloneSource
      end
    end

    if not includeInternalDetails then
      return kindLabel .. sourceLabel
    end
    if profileId ~= "" then
      return string.format("Profile Details: %s | ID: %s%s", kindLabel, profileId, sourceLabel)
    end
    return "Profile Details: " .. kindLabel .. sourceLabel
  end

  local function ClearLootProfileGroupDrag(self, preserveFeedback)
    if not self then
      return nil
    end
    local state = self.__lootProfileGroupDrag
    if not state then
      return nil
    end

    if state.sourceButton and state.sourceButton.SetAlpha then
      state.sourceButton:SetAlpha(1)
    end
    if state.sourceButton and state.sourceButton.__profileDragSourceBorder then
      state.sourceButton.__profileDragSourceBorder:Hide()
    end
    for _, button in ipairs(self.lootProfileGroupButtons or {}) do
      if button and button.__profileDragDropBorder then
        if button.__profileDragDropBorder.SetBackdropBorderColor then
          button.__profileDragDropBorder:SetBackdropBorderColor(0.6588, 0.4784, 0.9098, 0.95)
        end
        button.__profileDragDropBorder:Hide()
      end
    end
    if self.__lootProfileGroupDragMonitor then
      self.__lootProfileGroupDragMonitor:Hide()
    end
    if self.__lootProfileGroupDragBadge then
      self.__lootProfileGroupDragBadge:Hide()
    end
    if (not preserveFeedback) and self.lootProfilesFeedback and self.lootProfilesFeedback.GetText and self.lootProfilesFeedback:GetText() and string.find(self.lootProfilesFeedback:GetText(), "Dragging:", 1, true) == 1 then
      self.lootProfilesFeedback:SetText("")
    end
    self.__lootProfileGroupDrag = nil
    return state
  end

  local function RefreshLootProfileAfterGroupMove(self, profileName)
    self.selectedLootProfileName = profileName
    self.selectedProfileName = profileName
    self.selectedLootProfileGroupName = nil
    self.selectedProfileGroupName = nil
    if self.RefreshLootProfilePage then
      self:RefreshLootProfilePage()
    elseif self.Refresh then
      self:Refresh()
    end
  end

  local function MoveLootProfileToGroup(self, profileName, targetGroupName)
    if type(AssignProfileToGroup) ~= "function" then
      return false
    end
    local name = TrimText(profileName)
    if name == "" then
      return false
    end
    local targetName = TrimText(targetGroupName)
    local ok = AssignProfileToGroup(name, targetName ~= "" and targetName or nil)
    if ok then
      RefreshLootProfileAfterGroupMove(self, name)
    end
    return ok
  end

  local function EnsureLootProfileGroupDragMonitor(self)
    if not self then
      return nil
    end
    if self.__lootProfileGroupDragMonitor then
      return self.__lootProfileGroupDragMonitor
    end

    local monitor = CreateFrame("Frame", nil, self)
    monitor:SetAllPoints(self)
    monitor:Hide()
    monitor:SetScript("OnUpdate", function(frame)
      local state = self.__lootProfileGroupDrag
      if not state then
        frame:Hide()
        return
      end

      local hoveredButton = nil
      if type(MouseIsOver) == "function" then
        for _, button in ipairs(self.lootProfileGroupButtons or {}) do
          if button and button.IsShown and button:IsShown() and MouseIsOver(button) then
            hoveredButton = button
            break
          end
        end
      end

      if hoveredButton ~= state.hoveredButton then
        if state.hoveredButton and state.hoveredButton.__profileDragDropBorder then
          if state.hoveredButton.__profileDragDropBorder.SetBackdropBorderColor then
            state.hoveredButton.__profileDragDropBorder:SetBackdropBorderColor(0.6588, 0.4784, 0.9098, 0.42)
          end
          state.hoveredButton.__profileDragDropBorder:Show()
        end
        state.hoveredButton = hoveredButton
        if hoveredButton and hoveredButton.__profileDragDropBorder then
          if hoveredButton.__profileDragDropBorder.SetBackdropBorderColor then
            hoveredButton.__profileDragDropBorder:SetBackdropBorderColor(0.6588, 0.4784, 0.9098, 1.00)
          end
          hoveredButton.__profileDragDropBorder:Show()
        end
      end

      local overList = false
      if type(MouseIsOver) == "function" then
        overList = (self.lootProfilesListScroll and MouseIsOver(self.lootProfilesListScroll))
          or (self.lootProfilesListContent and MouseIsOver(self.lootProfilesListContent))
          or false
      end

      if self.lootProfilesFeedback then
        local targetName = hoveredButton and hoveredButton.__profileGroupName or nil
        if targetName and targetName ~= "" then
          self.lootProfilesFeedback:SetText("Dragging: " .. state.name .. " -> " .. targetName)
        elseif overList then
          self.lootProfilesFeedback:SetText("Dragging: " .. state.name .. " -> No group")
        else
          self.lootProfilesFeedback:SetText("Dragging: " .. state.name .. " | Drop on a group or release in the list to ungroup.")
        end
      end

      local badge = EnsureLootProfileGroupDragBadge(self)
      if badge and badge.text then
        local targetName = hoveredButton and hoveredButton.__profileGroupName or nil
        if targetName and targetName ~= "" then
          badge.text:SetText("Moving: " .. state.name .. " -> " .. targetName)
        elseif overList then
          badge.text:SetText("Moving: " .. state.name .. " -> No group")
        else
          badge.text:SetText("Moving: " .. state.name .. " | Drop on a group or release in the list.")
        end
        local scale = (UIParent and UIParent.GetEffectiveScale and UIParent:GetEffectiveScale()) or 1
        if scale == 0 then scale = 1 end
        local cx, cy = GetCursorPosition()
        if cx and cy then
          cx = cx / scale
          cy = cy / scale
          badge:ClearAllPoints()
          badge:SetPoint("BOTTOMLEFT", UIParent, "BOTTOMLEFT", cx + 18, cy - 16)
        end
        badge:Show()
      end

      if (IsMouseButtonDown and IsMouseButtonDown("LeftButton")) then
        return
      end

      frame:Hide()
      if hoveredButton and hoveredButton.__profileGroupName then
        local completedState = ClearLootProfileGroupDrag(self, true)
        if completedState then
          MoveLootProfileToGroup(self, completedState.name, hoveredButton.__profileGroupName)
        end
      elseif overList then
        local completedState = ClearLootProfileGroupDrag(self, true)
        if completedState then
          MoveLootProfileToGroup(self, completedState.name, nil)
        end
      else
        ClearLootProfileGroupDrag(self)
      end
    end)

    self.__lootProfileGroupDragMonitor = monitor
    return monitor
  end

  EnsureLootProfileGroupDragBadge = function(self)
    if not self then
      return nil
    end
    if self.__lootProfileGroupDragBadge then
      return self.__lootProfileGroupDragBadge
    end

    local badge = CreateFrame("Frame", nil, UIParent, "BackdropTemplate")
    badge:SetFrameStrata("TOOLTIP")
    badge:SetFrameLevel(250)
    badge:SetClampedToScreen(true)
    badge:SetSize(336, 42)
    badge:SetBackdrop({
      bgFile = "Interface\\Buttons\\WHITE8x8",
      edgeFile = "Interface\\Buttons\\WHITE8x8",
      edgeSize = 1,
    })
    badge:SetBackdropColor(0.13, 0.08, 0.20, 0.98)
    badge:SetBackdropBorderColor(0.6588, 0.4784, 0.9098, 1.00)
    badge:Hide()

    local text = badge:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall")
    text:SetPoint("LEFT", 12, 0)
    text:SetPoint("RIGHT", -12, 0)
    text:SetJustifyH("LEFT")
    text:SetTextColor(0.98, 0.94, 1.00, 1.00)
    badge.text = text

    self.__lootProfileGroupDragBadge = badge
    return badge
  end

  local function BeginLootProfileGroupDrag(self, profileName, sourceGroupName, sourceButton)
    if not self or not sourceButton then
      return false
    end
    local name = TrimText(profileName)
    if name == "" then
      return false
    end

    ClearLootProfileGroupDrag(self, true)

    if type(CreatePurpleOutline) == "function" then
      sourceButton.__profileDragSourceBorder = sourceButton.__profileDragSourceBorder or CreatePurpleOutline(sourceButton)
      if sourceButton.__profileDragSourceBorder then
        sourceButton.__profileDragSourceBorder:Show()
      end
      for _, button in ipairs(self.lootProfileGroupButtons or {}) do
        button.__profileDragDropBorder = button.__profileDragDropBorder or CreatePurpleOutline(button)
        if button.__profileDragDropBorder and button.__profileDragDropBorder.SetBackdropBorderColor then
          button.__profileDragDropBorder:SetBackdropBorderColor(0.6588, 0.4784, 0.9098, 0.42)
          button.__profileDragDropBorder:Show()
        end
      end
    end

    if sourceButton.SetAlpha then
      sourceButton:SetAlpha(0.72)
    end

    self.__lootProfileGroupDrag = {
      name = name,
      sourceGroupName = TrimText(sourceGroupName),
      sourceButton = sourceButton,
      hoveredButton = nil,
    }

    if self.lootProfilesFeedback then
      self.lootProfilesFeedback:SetText("Dragging: " .. name .. " | Drop on a group or release in the list to ungroup.")
    end

    local badge = EnsureLootProfileGroupDragBadge(self)
    if badge and badge.text then
      badge.text:SetText("Moving: " .. name .. " | Drop on a group or release in the list to ungroup.")
      badge:Show()
    end

    local monitor = EnsureLootProfileGroupDragMonitor(self)
    if monitor then
      monitor:Show()
    end
    return true
  end

  local function RefreshProfilePage(self)
    local function SetCurrentProfileFont(fontString, text, color)
      if not fontString then
        return
      end
      fontString:SetText(text)
      fontString.__lid_customTextColor = color
      if color and fontString.SetTextColor then
        fontString:SetTextColor(color[1], color[2], color[3], color[4] or 1)
      elseif fontString.SetTextColor then
        fontString:SetTextColor(0.92, 0.96, 1.00, 1.00)
      end
    end

    local owner = editor or self
    local root = RootDB()
    local currentName = GetSelectedProfileName(self)
    if TrimText(self.__lootProfileLastSelectedProfile) ~= TrimText(currentName) then
      self.__lootProfileLastSelectedProfile = currentName
      self.__lootProfileRaidersCollapsed = true
      self.__lootProfileOpenSection = nil
      self.__lootProfileRoleTarget = nil
    end
    self.selectedLootProfileName = currentName
    self.selectedProfileName = currentName
    local rows = BuildLootProfileNavRows(root)
    local selectedGroupKey = self.selectedLootProfileGroupName and ("group:" .. string.lower(self.selectedLootProfileGroupName)) or nil
    local selectedProfileName = TrimText(self.selectedLootProfileName or currentName)
    local profilePageFocus = selectedGroupKey or (selectedProfileName ~= "" and ("profile:" .. selectedProfileName) or nil)
    local selectedProfilePage = type(GetListPageForValue) == "function" and GetListPageForValue(rows, profilePageFocus, PROFILE_NAV_PAGE_SIZE, function(row)
      return row and row.key
    end) or nil
    local totalPages = math.max(1, math.ceil(#rows / PROFILE_NAV_PAGE_SIZE))
    if profilePageFocus ~= self.__lastLootProfilePageFocus and selectedProfilePage then
      self.lootProfileListPage = selectedProfilePage
    end
    self.lootProfileListPage = type(ClampListPage) == "function" and ClampListPage(self.lootProfileListPage or 1, totalPages) or math.max(1, math.min(self.lootProfileListPage or 1, totalPages))
    self.__lastLootProfilePageFocus = profilePageFocus
    local rowStartIndex = ((self.lootProfileListPage - 1) * PROFILE_NAV_PAGE_SIZE) + 1
    local rowEndIndex = math.min(#rows, rowStartIndex + PROFILE_NAV_PAGE_SIZE - 1)
    local visibleRowCount = math.max(1, rowEndIndex - rowStartIndex + 1)
    local totalHeight = math.max(1, visibleRowCount * 24)
    self.lootProfilesListContent:SetHeight(totalHeight)
    self.lootProfileGroupButtons = {}
    self.lootProfileButtons = EnsureTextListButtons(self.lootProfileButtons, self.lootProfilesListContent, visibleRowCount, function(row)
      if type(row) ~= "table" then return end
      if row.type == "group" then
        self.selectedLootProfileGroupName = row.name
        self.selectedProfileGroupName = row.name
        ToggleLootProfileGroupCollapsed(root, row.name)
      elseif row.type == "profile" and row.name then
        local _, nextSelectedProfileName = GetLootProfile(row.name)
        self.selectedLootProfileName = nextSelectedProfileName
        self.selectedProfileName = self.selectedLootProfileName
        self.selectedLootProfileGroupName = nil
        self.selectedProfileGroupName = nil
      end
      if self.Refresh then self:Refresh() end
    end)
    for i = 1, #self.lootProfileButtons do
      local button = self.lootProfileButtons[i]
      local row = rows[rowStartIndex + i - 1]
      if row then
        button.__value = row
        button.__row = row
        button:ClearAllPoints()
        button:SetPoint("TOPLEFT", row.type == "profile" and 16 or 0, -((i - 1) * 24))
        button:SetWidth(row.type == "profile" and 192 or 208)
        button.__lid_customText = nil

        if row.type == "group" then
          button.__profileGroupName = row.name
          button:SetScript("OnDragStart", nil)
          button:SetText(string.format("%s %s (%d)", row.collapsed and ">" or "v", tostring(row.name or ""), tonumber(row.childCount) or 0))
          button.__lid_customText = { 0.92, 0.82, 1.00, 1.00 }
          SetProfileNavButtonVariant(button, nil, selectedGroupKey == row.key)
          SetListButtonSelected(button, selectedGroupKey == row.key)
          SetTextListButtonTextColor(button, selectedGroupKey == row.key and { 1.00, 0.94, 0.62, 1.00 } or button.__lid_customText)
          self.lootProfileGroupButtons[#self.lootProfileGroupButtons + 1] = button
        else
          button.__profileGroupName = nil
          if type(CreatePurpleOutline) == "function" then
            button.__profileDragSourceBorder = button.__profileDragSourceBorder or CreatePurpleOutline(button)
            if button.__profileDragSourceBorder then
              button.__profileDragSourceBorder:Hide()
            end
          end
          button:RegisterForDrag("LeftButton")
          button:SetScript("OnDragStart", function(sourceButton)
            BeginLootProfileGroupDrag(self, row.name, row.groupName, sourceButton)
          end)
          local rowProfile = GetLootProfile(row.name)
          local enabledMark = rowProfile and rowProfile.settings and rowProfile.settings.enabled and "|TInterface\\Buttons\\UI-CheckBox-Check:14:14:0:0|t " or ""
          button:SetText(enabledMark .. tostring(row.name or ""))
          local isSelected = TrimText(row.name) == selectedProfileName
          local isSimulationRow = TrimText(row.name) == "Simulation"
          SetProfileNavButtonVariant(button, isSimulationRow and "SIMULATION" or nil, isSelected)
          SetListButtonSelected(button, isSelected)
          SetTextListButtonTextColor(button, isSelected and { 1.00, 0.94, 0.62, 1.00 } or (isSimulationRow and { 1.00, 0.78, 0.78, 1.00 } or { 0.82, 0.82, 0.86, 1.00 }))
        end

        button:Show()
      else
        button.__value = nil
        button.__row = nil
        SetProfileNavButtonVariant(button, nil, false)
        button:Hide()
      end
    end
    if self.lootProfilesListScroll then
      self.lootProfilesListScroll:SetVerticalScroll(0)
      if self.lootProfilesListScroll.UpdateScrollChildRect then
        self.lootProfilesListScroll:UpdateScrollChildRect()
      end
    end
    if type(UpdatePagerControls) == "function" then
      UpdatePagerControls(self.lootProfilesPrevBtn, self.lootProfilesNextBtn, self.lootProfilesPageText, self.lootProfileListPage, totalPages)
    end

    local hasProfile = type(currentName) == "string" and currentName ~= ""
    if not hasProfile then
      self.selectedLootProfileName = nil
      self.selectedProfileName = nil
      self.selectedLootProfileGroupName = nil
      self.selectedProfileGroupName = nil
      self.__lootProfilesHasVisibleSelection = false

      if self.lootProfilesRightScroll then
        self.lootProfilesRightScroll:Hide()
      end
      if self.lootProfilesEmptyStateFrame then
        self.lootProfilesEmptyStateFrame:Show()
      end
      if self.lootProfilesTitle then
        self.lootProfilesTitle:SetText("Profile Settings")
      end
      if self.lootProfileStatus then
        self.lootProfileStatus:SetText("No profile created")
        self.lootProfileStatus:SetTextColor(1.00, 0.82, 0.28, 1.00)
      end
      if self.lootProfileStatusDot and self.lootProfileStatusDot.SetVertexColor then
        self.lootProfileStatusDot:SetVertexColor(1.00, 0.82, 0.28, 1.00)
      end
      if self.lootProfileSizeFrame then
        self.lootProfileSizeFrame:Hide()
        self.lootProfileSizeFrame.__tooltipLines = nil
      end
      if self.lootProfileSizeText then
        self.lootProfileSizeText:SetText("")
      end
      SetCurrentProfileFont(self.profilesCurrentLabel, "Current Profile: No profile activated :(", { 1.00, 0.35, 0.25, 1.00 })
      SetCurrentProfileFont(self.profileBarText, "Current Profile: No profile activated :(", { 1.00, 0.35, 0.25, 1.00 })
      if self.lootProfilesFeedback then
        self.lootProfilesFeedback:SetText("")
        if self.lootProfilesFeedback.SetTextColor then
          self.lootProfilesFeedback:SetTextColor(0.82, 0.82, 0.86, 1.00)
        end
      end
      if self.lootAddGroupBtn and self.lootAddGroupBtn.Disable then
        self.lootAddGroupBtn:Disable()
      end
      if self.lootDeleteGroupBtn and self.lootDeleteGroupBtn.Disable then
        self.lootDeleteGroupBtn:Disable()
      end
      if self.lootActivateProfileBtn and self.lootActivateProfileBtn.Disable then
        self.lootActivateProfileBtn:Disable()
      end
      if self.lootDeactivateProfileBtn and self.lootDeactivateProfileBtn.Disable then
        self.lootDeactivateProfileBtn:Disable()
      end
      if self.lootCopyProfileBtn and self.lootCopyProfileBtn.Disable then
        self.lootCopyProfileBtn:Disable()
      end
      if self.lootDeleteProfileBtn and self.lootDeleteProfileBtn.Disable then
        self.lootDeleteProfileBtn:Disable()
      end
      if self.lootClearSimulationContentBtn then
        self.lootClearSimulationContentBtn:Hide()
      end
      return
    end

    self.__lootProfilesHasVisibleSelection = true
    if self.lootProfilesRightScroll then
      self.lootProfilesRightScroll:Show()
    end
    if self.lootProfilesEmptyStateFrame then
      self.lootProfilesEmptyStateFrame:Hide()
    end
    if self.lootAddGroupBtn and self.lootAddGroupBtn.Enable then
      self.lootAddGroupBtn:Enable()
    end

    local profile = GetLootProfile(currentName)
    local access = GetLootProfileAccessInfo(currentName)
    local roleEntries = GetLootProfileRoleEntries(currentName)
    local enabled = profile.settings and profile.settings.enabled
    local activeProfileLabel = TrimText(type(GetEnabledLootProfileName) == "function" and GetEnabledLootProfileName() or "")
    local canManageProfile = access.canManageProfile
    local canManageRights = access.canManageRights
    local roleBuckets = BuildLootProfileRoleBuckets(roleEntries, profile)
    local activeSession, activeSessionProfile = GetActiveLootSession()
    local hasRunningSession = activeSession and tostring(activeSessionProfile or activeSession.profileName or "") == tostring(currentName)
    local hasAnyRunningSession = activeSession ~= nil
    local identity = hasProfile and type(GetLootProfileIdentityInfo) == "function" and GetLootProfileIdentityInfo(currentName) or nil
    local isSharedReplica = type(identity) == "table" and string.upper(TrimText(identity.syncMode or "")) == "SHARED"
    local canDeleteProfile = hasProfile
      and currentName ~= "Default"
      and currentName ~= "Simulation"
      and not hasAnyRunningSession
      and not enabled
      and TrimText(currentName) ~= activeProfileLabel
      and (access.canDeleteProfile or isSharedReplica)
    local showSimulationProfile = type(root.ui) == "table" and root.ui.developerMode == true and root.ui.showSimulationProfile == true
    if activeProfileLabel == "Simulation" and not showSimulationProfile then
      activeProfileLabel = ""
    end
    if activeProfileLabel == "" then
      SetCurrentProfileFont(self.profilesCurrentLabel, "Current Profile: No profile activated :(", { 1.00, 0.35, 0.25, 1.00 })
      SetCurrentProfileFont(self.profileBarText, "Current Profile: No profile activated :(", { 1.00, 0.35, 0.25, 1.00 })
    else
      SetCurrentProfileFont(self.profilesCurrentLabel, "Current Profile: " .. activeProfileLabel, nil)
      SetCurrentProfileFont(self.profileBarText, "Current Profile: " .. activeProfileLabel, nil)
    end
    if self.lootProfilesTitle then
      self.lootProfilesTitle:SetText(tostring(currentName ~= "" and currentName or "Profile Settings"))
    end
    if self.lootProfileSizeFrame and self.lootProfileSizeText then
      local showProfileSize = type(root.ui) == "table"
        and root.ui.developerMode == true
        and root.ui.showProfileSize == true
      if showProfileSize then
        local sizeDisplay = BuildProfileSizeDisplay(currentName)
        if sizeDisplay then
          self.lootProfileSizeText:SetText(tostring(sizeDisplay.text or "Profile Size: unavailable"))
          self.lootProfileSizeFrame.__tooltipLines = type(sizeDisplay.lines) == "table" and sizeDisplay.lines or {}
          self.lootProfileSizeFrame:Show()
        else
          self.lootProfileSizeFrame:Hide()
          self.lootProfileSizeFrame.__tooltipLines = nil
        end
      else
        self.lootProfileSizeFrame:Hide()
        self.lootProfileSizeFrame.__tooltipLines = nil
        self.lootProfileSizeText:SetText("")
      end
    end
    if self.lootProfilesFeedback and self.lootProfilesFeedback.SetTextColor then
      if not canManageProfile then
        self.lootProfilesFeedback:SetText("Read-only access: your current role cannot edit this profile.")
        self.lootProfilesFeedback:SetTextColor(1.00, 0.32, 0.32, 1.00)
      else
        if self.lootProfilesFeedback.GetText and self.lootProfilesFeedback:GetText() == "Read-only access: your current role cannot edit this profile." then
          self.lootProfilesFeedback:SetText("")
        end
        self.lootProfilesFeedback:SetTextColor(0.82, 0.82, 0.86, 1.00)
      end
    end
    if self.lootProfileStatus then
      if enabled then
        self.lootProfileStatus:SetText(hasRunningSession and "Active | Session Running" or "Active")
        self.lootProfileStatus:SetTextColor(0.2, 0.9, 0.2, 1)
      else
        self.lootProfileStatus:SetText("Inactive")
        self.lootProfileStatus:SetTextColor(1.0, 0.35, 0.25, 1)
      end
    end
    if self.lootProfileStatusDot and self.lootProfileStatusDot.SetVertexColor then
      if enabled then
        self.lootProfileStatusDot:SetVertexColor(0.20, 0.90, 0.30, 1.00)
      else
        self.lootProfileStatusDot:SetVertexColor(0.95, 0.28, 0.24, 1.00)
      end
    end
    if self.lootActivateProfileBtn and self.lootActivateProfileBtn.Enable then
      if hasProfile and not enabled then self.lootActivateProfileBtn:Enable() else self.lootActivateProfileBtn:Disable() end
    end
    if self.lootDeactivateProfileBtn and self.lootDeactivateProfileBtn.Enable then
      if hasProfile and enabled then self.lootDeactivateProfileBtn:Enable() else self.lootDeactivateProfileBtn:Disable() end
    end
    if self.lootCopyProfileBtn and self.lootCopyProfileBtn.Enable then
      if hasProfile then self.lootCopyProfileBtn:Enable() else self.lootCopyProfileBtn:Disable() end
    end
    if self.lootClearSimulationContentBtn then
      local showClearSimulation = hasProfile and TrimText(currentName) == "Simulation"
      self.lootClearSimulationContentBtn:SetShown(showClearSimulation)
      if self.lootClearSimulationContentBtn.Enable then
        if showClearSimulation and not hasAnyRunningSession then
          self.lootClearSimulationContentBtn:Enable()
        else
          self.lootClearSimulationContentBtn:Disable()
        end
      end
    end
    if self.lootDeleteProfileBtn and self.lootDeleteProfileBtn.Enable then
      if self.lootDeleteProfileBtn.SetText then
        self.lootDeleteProfileBtn:SetText("Delete Profile")
      end
      if canDeleteProfile then self.lootDeleteProfileBtn:Enable() else self.lootDeleteProfileBtn:Disable() end
    end
    if self.lootDeleteGroupBtn and self.lootDeleteGroupBtn.Enable then
      if canManageProfile and TrimText(self.selectedLootProfileGroupName) ~= "" then
        self.lootDeleteGroupBtn:Enable()
      else
        self.lootDeleteGroupBtn:Disable()
      end
    end
    if self.lootProfileAccessSummary then
      self.lootProfileAccessSummary:SetText(string.format(
        "Your Role: %s\nSelect a member from the dropdown or click a council/raider row, then assign the role below.",
        FormatLootProfileRoleLabel(access.role)
      ))
    end
    if self.lootProfileAccessList then
      self.lootProfileAccessList:SetText(BuildLootProfileRoleListText(roleEntries))
      self.lootProfileAccessList:Hide()
    end
    do
      local masterPreview = type(GetLootProfilePermissionPolicyRoleState) == "function" and GetLootProfilePermissionPolicyRoleState(currentName, "MASTER")
        or (type(GetLootProfileAccessInfoForRole) == "function" and GetLootProfileAccessInfoForRole(currentName, "MASTER") or {})
      local sessionHostPreview = type(GetLootProfilePermissionPolicyRoleState) == "function" and GetLootProfilePermissionPolicyRoleState(currentName, "SESSION_HOST")
        or (type(GetLootProfileAccessInfoForRole) == "function" and GetLootProfileAccessInfoForRole(currentName, "SESSION_HOST") or {})
      local councilPreview = type(GetLootProfilePermissionPolicyRoleState) == "function" and GetLootProfilePermissionPolicyRoleState(currentName, "COUNCIL")
        or (type(GetLootProfileAccessInfoForRole) == "function" and GetLootProfileAccessInfoForRole(currentName, "COUNCIL") or {})
      local raiderPreview = type(GetLootProfilePermissionPolicyRoleState) == "function" and GetLootProfilePermissionPolicyRoleState(currentName, "RAIDER")
        or (type(GetLootProfileAccessInfoForRole) == "function" and GetLootProfileAccessInfoForRole(currentName, "RAIDER") or {})
      self.__lootProfilePermissionPolicyRowCount = #PermissionPolicyRowDefs

      if self.lootProfilePermissionPolicySummary then
        self.lootProfilePermissionPolicySummary:SetText(
          "Optional role overrides for this profile. Master permissions are fixed. OK * / X * marks fixed rights that cannot be changed."
        )
      end
      if self.lootProfilePermissionPolicyResetBtn then
        if access.canManageRights then
          self.lootProfilePermissionPolicyResetBtn:Show()
          if self.lootProfilePermissionPolicyResetBtn.Enable then
            self.lootProfilePermissionPolicyResetBtn:Enable()
          end
        else
          self.lootProfilePermissionPolicyResetBtn:Show()
          if self.lootProfilePermissionPolicyResetBtn.Disable then
            self.lootProfilePermissionPolicyResetBtn:Disable()
          end
        end
      end

      for index, rowDef in ipairs(PermissionPolicyRowDefs) do
        local row = self.lootProfilePermissionPolicyRows and self.lootProfilePermissionPolicyRows[index] or nil
        if row then
          row.__permissionKey = rowDef.key
          row:Show()
          row.__isPermissionSection = rowDef.section and true or false
          if row.__isPermissionSection then
            if row.SetBackdropColor then
              row:SetBackdropColor(0, 0, 0, 0)
            end
            if row.SetBackdropBorderColor then
              row:SetBackdropBorderColor(0, 0, 0, 0)
            end
            if row.labelText then
              row.labelText:SetText(tostring(rowDef.section or ""))
              row.labelText:SetTextColor(1.00, 0.82, 0.32, 1.00)
            end
            if row.masterCell then row.masterCell:Hide() end
            if row.sessionHostCell then row.sessionHostCell:Hide() end
            if row.councilCell then row.councilCell:Hide() end
            if row.raiderCell then row.raiderCell:Hide() end
          else
            if row.SetBackdropColor then
              row:SetBackdropColor(0.05, 0.05, 0.07, 0.98)
            end
            if row.labelText then
              row.labelText:SetText(tostring(rowDef.label or rowDef.key or ""))
              row.labelText:SetTextColor(0.92, 0.92, 0.96, 1.00)
            end
            if row.masterCell then
              row.masterCell:Show()
              SetPermissionPolicyCellState(row.masterCell, masterPreview[rowDef.key], false, false)
            end
            if row.sessionHostCell then
              local locked = IsPermissionPolicyLocked("SESSION_HOST", rowDef.key)
              local interactive = access.canManageRights and not locked
              row.sessionHostCell:Show()
              SetPermissionPolicyCellState(row.sessionHostCell, sessionHostPreview[rowDef.key], interactive, locked)
              row.sessionHostCell:SetScript("OnClick", nil)
              if locked and access.canManageRights then
                SetLockedPermissionPolicyFeedbackCell(self, row.sessionHostCell, rowDef.key)
              elseif interactive then
                row.sessionHostCell:SetScript("OnClick", function()
                if not access.canManageRights or type(SetLootProfilePermissionPolicyValue) ~= "function" then
                  return
                end
                local desiredEnabled = not (sessionHostPreview[rowDef.key] and true or false)
                local ok, result = SetLootProfilePermissionPolicyValue(currentName, "SESSION_HOST", rowDef.key, desiredEnabled)
                FinishPermissionPolicyUpdate(self, currentName, "SESSION_HOST", "Session Host", rowDef.label or rowDef.key, rowDef.key, desiredEnabled, ok, result, "Could not update the Session Host permission.")
                end)
              end
            end
            if row.councilCell then
              local locked = IsPermissionPolicyLocked("COUNCIL", rowDef.key)
              local interactive = access.canManageRights and not locked
              row.councilCell:Show()
              SetPermissionPolicyCellState(row.councilCell, councilPreview[rowDef.key], interactive, locked)
              row.councilCell:SetScript("OnClick", nil)
              if locked and access.canManageRights then
                SetLockedPermissionPolicyFeedbackCell(self, row.councilCell, rowDef.key)
              elseif interactive then
                row.councilCell:SetScript("OnClick", function()
                if not access.canManageRights or type(SetLootProfilePermissionPolicyValue) ~= "function" then
                  return
                end
                local desiredEnabled = not (councilPreview[rowDef.key] and true or false)
                local ok, result = SetLootProfilePermissionPolicyValue(currentName, "COUNCIL", rowDef.key, desiredEnabled)
                FinishPermissionPolicyUpdate(self, currentName, "COUNCIL", "Council", rowDef.label or rowDef.key, rowDef.key, desiredEnabled, ok, result, "Could not update the Council permission.")
                end)
              end
            end
            if row.raiderCell then
              local locked = IsPermissionPolicyLocked("RAIDER", rowDef.key)
              local interactive = access.canManageRights and not locked
              row.raiderCell:Show()
              SetPermissionPolicyCellState(row.raiderCell, raiderPreview[rowDef.key], interactive, locked)
              row.raiderCell:SetScript("OnClick", nil)
              if locked and access.canManageRights then
                SetLockedPermissionPolicyFeedbackCell(self, row.raiderCell, rowDef.key)
              elseif interactive then
                row.raiderCell:SetScript("OnClick", function()
                  if not access.canManageRights or type(SetLootProfilePermissionPolicyValue) ~= "function" then
                    return
                  end
                  local desiredEnabled = not (raiderPreview[rowDef.key] and true or false)
                  local ok, result = SetLootProfilePermissionPolicyValue(currentName, "RAIDER", rowDef.key, desiredEnabled)
                  FinishPermissionPolicyUpdate(self, currentName, "RAIDER", "Raider", rowDef.label or rowDef.key, rowDef.key, desiredEnabled, ok, result, "Could not update the Raider permission.")
                end)
              end
            end
          end
        end
      end
      for index = (#PermissionPolicyRowDefs + 1), #(self.lootProfilePermissionPolicyRows or {}) do
        local row = self.lootProfilePermissionPolicyRows[index]
        if row then
          row:Hide()
        end
      end
    end
    do
      local masterDisplay = ResolveProfileMemberDisplay(profile, roleBuckets.master)
      local masterIconData = ResolveProfileIconData(masterDisplay)
      local masterR, masterG, masterB = GetProfileClassColor(masterDisplay.classFile)
      local masterMetaParts = {}
      if TrimText(masterDisplay.specName) ~= "" then
        masterMetaParts[#masterMetaParts + 1] = masterDisplay.specName
      end
      if TrimText(masterDisplay.className) ~= "" then
        masterMetaParts[#masterMetaParts + 1] = masterDisplay.className
      end
      if self.lootProfileMasterCardIcon then
        ApplyProfileIcon(self.lootProfileMasterCardIcon, masterIconData)
      end
      if self.lootProfileMasterCardValue then
        self.lootProfileMasterCardValue:SetText(roleBuckets.master ~= "" and tostring(roleBuckets.master) or "Unassigned")
        self.lootProfileMasterCardValue:SetTextColor(masterR, masterG, masterB, 1)
      end
      if self.lootProfileMasterCardMeta then
        self.lootProfileMasterCardMeta:SetText((#masterMetaParts > 0) and table.concat(masterMetaParts, " | ") or "Full profile control")
      end
    end
    if self.lootProfileMasterCardValue then
      if roleBuckets.master == "" then
        self.lootProfileMasterCardValue:SetTextColor(0.82, 0.82, 0.86, 1)
      end
    end
    if self.lootProfileMasterCardTitle then
      self.lootProfileMasterCardTitle:SetText("Profile Master")
    end
    if self.lootProfileCouncilCardValue then
      self.lootProfileCouncilCardValue:SetText(string.format("%d member(s)", #roleBuckets.council))
    end
    if self.lootProfileCouncilCardMeta then
      self.lootProfileCouncilCardMeta:SetText(BuildProfileClassSummary(profile, roleBuckets.council))
    end
    if self.lootProfileRaiderToggleBtn then
      if self.lootProfileRaiderToggleBtn.arrowText then
        self.lootProfileRaiderToggleBtn.arrowText:SetText(self.__lootProfileRaidersCollapsed and ">" or "v")
      end
      if self.lootProfileRaiderToggleBtn.labelText then
        self.lootProfileRaiderToggleBtn.labelText:SetText(string.format("Raiders (%d)", #roleBuckets.raiders))
      end
    end
    if self.lootProfileRaiderSummary then
      self.lootProfileRaiderSummary:SetText(BuildProfileClassSummary(profile, roleBuckets.raiders))
    end
    self.__lootProfileCouncilRowCount = #roleBuckets.council
    self.__lootProfileRaiderRowCount = #roleBuckets.raiders
    self.__lootProfileCouncilRowsHeight = RefreshProfileMemberRows("lootProfileCouncilRows", self.lootProfileCouncilRowsFrame, roleBuckets.council, profile, "COUNCIL")
    self.__lootProfileRaiderRowsHeight = RefreshProfileMemberRows("lootProfileRaiderRows", self.lootProfileRaiderRowsFrame, roleBuckets.raiders, profile, "RAIDER")

    local selectedRoleTarget = TrimText(self.__lootProfileRoleTarget)
    local selectedRoleEntry = nil
    for _, entry in ipairs(roleEntries) do
      if not entry.isMaster and string.lower(tostring(entry.character or "")) == string.lower(selectedRoleTarget) then
        selectedRoleEntry = entry
        break
      end
    end
    self.__lootProfileRoleTarget = selectedRoleEntry and selectedRoleEntry.character or nil
    self.__lootProfileRoleValue = string.upper(TrimText((selectedRoleEntry and selectedRoleEntry.role) or self.__lootProfileRoleValue or "RAIDER"))
    if self.__lootProfileRoleValue ~= "COUNCIL" then
      self.__lootProfileRoleValue = "RAIDER"
    end

    if self.lootProfileRoleTargetDropdown then
      if self.lootProfileRoleTargetDropdown.__lidcouncilCustomDropdown then
        if selectedRoleEntry then
          self.lootProfileRoleTargetDropdown:SetSelectedValue(selectedRoleEntry.character)
          self.lootProfileRoleTargetDropdown:SetText(BuildProfileMemberDropdownText(profile, selectedRoleEntry.character, selectedRoleEntry.role))
        else
          self.lootProfileRoleTargetDropdown:SetSelectedValue(nil)
          self.lootProfileRoleTargetDropdown:SetText("(select character)")
        end
      elseif self.lootProfileRoleTargetDropdown.SetText then
        self.lootProfileRoleTargetDropdown:SetText(selectedRoleEntry and tostring(selectedRoleEntry.character or "") or "")
      end
      if canManageRights then
        self.lootProfileRoleTargetDropdown:Show()
        if self.lootProfileRoleTargetDropdown.Enable then
          self.lootProfileRoleTargetDropdown:Enable()
        end
      else
        self.lootProfileRoleTargetDropdown:Hide()
        if self.lootProfileRoleTargetDropdown.Disable then
          self.lootProfileRoleTargetDropdown:Disable()
        end
      end
    end

    if self.lootProfileRoleDropdown then
      if self.lootProfileRoleDropdown.__lidcouncilCustomDropdown then
        self.lootProfileRoleDropdown:SetSelectedValue(self.__lootProfileRoleValue)
        self.lootProfileRoleDropdown:SetText(FormatLootProfileRoleLabel(self.__lootProfileRoleValue))
      elseif self.lootProfileRoleDropdown.SetText then
        self.lootProfileRoleDropdown:SetText(FormatLootProfileRoleLabel(self.__lootProfileRoleValue))
      end
      if canManageRights and selectedRoleEntry then
        self.lootProfileRoleDropdown:Show()
        if self.lootProfileRoleDropdown.Enable then
          self.lootProfileRoleDropdown:Enable()
        end
      else
        self.lootProfileRoleDropdown:Hide()
        if self.lootProfileRoleDropdown.Enable then
          self.lootProfileRoleDropdown:Disable()
        end
      end
    end

    if self.lootProfileApplyRoleBtn and self.lootProfileApplyRoleBtn.Enable then
      if canManageRights and selectedRoleEntry then
        self.lootProfileApplyRoleBtn:Show()
        self.lootProfileApplyRoleBtn:Enable()
      else
        self.lootProfileApplyRoleBtn:Hide()
        self.lootProfileApplyRoleBtn:Disable()
      end
    end
    if self.lootProfileTransferMasterBtn then
      ApplyProfileActionButtonStyle(self.lootProfileTransferMasterBtn, "transfer")
      if self.lootProfileTransferMasterBtn.label then
        self.lootProfileTransferMasterBtn.label:SetText("Transfer Master")
      end
      if access.canTransferMaster then
        self.lootProfileTransferMasterBtn:Show()
        if self.lootProfileTransferMasterBtn.Enable then
          if selectedRoleEntry then
            self.lootProfileTransferMasterBtn:Enable()
          else
            self.lootProfileTransferMasterBtn:Disable()
          end
        end
      else
        self.lootProfileTransferMasterBtn:Hide()
        if self.lootProfileTransferMasterBtn.Enable then
          self.lootProfileTransferMasterBtn:Disable()
        end
      end
      ApplyProfileActionButtonStyle(self.lootProfileTransferMasterBtn, "transfer")
    end

    if self.lootProfileRoleSelectionCard then
      local selectedDisplay = ResolveProfileMemberDisplay(profile, selectedRoleEntry and selectedRoleEntry.character or "")
      local selectedIconData = ResolveProfileIconData(selectedDisplay)
      local nameR, nameG, nameB = GetProfileClassColor(selectedDisplay.classFile)
      local selectedMetaParts = {}
      if TrimText(selectedDisplay.specName) ~= "" then
        selectedMetaParts[#selectedMetaParts + 1] = selectedDisplay.specName
      end
      if TrimText(selectedDisplay.className) ~= "" then
        selectedMetaParts[#selectedMetaParts + 1] = selectedDisplay.className
      end
      if self.lootProfileRoleSelectionIcon then
        ApplyProfileIcon(self.lootProfileRoleSelectionIcon, selectedRoleEntry and selectedIconData or nil)
      end
      if self.lootProfileRoleSelectionName then
        self.lootProfileRoleSelectionName:SetText(selectedRoleEntry and tostring(selectedRoleEntry.character or "") or "No member selected")
        if selectedRoleEntry then
          self.lootProfileRoleSelectionName:SetTextColor(nameR, nameG, nameB, 1)
        else
          self.lootProfileRoleSelectionName:SetTextColor(0.82, 0.82, 0.86, 1)
        end
      end
      if self.lootProfileRoleSelectionMeta then
        self.lootProfileRoleSelectionMeta:SetText(selectedRoleEntry and ((#selectedMetaParts > 0 and table.concat(selectedMetaParts, " | ")) or "Class data not known yet.") or "Click a council member or raider above to manage access.")
      end
      if self.lootProfileRoleSelectionRole then
        self.lootProfileRoleSelectionRole:SetText(selectedRoleEntry and ("Current Role: " .. FormatLootProfileRoleLabel(selectedRoleEntry.role)) or "")
      end
      if self.lootProfileRoleSelectionHint then
        self.lootProfileRoleSelectionHint:SetText(selectedRoleEntry and "Choose a new role below, then click Apply Role." or "")
      end
    end

    local seasonContext, seasonLootItems = CollectSeasonLootEntries(profile)
    local selectedRaidEntry = FindRaidEntryByProfile(profile)
    local selectedRaidInSeason = nil
    if type(selectedRaidEntry) == "table" and not selectedRaidEntry.unresolved and tonumber(selectedRaidEntry.instanceID) and tonumber(selectedRaidEntry.tier) == tonumber(seasonContext and seasonContext.tier) then
      selectedRaidInSeason = selectedRaidEntry
    end
    local seasonName = tostring(seasonContext and seasonContext.tierName or "Current Season")
    local seasonRaidNamesText = BuildSeasonRaidNamesText(seasonContext)
    local pointMode = ResolvePointMode(profile)
    local rollTemplate = ResolveRollTemplate(profile)
    self.__lootPointMode = pointMode
    local rollCount = profile.settings and profile.settings.rollOptions and #profile.settings.rollOptions or 0
    local sessionCount = profile.sessions and #profile.sessions or 0
    local awardedItemCount = 0
    local participantSeen = {}
    local participantCount = 0
    local raidPreviewTexture = selectedRaidInSeason and ResolveRaidPreviewTexture(selectedRaidInSeason.instanceID) or nil
    for _, ledgerRow in pairs(profile.lootLedger or {}) do
      if type(ledgerRow) == "table" and type(ledgerRow.items) == "table" then
        awardedItemCount = awardedItemCount + #ledgerRow.items
      end
    end
    for participantKey in pairs(profile.lootLedger or {}) do
      participantSeen[tostring(participantKey)] = true
    end
    for memberKey in pairs(profile.lootLedgerMeta or {}) do
      participantSeen[tostring(memberKey)] = true
    end
    for _, roleEntry in ipairs(type(roleEntries) == "table" and roleEntries or {}) do
      local characterKey = TrimText(type(roleEntry) == "table" and roleEntry.character or "")
      if characterKey ~= "" then
        participantSeen[characterKey] = true
      end
    end
    for _ in pairs(participantSeen) do
      participantCount = participantCount + 1
    end
    if self.lootProfileSummary then
      local root = type(RootDB) == "function" and RootDB() or nil
      local showDeveloperDetails = type(root) == "table" and type(root.ui) == "table" and root.ui.showInternalProfileId == true
      local seasonSummaryName = tostring(seasonName) .. ((seasonContext and seasonContext.frozen == true) and " (Profile Season)" or "")
      local summaryLines = {
        "Season: " .. seasonSummaryName,
        "Point Mode: " .. tostring(pointMode == "CUSTOM" and "Custom" or "LidTable"),
        "Roll Template: " .. tostring(GetRollTemplateText(rollTemplate)),
      }
      if showDeveloperDetails then
        summaryLines[#summaryLines + 1] = BuildLootProfileIdentitySummary(identity, true)
      end
      self.lootProfileSummary:SetText(table.concat(summaryLines, "\n"))
    end

    if self.lootProfileStatCards then
      if self.lootProfileStatCards.sessions and self.lootProfileStatCards.sessions.value then
        self.lootProfileStatCards.sessions.value:SetText(tostring(sessionCount))
      end
      if self.lootProfileStatCards.items and self.lootProfileStatCards.items.value then
        self.lootProfileStatCards.items.value:SetText(tostring(awardedItemCount))
      end
      if self.lootProfileStatCards.participants and self.lootProfileStatCards.participants.value then
        self.lootProfileStatCards.participants.value:SetText(tostring(participantCount))
      end
      if self.lootProfileStatCards.rolls and self.lootProfileStatCards.rolls.value then
        self.lootProfileStatCards.rolls.value:SetText(tostring(rollCount))
      end
    end

    if self.__lootPointItemSeasonTier ~= tonumber(seasonContext and seasonContext.tier) then
      self.__lootPointItemSeasonTier = tonumber(seasonContext and seasonContext.tier)
      ClearItemRuleSelection()
    end

    owner.__lootRaidSelectedTier = tonumber(seasonContext and seasonContext.tier)
    local hasFrozenSeason = seasonContext and seasonContext.frozen == true

    if self.lootRaidDropdown then
      if selectedRaidInSeason then
        SetDropdownValue(self.lootRaidDropdown, tonumber(selectedRaidInSeason.instanceID), tostring(selectedRaidInSeason.name or "?"))
      else
        local selectText = hasFrozenSeason and "(select profile-season raid)" or "(select current-season raid)"
        local emptyText = hasFrozenSeason and "(no profile-season raids)" or "(no current-season raids)"
        SetDropdownValue(self.lootRaidDropdown, nil, (#(seasonContext and seasonContext.raids or {}) > 0) and selectText or emptyText)
      end
    end
    if self.lootRaidSeasonDropdown then
      SetDropdownValue(self.lootRaidSeasonDropdown, tonumber(seasonContext and seasonContext.tier), seasonName)
      if self.lootRaidSeasonDropdown.SetEnabled then
        self.lootRaidSeasonDropdown:SetEnabled(not hasFrozenSeason)
      end
    end
    if self.lootPointModeDropdown then
      local pointModeText = pointMode == "CUSTOM" and "Custom" or "LidTable"
      SetDropdownValue(self.lootPointModeDropdown, pointMode, pointModeText)
    end
    if self.lootRollTemplateDropdown then
      SetDropdownValue(self.lootRollTemplateDropdown, rollTemplate, GetRollTemplateText(rollTemplate))
    end

    if self.lootPointItemDropdown then
      local selectedItemEntry = FindSeasonLootEntry(self.__lootSelectedRuleItemID, profile)
      if selectedItemEntry then
        owner.__lootSelectedRuleItemID = tonumber(selectedItemEntry.itemID)
        owner.__lootSelectedRuleItemName = selectedItemEntry.name
        owner.__lootSelectedRuleItemLink = selectedItemEntry.link
        owner.__lootSelectedRuleItemLevel = tonumber(selectedItemEntry.itemLevel)
        SetDropdownValue(self.lootPointItemDropdown, selectedItemEntry.itemID, string.format("%s | %s", FormatRaidLootItemLabel(selectedItemEntry), tostring(selectedItemEntry.sourceRaidName or "?")))
      else
        local itemText = hasFrozenSeason and "(select profile-season loot item)" or "(select current-season loot item)"
        SetDropdownValue(self.lootPointItemDropdown, nil, #seasonLootItems > 0 and itemText or "(no season loot items found)")
      end
    end

    if self.lootRaidHint then
      local seasonLabel = hasFrozenSeason and "Profile season" or "Current season"
      self.lootRaidHint:SetText(string.format(
        "%s: %s\nIncludes: %s\nSelected raid preview: %s",
        seasonLabel,
        seasonName,
        seasonRaidNamesText,
        selectedRaidInSeason and tostring(selectedRaidInSeason.name or "?") or "None"
      ))
    end
    if self.lootRaidPreviewTexture then
      if raidPreviewTexture then
        self.lootRaidPreviewTexture:SetTexture(raidPreviewTexture)
        self.lootRaidPreviewTexture:SetVertexColor(1, 1, 1, 1)
        self.lootRaidPreviewTexture:SetTexCoord(0.05, 0.80, 0.04, 0.64)
        self.lootRaidPreviewTexture:Show()
      else
        self.lootRaidPreviewTexture:SetTexture(nil)
        self.lootRaidPreviewTexture:Hide()
      end
    end
    if self.lootRaidPreviewLabel then
      self.lootRaidPreviewLabel:SetText("Selected Raid Thumbnail")
    end
    if self.lootRaidPreviewMeta then
      self.lootRaidPreviewMeta:SetText(selectedRaidInSeason and tostring(selectedRaidInSeason.name or "?") or "No raid thumbnail selected.")
    end
    if self.lootPointsHint then
      self.lootPointsHint:SetText("")
    end

    if self.lootProfileHeroRaidPreviewTitle then
      self.lootProfileHeroRaidPreviewTitle:Hide()
    end
    if self.lootProfileHeroRaidPreviewLabel then
      self.lootProfileHeroRaidPreviewLabel:SetText("")
      self.lootProfileHeroRaidPreviewLabel:Hide()
    end
    if self.lootProfileHeroRaidPreviewFrame then
      if self.lootProfileHeroRaidPreviewFrame.SetBackdropColor then
        self.lootProfileHeroRaidPreviewFrame:SetBackdropColor(0, 0, 0, 0)
      end
      if self.lootProfileHeroRaidPreviewFrame.SetBackdropBorderColor then
        self.lootProfileHeroRaidPreviewFrame:SetBackdropBorderColor(0, 0, 0, 0)
      end
    end
    if self.lootProfileHeroRaidPreviewTexture then
      if raidPreviewTexture then
        self.lootProfileHeroRaidPreviewTexture:SetTexture(raidPreviewTexture)
        self.lootProfileHeroRaidPreviewTexture:SetVertexColor(1, 1, 1, 1)
        self.lootProfileHeroRaidPreviewTexture:SetTexCoord(0.05, 0.80, 0.04, 0.64)
        self.lootProfileHeroRaidPreviewTexture:Show()
      else
        self.lootProfileHeroRaidPreviewTexture:SetTexture(nil)
        self.lootProfileHeroRaidPreviewTexture:Hide()
      end
    end
    if self.lootProfileHeroRaidPreviewEmpty then
      if raidPreviewTexture then
        self.lootProfileHeroRaidPreviewEmpty:Hide()
      else
        self.lootProfileHeroRaidPreviewEmpty:SetText("Click here to choose a profile-season raid.")
        self.lootProfileHeroRaidPreviewEmpty:Show()
      end
    end

    local function SetControlInteractive(control, allow)
      if not control then
        return
      end
      if control.Enable and control.Disable then
        if allow then
          control:Enable()
        else
          control:Disable()
        end
      elseif control.SetEnabled then
        control:SetEnabled(allow and true or false)
      end
      if control.SetAlpha then
        control:SetAlpha(allow and 1.00 or 0.52)
      end
    end

    SetControlInteractive(self.lootRollOptionEdit, access.canEditRollSettings)
    SetControlInteractive(self.lootAddRollOptionBtn, access.canEditRollSettings)
    SetControlInteractive(self.lootRemoveRollOptionBtn, access.canEditRollSettings)
    SetControlInteractive(self.lootTestRollPopupBtn, access.canEditRollSettings)
    SetControlInteractive(self.lootPreviewHostBoardBtn, access.canEditRollSettings)
    SetControlInteractive(self.lootRollTemplateDropdown, access.canEditRollSettings)
    SetControlInteractive(self.lootRollExportBtn, access.canEditRollSettings)
    SetControlInteractive(self.lootRollImportStringBtn, access.canEditRollSettings)
    SetControlInteractive(self.lootRollImportProfileDropdown, access.canEditRollSettings)
    SetControlInteractive(self.lootProfileHeroRaidPreviewButton, access.canEditRaidSettings)
    SetControlInteractive(self.lootRaidDropdown, access.canEditRaidSettings)
    SetControlInteractive(self.lootSaveRaidBtn, access.canEditRaidSettings)
    SetControlInteractive(self.lootPointModeDropdown, access.canEditPointSettings)
    SetControlInteractive(self.lootPointItemLevelEdit, access.canEditPointSettings)
    SetControlInteractive(self.lootPointItemDropdown, access.canEditPointSettings)
    SetControlInteractive(self.lootPointValueEdit, access.canEditPointSettings)
    SetControlInteractive(self.lootAddPointRuleBtn, access.canEditPointSettings)
    SetControlInteractive(self.lootAddItemPointRuleBtn, access.canEditPointSettings)
    SetControlInteractive(self.lootRemovePointRuleBtn, access.canEditPointSettings)
    SetControlInteractive(self.lootPointExportBtn, access.canEditPointSettings)
    SetControlInteractive(self.lootPointImportStringBtn, access.canEditPointSettings)
    SetControlInteractive(self.lootPointImportProfileDropdown, access.canEditPointSettings)

    RefreshRollOptionRows(profile)
    RefreshLidTableRows(profile)
    local rollOptionCount = tonumber(self.__lootRollOptionRowCount) or 0
    for _, row in ipairs(self.lootRollOptionRows or {}) do
      if row and row:IsShown() then
        local optionIndex = tonumber(row.__optionIndex) or 0
        SetControlInteractive(row.nameEdit, access.canEditRollSettings)
        SetControlInteractive(row.moveUpBtn, access.canEditRollSettings and optionIndex > 1)
        SetControlInteractive(row.moveDownBtn, access.canEditRollSettings and optionIndex < rollOptionCount)
        SetControlInteractive(row.iconDropdown, access.canEditRollSettings)
        SetControlInteractive(row.pointBehaviorDropdown, access.canEditRollSettings)
        SetControlInteractive(row.popupSectionDropdown, access.canEditRollSettings)
        SetControlInteractive(row.colorButton, access.canEditRollSettings)
      end
    end
    for _, row in ipairs(self.lootLidTableRows or {}) do
      SetControlInteractive(row and row.pointsEdit, access.canEditPointSettings)
      SetControlInteractive(row and row.itemLevelEdit, access.canEditPointSettings)
      SetControlInteractive(row and row.setPieceEdit, access.canEditPointSettings)
      SetControlInteractive(row and row.offSpecEdit, access.canEditPointSettings)
      SetControlInteractive(row and row.transmogEdit, access.canEditPointSettings)
      SetControlInteractive(row and row.disenchantEdit, access.canEditPointSettings)
    end
    if self.lootRollOptionsText then
      self.lootRollOptionsText:SetText(BuildRollOptionsText(profile))
    end
    if self.lootPointRulesText then
      if pointMode == "CUSTOM" then
        self.lootPointRulesText:SetText(BuildPointRulesText(profile))
      else
        self.lootPointRulesText:SetText(BuildLidTableSummaryText(profile))
      end
    end
    LayoutProfileContent(self)
    if self.currentPage == "Profiles" and self.UpdateScrollLayout then
      self:UpdateScrollLayout()
    end
  end

  return {
    RefreshProfilePage = RefreshProfilePage,
  }
end
