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

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

  local TrimText = deps.TrimText
  local ClampLayoutValue = deps.ClampLayoutValue
  local BuildLootLedgerNavRows = deps.BuildLootLedgerNavRows
  local ToggleLootLedgerGroupCollapsedLocal = deps.ToggleLootLedgerGroupCollapsedLocal
  local ApplyLootLedgerTextureIcon = deps.ApplyLootLedgerTextureIcon
  local GetEditorThemePalette = deps.GetEditorThemePalette

  local LOOTLIST_CLASS_ICON_TEXTURE = "Interface\\GLUES\\CHARACTERCREATE\\UI-CHARACTERCREATE-CLASSES"

  local function GetLootListHighlightColors()
    local themePalette = GetEditorThemePalette and GetEditorThemePalette() or nil
    local active = type(themePalette) == "table" and themePalette.active or nil
    if type(active) ~= "table" then
      active = { 0.74, 0.22, 0.30, 0.92 }
    end
    return {
      active[1] or 0.74,
      active[2] or 0.22,
      active[3] or 0.30,
      0.18,
    }, {
      active[1] or 0.74,
      active[2] or 0.22,
      active[3] or 0.30,
      0.28,
    }
  end

  local function GetClassColorForRow(row)
    local classFile = TrimText(type(row) == "table" and row.classFile or "")
    local colorTable = (type(CUSTOM_CLASS_COLORS) == "table" and CUSTOM_CLASS_COLORS[classFile]) or (type(RAID_CLASS_COLORS) == "table" and RAID_CLASS_COLORS[classFile]) or nil
    if colorTable then
      return tonumber(colorTable.r or colorTable[1]) or 0.82, tonumber(colorTable.g or colorTable[2]) or 0.82, tonumber(colorTable.b or colorTable[3]) or 0.86, 1
    end
    return 0.82, 0.82, 0.86, 1
  end

  local function BuildSpecLabel(row)
    if type(row) ~= "table" then
      return "-"
    end
    local specName = TrimText(row.specName)
    if specName ~= "" then
      return specName
    end
    local className = TrimText(row.className)
    if className ~= "" then
      return className
    end
    return "-"
  end

  local function GetLootLedgerHeaderIconData(row)
    if type(row) ~= "table" then
      return nil
    end
    local specIcon = TrimText(row.specIcon)
    if specIcon ~= "" then
      return { texture = specIcon }
    end
    local classFile = TrimText(row.classFile)
    local coords = classFile ~= "" and type(CLASS_ICON_TCOORDS) == "table" and CLASS_ICON_TCOORDS[classFile] or nil
    if type(coords) == "table" then
      return {
        texture = LOOTLIST_CLASS_ICON_TEXTURE,
        fileWidth = 256,
        fileHeight = 256,
        left = coords[1],
        right = coords[2],
        top = coords[3],
        bottom = coords[4],
      }
    end
    return nil
  end

  local function EnsureLootLedgerRowFrames(rows, parent, count)
    rows = rows or {}
    while #rows < count do
      local button = CreateFrame("Button", nil, parent)
      button:SetSize(394, 22)
      button:EnableMouse(true)
      button:RegisterForClicks("LeftButtonUp")
      button:RegisterForDrag("LeftButton")

      local bg = button:CreateTexture(nil, "BACKGROUND")
      bg:SetAllPoints(true)
      bg:SetTexture("Interface\\Buttons\\WHITE8x8")
      bg:SetVertexColor(0.09, 0.06, 0.08, 0.88)
      button.__bg = bg

      local highlight = button:CreateTexture(nil, "ARTWORK")
      highlight:SetAllPoints(true)
      highlight:SetTexture("Interface\\Buttons\\WHITE8x8")
      highlight:SetVertexColor(0, 0, 0, 0)
      button.__highlight = highlight

      local arrowButton = CreateFrame("Button", nil, button)
      arrowButton:SetSize(16, 16)
      arrowButton:SetPoint("LEFT", 2, 0)
      local arrowText = arrowButton:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall")
      arrowText:SetAllPoints(true)
      arrowText:SetJustifyH("CENTER")
      arrowText:SetText("")
      button.__arrowButton = arrowButton
      button.__arrowText = arrowText

      local function MakeCol(x, width)
        local text = button:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall")
        text:SetPoint("LEFT", x, 0)
        text:SetWidth(width)
        text:SetJustifyH("LEFT")
        if text.SetMaxLines then
          text:SetMaxLines(1)
        end
        return text
      end

      local specIcon = button:CreateTexture(nil, "ARTWORK")
      specIcon:SetSize(16, 16)
      specIcon:SetPoint("LEFT", 22, 0)
      specIcon:SetTexture("Interface\\Icons\\INV_Misc_QuestionMark")
      button.__specIcon = specIcon

      button.__specText = MakeCol(42, 52)
      button.__nameText = MakeCol(98, 164)
      button.__noteText = MakeCol(266, 96)
      button.__sessionsText = MakeCol(244, 38)
      button.__itemsText = MakeCol(286, 36)
      button.__offSpecText = MakeCol(326, 28)
      button.__transmogText = MakeCol(358, 28)
      button.__disenchantText = MakeCol(390, 28)
      button.__pointsText = MakeCol(424, 40)
      button.__bisText = MakeCol(468, 28)
      button.__totalText = MakeCol(502, 38)

      button:SetScript("OnEnter", function(frame)
        if frame.__rowSelected then
          return
        end
        local hoverColor = select(1, GetLootListHighlightColors())
        frame.__highlight:SetVertexColor(hoverColor[1], hoverColor[2], hoverColor[3], hoverColor[4])
      end)
      button:SetScript("OnLeave", function(frame)
        if frame.__rowSelected then
          local _, selectedColor = GetLootListHighlightColors()
          frame.__highlight:SetVertexColor(selectedColor[1], selectedColor[2], selectedColor[3], selectedColor[4])
        else
          frame.__highlight:SetVertexColor(0, 0, 0, 0)
        end
      end)

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

  local function GetSelectedLootLedgerRow(rows, selectedType, selectedKey)
    local targetKey = string.lower(TrimText(selectedKey))
    if targetKey ~= "" then
      for _, row in ipairs(rows or {}) do
        if tostring(row.type or "") == tostring(selectedType or "character") then
          local rowKey = string.lower(tostring(row.character or ""))
          if rowKey == targetKey then
            return row
          end
        end
      end
    end
    for _, row in ipairs(rows or {}) do
      if row.type == "character" then
        return row
      end
    end
    return rows and rows[1] or nil
  end

  local function RefreshLootListTableView(self, page, options)
    options = type(options) == "table" and options or {}
    local profile = options.profile
    local profileName = options.profileName
    local detailsMode = options.detailsMode == true
    local popupOpen = options.popupOpen == true
    local pageWidth = tonumber(options.pageWidth) or ((page and page.GetWidth and page:GetWidth()) or (self.scrollChild and self.scrollChild:GetWidth()) or 980)
    local showRightPane = detailsMode or popupOpen
    local maxNavWidth = math.max(380, pageWidth - 320)
    local navWidth = detailsMode and ClampLayoutValue(math.floor((pageWidth - 12) * 0.55), 380, math.min(620, maxNavWidth)) or math.max(420, pageWidth - 12)
    local listWidth = math.max(340, navWidth - 38)
    local specHeaderX = 22
    local specIconBaseX = 24
    local specTextBaseX = 42
    local specWidth = 12
    local totalX = listWidth - 38
    local bisX = totalX - 34
    local pointsX = bisX - 44
    local disenchantX = pointsX - 36
    local transmogX = disenchantX - 34
    local offSpecX = transmogX - 34
    local itemsX = offSpecX - 40
    local sessionsX = itemsX - 44
    local nameX = 58
    local minNoteWidth = 48
    local availableLabelWidth = math.max(120, sessionsX - nameX - 8)
    local maxNameWidth = math.max(56, math.min(180, availableLabelWidth - minNoteWidth - 8))
    local nameWidth = ClampLayoutValue(math.floor(availableLabelWidth * 0.58), 56, maxNameWidth)
    local noteX = nameX + nameWidth + 8
    local noteWidth = math.max(minNoteWidth, sessionsX - noteX - 8)

    if self.lootListNavBg then
      self.lootListNavBg:SetWidth(navWidth)
    end
    if self.lootListRightBg then
      self.lootListRightBg:SetShown(showRightPane)
    end
    if self.lootLedgerRightScroll then
      self.lootLedgerRightScroll:SetShown(showRightPane)
    end
    if self.lootLedgerRightContent then
      self.lootLedgerRightContent:SetShown(showRightPane)
    end
    if self.UpdateLootListModeButtons then
      self:UpdateLootListModeButtons()
    end
    if self.lootLedgerSearchEdit then
      self.lootLedgerSearchEdit:SetWidth(math.max(120, navWidth - 92))
    end
    if self.lootLedgerListHeader then
      self.lootLedgerListHeader:SetWidth(listWidth)
    end
    if self.lootLedgerCharContent then
      self.lootLedgerCharContent:SetWidth(listWidth)
    end
    if self.lootLedgerDragHint then
      self.lootLedgerDragHint:SetWidth(navWidth - 16)
    end
    if self.lootLedgerHeaderSpec then
      self.lootLedgerHeaderSpec:ClearAllPoints()
      self.lootLedgerHeaderSpec:SetPoint("TOPLEFT", specHeaderX, 0)
      self.lootLedgerHeaderSpec:SetWidth(28)
    end
    if self.lootLedgerHeaderName then
      self.lootLedgerHeaderName:ClearAllPoints()
      self.lootLedgerHeaderName:SetPoint("TOPLEFT", nameX, 0)
      self.lootLedgerHeaderName:SetWidth(nameWidth)
    end
    if self.lootLedgerHeaderNote then
      self.lootLedgerHeaderNote:ClearAllPoints()
      self.lootLedgerHeaderNote:SetPoint("TOPLEFT", noteX, 0)
      self.lootLedgerHeaderNote:SetWidth(noteWidth)
    end
    if self.lootLedgerHeaderSessions then
      self.lootLedgerHeaderSessions:ClearAllPoints()
      self.lootLedgerHeaderSessions:SetPoint("TOPLEFT", sessionsX, 0)
    end
    if self.lootLedgerHeaderItems then
      self.lootLedgerHeaderItems:ClearAllPoints()
      self.lootLedgerHeaderItems:SetPoint("TOPLEFT", itemsX, 0)
    end
    if self.lootLedgerHeaderOffSpec then
      self.lootLedgerHeaderOffSpec:ClearAllPoints()
      self.lootLedgerHeaderOffSpec:SetPoint("TOPLEFT", offSpecX, 0)
    end
    if self.lootLedgerHeaderTransmog then
      self.lootLedgerHeaderTransmog:ClearAllPoints()
      self.lootLedgerHeaderTransmog:SetPoint("TOPLEFT", transmogX, 0)
    end
    if self.lootLedgerHeaderDisenchant then
      self.lootLedgerHeaderDisenchant:ClearAllPoints()
      self.lootLedgerHeaderDisenchant:SetPoint("TOPLEFT", disenchantX, 0)
    end
    if self.lootLedgerHeaderPoints then
      self.lootLedgerHeaderPoints:ClearAllPoints()
      self.lootLedgerHeaderPoints:SetPoint("TOPLEFT", pointsX, 0)
    end
    if self.lootLedgerHeaderBis then
      self.lootLedgerHeaderBis:ClearAllPoints()
      self.lootLedgerHeaderBis:SetPoint("TOPLEFT", bisX, 0)
    end
    if self.lootLedgerHeaderTotal then
      self.lootLedgerHeaderTotal:ClearAllPoints()
      self.lootLedgerHeaderTotal:SetPoint("TOPLEFT", totalX, 0)
    end

    if self.UpdateLootLedgerSortHeaderState then
      self:UpdateLootLedgerSortHeaderState()
    end

    local rows, allCharactersByKey = BuildLootLedgerNavRows(profile, profileName, self.__lootLedgerSearchText or "", {
      key = self.__lootLedgerSortKey,
      descending = self.__lootLedgerSortDescending,
    })
    self.lootLedgerCharacterRows = EnsureLootLedgerRowFrames(self.lootLedgerCharacterRows, self.lootLedgerCharContent, math.max(1, #rows))

    local selectedRow = GetSelectedLootLedgerRow(rows, self.selectedLootLedgerType, self.selectedLootLedgerKey)
    if selectedRow then
      self.selectedLootLedgerType = selectedRow.type
      self.selectedLootLedgerKey = selectedRow.character
      self.selectedLootLedgerCharacter = selectedRow.character
    else
      self.selectedLootLedgerType = nil
      self.selectedLootLedgerKey = nil
      self.selectedLootLedgerCharacter = nil
    end

    local listHeight = math.max(1, #rows * 24)
    for index = 1, #self.lootLedgerCharacterRows do
      local button = self.lootLedgerCharacterRows[index]
      local row = rows[index]
      if row then
        local isSelected = selectedRow and selectedRow.key == row.key
        local textR, textG, textB, textA = GetClassColorForRow(row)
        local indent = (tonumber(row.depth) or 0) * 18
        local specIconX = specIconBaseX + indent
        local specTextX = specTextBaseX + indent
        local rowNameX = nameX + indent
        local rowNameWidth = math.max(56, nameWidth - indent)
        local rowNameText = tostring(row.character or "?")
        local rowSessions = tonumber(row.displaySessionCount ~= nil and row.displaySessionCount or row.sessionCount) or 0
        local rowItems = tonumber(row.displayItemCount ~= nil and row.displayItemCount or row.itemCount) or 0
        local rowPoints = tonumber(row.displayTotalPoints ~= nil and row.displayTotalPoints or row.totalPoints) or 0
        local rowTotal = tonumber(row.groupTotalPoints ~= nil and row.groupTotalPoints or row.totalPoints) or rowPoints
        local rowBis = tonumber(row.displayBisCount ~= nil and row.displayBisCount or row.bisCount) or 0
        local rowOffSpec = tonumber(row.displayOffSpecCount ~= nil and row.displayOffSpecCount or row.offSpecCount) or 0
        local rowTransmog = tonumber(row.displayTransmogCount ~= nil and row.displayTransmogCount or row.transmogCount) or 0
        local rowDisenchant = tonumber(row.displayDisenchantCount ~= nil and row.displayDisenchantCount or row.disenchantCount) or 0

        button.__row = row
        button.__rowSelected = isSelected
        button:ClearAllPoints()
        button:SetPoint("TOPLEFT", 0, -((index - 1) * 24))
        button:SetSize(listWidth, 22)
        button:Show()

        if isSelected then
          local _, selectedColor = GetLootListHighlightColors()
          button.__highlight:SetVertexColor(selectedColor[1], selectedColor[2], selectedColor[3], selectedColor[4])
        else
          button.__highlight:SetVertexColor(0, 0, 0, 0)
        end
        if tonumber(row.depth) and tonumber(row.depth) > 0 then
          button.__bg:SetVertexColor(0.07, 0.05, 0.07, 0.84)
        else
          button.__bg:SetVertexColor(0.09, 0.06, 0.08, 0.88)
        end

        if button.__arrowButton then
          if row.isExpandable then
            button.__arrowButton:Show()
            button.__arrowButton:ClearAllPoints()
            button.__arrowButton:SetPoint("LEFT", 2, 0)
            button.__arrowText:SetText(row.collapsed and ">" or "v")
            button.__arrowButton:SetScript("OnClick", function()
              ToggleLootLedgerGroupCollapsedLocal(profile, row.rootCharacter or row.character)
              self.selectedLootLedgerType = row.type
              self.selectedLootLedgerKey = row.rootCharacter or row.character
              self.selectedLootLedgerCharacter = row.rootCharacter or row.character
              if self.Refresh then self:Refresh() end
            end)
          else
            button.__arrowButton:Hide()
            button.__arrowButton:SetScript("OnClick", nil)
          end
        end

        if button.__specIcon then
          button.__specIcon:ClearAllPoints()
          button.__specIcon:SetPoint("LEFT", specIconX, 0)
        end
        button.__specText:ClearAllPoints()
        button.__specText:SetPoint("LEFT", specTextX, 0)
        button.__specText:SetWidth(specWidth)
        button.__nameText:ClearAllPoints()
        button.__nameText:SetPoint("LEFT", rowNameX, 0)
        button.__nameText:SetWidth(rowNameWidth)
        if button.__noteText then
          button.__noteText:ClearAllPoints()
          button.__noteText:SetPoint("LEFT", noteX, 0)
          button.__noteText:SetWidth(noteWidth)
        end
        button.__sessionsText:ClearAllPoints()
        button.__sessionsText:SetPoint("LEFT", sessionsX, 0)
        button.__itemsText:ClearAllPoints()
        button.__itemsText:SetPoint("LEFT", itemsX, 0)
        button.__offSpecText:ClearAllPoints()
        button.__offSpecText:SetPoint("LEFT", offSpecX, 0)
        button.__transmogText:ClearAllPoints()
        button.__transmogText:SetPoint("LEFT", transmogX, 0)
        button.__disenchantText:ClearAllPoints()
        button.__disenchantText:SetPoint("LEFT", disenchantX, 0)
        button.__pointsText:ClearAllPoints()
        button.__pointsText:SetPoint("LEFT", pointsX, 0)
        button.__bisText:ClearAllPoints()
        button.__bisText:SetPoint("LEFT", bisX, 0)
        button.__totalText:ClearAllPoints()
        button.__totalText:SetPoint("LEFT", totalX, 0)

        if button.__specIcon then
          ApplyLootLedgerTextureIcon(button.__specIcon, GetLootLedgerHeaderIconData(row))
        end
        button.__specText:SetText("")
        if tonumber(row.depth) and tonumber(row.depth) > 0 then
          rowNameText = "- " .. rowNameText
        elseif row.isExpandable and tonumber(row.summaryMemberCount) and tonumber(row.summaryMemberCount) > 1 then
          rowNameText = rowNameText .. string.format(" (%d)", tonumber(row.summaryMemberCount) or 1)
        end
        button.__nameText:SetText(rowNameText)
        if button.__noteText then
          button.__noteText:SetText(TrimText(row.note) ~= "" and TrimText(row.note) or "")
        end
        button.__sessionsText:SetText(tostring(rowSessions))
        button.__itemsText:SetText(tostring(rowItems))
        button.__pointsText:SetText(tostring(rowPoints))
        button.__totalText:SetText(tostring(rowTotal))
        button.__bisText:SetText(tostring(rowBis))
        button.__offSpecText:SetText(tostring(rowOffSpec))
        button.__transmogText:SetText(tostring(rowTransmog))
        button.__disenchantText:SetText(tostring(rowDisenchant))

        button.__specText:SetTextColor(textR, textG, textB, textA)
        button.__nameText:SetTextColor(textR, textG, textB, textA)
        if button.__noteText then
          button.__noteText:SetTextColor(0.80, 0.78, 0.84, 1)
        end
        button.__sessionsText:SetTextColor(textR, textG, textB, textA)
        button.__itemsText:SetTextColor(textR, textG, textB, textA)
        button.__offSpecText:SetTextColor(textR, textG, textB, textA)
        button.__transmogText:SetTextColor(textR, textG, textB, textA)
        button.__disenchantText:SetTextColor(textR, textG, textB, textA)
        button.__pointsText:SetTextColor(textR, textG, textB, textA)
        button.__bisText:SetTextColor(textR, textG, textB, textA)
        button.__totalText:SetTextColor(textR, textG, textB, textA)

        button:SetScript("OnClick", function()
          self.selectedLootLedgerType = row.type
          self.selectedLootLedgerKey = row.character
          self.selectedLootLedgerCharacter = row.character
          if self.Refresh then self:Refresh() end
          if not detailsMode and self.OpenLootLedgerDetailsPopup then
            self:OpenLootLedgerDetailsPopup(row)
          end
        end)
        button:SetScript("OnReceiveDrag", nil)
        button:SetScript("OnDragStart", nil)
      else
        button.__row = nil
        button.__rowSelected = false
        button:Hide()
      end
    end
    self.lootLedgerCharContent:SetHeight(math.max(1, listHeight))
    if self.lootLedgerCharScroll and self.lootLedgerCharScroll.UpdateScrollChildRect then
      self.lootLedgerCharScroll:UpdateScrollChildRect()
    end

    return {
      allCharactersByKey = allCharactersByKey,
      listWidth = listWidth,
      navWidth = navWidth,
      selectedRow = selectedRow,
      showRightPane = showRightPane,
    }
  end

  return {
    GetLootListHighlightColors = GetLootListHighlightColors,
    GetClassColorForRow = GetClassColorForRow,
    BuildSpecLabel = BuildSpecLabel,
    GetLootLedgerHeaderIconData = GetLootLedgerHeaderIconData,
    EnsureLootLedgerRowFrames = EnsureLootLedgerRowFrames,
    GetSelectedLootLedgerRow = GetSelectedLootLedgerRow,
    RefreshLootListTableView = RefreshLootListTableView,
  }
end
