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_CreateLootSessionSyncHistoryHelpers_Impl = function(deps)
  deps = type(deps) == "table" and deps or {}

  local ApplyFrameSkin = deps.ApplyFrameSkin
  local TrimText = deps.TrimText
  local FormatDateTime = deps.FormatDateTime
  local ResolveOptionalApiFunction = deps.ResolveOptionalApiFunction

  local function trim(value)
    if type(TrimText) == "function" then
      return TrimText(value)
    end
    local text = tostring(value or "")
    text = text:gsub("^%s+", "")
    text = text:gsub("%s+$", "")
    return text
  end

  local function formatWhen(value)
    if type(FormatDateTime) == "function" and tonumber(value) and tonumber(value) > 0 then
      return FormatDateTime(value)
    end
    return "-"
  end

  local function ensureRows(frame, count)
    frame.rows = frame.rows or {}
    while #frame.rows < count do
      local row = frame:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall")
      row:SetJustifyH("LEFT")
      row:SetText("")
      frame.rows[#frame.rows + 1] = row
    end
  end

  local function EnsureSyncHistoryPanel(editor)
    if not editor then
      return nil
    end
    if editor.lootSessionSyncHistoryFrame then
      return editor.lootSessionSyncHistoryFrame
    end

    local parent = editor.lootSessionRightContent or editor.lootSessionRightBg or UIParent
    local frame = CreateFrame("Frame", nil, parent, "BackdropTemplate")
    ApplyFrameSkin(frame)
    if frame.SetBackdropColor then
      frame:SetBackdropColor(0.05, 0.06, 0.08, 0.96)
    end

    local header = frame:CreateFontString(nil, "OVERLAY", "GameFontNormal")
    header:SetJustifyH("LEFT")
    header:SetText("Repair History and Undo")
    frame.header = header

    local undoBtn = CreateFrame("Button", nil, frame, "UIPanelButtonTemplate")
    undoBtn:SetSize(152, 22)
    undoBtn:SetText("Undo Last Host Apply")
    frame.undoBtn = undoBtn

    local status = frame:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall")
    status:SetJustifyH("LEFT")
    status:SetText("")
    frame.status = status

    local empty = frame:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall")
    empty:SetJustifyH("LEFT")
    empty:SetText("No repair history has been recorded yet.")
    frame.empty = empty

    editor.lootSessionSyncHistoryFrame = frame
    return frame
  end

  local function RefreshSyncHistoryPanel(editor, context)
    local frame = EnsureSyncHistoryPanel(editor)
    if not frame then
      return nil
    end

    context = type(context) == "table" and context or {}
    local activeSession = context.activeSession
    local activeSessionIsHost = context.activeSessionIsHost and true or false
    local access = type(context.access) == "table" and context.access or {}
    local profileName = trim(type(activeSession) == "table" and activeSession.profileName or "")
    local sessionId = trim(type(activeSession) == "table" and activeSession.id or "")
    local inCombat = context.inCombat and true or false

    local getHistory = type(ResolveOptionalApiFunction) == "function"
      and ResolveOptionalApiFunction("LIDCOUNCIL_GetProfileRepairHistory")
      or nil
    local getUndoStatus = type(ResolveOptionalApiFunction) == "function"
      and ResolveOptionalApiFunction("LIDCOUNCIL_GetProfileUndoStatus")
      or nil
    local undoLastRepair = type(ResolveOptionalApiFunction) == "function"
      and ResolveOptionalApiFunction("LIDCOUNCIL_UndoLastProfileRepair")
      or nil

    local history = type(getHistory) == "function" and getHistory(profileName, sessionId) or {}
    local undoStatus = type(getUndoStatus) == "function" and getUndoStatus(profileName) or {
      available = false,
      count = 0,
      last = nil,
    }

    if frame.undoBtn then
      frame.undoBtn:SetScript("OnClick", function()
        if type(undoLastRepair) == "function" and profileName ~= "" then
          undoLastRepair(profileName)
          if editor and editor.Refresh then
            editor:Refresh()
          end
        end
      end)
      if activeSession and activeSessionIsHost and access.canManageSession and not inCombat and undoStatus.available then
        frame.undoBtn:Enable()
      else
        frame.undoBtn:Disable()
      end
    end

    if frame.status then
      if not activeSession then
        frame.status:SetText("Undo becomes available after a host-side repair changes the active shared profile.")
        frame.status:SetTextColor(0.82, 0.84, 0.92, 1.00)
      elseif undoStatus.available then
        frame.status:SetText("Manual safety net: " .. tostring(undoStatus.count or 0) .. " undo snapshot(s) ready for this active shared profile.")
        frame.status:SetTextColor(0.30, 0.90, 0.36, 1.00)
      else
        frame.status:SetText("No host-side repair undo snapshot is currently available.")
        frame.status:SetTextColor(1.00, 0.82, 0.32, 1.00)
      end
    end

    local visibleRows = {}
    for index = 1, math.min(6, #history) do
      local entry = type(history[index]) == "table" and history[index] or {}
      local memberKey = trim(entry.memberKey)
      local prefix = "[" .. formatWhen(entry.createdAt) .. "]"
      local suffix = trim(entry.summary)
      if memberKey ~= "" and memberKey ~= "UNKNOWN" then
        suffix = suffix ~= "" and (suffix .. " [" .. memberKey .. "]") or ("Member: " .. memberKey)
      end
      visibleRows[#visibleRows + 1] = prefix .. " " .. (suffix ~= "" and suffix or "Repair activity recorded.")
    end

    ensureRows(frame, math.max(1, #visibleRows))
    for index, row in ipairs(frame.rows or {}) do
      if visibleRows[index] then
        row:SetText(visibleRows[index])
        row:Show()
      else
        row:SetText("")
        row:Hide()
      end
    end

    if frame.empty then
      frame.empty:SetShown(#visibleRows == 0)
    end

    frame.__visibleRowCount = #visibleRows
    return frame
  end

  local function LayoutSyncHistoryPanel(editor, top, width)
    local frame = EnsureSyncHistoryPanel(editor)
    if not frame then
      return 0
    end

    width = math.max(320, tonumber(width) or 320)
    frame:ClearAllPoints()
    frame:SetPoint("TOPLEFT", 18, top)
    frame:SetWidth(width)

    frame.header:ClearAllPoints()
    frame.header:SetPoint("TOPLEFT", 12, -12)

    frame.undoBtn:ClearAllPoints()
    frame.undoBtn:SetPoint("TOPRIGHT", -12, -10)

    frame.status:ClearAllPoints()
    frame.status:SetPoint("TOPLEFT", 12, -38)
    frame.status:SetWidth(width - 24)

    local statusHeight = math.max(18, math.ceil(frame.status:GetStringHeight() or 0))
    local rowsTop = -42 - statusHeight - 10

    frame.empty:ClearAllPoints()
    frame.empty:SetPoint("TOPLEFT", 12, rowsTop)
    frame.empty:SetWidth(width - 24)

    local rowHeight = 18
    local visibleCount = math.max(1, tonumber(frame.__visibleRowCount) or 0)
    for index, row in ipairs(frame.rows or {}) do
      row:ClearAllPoints()
      row:SetPoint("TOPLEFT", 12, rowsTop - ((index - 1) * rowHeight))
      row:SetWidth(width - 24)
    end

    local rowsHeight = math.max(frame.empty:IsShown() and 18 or 0, visibleCount * rowHeight)
    local totalHeight = 56 + statusHeight + rowsHeight + 14
    frame:SetHeight(totalHeight)
    return totalHeight
  end

  return {
    RefreshSyncHistoryPanel = RefreshSyncHistoryPanel,
    LayoutSyncHistoryPanel = LayoutSyncHistoryPanel,
  }
end
