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 RequireApi = INTERNAL_API.LIDCOUNCIL_RequireApi_Impl
local RegisterTutorialTexture = INTERNAL_API.LIDCOUNCIL_RegisterTutorialTexture_Impl
local SetDropdownSelection = INTERNAL_API.LIDCOUNCIL_SetDropdownSelection_Impl
local GetDropdownMenuWidth = INTERNAL_API.LIDCOUNCIL_GetDropdownMenuWidth_Impl
local BindMouseWheelScroll = INTERNAL_API.LIDCOUNCIL_BindMouseWheelScroll_Impl
local BindScrollChildWidth = INTERNAL_API.LIDCOUNCIL_BindScrollChildWidth_Impl
if type(RequireApi) ~= "function"
  or type(RegisterTutorialTexture) ~= "function"
  or type(SetDropdownSelection) ~= "function"
  or type(GetDropdownMenuWidth) ~= "function"
  or type(BindMouseWheelScroll) ~= "function"
  or type(BindScrollChildWidth) ~= "function" then
  error("LidCouncil missing shared editor page helpers.")
end

local RootDB = RequireApi("LIDCOUNCIL_RootDB", _G.LIDCOUNCIL_RootDB)
local EnsureDefaults = RequireApi("LIDCOUNCIL_EnsureDefaults", _G.LIDCOUNCIL_EnsureDefaults)
local Print = RequireApi("LIDCOUNCIL_Print", _G.LIDCOUNCIL_Print)
local ExportProfile = RequireApi("LIDCOUNCIL_ExportProfile", _G.LIDCOUNCIL_ExportProfile)
local ImportProfile = RequireApi("LIDCOUNCIL_ImportProfile", _G.LIDCOUNCIL_ImportProfile)
local GetCurrentSpecID = RequireApi("LIDCOUNCIL_GetCurrentSpecID", _G.LIDCOUNCIL_GetCurrentSpecID)
local GetCharacterKey = RequireApi("LIDCOUNCIL_GetCharacterKey", _G.LIDCOUNCIL_GetCharacterKey)
local GetCharacterList = RequireApi("LIDCOUNCIL_GetCharacterList", _G.LIDCOUNCIL_GetCharacterList)
local ApplyFrameSkin = RequireApi("LIDCOUNCIL_ApplyFrameSkin", _G.LIDCOUNCIL_ApplyFrameSkin)
local MakeYellowSubHeader = RequireApi("LIDCOUNCIL_MakeYellowSubHeader", _G.LIDCOUNCIL_MakeYellowSubHeader)
local CARD_W = RequireApi("LIDCOUNCIL_CARD_W", _G.LIDCOUNCIL_CARD_W)
local CARD_H = RequireApi("LIDCOUNCIL_CARD_H", _G.LIDCOUNCIL_CARD_H)
local RebuildAllPanels = RequireApi("LIDCOUNCIL_RebuildAllPanels", _G.LIDCOUNCIL_RebuildAllPanels)
local SwitchProfile = RequireApi("LIDCOUNCIL_SwitchProfile", _G.LIDCOUNCIL_SwitchProfile)
local ShowExportWindow = RequireApi("LIDCOUNCIL_ShowExportWindow", _G.LIDCOUNCIL_ShowExportWindow)
local ShowImportWindow = RequireApi("LIDCOUNCIL_ShowImportWindow", _G.LIDCOUNCIL_ShowImportWindow)
local CreateCustomDropdownControl = RequireApi("LIDCOUNCIL_CreateCustomDropdownControl", _G.LIDCOUNCIL_CreateCustomDropdownControl)

local LogSilent = rawget(_G, "LIDCOUNCIL_LogSilent")

local PROFILE_DROPDOWN_PAGE_SIZE = 19
local PROFILE_DROPDOWN_WIDTH = 250

local function RefreshProfilesList(editor)
  if editor.RefreshProfilesListSection then
    editor:RefreshProfilesListSection()
  elseif editor.RefreshProfilesSection then
    editor:RefreshProfilesSection()
  elseif editor.Refresh then
    editor:Refresh()
  end
end

local function RefreshProfileDetails(editor)
  if editor.RefreshProfileDetailsSection then
    editor:RefreshProfileDetailsSection()
  elseif editor.RefreshProfilesSection then
    editor:RefreshProfilesSection()
  elseif editor.Refresh then
    editor:Refresh()
  end
end

local function RefreshCurrentProfile(editor)
  if editor.RefreshCurrentProfileSections then
    editor:RefreshCurrentProfileSections()
  elseif editor.Refresh then
    editor:Refresh()
  end
end

local function SetCheckButtonLabel(checkButton, text)
  if not checkButton or not checkButton.GetName then return nil end
  local label = _G[checkButton:GetName() .. "Text"]
  if label then
    label:SetText(text or "")
  end
  return label
end

local function EnsureProfileAutoSwitchConfig(profile)
  if not profile then return nil end
  profile.profileSpec = profile.profileSpec or {
    enabled = false,
    mode = "SPEC",
    specID = nil,
    character = nil,
  }
  if profile.profileSpec.enabled == nil then
    profile.profileSpec.enabled = false
  end
  if profile.profileSpec.mode ~= "CHARACTER" then
    profile.profileSpec.mode = "SPEC"
  end
  return profile.profileSpec
end

local function GetCurrentCharacterKeyForProfiles()
  return GetCharacterKey and GetCharacterKey() or nil
end

local specOptionsCache

local function BuildSpecOptions()
  if specOptionsCache then
    return specOptionsCache
  end

  local options = {}
  local seen = {}
  if type(GetNumClasses) == "function"
    and type(GetNumSpecializationsForClassID) == "function"
    and type(GetSpecializationInfoForClassID) == "function"
    and type(GetClassInfo) == "function" then
    local numClasses = GetNumClasses()
    for classID = 1, numClasses do
      local className = select(1, GetClassInfo(classID))
      local specCount = GetNumSpecializationsForClassID(classID)
      for index = 1, specCount do
        local id, name, _, icon, role = GetSpecializationInfoForClassID(classID, index)
        if id and name and not seen[id] then
          local text = (className and (className .. "_" .. name)) or name
          if role then
            text = text .. " (" .. role .. ")"
          end
          options[#options + 1] = {
            id = id,
            text = text,
            icon = icon,
            iconSize = 16,
            iconXOffset = -8,
          }
          seen[id] = true
        end
      end
    end
  elseif type(GetNumSpecializations) == "function" and type(GetSpecializationInfo) == "function" then
    local specCount = GetNumSpecializations()
    for index = 1, specCount do
      local id, name, _, icon, role, className = GetSpecializationInfo(index)
      if id and name then
        local text = name
        if className then
          text = className .. "_" .. name
        end
        if role then
          text = text .. " (" .. role .. ")"
        end
        options[#options + 1] = {
          id = id,
          text = text,
          icon = icon,
          iconSize = 16,
          iconXOffset = -8,
        }
      end
    end
  end

  table.sort(options, function(a, b)
    return a.text < b.text
  end)
  specOptionsCache = options
  return specOptionsCache
end

local characterOptionsCacheKey
local characterOptionsCache

local function BuildCharacterOptions()
  local list = GetCharacterList and GetCharacterList() or {}
  if #list == 0 then
    local current = GetCurrentCharacterKeyForProfiles()
    if current then
      list = { current }
    end
  end

  local keyParts = {}
  for index, name in ipairs(list) do
    keyParts[index] = tostring(name or "")
  end
  local cacheKey = table.concat(keyParts, "\31")
  if characterOptionsCacheKey == cacheKey and characterOptionsCache then
    return characterOptionsCache
  end

  local cached = {}
  for index, name in ipairs(list) do
    cached[index] = name
  end
  characterOptionsCacheKey = cacheKey
  characterOptionsCache = cached
  return characterOptionsCache
end

local function ClampProfileDropdownPage(page, totalPages)
  if page < 1 then return 1 end
  if page > totalPages then return totalPages end
  return page
end

local function BuildProfilePagedEntries(editor, pageKey, options, currentValue, onSelect, opts)
  opts = opts or {}
  options = options or {}

  local total = #options
  local totalPages = math.max(1, math.ceil(total / PROFILE_DROPDOWN_PAGE_SIZE))
  local pages = editor.profileDropdownPages or {}
  local page = ClampProfileDropdownPage(pages[pageKey] or 1, totalPages)
  pages[pageKey] = page
  editor.profileDropdownPages = pages

  local first = ((page - 1) * PROFILE_DROPDOWN_PAGE_SIZE) + 1
  local last = math.min(total, first + PROFILE_DROPDOWN_PAGE_SIZE - 1)

  local extraLabels = {}
  for _, label in ipairs(opts.extraLabels or {}) do
    extraLabels[#extraLabels + 1] = label
  end
  if totalPages > 1 then
    extraLabels[#extraLabels + 1] = string.format("Page %d/%d", totalPages, totalPages)
    extraLabels[#extraLabels + 1] = "< Prev"
    extraLabels[#extraLabels + 1] = "Next >"
  end

  local listWidth = GetDropdownMenuWidth(
    editor,
    opts.measurerKey or "__lidLootProfileDropdownMeasurer",
    opts.minWidth or PROFILE_DROPDOWN_WIDTH,
    options,
    extraLabels,
    opts.maxWidth or 420
  )

  local entries = {}
  for index = first, last do
    local option = options[index]
    if option then
      local value = option.value or option.id
      entries[#entries + 1] = {
        text = option.text,
        value = value,
        icon = option.icon,
        iconSize = option.iconSize or (option.icon and 16 or nil),
        iconXOffset = option.iconXOffset,
        checked = (value == currentValue),
        func = function()
          if onSelect then
            onSelect(option)
          end
        end,
      }
    end
  end

  if totalPages > 1 then
    entries[#entries + 1] = {
      text = string.format("Page %d/%d", page, totalPages),
      isTitle = true,
      notCheckable = true,
    }
    entries[#entries + 1] = {
      text = "< Prev",
      notCheckable = true,
      disabled = (page <= 1),
      keepShownOnClick = true,
      func = function()
        local pagesRef = editor.profileDropdownPages or {}
        pagesRef[pageKey] = ClampProfileDropdownPage(page - 1, totalPages)
        editor.profileDropdownPages = pagesRef
      end,
    }
    entries[#entries + 1] = {
      text = "Next >",
      notCheckable = true,
      disabled = (page >= totalPages),
      keepShownOnClick = true,
      func = function()
        local pagesRef = editor.profileDropdownPages or {}
        pagesRef[pageKey] = ClampProfileDropdownPage(page + 1, totalPages)
        editor.profileDropdownPages = pagesRef
      end,
    }
  end

  local function OnMouseWheel(delta)
    if totalPages <= 1 then
      return false
    end
    local pagesRef = editor.profileDropdownPages or {}
    local currentPage = ClampProfileDropdownPage(pagesRef[pageKey] or 1, totalPages)
    local targetPage = ClampProfileDropdownPage(currentPage - delta, totalPages)
    if targetPage == currentPage then
      return false
    end
    pagesRef[pageKey] = targetPage
    editor.profileDropdownPages = pagesRef
    return true
  end

  return entries, listWidth, OnMouseWheel
end

local function BuildProfilesPage(editor, profilesPage)
  if not editor or not profilesPage then return end

  local profTitle = profilesPage:CreateFontString(nil, "OVERLAY", "GameFontHighlight")
  profTitle:SetPoint("TOPLEFT", 0, 0)
  profTitle:SetText("Profiles")

  local currentLabel = profilesPage:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall")
  currentLabel:SetPoint("TOPLEFT", 0, -22)
  editor.profileLabel = currentLabel

  local profListBg = CreateFrame("Frame", nil, profilesPage, "BackdropTemplate")
  profListBg:SetPoint("TOPLEFT", 0, -44)
  profListBg:SetPoint("BOTTOMLEFT", 0, 0)
  profListBg:SetWidth(240)
  ApplyFrameSkin(profListBg)
  editor.profListBg = profListBg

  local profScroll = CreateFrame("ScrollFrame", nil, profListBg, "UIPanelScrollFrameTemplate")
  profScroll:SetPoint("TOPLEFT", 6, -6)
  profScroll:SetPoint("BOTTOMRIGHT", -28, 64)
  editor.profScroll = profScroll

  local profContent = CreateFrame("Frame", nil, profScroll)
  profContent:SetSize(1, 1)
  profScroll:SetScrollChild(profContent)
  editor.profContent = profContent
  editor.profButtons = {}
  editor.selectedProfileName = nil
  editor.selectedProfileGroupName = nil

  local profPrevBtn = CreateFrame("Button", nil, profListBg, "UIPanelButtonTemplate")
  profPrevBtn:SetSize(60, 20)
  profPrevBtn:SetPoint("BOTTOMLEFT", 6, 34)
  profPrevBtn:SetText("< Prev")
  profPrevBtn:SetScript("OnClick", function()
    editor.profListPage = math.max(1, (editor.profListPage or 1) - 1)
    RefreshProfilesList(editor)
  end)
  editor.profPrevBtn = profPrevBtn

  local profNextBtn = CreateFrame("Button", nil, profListBg, "UIPanelButtonTemplate")
  profNextBtn:SetSize(60, 20)
  profNextBtn:SetPoint("BOTTOMLEFT", 138, 34)
  profNextBtn:SetText("Next >")
  profNextBtn:SetScript("OnClick", function()
    editor.profListPage = (editor.profListPage or 1) + 1
    RefreshProfilesList(editor)
  end)
  editor.profNextBtn = profNextBtn

  local profPageText = profListBg:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall")
  profPageText:SetPoint("LEFT", profPrevBtn, "RIGHT", 8, 0)
  profPageText:SetWidth(64)
  profPageText:SetJustifyH("CENTER")
  editor.profPageText = profPageText

  local newProfBtn = CreateFrame("Button", nil, profListBg, "UIPanelButtonTemplate")
  newProfBtn:SetSize(96, 22)
  newProfBtn:SetPoint("BOTTOMLEFT", 6, 8)
  newProfBtn:SetText("Create Profile")
  newProfBtn:SetScript("OnClick", function()
    StaticPopup_Show("LIDCOUNCIL_CREATE_PROFILE")
  end)
  editor.newProfBtn = newProfBtn

  local newProfGroupBtn = CreateFrame("Button", nil, profListBg, "UIPanelButtonTemplate")
  newProfGroupBtn:SetSize(96, 22)
  newProfGroupBtn:SetPoint("LEFT", newProfBtn, "RIGHT", 8, 0)
  newProfGroupBtn:SetText("Create Group")
  newProfGroupBtn:SetScript("OnClick", function()
    StaticPopup_Show("LIDCOUNCIL_CREATE_PROFILE_GROUP")
  end)
  editor.newProfGroupBtn = newProfGroupBtn

  local profRightBg = CreateFrame("Frame", nil, profilesPage, "BackdropTemplate")
  profRightBg:SetPoint("TOPLEFT", profListBg, "TOPRIGHT", 12, 0)
  profRightBg:SetPoint("BOTTOMRIGHT", 0, 0)
  ApplyFrameSkin(profRightBg)
  editor.profRightBg = profRightBg

  local profRightScroll = CreateFrame("ScrollFrame", nil, profRightBg, "UIPanelScrollFrameTemplate")
  profRightScroll:SetPoint("TOPLEFT", 18, -12)
  profRightScroll:SetPoint("BOTTOMRIGHT", -28, 12)
  BindMouseWheelScroll(profRightScroll)

  local profRight = CreateFrame("Frame", nil, profRightScroll)
  profRight:SetSize(1, 1)
  profRightScroll:SetScrollChild(profRight)
  editor.profRightScroll = profRightScroll
  BindScrollChildWidth(profRightScroll, profRight, {
    logSilent = LogSilent,
    warningPrefix = "Profiles right scroll OnSizeChanged failed: ",
  })

  local profGroupScroll = CreateFrame("ScrollFrame", nil, profRightBg, "UIPanelScrollFrameTemplate")
  profGroupScroll:SetPoint("TOPLEFT", 18, -12)
  profGroupScroll:SetPoint("BOTTOMRIGHT", -28, 12)
  BindMouseWheelScroll(profGroupScroll)
  profGroupScroll:Hide()
  editor.profGroupScroll = profGroupScroll

  local profGroup = CreateFrame("Frame", nil, profGroupScroll)
  profGroup:SetSize(1, 1)
  profGroupScroll:SetScrollChild(profGroup)
  editor.profGroupFrame = profGroup
  BindScrollChildWidth(profGroupScroll, profGroup, {
    logSilent = LogSilent,
    warningPrefix = "Profiles group scroll OnSizeChanged failed: ",
  })

  local profWelcomeScroll = CreateFrame("ScrollFrame", nil, profRightBg, "UIPanelScrollFrameTemplate")
  profWelcomeScroll:SetPoint("TOPLEFT", 18, -12)
  profWelcomeScroll:SetPoint("BOTTOMRIGHT", -28, 12)
  BindMouseWheelScroll(profWelcomeScroll)
  profWelcomeScroll:Hide()
  editor.profWelcomeScroll = profWelcomeScroll

  local profWelcomeFrame = CreateFrame("Frame", nil, profWelcomeScroll)
  profWelcomeFrame:SetPoint("TOPLEFT", 0, 0)
  profWelcomeFrame:SetSize(1, 1)
  profWelcomeFrame:SetClipsChildren(true)
  profWelcomeScroll:SetScrollChild(profWelcomeFrame)
  editor.profWelcomeFrame = profWelcomeFrame
  BindScrollChildWidth(profWelcomeScroll, profWelcomeFrame, {
    onResize = function()
      if editor and editor.LayoutProfileWelcome then
        editor:LayoutProfileWelcome()
      end
    end,
    logSilent = LogSilent,
    warningPrefix = "Profiles welcome scroll OnSizeChanged failed: ",
  })

  local welcomeHeader = profWelcomeFrame:CreateTexture(nil, "ARTWORK")
  welcomeHeader:SetPoint("TOPLEFT", 18, -18)
  RegisterTutorialTexture(editor, welcomeHeader, "Interface\\AddOns\\LidCouncil\\Media\\LidCouncil\\Tutorials\\Profiles_1_Title.tga")
  welcomeHeader:SetTexCoord(0, 1, 0, 1)
  editor.profWelcomeHeader = welcomeHeader

  local function MakeProfileCard(parent, texturePath)
    local card = CreateFrame("Frame", nil, parent)
    card:SetPoint("TOPLEFT", 0, 0)
    card:SetSize(CARD_W, CARD_H)

    local texture = card:CreateTexture(nil, "ARTWORK")
    texture:SetPoint("TOPLEFT", 0, 0)
    texture:SetPoint("BOTTOMRIGHT", 0, 0)
    RegisterTutorialTexture(editor, texture, texturePath)
    texture:SetTexCoord(0, 1, 0, 1)
    card.texObj = texture
    return card
  end

  editor.profWelcomeCards = {
    MakeProfileCard(profWelcomeFrame, "Interface\\AddOns\\LidCouncil\\Media\\LidCouncil\\Tutorials\\Profile_2_Step1.tga"),
    MakeProfileCard(profWelcomeFrame, "Interface\\AddOns\\LidCouncil\\Media\\LidCouncil\\Tutorials\\Profile_3_Step2.tga"),
    MakeProfileCard(profWelcomeFrame, "Interface\\AddOns\\LidCouncil\\Media\\LidCouncil\\Tutorials\\Profile_4_Step3.tga"),
    MakeProfileCard(profWelcomeFrame, "Interface\\AddOns\\LidCouncil\\Media\\LidCouncil\\Tutorials\\Profile_5_Step4.tga"),
  }

  function editor:LayoutProfileWelcome()
    if not self.profWelcomeFrame or not self.profWelcomeCards then return end
    local availableWidth = self.profWelcomeFrame:GetWidth()
    if not availableWidth or availableWidth < 1 then return end

    local leftPad = 18
    local cols = 2
    local gap = 20
    local rowWidth = availableWidth - leftPad
    local cardWidth = math.max(1, math.floor((rowWidth - gap) / 2))
    local cardHeight = math.floor(cardWidth * 0.75)
    local headerWidth = (cardWidth * 2) + gap
    local headerHeight = math.floor(cardHeight * 0.6)

    if self.profWelcomeHeader then
      self.profWelcomeHeader:SetSize(headerWidth, headerHeight)
      self.profWelcomeHeader:ClearAllPoints()
      self.profWelcomeHeader:SetPoint("TOPLEFT", leftPad, -18)
    end

    local y = -18 - headerHeight - 20
    local index = 1
    for row = 1, 2 do
      for col = 1, cols do
        local card = self.profWelcomeCards[index]
        if not card then break end
        local x = leftPad + ((col - 1) * (cardWidth + gap))
        card:SetSize(cardWidth, cardHeight)
        card:ClearAllPoints()
        card:SetPoint("TOPLEFT", x, y)
        index = index + 1
      end
      y = y - cardHeight - 20
    end

    local contentHeight = math.max(400, (-y) + 80)
    self.profWelcomeFrame:SetHeight(contentHeight)
    if self.profWelcomeScroll and self.profWelcomeScroll.UpdateScrollChildRect then
      self.profWelcomeScroll:UpdateScrollChildRect()
    end
  end

  local selProf = profRight:CreateFontString(nil, "OVERLAY", "GameFontHighlight")
  selProf:SetPoint("TOPLEFT", 0, 0)
  selProf:SetText("Selected: (none)")
  editor.selProfLabel = selProf

  local selProfGroup = profGroup:CreateFontString(nil, "OVERLAY", "GameFontHighlight")
  selProfGroup:SetPoint("TOPLEFT", 0, 0)
  selProfGroup:SetText("Selected Group: (none)")
  editor.selProfGroupLabel = selProfGroup

  MakeYellowSubHeader(profGroup, "Modify Group", 0, -26)

  local renameProfGroupBtn = CreateFrame("Button", nil, profGroup, "UIPanelButtonTemplate")
  renameProfGroupBtn:SetSize(160, 22)
  renameProfGroupBtn:SetPoint("TOPLEFT", 0, -50)
  renameProfGroupBtn:SetText("Rename Group")
  renameProfGroupBtn:SetScript("OnClick", function()
    if not editor.selectedProfileGroupName then return end
    StaticPopup_Show("LIDCOUNCIL_RENAME_PROFILE_GROUP")
  end)
  editor.renameProfGroupBtn = renameProfGroupBtn

  local delProfGroupBtn = CreateFrame("Button", nil, profGroup, "UIPanelButtonTemplate")
  delProfGroupBtn:SetSize(160, 22)
  delProfGroupBtn:SetPoint("TOPLEFT", 0, -78)
  delProfGroupBtn:SetText("Delete Group")
  delProfGroupBtn:SetScript("OnClick", function()
    if not editor.selectedProfileGroupName then return end
    StaticPopup_Show("LIDCOUNCIL_DELETE_PROFILE_GROUP", editor.selectedProfileGroupName)
  end)
  editor.delProfGroupBtn = delProfGroupBtn

  local profGroupInfo = profGroup:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall")
  profGroupInfo:SetPoint("TOPLEFT", 0, -118)
  profGroupInfo:SetWidth(520)
  profGroupInfo:SetJustifyH("LEFT")
  profGroupInfo:SetText("Deleting a group will only ungroup its profiles.")
  editor.profGroupInfoLabel = profGroupInfo
  profGroup:SetHeight(220)

  MakeYellowSubHeader(profRight, "Activate Profile", 0, -26)

  local activateBtn = CreateFrame("Button", nil, profRight, "UIPanelButtonTemplate")
  activateBtn:SetSize(120, 22)
  activateBtn:SetPoint("TOPLEFT", 0, -50)
  activateBtn:SetText("Activate")
  activateBtn:SetScript("OnClick", function()
    if not editor.selectedProfileName then return end
    SwitchProfile(editor.selectedProfileName)
    EnsureDefaults()
    RebuildAllPanels()
    RefreshCurrentProfile(editor)
    Print("Loaded profile: " .. editor.selectedProfileName)
  end)
  editor.activateBtn = activateBtn

  local deactivateBtn = CreateFrame("Button", nil, profRight, "UIPanelButtonTemplate")
  deactivateBtn:SetSize(120, 22)
  deactivateBtn:SetPoint("LEFT", activateBtn, "RIGHT", 10, 0)
  deactivateBtn:SetText("Deactivate")
  deactivateBtn:SetScript("OnClick", function()
    SwitchProfile("Default")
    EnsureDefaults()
    RebuildAllPanels()
    RefreshCurrentProfile(editor)
    Print("No active profile.")
  end)
  editor.deactivateBtn = deactivateBtn

  MakeYellowSubHeader(profRight, "Automatic Profile Change", 0, -90)

  local specDesc = profRight:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall")
  specDesc:SetPoint("TOPLEFT", 0, -114)
  specDesc:SetWidth(520)
  specDesc:SetJustifyH("LEFT")
  specDesc:SetText("If this option is activated, this profile will automatically activate when you change to the selected specialization. You can optionally limit this behavior to a specific character.")
  editor.specDesc = specDesc

  local specAutoCheck = CreateFrame("CheckButton", "LIDCOUNCIL_SpecAutoCheck", profRight, "UICheckButtonTemplate")
  specAutoCheck:SetPoint("TOPLEFT", 0, -158)
  SetCheckButtonLabel(specAutoCheck, "Activate automatic profile change")
  editor.specAutoCheck = specAutoCheck

  local modeLabel = profRight:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall")
  modeLabel:SetPoint("TOPLEFT", 0, -196)
  modeLabel:SetText("Change Mode")
  editor.profileModeLabel = modeLabel

  local modeDrop = CreateCustomDropdownControl(editor, profRight, {
    width = 250,
    text = "Change by Specialization",
  })
  modeDrop:SetPoint("TOPLEFT", -12, -210)
  editor.profileModeDrop = modeDrop

  local charLabel = profRight:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall")
  charLabel:SetPoint("TOPLEFT", 0, -246)
  charLabel:SetText("Optional Character Filter")
  editor.charLabel = charLabel

  local charDrop = CreateCustomDropdownControl(editor, profRight, {
    width = 250,
    text = "Any character",
  })
  charDrop:SetPoint("TOPLEFT", -12, -260)
  editor.charDrop = charDrop

  local specLabel = profRight:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall")
  specLabel:SetPoint("TOPLEFT", 0, -296)
  specLabel:SetText("Choose Specialization")
  editor.specLabel = specLabel

  local specDrop = CreateCustomDropdownControl(editor, profRight, {
    width = 250,
    text = "Unbound",
  })
  specDrop:SetPoint("TOPLEFT", -12, -310)
  editor.specDrop = specDrop

  modeDrop:SetMenuBuilder(function()
    local currentMode = "SPEC"
    if editor.selectedProfileName then
      local profile = RootDB().profiles[editor.selectedProfileName]
      local profileSpec = EnsureProfileAutoSwitchConfig(profile)
      currentMode = profileSpec and profileSpec.mode or "SPEC"
    end

    local function ApplyMode(mode, text)
      SetDropdownSelection(modeDrop, mode, text)
      if editor.selectedProfileName then
        local profile = RootDB().profiles[editor.selectedProfileName]
        local profileSpec = EnsureProfileAutoSwitchConfig(profile)
        profileSpec.mode = mode
        if mode == "CHARACTER" then
          if not profileSpec.character then
            profileSpec.character = GetCurrentCharacterKeyForProfiles()
          end
        elseif not profileSpec.specID then
          profileSpec.specID = GetCurrentSpecID()
        end
        RefreshProfileDetails(editor)
      end
    end

    return {
      entries = {
        {
          text = "Change by Specialization",
          value = "SPEC",
          checked = (currentMode == "SPEC"),
          func = function()
            ApplyMode("SPEC", "Change by Specialization")
          end,
        },
        {
          text = "Change by Character",
          value = "CHARACTER",
          checked = (currentMode == "CHARACTER"),
          func = function()
            ApplyMode("CHARACTER", "Change by Character")
          end,
        },
      },
      width = 250,
    }
  end)

  editor.profileDropdownPages = editor.profileDropdownPages or { spec = 1, character = 1 }

  specDrop:SetMenuBuilder(function()
    local entries = {}
    local currentSpecID = nil
    if editor.selectedProfileName then
      local profile = RootDB().profiles[editor.selectedProfileName]
      local profileSpec = EnsureProfileAutoSwitchConfig(profile)
      if profileSpec then
        currentSpecID = profileSpec.specID
      end
    end

    entries[#entries + 1] = {
      text = "Unbound",
      value = "NONE",
      checked = (currentSpecID == nil),
      func = function()
        SetDropdownSelection(specDrop, "NONE", "Unbound")
        if editor.selectedProfileName then
          local profile = RootDB().profiles[editor.selectedProfileName]
          local profileSpec = EnsureProfileAutoSwitchConfig(profile)
          profileSpec.specID = nil
          RefreshProfileDetails(editor)
        end
      end,
    }

    local pagedEntries, listWidth, onMouseWheel = BuildProfilePagedEntries(
      editor,
      "spec",
      BuildSpecOptions(),
      currentSpecID,
      function(option)
        SetDropdownSelection(specDrop, option.id, option.text)
        if editor.selectedProfileName then
          local profile = RootDB().profiles[editor.selectedProfileName]
          local profileSpec = EnsureProfileAutoSwitchConfig(profile)
          profileSpec.specID = option.id
          RefreshProfileDetails(editor)
        end
      end,
      {
        measurerKey = "__lidLootProfileSpecDropdownMeasurer",
        minWidth = PROFILE_DROPDOWN_WIDTH,
        extraLabels = { "Unbound" },
      }
    )

    for _, entry in ipairs(pagedEntries) do
      entries[#entries + 1] = entry
    end

    return {
      entries = entries,
      width = listWidth,
      onMouseWheel = onMouseWheel,
    }
  end)

  charDrop:SetMenuBuilder(function()
    local entries = {}
    local currentCharacter = nil
    local currentMode = "SPEC"
    if editor.selectedProfileName then
      local profile = RootDB().profiles[editor.selectedProfileName]
      local profileSpec = EnsureProfileAutoSwitchConfig(profile)
      if profileSpec then
        currentCharacter = profileSpec.character
        currentMode = profileSpec.mode or "SPEC"
      end
    end

    if currentMode == "SPEC" then
      entries[#entries + 1] = {
        text = "Any character",
        value = "ANY",
        checked = (currentCharacter == nil),
        func = function()
          SetDropdownSelection(charDrop, "ANY", "Any character")
          if editor.selectedProfileName then
            local profile = RootDB().profiles[editor.selectedProfileName]
            local profileSpec = EnsureProfileAutoSwitchConfig(profile)
            profileSpec.character = nil
            RefreshProfileDetails(editor)
          end
        end,
      }
    end

    local options = {}
    for _, name in ipairs(BuildCharacterOptions()) do
      options[#options + 1] = {
        text = name,
        value = name,
      }
    end

    local pagedEntries, listWidth, onMouseWheel = BuildProfilePagedEntries(
      editor,
      "character",
      options,
      currentCharacter,
      function(option)
        SetDropdownSelection(charDrop, option.value, option.text)
        if editor.selectedProfileName then
          local profile = RootDB().profiles[editor.selectedProfileName]
          local profileSpec = EnsureProfileAutoSwitchConfig(profile)
          profileSpec.character = option.value
          RefreshProfileDetails(editor)
        end
      end,
      {
        measurerKey = "__lidLootProfileCharacterDropdownMeasurer",
        minWidth = PROFILE_DROPDOWN_WIDTH,
        extraLabels = (currentMode == "SPEC") and { "Any character" } or nil,
      }
    )

    for _, entry in ipairs(pagedEntries) do
      entries[#entries + 1] = entry
    end

    return {
      entries = entries,
      width = listWidth,
      onMouseWheel = onMouseWheel,
    }
  end)

  specAutoCheck:SetScript("OnClick", function(self)
    if not editor.selectedProfileName then return end
    local profile = RootDB().profiles[editor.selectedProfileName]
    local profileSpec = EnsureProfileAutoSwitchConfig(profile)
    profileSpec.enabled = self:GetChecked() and true or false
    if profileSpec.enabled then
      if profileSpec.mode == "CHARACTER" then
        if not profileSpec.character then
          profileSpec.character = GetCurrentCharacterKeyForProfiles()
        end
      elseif not profileSpec.specID then
        profileSpec.specID = GetCurrentSpecID()
      end
    end
    RefreshProfileDetails(editor)
  end)

  MakeYellowSubHeader(profRight, "Modify Profile", 0, -370)

  local renameProfBtn = CreateFrame("Button", nil, profRight, "UIPanelButtonTemplate")
  renameProfBtn:SetSize(160, 22)
  renameProfBtn:SetPoint("TOPLEFT", 0, -394)
  renameProfBtn:SetText("Rename Profile")
  renameProfBtn:SetScript("OnClick", function()
    if not editor.selectedProfileName then return end
    StaticPopup_Show("LIDCOUNCIL_RENAME_PROFILE")
  end)
  editor.renameProfBtn = renameProfBtn

  local copyProfBtn = CreateFrame("Button", nil, profRight, "UIPanelButtonTemplate")
  copyProfBtn:SetSize(160, 22)
  copyProfBtn:SetPoint("TOPLEFT", 0, -422)
  copyProfBtn:SetText("Copy Profile")
  copyProfBtn:SetScript("OnClick", function()
    if not editor.selectedProfileName then return end
    StaticPopup_Show("LIDCOUNCIL_COPY_PROFILE")
  end)
  editor.copyProfBtn = copyProfBtn

  local delProfBtn = CreateFrame("Button", nil, profRight, "UIPanelButtonTemplate")
  delProfBtn:SetSize(160, 22)
  delProfBtn:SetPoint("TOPLEFT", 0, -450)
  delProfBtn:SetText("Delete Profile")
  delProfBtn:SetScript("OnClick", function()
    if not editor.selectedProfileName then return end
    StaticPopup_Show("LIDCOUNCIL_DELETE_PROFILE", editor.selectedProfileName)
  end)
  editor.delProfBtn = delProfBtn

  MakeYellowSubHeader(profRight, "Import and Export", 0, -490)

  local exportBtn = CreateFrame("Button", nil, profRight, "UIPanelButtonTemplate")
  exportBtn:SetSize(100, 20)
  exportBtn:SetPoint("TOPLEFT", 0, -514)
  exportBtn:SetText("Export")
  exportBtn:SetScript("OnClick", function()
    local root = RootDB()
    local profileName = editor.selectedProfileName or root.currentProfile
    local exported = ExportProfile(profileName)
    if not exported then
      Print("Export failed.")
      return
    end
    ShowExportWindow(profileName, exported)
  end)
  editor.exportBtn = exportBtn

  local importBtn = CreateFrame("Button", nil, profRight, "UIPanelButtonTemplate")
  importBtn:SetSize(100, 20)
  importBtn:SetPoint("LEFT", exportBtn, "RIGHT", 8, 0)
  importBtn:SetText("Import")
  importBtn:SetScript("OnClick", function()
    ShowImportWindow(function(newName, pasted)
      local ok = ImportProfile(newName, pasted)
      if ok then
        if editor and editor.InvalidateSortedNameCaches then
          editor:InvalidateSortedNameCaches()
        end
        if editor and editor.Refresh then
          editor:Refresh()
        end
      end
    end)
  end)
  editor.importBtn = importBtn

  profRight:SetHeight(580)
end

INTERNAL_API.LIDCOUNCIL_BuildProfilesPage_Impl = BuildProfilesPage
