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

local shared = INTERNAL_API.LIDCOUNCIL_LootEditorShared_Impl
if type(shared) ~= "table" then
  error("LidCouncil missing loot editor shared helpers.")
end

local RequireApi = shared.RequireApi
local BindMouseWheelScroll = shared.BindMouseWheelScroll
local RootDB = shared.RootDB
local ApplyFrameSkin = shared.ApplyFrameSkin
local MakeYellowSubHeader = shared.MakeYellowSubHeader
local GetCharacterKey = shared.GetCharacterKey
local GetLootProfile = shared.GetLootProfile
local GetEnabledLootProfileName = shared.GetEnabledLootProfileName or RequireApi("LIDCOUNCIL_GetEnabledLootProfileName", _G.LIDCOUNCIL_GetEnabledLootProfileName)
local GetPrimaryLootProfileName = shared.GetPrimaryLootProfileName
local GetLootProfileNames = shared.GetLootProfileNames
local GetVisibleLootProfileNames = shared.GetVisibleLootProfileNames or shared.GetLootProfileNames
local GetLootProfileRoleEntries = shared.GetLootProfileRoleEntries
local GetLootProfileAccessInfo = shared.GetLootProfileAccessInfo
local GetLootProfileAccessInfoForRole = shared.GetLootProfileAccessInfoForRole
local GetLootProfilePermissionPolicyRoleState = shared.GetLootProfilePermissionPolicyRoleState
local SetCurrentLootProfile = shared.SetCurrentLootProfile
local CreateLootProfile = shared.CreateLootProfile
local DeleteLootProfile = shared.DeleteLootProfile
local CopyLootProfile = shared.CopyLootProfile
local SetLootProfileMemberRole = shared.SetLootProfileMemberRole
local SetLootProfilePermissionPolicyValue = shared.SetLootProfilePermissionPolicyValue
local ResetLootProfilePermissionPolicy = shared.ResetLootProfilePermissionPolicy
local TransferLootProfileMaster = shared.TransferLootProfileMaster
local SetLootProfileEnabled = shared.SetLootProfileEnabled
local SetLootProfileRaid = shared.SetLootProfileRaid
local ApplyLootRollTemplate = shared.ApplyLootRollTemplate
local AddLootRollOption = shared.AddLootRollOption
local UpdateLootRollOption = shared.UpdateLootRollOption
local MoveLootRollOption = shared.MoveLootRollOption
local RemoveLootRollOption = shared.RemoveLootRollOption
local UpdateLootPointMode = shared.UpdateLootPointMode
local UpdateLootLidTableRow = shared.UpdateLootLidTableRow
local AddLootPointRule = shared.AddLootPointRule
local RemoveLootPointRule = shared.RemoveLootPointRule
local StartLootSession = shared.StartLootSession
local StopLootSession = shared.StopLootSession
local GetActiveLootSession = shared.GetActiveLootSession
local AddLootLedgerEntry = shared.AddLootLedgerEntry
local GetLootLedgerCharacters = shared.GetLootLedgerCharacters
local ResolveOptionalApiFunction = shared.ResolveOptionalApiFunction
local CreateCustomDropdownControl = shared.CreateCustomDropdownControl
local TrimText = shared.TrimText
local FormatDateTime = shared.FormatDateTime
local FormatDuration = shared.FormatDuration
local CreateSimpleEditBox = shared.CreateSimpleEditBox
local SetListButtonSelected = shared.SetListButtonSelected
local SetTextListButtonTextColor = shared.SetTextListButtonTextColor
local EnsureTextListButtons = shared.EnsureTextListButtons
local CreateSectionShell = shared.CreateSectionShell
local ClampLayoutValue = shared.ClampLayoutValue
local GetResponsiveSectionLayout = shared.GetResponsiveSectionLayout
local SetControlWidth = shared.SetControlWidth
local GetFontStringWidth = shared.GetFontStringWidth
local CreateSectionDivider = shared.CreateSectionDivider
local FlowLayoutControls = shared.FlowLayoutControls
local LayoutRollOptionRow = shared.LayoutRollOptionRow
local LayoutLidTableEditorRow = shared.LayoutLidTableEditorRow
local BuildRollOptionsText = shared.BuildRollOptionsText
local ROLL_TEMPLATE_CHOICES = shared.ROLL_TEMPLATE_CHOICES
local DEFAULT_ROLL_OPTION_ICON_CHOICES = shared.DEFAULT_ROLL_OPTION_ICON_CHOICES
local ResolveTextureAsset = shared.ResolveTextureAsset
local ResolveDefaultRollOptionIcon = shared.ResolveDefaultRollOptionIcon
local ResolveRollOptionIcon = shared.ResolveRollOptionIcon
local GetRollOptionIconLabel = shared.GetRollOptionIconLabel
local ResolveRollTemplate = shared.ResolveRollTemplate
local GetRollTemplateText = shared.GetRollTemplateText
local EnsureRollOptionRows = shared.EnsureRollOptionRows
local EnsureLidTableEditorRows = shared.EnsureLidTableEditorRows
local ExtractItemID = shared.ExtractItemID
local ExtractItemLinkName = shared.ExtractItemLinkName
local FormatPointRuleItemLabel = shared.FormatPointRuleItemLabel
local FormatRaidLootItemLabel = shared.FormatRaidLootItemLabel
local LOOT_ITEM_MENU_PAGE_SIZE = shared.LOOT_ITEM_MENU_PAGE_SIZE
local NormalizeInstanceTuple = shared.NormalizeInstanceTuple
local NormalizeEncounterTuple = shared.NormalizeEncounterTuple
local NormalizeLootInfo = shared.NormalizeLootInfo
local EnsureEncounterJournalLoaded = shared.EnsureEncounterJournalLoaded
local CollectRaidEntries = shared.CollectRaidEntries
local CollectRaidLootEntries = shared.CollectRaidLootEntries
local FindRaidEntryByProfile = shared.FindRaidEntryByProfile
local FindRaidLootEntry = shared.FindRaidLootEntry
local EnsureLootLiveBoardMode = shared.EnsureLootLiveBoardMode
local ClampMenuPage = shared.ClampMenuPage
local GetSelectedValuePage = shared.GetSelectedValuePage
local EnsureLootProfileGroups = shared.EnsureLootProfileGroups
local FindLootProfileGroupIndex = shared.FindLootProfileGroupIndex
local RemoveLootProfileFromGroups = shared.RemoveLootProfileFromGroups
local ToggleLootProfileGroupCollapsed = shared.ToggleLootProfileGroupCollapsed
local GetLootProfileGroupName = shared.GetLootProfileGroupName
local BuildLootProfileNavRows = shared.BuildLootProfileNavRows
local BuildPointRulesText = shared.BuildPointRulesText
local ResolvePointMode = shared.ResolvePointMode
local GetLidTableRows = shared.GetLidTableRows
local BuildLidTableSummaryText = shared.BuildLidTableSummaryText
local POINT_MODE_CHOICES = shared.POINT_MODE_CHOICES
local GetSelectedProfileName = shared.GetSelectedProfileName

local function CreateRollColumnHeader(parent, text)
  local header = parent:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
  header:SetJustifyH("LEFT")
  header:SetText(tostring(text or ""))
  return header
end

local LOOT_PROFILE_PERMISSION_POLICY_ROWS = {
  { section = "Profile" },
  { key = "canManageRoles", label = "View Council Settings" },
  { key = "canManageRights", label = "Manage Rights" },
  { key = "canEditRaidSettings", label = "Edit Raid Settings" },
  { key = "canEditRollSettings", label = "Edit Roll Settings" },
  { key = "canEditPointSettings", label = "Edit Point Settings" },
  { key = "canDeleteProfile", label = "Delete Local Profile Copy" },
  { section = "Session" },
  { key = "canStartSession", label = "Start Session" },
  { key = "canManageSession", label = "Manage / Stop Session" },
  { key = "canOpenLiveBoard", label = "Open Live Board" },
  { key = "canVote", label = "Use Voting" },
  { key = "canAssignLoot", label = "Assign Loot" },
  { section = "Loot List" },
  { key = "canEditLootList", label = "Edit Loot List" },
  { key = "canEditManualPoints", label = "Edit Manual Points" },
  { key = "canDeleteLootListCharacter", label = "Delete Loot List Character" },
  { key = "canEditMainAlt", label = "Edit Main / Alt" },
  { key = "canEditNotes", label = "Edit Notes" },
}

local function CreatePermissionPolicyCell(parent, interactive)
  local cell = CreateFrame("Button", nil, parent, "BackdropTemplate")
  ApplyFrameSkin(cell)
  cell:SetSize(68, 20)
  cell.label = cell:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall")
  cell.label:SetPoint("CENTER", 0, 0)
  cell.__interactive = interactive and true or false
  if not cell.__interactive then
    cell:EnableMouse(false)
  end
  cell:SetScript("OnEnter", function(self)
    if self.__interactive and self.SetBackdropColor and self.__hoverBackdrop then
      self:SetBackdropColor(self.__hoverBackdrop[1], self.__hoverBackdrop[2], self.__hoverBackdrop[3], self.__hoverBackdrop[4])
    end
  end)
  cell:SetScript("OnLeave", function(self)
    if self.SetBackdropColor and self.__normalBackdrop then
      self:SetBackdropColor(self.__normalBackdrop[1], self.__normalBackdrop[2], self.__normalBackdrop[3], self.__normalBackdrop[4])
    end
  end)
  return cell
end

local function SetPermissionPolicyCellState(cell, allowed, interactive, mirrored)
  if not cell or not cell.label then
    return
  end

  cell.__interactive = interactive and true or false
  local isAllowed = allowed and true or false
  local text = isAllowed and "OK" or "X"
  if mirrored and not interactive then
    text = text .. " *"
  end
  cell.label:SetText(text)

  local normalBackdrop
  local textColor
  if not interactive then
    normalBackdrop = { 0.13, 0.13, 0.16, 0.94 }
    textColor = { 0.76, 0.76, 0.80, 1.00 }
  elseif isAllowed then
    normalBackdrop = { 0.08, 0.18, 0.12, 0.98 }
    textColor = { 0.58, 0.96, 0.70, 1.00 }
  else
    normalBackdrop = { 0.22, 0.09, 0.10, 0.98 }
    textColor = { 1.00, 0.58, 0.58, 1.00 }
  end

  cell.__normalBackdrop = normalBackdrop
  cell.__hoverBackdrop = interactive and {
    math.min(1, normalBackdrop[1] + 0.04),
    math.min(1, normalBackdrop[2] + 0.04),
    math.min(1, normalBackdrop[3] + 0.04),
    normalBackdrop[4],
  } or normalBackdrop

  if cell.SetBackdropColor then
    cell:SetBackdropColor(normalBackdrop[1], normalBackdrop[2], normalBackdrop[3], normalBackdrop[4])
  end
  cell.label:SetTextColor(textColor[1], textColor[2], textColor[3], textColor[4])

  if interactive then
    cell:EnableMouse(true)
    if cell.Enable then
      cell:Enable()
    end
  else
    cell:EnableMouse(false)
    if cell.Disable then
      cell:Disable()
    end
  end
end

local function EnsurePermissionPolicyRows(editor, parent)
  editor.lootProfilePermissionPolicyRows = editor.lootProfilePermissionPolicyRows or {}
  while #editor.lootProfilePermissionPolicyRows < #LOOT_PROFILE_PERMISSION_POLICY_ROWS do
    local row = CreateFrame("Frame", nil, parent, "BackdropTemplate")
    ApplyFrameSkin(row)
    if row.SetBackdropColor then
      row:SetBackdropColor(0.05, 0.05, 0.07, 0.98)
    end
    row:SetHeight(24)
    row.labelText = row:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall")
    row.labelText:SetJustifyH("LEFT")
    row.masterCell = CreatePermissionPolicyCell(row, false)
    row.sessionHostCell = CreatePermissionPolicyCell(row, false)
    row.councilCell = CreatePermissionPolicyCell(row, true)
    row.raiderCell = CreatePermissionPolicyCell(row, true)
    editor.lootProfilePermissionPolicyRows[#editor.lootProfilePermissionPolicyRows + 1] = row
  end
  return editor.lootProfilePermissionPolicyRows
end

local FormatLootProfileRoleLabel
local BuildLootProfileRoleListText
local BuildLootProfileRoleBuckets
local GetProfileClassColor
local ResolveProfileMemberDisplay
local ResolveProfileIconData
local ApplyProfileIcon
local BuildProfileClassSummary
local BuildProfileMemberDropdownText
local ResolveRaidPreviewTexture

local CreateLootProfileDisplayHelpers = INTERNAL_API.LIDCOUNCIL_CreateLootProfileDisplayHelpers_Impl
if type(CreateLootProfileDisplayHelpers) ~= "function" then
  error("LidCouncil missing loot profiles display helpers.")
end

local lootProfileDisplayHelpers = CreateLootProfileDisplayHelpers({
  TrimText = TrimText,
})

FormatLootProfileRoleLabel = lootProfileDisplayHelpers.FormatLootProfileRoleLabel
BuildLootProfileRoleListText = lootProfileDisplayHelpers.BuildLootProfileRoleListText
BuildLootProfileRoleBuckets = lootProfileDisplayHelpers.BuildLootProfileRoleBuckets
GetProfileClassColor = lootProfileDisplayHelpers.GetProfileClassColor
ResolveProfileMemberDisplay = lootProfileDisplayHelpers.ResolveProfileMemberDisplay
ResolveProfileIconData = lootProfileDisplayHelpers.ResolveProfileIconData
ApplyProfileIcon = lootProfileDisplayHelpers.ApplyProfileIcon
BuildProfileClassSummary = lootProfileDisplayHelpers.BuildProfileClassSummary
BuildProfileMemberDropdownText = lootProfileDisplayHelpers.BuildProfileMemberDropdownText
ResolveRaidPreviewTexture = lootProfileDisplayHelpers.ResolveRaidPreviewTexture

local CreateLootProfileLayoutHelpers = INTERNAL_API.LIDCOUNCIL_CreateLootProfileLayoutHelpers_Impl
if type(CreateLootProfileLayoutHelpers) ~= "function" then
  error("LidCouncil missing loot profiles layout helpers.")
end

local CreateLootProfileRefreshHelpers = INTERNAL_API.LIDCOUNCIL_CreateLootProfileRefreshHelpers_Impl
if type(CreateLootProfileRefreshHelpers) ~= "function" then
  error("LidCouncil missing loot profiles refresh helpers.")
end

local BuildLootProfilesPageScaffold = INTERNAL_API.LIDCOUNCIL_BuildLootProfilesPageScaffold_Impl
if type(BuildLootProfilesPageScaffold) ~= "function" then
  error("LidCouncil missing loot profiles page scaffold builder.")
end

local CreateLootProfileMemberHelpers = INTERNAL_API.LIDCOUNCIL_CreateLootProfileMemberHelpers_Impl
if type(CreateLootProfileMemberHelpers) ~= "function" then
  error("LidCouncil missing loot profiles member helpers.")
end

local CreateLootProfileSettingsHelpers = INTERNAL_API.LIDCOUNCIL_CreateLootProfileSettingsHelpers_Impl
if type(CreateLootProfileSettingsHelpers) ~= "function" then
  error("LidCouncil missing loot profiles settings helpers.")
end

local editorUiHelpers = INTERNAL_API.LIDCOUNCIL_EditorUiHelpers_Impl
local CreatePurpleOutline = type(editorUiHelpers) == "table" and editorUiHelpers.CreatePurpleOutline or nil
local ClampListPage = type(editorUiHelpers) == "table" and editorUiHelpers.ClampListPage or nil
local GetListPageForValue = type(editorUiHelpers) == "table" and editorUiHelpers.GetListPageForValue or nil
local UpdatePagerControls = type(editorUiHelpers) == "table" and editorUiHelpers.UpdatePagerControls or nil
local profileManagement = INTERNAL_API.LIDCOUNCIL_EditorProfileManagement_Impl
local AssignProfileToGroup = type(profileManagement) == "table" and profileManagement.AssignProfileToGroup or nil

local PROFILE_PAGE_DEPS = {
  INTERNAL_API = INTERNAL_API,
  BindMouseWheelScroll = BindMouseWheelScroll,
  RootDB = RootDB,
  ApplyFrameSkin = ApplyFrameSkin,
  MakeYellowSubHeader = MakeYellowSubHeader,
  GetCharacterKey = GetCharacterKey,
  GetLootProfile = GetLootProfile,
  GetLootProfileNames = GetLootProfileNames,
  GetLootProfileRoleEntries = GetLootProfileRoleEntries,
  GetLootProfileAccessInfo = GetLootProfileAccessInfo,
  GetLootProfileAccessInfoForRole = GetLootProfileAccessInfoForRole,
  SetCurrentLootProfile = SetCurrentLootProfile,
  CreateLootProfile = CreateLootProfile,
  DeleteLootProfile = DeleteLootProfile,
  CopyLootProfile = CopyLootProfile,
  SetLootProfileMemberRole = SetLootProfileMemberRole,
  SetLootProfilePermissionPolicyValue = SetLootProfilePermissionPolicyValue,
  ResetLootProfilePermissionPolicy = ResetLootProfilePermissionPolicy,
  TransferLootProfileMaster = TransferLootProfileMaster,
  SetLootProfileEnabled = SetLootProfileEnabled,
  SetLootProfileRaid = SetLootProfileRaid,
  ApplyLootRollTemplate = ApplyLootRollTemplate,
  AddLootRollOption = AddLootRollOption,
  UpdateLootRollOption = UpdateLootRollOption,
  MoveLootRollOption = MoveLootRollOption,
  RemoveLootRollOption = RemoveLootRollOption,
  UpdateLootPointMode = UpdateLootPointMode,
  UpdateLootLidTableRow = UpdateLootLidTableRow,
  AddLootPointRule = AddLootPointRule,
  RemoveLootPointRule = RemoveLootPointRule,
  StartLootSession = StartLootSession,
  StopLootSession = StopLootSession,
  GetActiveLootSession = GetActiveLootSession,
  AddLootLedgerEntry = AddLootLedgerEntry,
  GetLootLedgerCharacters = GetLootLedgerCharacters,
  ResolveOptionalApiFunction = ResolveOptionalApiFunction,
  CreateCustomDropdownControl = CreateCustomDropdownControl,
  TrimText = TrimText,
  FormatDateTime = FormatDateTime,
  FormatDuration = FormatDuration,
  CreateSimpleEditBox = CreateSimpleEditBox,
  SetListButtonSelected = SetListButtonSelected,
  SetTextListButtonTextColor = SetTextListButtonTextColor,
  EnsureTextListButtons = EnsureTextListButtons,
  CreateSectionShell = CreateSectionShell,
  ClampLayoutValue = ClampLayoutValue,
  GetResponsiveSectionLayout = GetResponsiveSectionLayout,
  SetControlWidth = SetControlWidth,
  GetFontStringWidth = GetFontStringWidth,
  CreateSectionDivider = CreateSectionDivider,
  FlowLayoutControls = FlowLayoutControls,
  LayoutRollOptionRow = LayoutRollOptionRow,
  LayoutLidTableEditorRow = LayoutLidTableEditorRow,
  BuildRollOptionsText = BuildRollOptionsText,
  ROLL_TEMPLATE_CHOICES = ROLL_TEMPLATE_CHOICES,
  DEFAULT_ROLL_OPTION_ICON_CHOICES = DEFAULT_ROLL_OPTION_ICON_CHOICES,
  ResolveTextureAsset = ResolveTextureAsset,
  ResolveDefaultRollOptionIcon = ResolveDefaultRollOptionIcon,
  ResolveRollOptionIcon = ResolveRollOptionIcon,
  GetRollOptionIconLabel = GetRollOptionIconLabel,
  ResolveRollTemplate = ResolveRollTemplate,
  GetRollTemplateText = GetRollTemplateText,
  EnsureRollOptionRows = EnsureRollOptionRows,
  EnsureLidTableEditorRows = EnsureLidTableEditorRows,
  ExtractItemID = ExtractItemID,
  ExtractItemLinkName = ExtractItemLinkName,
  FormatPointRuleItemLabel = FormatPointRuleItemLabel,
  FormatRaidLootItemLabel = FormatRaidLootItemLabel,
  LOOT_ITEM_MENU_PAGE_SIZE = LOOT_ITEM_MENU_PAGE_SIZE,
  NormalizeInstanceTuple = NormalizeInstanceTuple,
  NormalizeEncounterTuple = NormalizeEncounterTuple,
  NormalizeLootInfo = NormalizeLootInfo,
  EnsureEncounterJournalLoaded = EnsureEncounterJournalLoaded,
  CollectRaidEntries = CollectRaidEntries,
  CollectRaidLootEntries = CollectRaidLootEntries,
  FindRaidEntryByProfile = FindRaidEntryByProfile,
  FindRaidLootEntry = FindRaidLootEntry,
  EnsureLootLiveBoardMode = EnsureLootLiveBoardMode,
  ClampMenuPage = ClampMenuPage,
  GetSelectedValuePage = GetSelectedValuePage,
  EnsureLootProfileGroups = EnsureLootProfileGroups,
  FindLootProfileGroupIndex = FindLootProfileGroupIndex,
  RemoveLootProfileFromGroups = RemoveLootProfileFromGroups,
  ToggleLootProfileGroupCollapsed = ToggleLootProfileGroupCollapsed,
  GetLootProfileGroupName = GetLootProfileGroupName,
  BuildLootProfileNavRows = BuildLootProfileNavRows,
  BuildPointRulesText = BuildPointRulesText,
  ResolvePointMode = ResolvePointMode,
  GetLidTableRows = GetLidTableRows,
  BuildLidTableSummaryText = BuildLidTableSummaryText,
  POINT_MODE_CHOICES = POINT_MODE_CHOICES,
  GetSelectedProfileName = GetSelectedProfileName,
  FormatLootProfileRoleLabel = FormatLootProfileRoleLabel,
  BuildLootProfileRoleListText = BuildLootProfileRoleListText,
  BuildLootProfileRoleBuckets = BuildLootProfileRoleBuckets,
  PermissionPolicyRowDefs = LOOT_PROFILE_PERMISSION_POLICY_ROWS,
  SetPermissionPolicyCellState = SetPermissionPolicyCellState,
  GetProfileClassColor = GetProfileClassColor,
  ResolveProfileMemberDisplay = ResolveProfileMemberDisplay,
  ResolveProfileIconData = ResolveProfileIconData,
  ApplyProfileIcon = ApplyProfileIcon,
  BuildProfileClassSummary = BuildProfileClassSummary,
  BuildProfileMemberDropdownText = BuildProfileMemberDropdownText,
  CreatePurpleOutline = CreatePurpleOutline,
  ClampListPage = ClampListPage,
  GetListPageForValue = GetListPageForValue,
  UpdatePagerControls = UpdatePagerControls,
  AssignProfileToGroup = AssignProfileToGroup,
}

local function BuildLootProfilesPage(editor, page)
  if not editor or not page then return end

  local deps = PROFILE_PAGE_DEPS
  local INTERNAL_API = deps.INTERNAL_API
  local ApplyFrameSkin = deps.ApplyFrameSkin
  local GetLootProfile = deps.GetLootProfile
  local GetLootProfileRoleEntries = deps.GetLootProfileRoleEntries
  local GetLootProfileAccessInfo = deps.GetLootProfileAccessInfo
  local GetLootProfileAccessInfoForRole = deps.GetLootProfileAccessInfoForRole
  local SetLootProfileMemberRole = deps.SetLootProfileMemberRole
  local SetLootProfilePermissionPolicyValue = deps.SetLootProfilePermissionPolicyValue
  local ResetLootProfilePermissionPolicy = deps.ResetLootProfilePermissionPolicy
  local SetLootProfileEnabled = deps.SetLootProfileEnabled
  local SetLootProfileRaid = deps.SetLootProfileRaid
  local UpdateLootRollOption = deps.UpdateLootRollOption
  local AddLootPointRule = deps.AddLootPointRule
  local GetActiveLootSession = deps.GetActiveLootSession
  local ResolveOptionalApiFunction = deps.ResolveOptionalApiFunction
  local TrimText = deps.TrimText
  local SetListButtonSelected = deps.SetListButtonSelected
  local SetTextListButtonTextColor = deps.SetTextListButtonTextColor
  local ClampLayoutValue = deps.ClampLayoutValue
  local SetControlWidth = deps.SetControlWidth
  local GetFontStringWidth = deps.GetFontStringWidth
  local FlowLayoutControls = deps.FlowLayoutControls
  local ResolveTextureAsset = deps.ResolveTextureAsset
  local ResolveRollOptionIcon = deps.ResolveRollOptionIcon
  local EnsureLidTableEditorRows = deps.EnsureLidTableEditorRows
  local FormatRaidLootItemLabel = deps.FormatRaidLootItemLabel
  local LOOT_ITEM_MENU_PAGE_SIZE = deps.LOOT_ITEM_MENU_PAGE_SIZE
  local CollectRaidEntries = deps.CollectRaidEntries
  local ClampMenuPage = deps.ClampMenuPage
  local GetSelectedValuePage = deps.GetSelectedValuePage
  local ResolvePointMode = deps.ResolvePointMode
  local GetLidTableRows = deps.GetLidTableRows
  local GetSelectedProfileName = deps.GetSelectedProfileName
  local FormatLootProfileRoleLabel = deps.FormatLootProfileRoleLabel
  local GetProfileClassColor = deps.GetProfileClassColor
  local ResolveProfileMemberDisplay = deps.ResolveProfileMemberDisplay
  local ResolveProfileIconData = deps.ResolveProfileIconData
  local ApplyProfileIcon = deps.ApplyProfileIcon
  local BuildProfileClassSummary = deps.BuildProfileClassSummary
  local PermissionPolicyRowDefs = deps.PermissionPolicyRowDefs
  local SetPermissionPolicyCellState = deps.SetPermissionPolicyCellState

  if type(editor.ShowIconPicker) ~= "function" then
    local createPanelAssetPickers = INTERNAL_API.LIDCOUNCIL_CreatePanelAssetPickers_Impl
    if type(createPanelAssetPickers) == "function" then
      createPanelAssetPickers(editor, {})
    end
  end
  BuildLootProfilesPageScaffold(editor, page)
  EnsurePermissionPolicyRows(editor, editor.lootProfileAccessFrame)

  local rightBg = editor.lootProfilesRightBg
  local rightContent = editor.lootProfilesRightContent
  local addGroupBtn = editor.lootAddGroupBtn
  local addProfileBtn = editor.lootAddProfileBtn
  local prevPageBtn = editor.lootProfilesPrevBtn
  local nextPageBtn = editor.lootProfilesNextBtn
  local deleteGroupBtn = editor.lootDeleteGroupBtn
  local deleteBtn = editor.lootDeleteProfileBtn
  local feedback = editor.lootProfilesFeedback
  local activateBtn = editor.lootActivateProfileBtn
  local deactivateBtn = editor.lootDeactivateProfileBtn
  local copyBtn = editor.lootCopyProfileBtn
  local clearSimulationBtn = editor.lootClearSimulationContentBtn
  local accessTargetDropdown = editor.lootProfileRoleTargetDropdown
  local accessRoleDropdown = editor.lootProfileRoleDropdown
  local applyRoleBtn = editor.lootProfileApplyRoleBtn
  local pointModeDropdown = editor.lootPointModeDropdown
  local raidSeasonDropdown = editor.lootRaidSeasonDropdown
  local raidDropdown = editor.lootRaidDropdown
  local saveRaidBtn = editor.lootSaveRaidBtn
  local rollTemplateDropdown = editor.lootRollTemplateDropdown
  local rollEdit = editor.lootRollOptionEdit
  local addRollBtn = editor.lootAddRollOptionBtn
  local removeRollBtn = editor.lootRemoveRollOptionBtn
  local testRollBtn = editor.lootTestRollPopupBtn
  local previewHostBoardBtn = editor.lootPreviewHostBoardBtn
  local rollExportBtn = editor.lootRollExportBtn
  local rollImportStringBtn = editor.lootRollImportStringBtn
  local rollImportProfileDropdown = editor.lootRollImportProfileDropdown
  local levelEdit = editor.lootPointItemLevelEdit
  local itemDropdown = editor.lootPointItemDropdown
  local pointsEdit = editor.lootPointValueEdit
  local addLevelRuleBtn = editor.lootAddPointRuleBtn
  local addItemRuleBtn = editor.lootAddItemPointRuleBtn
  local removeRuleBtn = editor.lootRemovePointRuleBtn
  local pointExportBtn = editor.lootPointExportBtn
  local pointImportStringBtn = editor.lootPointImportStringBtn
  local pointImportProfileDropdown = editor.lootPointImportProfileDropdown
  local raiderFrame = editor.lootProfileRaiderFrame
  local raiderToggleBtn = editor.lootProfileRaiderToggleBtn
  local accessToggleBtn = editor.lootProfileAccessToggleBtn
  local raidToggleBtn = editor.lootProfileRaidToggleBtn
  local rollToggleBtn = editor.lootProfileRollToggleBtn
  local pointsToggleBtn = editor.lootProfilePointsToggleBtn
  local backupToggleBtn = editor.lootProfileBackupToggleBtn
  local saveBackupBtn = editor.lootProfileSaveBackupBtn
  local backupDropdown = editor.lootProfileBackupDropdown
  local loadBackupBtn = editor.lootProfileLoadBackupBtn
  local deleteBackupBtn = editor.lootProfileDeleteBackupBtn
  local transferMasterBtn = editor.lootProfileTransferMasterBtn

  local memberHelpersContext = {
    editor = editor,
    rightContent = rightContent,
    feedback = feedback,
    GetLootProfileAccessInfo = GetLootProfileAccessInfo,
    GetSelectedProfileName = GetSelectedProfileName,
    ResolveProfileMemberDisplay = ResolveProfileMemberDisplay,
    ResolveProfileIconData = ResolveProfileIconData,
    GetProfileClassColor = GetProfileClassColor,
    ApplyProfileIcon = ApplyProfileIcon,
    SetListButtonSelected = SetListButtonSelected,
    TrimText = TrimText,
    FormatLootProfileRoleLabel = FormatLootProfileRoleLabel,
    SetLootProfileMemberRole = SetLootProfileMemberRole,
    GetLootProfileRoleEntries = GetLootProfileRoleEntries,
    ResolveOptionalApiFunction = ResolveOptionalApiFunction,
  }
  local memberHelpers = CreateLootProfileMemberHelpers(memberHelpersContext)
  local ApplyProfileActionButtonStyle = memberHelpers.ApplyProfileActionButtonStyle
  local RefreshProfileMemberRows = memberHelpers.RefreshProfileMemberRows

  local settingsHelpersContext = {
    editor = editor,
    rightContent = rightContent,
    feedback = feedback,
    GetSelectedProfileName = GetSelectedProfileName,
    GetLootProfile = GetLootProfile,
    SetLootProfileRaid = SetLootProfileRaid,
    ApplyLootRollTemplate = ApplyLootRollTemplate,
    UpdateLootRollOption = UpdateLootRollOption,
    UpdateLootPointMode = UpdateLootPointMode,
    UpdateLootLidTableRow = UpdateLootLidTableRow,
    EnsureLidTableEditorRows = EnsureLidTableEditorRows,
    EnsureRollOptionRows = EnsureRollOptionRows,
    GetLidTableRows = GetLidTableRows,
    TrimText = TrimText,
    ResolveOptionalApiFunction = ResolveOptionalApiFunction,
    ResolveTextureAsset = ResolveTextureAsset,
    ResolveDefaultRollOptionIcon = ResolveDefaultRollOptionIcon,
    ResolveRollOptionIcon = ResolveRollOptionIcon,
    GetRollOptionIconLabel = GetRollOptionIconLabel,
    ResolveRollTemplate = ResolveRollTemplate,
    GetRollTemplateText = GetRollTemplateText,
    ROLL_TEMPLATE_CHOICES = ROLL_TEMPLATE_CHOICES,
    DEFAULT_ROLL_OPTION_ICON_CHOICES = DEFAULT_ROLL_OPTION_ICON_CHOICES,
    LOOT_ITEM_MENU_PAGE_SIZE = LOOT_ITEM_MENU_PAGE_SIZE,
    ClampMenuPage = ClampMenuPage,
    GetSelectedValuePage = GetSelectedValuePage,
    CollectRaidEntries = CollectRaidEntries,
    CollectRaidLootEntries = CollectRaidLootEntries,
    FindRaidEntryByProfile = FindRaidEntryByProfile,
    ResolvePointMode = ResolvePointMode,
    POINT_MODE_CHOICES = POINT_MODE_CHOICES,
    FormatRaidLootItemLabel = FormatRaidLootItemLabel,
    MoveLootRollOption = deps.MoveLootRollOption,
  }
  local settingsHelpers = CreateLootProfileSettingsHelpers(settingsHelpersContext)
  local SetDropdownValue = settingsHelpers.SetDropdownValue
  local ClearItemRuleSelection = settingsHelpers.ClearItemRuleSelection
  local RefreshLidTableRows = settingsHelpers.RefreshLidTableRows
  local BindAllLidTableRows = settingsHelpers.BindAllLidTableRows
  local RefreshRollOptionRows = settingsHelpers.RefreshRollOptionRows
  local GetResolvedRaidEntry = settingsHelpers.GetResolvedRaidEntry
  local GetCurrentLootSeasonContext = settingsHelpers.GetCurrentLootSeasonContext
  local BuildSeasonRaidNamesText = settingsHelpers.BuildSeasonRaidNamesText
  local CollectSeasonLootEntries = settingsHelpers.CollectSeasonLootEntries
  local FindSeasonLootEntry = settingsHelpers.FindSeasonLootEntry
  local BuildRaidSeasonDropdownMenu = settingsHelpers.BuildRaidSeasonDropdownMenu
  local BuildRaidDropdownMenu = settingsHelpers.BuildRaidDropdownMenu
  local BuildLootItemDropdownMenu = settingsHelpers.BuildLootItemDropdownMenu
  local BuildRollTemplateDropdownMenu = settingsHelpers.BuildRollTemplateDropdownMenu
  local BuildPointModeDropdownMenu = settingsHelpers.BuildPointModeDropdownMenu
  local BroadcastActiveRoleUpdate = settingsHelpers.BroadcastActiveRoleUpdate

  local SelectProfileRoleTarget
  local ForceLocalRoleState

  SelectProfileRoleTarget = function(characterKey, roleValue)
    local resolvedCharacter = TrimText(characterKey)
    local resolvedRole = string.upper(TrimText(roleValue or "RAIDER"))
    if resolvedRole ~= "COUNCIL" then
      resolvedRole = "RAIDER"
    end
    editor.__lootProfileOpenSection = "access"
    editor.__lootProfileRoleTarget = resolvedCharacter ~= "" and resolvedCharacter or nil
    editor.__lootProfileRoleValue = resolvedRole

    if editor.lootProfileRoleTargetDropdown then
      if editor.lootProfileRoleTargetDropdown.__lidcouncilCustomDropdown then
        local selectedProfile = GetLootProfile(GetSelectedProfileName(editor))
        editor.lootProfileRoleTargetDropdown:SetSelectedValue(editor.__lootProfileRoleTarget)
        editor.lootProfileRoleTargetDropdown:SetText(editor.__lootProfileRoleTarget and deps.BuildProfileMemberDropdownText(selectedProfile, editor.__lootProfileRoleTarget, resolvedRole) or "(no non-master members)")
      elseif editor.lootProfileRoleTargetDropdown.SetText then
        editor.lootProfileRoleTargetDropdown:SetText(editor.__lootProfileRoleTarget or "")
      end
    end

    if editor.lootProfileRoleDropdown then
      if editor.lootProfileRoleDropdown.__lidcouncilCustomDropdown then
        editor.lootProfileRoleDropdown:SetSelectedValue(resolvedRole)
        editor.lootProfileRoleDropdown:SetText(FormatLootProfileRoleLabel(resolvedRole))
      elseif editor.lootProfileRoleDropdown.SetText then
        editor.lootProfileRoleDropdown:SetText(FormatLootProfileRoleLabel(resolvedRole))
      end
    end
  end
  memberHelpersContext.SelectProfileRoleTarget = SelectProfileRoleTarget

  ForceLocalRoleState = function(profileName, characterKey, roleValue)
    local resolvedProfileName = TrimText(profileName)
    local resolvedCharacter = TrimText(characterKey)
    local resolvedRole = string.upper(TrimText(roleValue))
    if resolvedProfileName == "" or resolvedCharacter == "" then
      return
    end
    if resolvedRole ~= "COUNCIL" then
      resolvedRole = "RAIDER"
    end

    local profile = GetLootProfile(resolvedProfileName)
    if type(profile) ~= "table" then
      return
    end

    profile.meta = profile.meta or {}
    local permissions = type(profile.meta.permissions) == "table" and profile.meta.permissions or { master = "", members = {} }
    permissions.master = TrimText(permissions.master)
    permissions.members = type(permissions.members) == "table" and permissions.members or {}
    profile.meta.permissions = permissions

    local masterLower = string.lower(permissions.master or "")
    if masterLower ~= "" and masterLower == string.lower(resolvedCharacter) then
      return
    end

    for storedKey in pairs(permissions.members) do
      if string.lower(TrimText(storedKey)) == string.lower(resolvedCharacter) then
        permissions.members[storedKey] = nil
      end
    end
    permissions.members[resolvedCharacter] = resolvedRole
    local touchLootProfileDomain = ResolveOptionalApiFunction("LIDCOUNCIL_TouchLootProfileDomain")
    if type(touchLootProfileDomain) == "function" then
      touchLootProfileDomain(profile, "permissions")
    else
      profile.meta.revision = math.max(0, tonumber(profile.meta.revision) or 0) + 1
      profile.meta.updatedAt = time and time() or 0
    end
  end
  memberHelpersContext.ForceLocalRoleState = ForceLocalRoleState

  BindAllLidTableRows()

  if pointModeDropdown and pointModeDropdown.__lidcouncilCustomDropdown then
    pointModeDropdown:SetMenuBuilder(function(dropdownControl)
      return BuildPointModeDropdownMenu(dropdownControl)
    end)
  end
  if raidDropdown and raidDropdown.__lidcouncilCustomDropdown then
    raidDropdown:SetMenuBuilder(function(dropdownControl)
      return BuildRaidDropdownMenu(dropdownControl)
    end)
  end
  if raidSeasonDropdown and raidSeasonDropdown.__lidcouncilCustomDropdown then
    raidSeasonDropdown:SetMenuBuilder(function(dropdownControl)
      return BuildRaidSeasonDropdownMenu(dropdownControl)
    end)
  end
  if itemDropdown and itemDropdown.__lidcouncilCustomDropdown then
    itemDropdown:SetMenuBuilder(function(dropdownControl)
      return BuildLootItemDropdownMenu(dropdownControl)
    end)
  end
  if rollTemplateDropdown and rollTemplateDropdown.__lidcouncilCustomDropdown then
    rollTemplateDropdown:SetMenuBuilder(function(dropdownControl)
      return BuildRollTemplateDropdownMenu(dropdownControl)
    end)
  end
  if rollImportProfileDropdown and rollImportProfileDropdown.__lidcouncilCustomDropdown then
    rollImportProfileDropdown:SetMenuBuilder(function(control)
      local targetProfileName = GetSelectedProfileName(editor)
      local entries = {}
      for _, profileName in ipairs(GetVisibleLootProfileNames() or {}) do
        if tostring(profileName) ~= tostring(targetProfileName) then
          entries[#entries + 1] = {
            text = tostring(profileName),
            value = tostring(profileName),
            func = function()
              local copyRollSettings = ResolveOptionalApiFunction("LIDCOUNCIL_CopyLootRollSettings")
              if type(copyRollSettings) ~= "function" then
                feedback:SetText("Roll settings import API unavailable.")
                return
              end
              local ok, result = copyRollSettings(profileName, targetProfileName)
              if not ok then
                feedback:SetText(tostring(result or "Could not import roll settings from profile."))
                return
              end
              control:SetSelectedValue(nil)
              control:SetText("Import From Profile")
              feedback:SetText(string.format("Imported roll settings from %s.", tostring(profileName)))
              if editor.Refresh then editor:Refresh() end
            end,
          }
        end
      end
      if #entries == 0 then
        entries[1] = { text = "No other profiles", disabled = true, notCheckable = true }
      end
      return {
        width = 180,
        entries = entries,
      }
    end)
  end
  if pointImportProfileDropdown and pointImportProfileDropdown.__lidcouncilCustomDropdown then
    pointImportProfileDropdown:SetMenuBuilder(function(control)
      local targetProfileName = GetSelectedProfileName(editor)
      local entries = {}
      for _, profileName in ipairs(GetVisibleLootProfileNames() or {}) do
        if tostring(profileName) ~= tostring(targetProfileName) then
          entries[#entries + 1] = {
            text = tostring(profileName),
            value = tostring(profileName),
            func = function()
              local copyPointSettings = ResolveOptionalApiFunction("LIDCOUNCIL_CopyLootPointSettings")
              if type(copyPointSettings) ~= "function" then
                feedback:SetText("Point settings import API unavailable.")
                return
              end
              local ok, result = copyPointSettings(profileName, targetProfileName)
              if not ok then
                feedback:SetText(tostring(result or "Could not import point settings from profile."))
                return
              end
              control:SetSelectedValue(nil)
              control:SetText("Import From Profile")
              feedback:SetText(string.format("Imported point settings from %s.", tostring(profileName)))
              if editor.Refresh then editor:Refresh() end
            end,
          }
        end
      end
      if #entries == 0 then
        entries[1] = { text = "No other profiles", disabled = true, notCheckable = true }
      end
      return {
        width = 180,
        entries = entries,
      }
    end)
  end

  if accessRoleDropdown and accessRoleDropdown.__lidcouncilCustomDropdown then
    accessRoleDropdown:SetMenuBuilder(function(control)
      local selectedRole = string.upper(TrimText((control and control.GetSelectedValue and control:GetSelectedValue()) or editor.__lootProfileRoleValue or "RAIDER"))
      local entries = {
        {
          text = "Council Member",
          value = "COUNCIL",
          checked = selectedRole == "COUNCIL",
          func = function()
            control:SetSelectedValue("COUNCIL")
            control:SetText("Council Member")
            editor.__lootProfileRoleValue = "COUNCIL"
          end,
        },
        {
          text = "Raider",
          value = "RAIDER",
          checked = selectedRole ~= "COUNCIL",
          func = function()
            control:SetSelectedValue("RAIDER")
            control:SetText("Raider")
            editor.__lootProfileRoleValue = "RAIDER"
          end,
        },
      }
      return {
        width = 180,
        entries = entries,
      }
    end)
  end

  if accessTargetDropdown and accessTargetDropdown.__lidcouncilCustomDropdown then
    accessTargetDropdown:SetMenuBuilder(function(control)
      local currentProfile = GetLootProfile(GetSelectedProfileName(editor))
      local currentEntries = GetLootProfileRoleEntries(GetSelectedProfileName(editor))
      local menuEntries = {}
      for _, entry in ipairs(currentEntries or {}) do
        if not entry.isMaster then
          local entryText = deps.BuildProfileMemberDropdownText(currentProfile, entry.character, entry.role)
          menuEntries[#menuEntries + 1] = {
            text = entryText,
            searchText = string.format(
              "%s %s %s %s",
              tostring(entry.character or ""),
              tostring(entry.role or ""),
              tostring((deps.ResolveProfileMemberDisplay(currentProfile, entry.character) or {}).specName or ""),
              tostring((deps.ResolveProfileMemberDisplay(currentProfile, entry.character) or {}).className or "")
            ),
            value = entry.character,
            checked = string.lower(tostring(entry.character or "")) == string.lower(tostring(editor.__lootProfileRoleTarget or "")),
            func = function()
              control:SetSelectedValue(entry.character)
              control:SetText(entryText)
              editor.__lootProfileRoleTarget = entry.character
              editor.__lootProfileRoleValue = string.upper(TrimText(entry.role)) ~= "MASTER" and string.upper(TrimText(entry.role)) or "RAIDER"
              if editor.lootProfileRoleDropdown and editor.lootProfileRoleDropdown.__lidcouncilCustomDropdown then
                editor.lootProfileRoleDropdown:SetSelectedValue(editor.__lootProfileRoleValue)
                editor.lootProfileRoleDropdown:SetText(FormatLootProfileRoleLabel(editor.__lootProfileRoleValue))
              elseif editor.lootProfileRoleDropdown and editor.lootProfileRoleDropdown.SetText then
                editor.lootProfileRoleDropdown:SetText(FormatLootProfileRoleLabel(editor.__lootProfileRoleValue))
              end
              if editor.Refresh then
                editor:Refresh()
              end
            end,
          }
        end
      end
      if #menuEntries == 0 then
        menuEntries[1] = {
          text = "No non-master members available",
          disabled = true,
          notCheckable = true,
        }
      end
      return {
        width = 320,
        entries = menuEntries,
        enableSearch = true,
        searchPlaceholder = "Search Character-Realm",
      }
    end)
  end

  local lootProfileLayoutHelpers = CreateLootProfileLayoutHelpers({
    GetResponsiveSectionLayout = GetResponsiveSectionLayout,
    ClampLayoutValue = ClampLayoutValue,
    SetControlWidth = SetControlWidth,
    GetFontStringWidth = GetFontStringWidth,
    FlowLayoutControls = FlowLayoutControls,
    LayoutRollOptionRow = LayoutRollOptionRow,
    LayoutLidTableEditorRow = LayoutLidTableEditorRow,
    TrimText = TrimText,
  })

  local function LayoutProfileContent(self)
    lootProfileLayoutHelpers.LayoutProfileContent(self, page)
  end
  if rightBg and rightBg.HookScript then
    rightBg:HookScript("OnSizeChanged", function()
      LayoutProfileContent(editor)
    end)
  end

  local lootProfileRefreshHelpers = CreateLootProfileRefreshHelpers({
    editor = editor,
    RootDB = RootDB,
    GetSelectedProfileName = GetSelectedProfileName,
    GetLootProfile = GetLootProfile,
    GetLootProfileAccessInfo = GetLootProfileAccessInfo,
    GetLootProfileAccessInfoForRole = GetLootProfileAccessInfoForRole,
    GetLootProfilePermissionPolicyRoleState = GetLootProfilePermissionPolicyRoleState,
    GetLootProfileRoleEntries = GetLootProfileRoleEntries,
    SetLootProfilePermissionPolicyValue = SetLootProfilePermissionPolicyValue,
    ResetLootProfilePermissionPolicy = ResetLootProfilePermissionPolicy,
    PermissionPolicyRowDefs = PermissionPolicyRowDefs,
    SetPermissionPolicyCellState = SetPermissionPolicyCellState,
    BuildLootProfileNavRows = BuildLootProfileNavRows,
    EnsureTextListButtons = EnsureTextListButtons,
    ToggleLootProfileGroupCollapsed = ToggleLootProfileGroupCollapsed,
    SetListButtonSelected = SetListButtonSelected,
    SetTextListButtonTextColor = SetTextListButtonTextColor,
    TrimText = TrimText,
    GetActiveLootSession = GetActiveLootSession,
    GetEnabledLootProfileName = GetEnabledLootProfileName,
    GetPrimaryLootProfileName = GetPrimaryLootProfileName,
    FormatLootProfileRoleLabel = FormatLootProfileRoleLabel,
    BuildLootProfileRoleListText = BuildLootProfileRoleListText,
    BuildLootProfileRoleBuckets = BuildLootProfileRoleBuckets,
    ResolveProfileMemberDisplay = ResolveProfileMemberDisplay,
    ResolveProfileIconData = ResolveProfileIconData,
    GetProfileClassColor = GetProfileClassColor,
    ApplyProfileIcon = ApplyProfileIcon,
    BuildProfileClassSummary = BuildProfileClassSummary,
    BuildProfileMemberDropdownText = BuildProfileMemberDropdownText,
    RefreshProfileMemberRows = RefreshProfileMemberRows,
    ApplyProfileActionButtonStyle = ApplyProfileActionButtonStyle,
    CollectSeasonLootEntries = CollectSeasonLootEntries,
    FindRaidEntryByProfile = FindRaidEntryByProfile,
    BuildSeasonRaidNamesText = BuildSeasonRaidNamesText,
    ResolvePointMode = ResolvePointMode,
    ResolveRollTemplate = ResolveRollTemplate,
    GetRollTemplateText = GetRollTemplateText,
    ResolveRaidPreviewTexture = ResolveRaidPreviewTexture,
    ClearItemRuleSelection = ClearItemRuleSelection,
    SetDropdownValue = SetDropdownValue,
    FindSeasonLootEntry = FindSeasonLootEntry,
    FormatRaidLootItemLabel = FormatRaidLootItemLabel,
    RefreshRollOptionRows = RefreshRollOptionRows,
    RefreshLidTableRows = RefreshLidTableRows,
    BuildRollOptionsText = BuildRollOptionsText,
    BuildPointRulesText = BuildPointRulesText,
    BuildLidTableSummaryText = BuildLidTableSummaryText,
    LayoutProfileContent = LayoutProfileContent,
    CreatePurpleOutline = CreatePurpleOutline,
    AssignProfileToGroup = AssignProfileToGroup,
  })

  local function RefreshProfileBackupControls(self)
    local profileName = GetSelectedProfileName(self)
    local getBackups = type(ResolveOptionalApiFunction) == "function"
      and ResolveOptionalApiFunction("LIDCOUNCIL_GetLootProfileBackups")
      or nil
    local backups = type(getBackups) == "function" and getBackups(profileName) or {}
    backups = type(backups) == "table" and backups or {}
    self.__lootProfileBackups = backups

    local selectedId = TrimText(self.selectedLootProfileBackupId)
    local selectedLabel = ""
    for _, backup in ipairs(backups) do
      if TrimText(backup.id) == selectedId then
        selectedLabel = TrimText(backup.label)
        break
      end
    end
    if selectedLabel == "" then
      selectedId = ""
      self.selectedLootProfileBackupId = nil
    end

    if backupDropdown and backupDropdown.SetMenuBuilder then
      backupDropdown:SetMenuBuilder(function()
        local entries = {}
        for _, backup in ipairs(backups) do
          local backupId = TrimText(backup.id)
          local label = TrimText(backup.label)
          entries[#entries + 1] = {
            text = label ~= "" and label or backupId,
            checked = backupId ~= "" and backupId == TrimText(self.selectedLootProfileBackupId),
            func = function()
              self.selectedLootProfileBackupId = backupId
              if backupDropdown.SetSelectedValue then
                backupDropdown:SetSelectedValue(backupId)
              end
              if backupDropdown.SetText then
                backupDropdown:SetText(label ~= "" and label or backupId)
              end
              RefreshProfileBackupControls(self)
            end,
          }
        end
        if #entries == 0 then
          entries[1] = {
            text = "No local backups saved yet.",
            disabled = true,
            notCheckable = true,
          }
        end
        return { width = 300, entries = entries }
      end)
      if selectedId ~= "" then
        if backupDropdown.SetSelectedValue then backupDropdown:SetSelectedValue(selectedId) end
        if backupDropdown.SetText then backupDropdown:SetText(selectedLabel) end
      else
        if backupDropdown.SetSelectedValue then backupDropdown:SetSelectedValue(nil) end
        if backupDropdown.SetText then backupDropdown:SetText(#backups > 0 and "Select Backup" or "No Backups") end
      end
    end

    local hasProfile = TrimText(profileName) ~= ""
    local hasSelected = TrimText(self.selectedLootProfileBackupId) ~= ""
    if saveBackupBtn and saveBackupBtn.Enable then
      if hasProfile then saveBackupBtn:Enable() else saveBackupBtn:Disable() end
    end
    if loadBackupBtn and loadBackupBtn.Enable then
      if hasSelected then loadBackupBtn:Enable() else loadBackupBtn:Disable() end
    end
    if deleteBackupBtn and deleteBackupBtn.Enable then
      if hasSelected then deleteBackupBtn:Enable() else deleteBackupBtn:Disable() end
    end
  end

  local function RefreshProfilePage(self)
    lootProfileRefreshHelpers.RefreshProfilePage(self)
    RefreshProfileBackupControls(self)
  end

  addGroupBtn:SetScript("OnClick", function()
    StaticPopup_Show("LIDCOUNCIL_CREATE_PROFILE_GROUP")
  end)

  prevPageBtn:SetScript("OnClick", function()
    editor.lootProfileListPage = math.max(1, tonumber(editor.lootProfileListPage or 1) - 1)
    if editor.RefreshLootProfilePage then
      editor:RefreshLootProfilePage()
    elseif editor.Refresh then
      editor:Refresh()
    end
  end)

  nextPageBtn:SetScript("OnClick", function()
    editor.lootProfileListPage = math.max(1, tonumber(editor.lootProfileListPage or 1) + 1)
    if editor.RefreshLootProfilePage then
      editor:RefreshLootProfilePage()
    elseif editor.Refresh then
      editor:Refresh()
    end
  end)

  addProfileBtn:SetScript("OnClick", function()
    StaticPopup_Show("LIDCOUNCIL_CREATE_PROFILE")
  end)

  deleteGroupBtn:SetScript("OnClick", function()
    local groupName = TrimText(editor.selectedLootProfileGroupName)
    if groupName == "" then
      feedback:SetText("Select a profile group first.")
      return
    end
    editor.selectedProfileGroupName = groupName
    editor.selectedLootProfileGroupName = groupName
    StaticPopup_Show("LIDCOUNCIL_DELETE_PROFILE_GROUP", groupName)
  end)

  deleteBtn:SetScript("OnClick", function()
    local currentName = GetSelectedProfileName(editor)
    if TrimText(currentName) == "Simulation" then
      feedback:SetText("Delete the Simulation profile from About > Developer Mode.")
      if feedback.SetTextColor then
        feedback:SetTextColor(1.00, 0.82, 0.24, 1.00)
      end
      return
    end
    local activeSession = GetActiveLootSession()
    if activeSession then
      feedback:SetText("Stop the active loot session before deleting local profile copies.")
      if feedback.SetTextColor then
        feedback:SetTextColor(1.00, 0.32, 0.32, 1.00)
      end
      return
    end
    editor.selectedProfileName = currentName
    StaticPopup_Show("LIDCOUNCIL_DELETE_PROFILE", currentName)
  end)

  activateBtn:SetScript("OnClick", function()
    local ok, message = SetLootProfileEnabled(GetSelectedProfileName(editor), true)
    if ok == false and TrimText(message) ~= "" then
      StaticPopup_Show("LIDCOUNCIL_ACTIVE_SESSION_PROFILE_LOCK")
    end
    if editor.Refresh then editor:Refresh() end
  end)

  deactivateBtn:SetScript("OnClick", function()
    local ok, message = SetLootProfileEnabled(GetSelectedProfileName(editor), false)
    if ok == false and TrimText(message) ~= "" then
      StaticPopup_Show("LIDCOUNCIL_ACTIVE_SESSION_PROFILE_LOCK")
    end
    if editor.Refresh then editor:Refresh() end
  end)

  copyBtn:SetScript("OnClick", function()
    editor.selectedProfileName = GetSelectedProfileName(editor)
    StaticPopup_Show("LIDCOUNCIL_COPY_PROFILE")
  end)

  if clearSimulationBtn then
    clearSimulationBtn:SetScript("OnClick", function()
      local currentName = GetSelectedProfileName(editor)
      if TrimText(currentName) ~= "Simulation" then
        feedback:SetText("Clear Content is only available for the Simulation profile.")
        if feedback.SetTextColor then
          feedback:SetTextColor(1.00, 0.32, 0.32, 1.00)
        end
        return
      end
      StaticPopup_Show("LIDCOUNCIL_CLEAR_SIMULATION_PROFILE_CONTENT", currentName)
    end)
  end

  applyRoleBtn:SetScript("OnClick", function()
    local profileName = GetSelectedProfileName(editor)
    local targetKey = TrimText(editor.__lootProfileRoleTarget)
    local nextRole = string.upper(TrimText(editor.__lootProfileRoleValue or "RAIDER"))
    local ok, result = SetLootProfileMemberRole(profileName, targetKey, nextRole)
    if ok then
      local verifiedRole = nil
      for _, entry in ipairs(GetLootProfileRoleEntries(profileName) or {}) do
        if string.lower(TrimText(entry and entry.character)) == string.lower(targetKey) then
          verifiedRole = string.upper(TrimText(entry.role))
          break
        end
      end
      if verifiedRole ~= string.upper(TrimText(result or nextRole)) then
        ForceLocalRoleState(profileName, targetKey, result or nextRole)
      end
      editor.__lootProfileRoleTarget = targetKey
      editor.__lootProfileRoleValue = string.upper(TrimText(result or nextRole))
      feedback:SetText(string.format("%s is now %s.", tostring(targetKey), FormatLootProfileRoleLabel(result)))
      BroadcastActiveRoleUpdate(profileName, targetKey)
      if editor.Refresh then editor:Refresh() end
    else
      feedback:SetText(tostring(result or "Could not update the profile role."))
    end
  end)

  transferMasterBtn:SetScript("OnClick", function()
    local profileName = GetSelectedProfileName(editor)
    local targetKey = TrimText(editor.__lootProfileRoleTarget)
    local ok, newMaster, previousMaster = TransferLootProfileMaster(profileName, targetKey)
    if ok then
      editor.__lootProfileRoleTarget = previousMaster
      editor.__lootProfileRoleValue = "COUNCIL"
      feedback:SetText(string.format("Transferred Master to %s.", tostring(newMaster or targetKey)))
      BroadcastActiveRoleUpdate(profileName, newMaster)
      BroadcastActiveRoleUpdate(profileName, previousMaster)
      if editor.Refresh then editor:Refresh() end
    else
      feedback:SetText(tostring(newMaster or "Could not transfer the Master role."))
    end
  end)

  if editor.lootProfilePermissionPolicyResetBtn then
    editor.lootProfilePermissionPolicyResetBtn:SetScript("OnClick", function()
      local profileName = GetSelectedProfileName(editor)
      local ok, result = ResetLootProfilePermissionPolicy(profileName)
      if ok then
        feedback:SetText("Reset permission policy to the default LidCouncil role behavior.")
        if editor.Refresh then editor:Refresh() end
      else
        feedback:SetText(tostring(result or "Could not reset the permission policy."))
      end
    end)
  end

  if raiderToggleBtn and raiderToggleBtn.SetScript then
    raiderToggleBtn:SetScript("OnClick", function()
      editor.__lootProfileRaidersCollapsed = not (editor.__lootProfileRaidersCollapsed and true or false)
      if editor.Refresh then
        editor:Refresh()
      else
        LayoutProfileContent(editor)
      end
    end)
    raiderToggleBtn:SetScript("OnEnter", function(self)
      if self.SetBackdropColor then
        self:SetBackdropColor(0.12, 0.12, 0.16, 0.98)
      end
    end)
    raiderToggleBtn:SetScript("OnLeave", function(self)
      if self.SetBackdropColor then
        self:SetBackdropColor(0.08, 0.08, 0.11, 0.98)
      end
    end)
  end
  if raiderFrame and raiderFrame.SetScript then
    raiderFrame:EnableMouse(false)
    raiderFrame:SetScript("OnMouseUp", nil)
  end

  local function ToggleProfileAccordionSection(sectionKey)
    local resolvedKey = string.lower(TrimText(sectionKey))
    if resolvedKey == "" then
      return
    end
    if string.lower(TrimText(editor.__lootProfileOpenSection)) == resolvedKey then
      editor.__lootProfileOpenSection = nil
    else
      editor.__lootProfileOpenSection = resolvedKey
    end
    if editor.Refresh then
      editor:Refresh()
    else
      LayoutProfileContent(editor)
    end
  end

  if accessToggleBtn and accessToggleBtn.SetScript then
    accessToggleBtn:SetScript("OnClick", function()
      ToggleProfileAccordionSection("access")
    end)
  end
  if raidToggleBtn and raidToggleBtn.SetScript then
    raidToggleBtn:SetScript("OnClick", function()
      ToggleProfileAccordionSection("raid")
    end)
  end
  if rollToggleBtn and rollToggleBtn.SetScript then
    rollToggleBtn:SetScript("OnClick", function()
      ToggleProfileAccordionSection("roll")
    end)
  end
  if pointsToggleBtn and pointsToggleBtn.SetScript then
    pointsToggleBtn:SetScript("OnClick", function()
      ToggleProfileAccordionSection("points")
    end)
  end
  if backupToggleBtn and backupToggleBtn.SetScript then
    backupToggleBtn:SetScript("OnClick", function()
      ToggleProfileAccordionSection("backups")
    end)
  end

  if saveBackupBtn and saveBackupBtn.SetScript then
    saveBackupBtn:SetScript("OnClick", function()
      local saveBackup = type(ResolveOptionalApiFunction) == "function"
        and ResolveOptionalApiFunction("LIDCOUNCIL_SaveLootProfileBackup")
        or nil
      if type(saveBackup) ~= "function" then
        feedback:SetText("Backup API unavailable.")
        return
      end
      local ok, backupOrError = saveBackup(GetSelectedProfileName(editor))
      if ok then
        editor.selectedLootProfileBackupId = type(backupOrError) == "table" and TrimText(backupOrError.id) or nil
        feedback:SetText("Saved local profile backup.")
        RefreshProfileBackupControls(editor)
      else
        feedback:SetText(tostring(backupOrError or "Could not save the backup."))
      end
    end)
  end

  if loadBackupBtn and loadBackupBtn.SetScript then
    loadBackupBtn:SetScript("OnClick", function()
      local loadBackup = type(ResolveOptionalApiFunction) == "function"
        and ResolveOptionalApiFunction("LIDCOUNCIL_LoadLootProfileBackup")
        or nil
      if type(loadBackup) ~= "function" then
        feedback:SetText("Backup API unavailable.")
        return
      end
      local backupId = TrimText(editor.selectedLootProfileBackupId)
      if backupId == "" then
        feedback:SetText("Select a backup first.")
        return
      end
      local ok, result = loadBackup(GetSelectedProfileName(editor), backupId)
      if ok then
        feedback:SetText("Loaded local profile backup.")
        if editor.Refresh then editor:Refresh() end
      else
        feedback:SetText(tostring(result or "Could not load the backup."))
      end
    end)
  end

  if deleteBackupBtn and deleteBackupBtn.SetScript then
    deleteBackupBtn:SetScript("OnClick", function()
      local deleteBackup = type(ResolveOptionalApiFunction) == "function"
        and ResolveOptionalApiFunction("LIDCOUNCIL_DeleteLootProfileBackup")
        or nil
      if type(deleteBackup) ~= "function" then
        feedback:SetText("Backup API unavailable.")
        return
      end
      local backupId = TrimText(editor.selectedLootProfileBackupId)
      if backupId == "" then
        feedback:SetText("Select a backup first.")
        return
      end
      local ok, result = deleteBackup(GetSelectedProfileName(editor), backupId)
      if ok then
        editor.selectedLootProfileBackupId = nil
        feedback:SetText("Deleted local profile backup.")
        RefreshProfileBackupControls(editor)
      else
        feedback:SetText(tostring(result or "Could not delete the backup."))
      end
    end)
  end

  saveRaidBtn:SetScript("OnClick", function()
    local profileName = GetSelectedProfileName(editor)
    if not GetLootProfileAccessInfo(profileName).canEditRaidSettings then
      feedback:SetText("Your current role cannot edit raid settings for this profile.")
      return
    end
    local ok, result = SetLootProfileRaid(profileName, nil, nil)
    if ok == false then
      feedback:SetText(tostring(result or "Could not update the raid selection."))
      return
    end
    feedback:SetText("Cleared raid selection.")
    ClearItemRuleSelection()
    if editor.Refresh then editor:Refresh() end
  end)

  addRollBtn:SetScript("OnClick", function()
    local profileName = GetSelectedProfileName(editor)
    if not GetLootProfileAccessInfo(profileName).canEditRollSettings then
      feedback:SetText("Your current role cannot edit roll settings for this profile.")
      return
    end
    local ok, result = AddLootRollOption(profileName, rollEdit:GetText())
    if ok then
      rollEdit:SetText("")
      if editor.Refresh then editor:Refresh() end
    else
      feedback:SetText(tostring(result or "Could not add roll option."))
    end
  end)

  removeRollBtn:SetScript("OnClick", function()
    local profileName = GetSelectedProfileName(editor)
    if not GetLootProfileAccessInfo(profileName).canEditRollSettings then
      feedback:SetText("Your current role cannot edit roll settings for this profile.")
      return
    end
    local profile = GetLootProfile(profileName)
    local options = profile.settings and profile.settings.rollOptions or {}
    local ok, result = RemoveLootRollOption(profileName, #options)
    if not ok then
      feedback:SetText(tostring(result or "Could not remove the roll option."))
      return
    end
    if editor.Refresh then editor:Refresh() end
  end)

  testRollBtn:SetScript("OnClick", function()
    local profileName = GetSelectedProfileName(editor)
    if not GetLootProfileAccessInfo(profileName).canEditRollSettings then
      feedback:SetText("Your current role cannot edit roll settings for this profile.")
      return
    end
    local previewPopup = ResolveOptionalApiFunction("LIDCOUNCIL_PreviewRollChoicePopup")
    if previewPopup then
      previewPopup(profileName)
    end
  end)

  previewHostBoardBtn:SetScript("OnClick", function()
    local profileName = GetSelectedProfileName(editor)
    if not GetLootProfileAccessInfo(profileName).canEditRollSettings then
      feedback:SetText("Your current role cannot edit roll settings for this profile.")
      return
    end
    local previewBoard = ResolveOptionalApiFunction("LIDCOUNCIL_PreviewLiveLootBoard")
    if previewBoard then
      previewBoard(profileName)
    end
  end)

  if rollExportBtn then
    rollExportBtn:SetScript("OnClick", function()
      local exportRollSettings = ResolveOptionalApiFunction("LIDCOUNCIL_ExportLootRollSettings")
      local showExportWindow = ResolveOptionalApiFunction("LIDCOUNCIL_ShowExportWindow")
      if type(exportRollSettings) ~= "function" or type(showExportWindow) ~= "function" then
        feedback:SetText("Roll settings export window unavailable.")
        return
      end
      local profileName = GetSelectedProfileName(editor)
      if not GetLootProfileAccessInfo(profileName).canEditRollSettings then
        feedback:SetText("Your current role cannot edit roll settings for this profile.")
        return
      end
      local exported = exportRollSettings(profileName)
      if not exported then
        feedback:SetText("Roll settings export failed.")
        return
      end
      showExportWindow(profileName .. " Roll Settings", exported)
    end)
  end

  if rollImportStringBtn then
    rollImportStringBtn:SetScript("OnClick", function()
      local importRollSettings = ResolveOptionalApiFunction("LIDCOUNCIL_ImportLootRollSettings")
      local showImportWindow = ResolveOptionalApiFunction("LIDCOUNCIL_ShowSettingsImportWindow")
      if type(importRollSettings) ~= "function" or type(showImportWindow) ~= "function" then
        feedback:SetText("Roll settings import window unavailable.")
        return
      end
      local profileName = GetSelectedProfileName(editor)
      if not GetLootProfileAccessInfo(profileName).canEditRollSettings then
        feedback:SetText("Your current role cannot edit roll settings for this profile.")
        return
      end
      showImportWindow(function(_, pasted)
        local ok, result = importRollSettings(profileName, pasted)
        if not ok then
          feedback:SetText(tostring(result or "Could not import roll settings."))
          return
        end
        feedback:SetText("Imported roll settings.")
        if editor.Refresh then editor:Refresh() end
      end, {
        title = "Import Roll Settings",
        requireName = false,
        buttonText = "Import",
        placeholder = "Click here and insert your roll settings string",
      })
    end)
  end

  addLevelRuleBtn:SetScript("OnClick", function()
    local profileName = GetSelectedProfileName(editor)
    if not GetLootProfileAccessInfo(profileName).canEditPointSettings then
      feedback:SetText("Your current role cannot edit point settings for this profile.")
      return
    end
    local ok, result = AddLootPointRule(profileName, {
      mode = "itemLevel",
      itemLevel = levelEdit:GetText(),
      points = pointsEdit:GetText(),
    })
    if ok then
      levelEdit:SetText("")
      pointsEdit:SetText("")
      if editor.Refresh then editor:Refresh() end
    else
      feedback:SetText(tostring(result or "Could not add item-level rule."))
    end
  end)

  addItemRuleBtn:SetScript("OnClick", function()
    local profileName = GetSelectedProfileName(editor)
    if not GetLootProfileAccessInfo(profileName).canEditPointSettings then
      feedback:SetText("Your current role cannot edit point settings for this profile.")
      return
    end
    local selectedItemID = ExtractItemID(editor.__lootSelectedRuleItemID)
    local selectedItem = FindSeasonLootEntry(selectedItemID)
    local ok, result = AddLootPointRule(profileName, {
      mode = "item",
      itemID = selectedItem and selectedItem.itemID or selectedItemID,
      itemName = selectedItem and selectedItem.name or editor.__lootSelectedRuleItemName,
      itemLink = selectedItem and selectedItem.link or editor.__lootSelectedRuleItemLink,
      itemLevel = selectedItem and selectedItem.itemLevel or editor.__lootSelectedRuleItemLevel,
      points = pointsEdit:GetText(),
    })
    if ok then
      pointsEdit:SetText("")
      if editor.Refresh then editor:Refresh() end
    else
      feedback:SetText(tostring(result or "Could not add item rule."))
    end
  end)

  removeRuleBtn:SetScript("OnClick", function()
    local profileName = GetSelectedProfileName(editor)
    if not GetLootProfileAccessInfo(profileName).canEditPointSettings then
      feedback:SetText("Your current role cannot edit point settings for this profile.")
      return
    end
    local profile = GetLootProfile(profileName)
    local rules = profile.settings and profile.settings.pointRules or {}
    local ok, result = RemoveLootPointRule(profileName, #rules)
    if not ok then
      feedback:SetText(tostring(result or "Could not remove the point rule."))
      return
    end
    if editor.Refresh then editor:Refresh() end
  end)

  if pointExportBtn then
    pointExportBtn:SetScript("OnClick", function()
      local exportPointSettings = ResolveOptionalApiFunction("LIDCOUNCIL_ExportLootPointSettings")
      local showExportWindow = ResolveOptionalApiFunction("LIDCOUNCIL_ShowExportWindow")
      if type(exportPointSettings) ~= "function" or type(showExportWindow) ~= "function" then
        feedback:SetText("Point settings export window unavailable.")
        return
      end
      local profileName = GetSelectedProfileName(editor)
      if not GetLootProfileAccessInfo(profileName).canEditPointSettings then
        feedback:SetText("Your current role cannot edit point settings for this profile.")
        return
      end
      local exported = exportPointSettings(profileName)
      if not exported then
        feedback:SetText("Point settings export failed.")
        return
      end
      showExportWindow(profileName .. " Point Settings", exported)
    end)
  end

  if pointImportStringBtn then
    pointImportStringBtn:SetScript("OnClick", function()
      local importPointSettings = ResolveOptionalApiFunction("LIDCOUNCIL_ImportLootPointSettings")
      local showImportWindow = ResolveOptionalApiFunction("LIDCOUNCIL_ShowSettingsImportWindow")
      if type(importPointSettings) ~= "function" or type(showImportWindow) ~= "function" then
        feedback:SetText("Point settings import window unavailable.")
        return
      end
      local profileName = GetSelectedProfileName(editor)
      if not GetLootProfileAccessInfo(profileName).canEditPointSettings then
        feedback:SetText("Your current role cannot edit point settings for this profile.")
        return
      end
      showImportWindow(function(_, pasted)
        local ok, result = importPointSettings(profileName, pasted)
        if not ok then
          feedback:SetText(tostring(result or "Could not import point settings."))
          return
        end
        feedback:SetText("Imported point settings.")
        if editor.Refresh then editor:Refresh() end
      end, {
        title = "Import Point Settings",
        requireName = false,
        buttonText = "Import",
        placeholder = "Click here and insert your point settings string",
      })
    end)
  end

  editor.RefreshLootProfilePage = function(self)
    RefreshProfilePage(self)
    if self and (not self.__refreshing) and self.ApplyTheme then
      self:ApplyTheme()
    end
  end
  editor.LayoutLootProfilePage = LayoutProfileContent
end

INTERNAL_API.LIDCOUNCIL_BuildLootProfilesPage_Impl = BuildLootProfilesPage

