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 ApplyFrameSkin = shared.ApplyFrameSkin

local function CreateLootProfileMemberHelpers(context)
  context = type(context) == "table" and context or {}
  local editor = context.editor
  local rightContent = context.rightContent

  local function ApplyProfileActionButtonStyle(button, variant)
    if not button then
      return
    end

    local normal = { 0.10, 0.10, 0.13, 0.98 }
    local hover = { 0.14, 0.14, 0.18, 0.98 }
    local text = { 1.00, 0.82, 0.24, 1.00 }
    local disabledText = { 0.50, 0.50, 0.56, 1.00 }

    if variant == "promote" then
      normal = { 0.08, 0.17, 0.12, 0.98 }
      hover = { 0.12, 0.23, 0.16, 0.98 }
      text = { 0.54, 0.94, 0.68, 1.00 }
    elseif variant == "degrade" then
      normal = { 0.18, 0.10, 0.09, 0.98 }
      hover = { 0.24, 0.13, 0.11, 0.98 }
      text = { 1.00, 0.66, 0.58, 1.00 }
    end

    button.__normalBackdrop = normal
    button.__hoverBackdrop = hover
    button.__normalTextColor = text
    button.__disabledTextColor = disabledText
    if button.SetBackdropColor then
      button:SetBackdropColor(normal[1], normal[2], normal[3], normal[4])
    end
    if button.label and button.label.SetTextColor then
      if button.IsEnabled and not button:IsEnabled() then
        button.label:SetTextColor(disabledText[1], disabledText[2], disabledText[3], disabledText[4])
      else
        button.label:SetTextColor(text[1], text[2], text[3], text[4])
      end
    end
  end

  local function EnsureProfileMemberRows(storageKey, parent, count)
    editor[storageKey] = editor[storageKey] or {}
    local rows = editor[storageKey]
    while #rows < count do
      local row = CreateFrame("Frame", nil, parent or rightContent, "BackdropTemplate")
      ApplyFrameSkin(row)
      if row.SetBackdropColor then
        row:SetBackdropColor(0.06, 0.06, 0.08, 0.98)
      end
      row:SetHeight(40)

      local icon = row:CreateTexture(nil, "ARTWORK")
      icon:SetSize(18, 18)
      row.icon = icon

      local nameText = row:CreateFontString(nil, "OVERLAY", "GameFontNormal")
      nameText:SetJustifyH("LEFT")
      if nameText.SetMaxLines then
        nameText:SetMaxLines(1)
      end
      row.nameText = nameText

      local metaText = row:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall")
      metaText:SetJustifyH("LEFT")
      if metaText.SetMaxLines then
        metaText:SetMaxLines(1)
      end
      row.metaText = metaText

      local actionBtn = CreateFrame("Button", nil, row, "BackdropTemplate")
      ApplyFrameSkin(actionBtn)
      actionBtn:SetSize(84, 22)
      actionBtn.label = actionBtn:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall")
      actionBtn.label:SetPoint("CENTER", 0, 0)
      actionBtn:SetScript("OnEnter", function(self)
        if self.SetBackdropColor and self.__hoverBackdrop then
          self:SetBackdropColor(self.__hoverBackdrop[1], self.__hoverBackdrop[2], self.__hoverBackdrop[3], self.__hoverBackdrop[4])
        end
      end)
      actionBtn: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)
      actionBtn:Hide()
      row.actionBtn = actionBtn

      rows[#rows + 1] = row
    end
    return rows
  end

  local function RefreshProfileMemberRows(storageKey, parent, characters, profile, roleValue)
    local rows = EnsureProfileMemberRows(storageKey, parent, #characters)
    local totalHeight = 0
    local access = context.GetLootProfileAccessInfo(context.GetSelectedProfileName(editor))
    local canManageRoles = access and access.canManageRoles
    for index, row in ipairs(rows) do
      local characterKey = characters[index]
      if characterKey then
        local display = context.ResolveProfileMemberDisplay(profile, characterKey)
        local iconData = context.ResolveProfileIconData(display)
        local r, g, b = context.GetProfileClassColor(display.classFile)
        local metaParts = {}
        local actionVisible = false
        if context.TrimText(display.specName) ~= "" then
          metaParts[#metaParts + 1] = display.specName
        end
        if context.TrimText(display.className) ~= "" then
          metaParts[#metaParts + 1] = display.className
        end
        row:ClearAllPoints()
        row:SetPoint("TOPLEFT", parent, "TOPLEFT", 0, -((index - 1) * 44))
        row:SetPoint("TOPRIGHT", parent, "TOPRIGHT", 0, -((index - 1) * 44))
        row:SetHeight(40)
        local isSelected = string.lower(context.TrimText(editor.__lootProfileRoleTarget or "")) == string.lower(characterKey)
        row.icon:ClearAllPoints()
        row.icon:SetPoint("TOPLEFT", 8, -10)
        context.ApplyProfileIcon(row.icon, iconData)
        if row.actionBtn then
          row.actionBtn:ClearAllPoints()
          row.actionBtn:SetPoint("RIGHT", row, "RIGHT", -8, 0)
          local actionVariant = string.upper(context.TrimText(roleValue)) == "COUNCIL" and "degrade" or "promote"
          if row.actionBtn.label then
            row.actionBtn.label:SetText(actionVariant == "degrade" and "Degrade" or "Promote")
          end
          ApplyProfileActionButtonStyle(row.actionBtn, actionVariant)
          actionVisible = isSelected and canManageRoles
          row.actionBtn:SetShown(actionVisible)
          if row.actionBtn.Enable then
            if actionVisible then
              row.actionBtn:Enable()
            else
              row.actionBtn:Disable()
            end
          end
          ApplyProfileActionButtonStyle(row.actionBtn, actionVariant)
          row.actionBtn:SetScript("OnClick", function()
            local profileName = context.GetSelectedProfileName(editor)
            local nextRole = string.upper(context.TrimText(roleValue)) == "COUNCIL" and "RAIDER" or "COUNCIL"
            local ok, result = context.SetLootProfileMemberRole(profileName, characterKey, nextRole)
            if ok then
              local verifiedRole = nil
              for _, entry in ipairs(context.GetLootProfileRoleEntries(profileName) or {}) do
                if string.lower(context.TrimText(entry and entry.character)) == string.lower(characterKey) then
                  verifiedRole = string.upper(context.TrimText(entry.role))
                  break
                end
              end
              if verifiedRole ~= string.upper(context.TrimText(result or nextRole)) and type(context.ForceLocalRoleState) == "function" then
                context.ForceLocalRoleState(profileName, characterKey, result or nextRole)
              end
              editor.__lootProfileRoleTarget = characterKey
              editor.__lootProfileRoleValue = string.upper(context.TrimText(result or nextRole))
              if context.feedback and context.feedback.SetText then
                context.feedback:SetText(string.format("%s is now %s.", tostring(characterKey), context.FormatLootProfileRoleLabel(result or nextRole)))
              end
              local broadcastRoleUpdate = context.ResolveOptionalApiFunction("LIDCOUNCIL_BroadcastActiveSessionRoleUpdate")
              if type(broadcastRoleUpdate) == "function" then
                broadcastRoleUpdate(profileName, characterKey)
              end
              if editor.Refresh then
                editor:Refresh()
              end
            else
              if context.feedback and context.feedback.SetText then
                context.feedback:SetText(tostring(result or "Could not update the profile role."))
              end
            end
          end)
        end
        row.nameText:ClearAllPoints()
        row.nameText:SetPoint("TOPLEFT", row, "TOPLEFT", 36, -8)
        row.nameText:SetPoint("RIGHT", row, "RIGHT", actionVisible and -92 or -8, 0)
        row.nameText:SetText(tostring(characterKey))
        row.nameText:SetTextColor(r, g, b, 1)
        row.metaText:ClearAllPoints()
        row.metaText:SetPoint("TOPLEFT", row, "TOPLEFT", 36, -24)
        row.metaText:SetPoint("RIGHT", row, "RIGHT", actionVisible and -92 or -8, 0)
        row.metaText:SetText(#metaParts > 0 and table.concat(metaParts, " | ") or "Class data not known yet.")
        row.__roleValue = roleValue
        row.__characterKey = characterKey
        context.SetListButtonSelected(row, isSelected)
        row:SetScript("OnMouseUp", function(_, button)
          if button ~= "LeftButton" then
            return
          end
          if type(context.SelectProfileRoleTarget) == "function" then
            context.SelectProfileRoleTarget(characterKey, roleValue)
          end
          if editor.Refresh then
            editor:Refresh()
          end
        end)
        row:Show()
        totalHeight = totalHeight + 44
      else
        if row.actionBtn then
          row.actionBtn:SetScript("OnClick", nil)
          if row.actionBtn.Enable then
            row.actionBtn:Disable()
          end
          row.actionBtn:Hide()
        end
        row:SetScript("OnMouseUp", nil)
        row:Hide()
      end
    end
    for index = #characters + 1, #rows do
      rows[index]:Hide()
    end
    if parent and parent.SetHeight then
      parent:SetHeight(math.max(1, totalHeight))
    end
    return totalHeight
  end

  return {
    ApplyProfileActionButtonStyle = ApplyProfileActionButtonStyle,
    RefreshProfileMemberRows = RefreshProfileMemberRows,
  }
end

INTERNAL_API.LIDCOUNCIL_CreateLootProfileMemberHelpers_Impl = CreateLootProfileMemberHelpers
