local EnsureApiRegistry = rawget(_G, "LIDCOUNCIL_EnsureApiRegistry")
local API, INTERNAL_API
if type(EnsureApiRegistry) == "function" then
  API, INTERNAL_API = EnsureApiRegistry()
else
  API = rawget(_G, "LIDCOUNCIL_API")
  if type(API) ~= "table" then
    API = {}
    _G.LIDCOUNCIL_API = API
  end
  if type(API.__internal) ~= "table" then
    API.__internal = {}
  end
  INTERNAL_API = API.__internal
end

INTERNAL_API.LIDCOUNCIL_CreateOutboundEndpointTelemetryHelpers_Impl = function(deps)
  deps = type(deps) == "table" and deps or {}
  local stats = type(deps.Stats) == "table" and deps.Stats or {}
  local TrimText = type(deps.TrimText) == "function" and deps.TrimText or function(value)
    return tostring(value or "")
  end
  local NormalizeCharacterKey = type(deps.NormalizeCharacterKey) == "function" and deps.NormalizeCharacterKey or TrimText
  local ResolveProfileSyncTransferReason = type(deps.ResolveProfileSyncTransferReason) == "function"
    and deps.ResolveProfileSyncTransferReason
    or function()
      return ""
    end
  local ResolveProfileSyncTransferLane = type(deps.ResolveProfileSyncTransferLane) == "function"
    and deps.ResolveProfileSyncTransferLane
    or function()
      return "live"
    end

  local function ResolveOutboundCommTelemetryLane(item)
    item = type(item) == "table" and item or {}
    local kind = TrimText(item.kind)
    local profileTraffic = kind == "PSYNC_START"
      or kind == "PSYNC_CHUNK"
      or kind == "PSYNC_END"
      or kind == "PSYNC_REQ"
      or kind == "PSYNC_ACK"
      or kind == "PSUB_REQ"
      or kind == "PSUB_STATE"
      or kind == "PSUBPATCH_REQ"
      or kind == "PSUBPATCH_STATE"
      or kind == "PDELTA_REQ"
      or kind == "PDELTA"
      or kind == "PDELTA_ACK"
      or kind == "PDELTA_NACK"
    if not profileTraffic then
      return "control"
    end
    local metadata = type(item.metadata) == "table" and item.metadata or {}
    local reason = string.lower(ResolveProfileSyncTransferReason(metadata))
    if string.find(reason, "bootstrap", 1, true) then
      return "bootstrap"
    end
    return ResolveProfileSyncTransferLane(metadata)
  end

  local function RecordOutboundCommLaneTelemetry(item, eventName)
    local lane = ResolveOutboundCommTelemetryLane(item)
    local byLane = type(stats.byLane) == "table" and stats.byLane or {}
    stats.byLane = byLane
    local entry = type(byLane[lane]) == "table" and byLane[lane] or {
      attempted = 0,
      sent = 0,
      throttled = 0,
      failed = 0,
      bytesAttempted = 0,
      bytesSent = 0,
    }
    byLane[lane] = entry
    local payloadBytes = #(type(item) == "table" and tostring(item.payload or "") or "")
    if eventName == "attempted" then
      entry.attempted = math.max(0, tonumber(entry.attempted) or 0) + 1
      entry.bytesAttempted = math.max(0, tonumber(entry.bytesAttempted) or 0) + payloadBytes
    elseif eventName == "sent" then
      entry.sent = math.max(0, tonumber(entry.sent) or 0) + 1
      entry.bytesSent = math.max(0, tonumber(entry.bytesSent) or 0) + payloadBytes
    elseif eventName == "throttled" then
      entry.throttled = math.max(0, tonumber(entry.throttled) or 0) + 1
    elseif eventName == "failed" then
      entry.failed = math.max(0, tonumber(entry.failed) or 0) + 1
    end
    return lane
  end

  local function GetOutboundCommLaneTelemetry()
    local byLane = type(stats.byLane) == "table" and stats.byLane or {}
    local snapshot = {}
    for _, lane in ipairs({ "live", "bootstrap", "archive", "stats", "control" }) do
      local entry = type(byLane[lane]) == "table" and byLane[lane] or {}
      snapshot[lane] = {
        attempted = math.max(0, tonumber(entry.attempted) or 0),
        sent = math.max(0, tonumber(entry.sent) or 0),
        throttled = math.max(0, tonumber(entry.throttled) or 0),
        failed = math.max(0, tonumber(entry.failed) or 0),
        bytesAttempted = math.max(0, tonumber(entry.bytesAttempted) or 0),
        bytesSent = math.max(0, tonumber(entry.bytesSent) or 0),
      }
    end
    return snapshot
  end

  local function ResolveOutboundCommTelemetryTarget(item)
    item = type(item) == "table" and item or {}
    if string.upper(TrimText(item.distribution)) ~= "WHISPER" then
      return ""
    end
    return NormalizeCharacterKey(item.targetName)
  end

  local function SelectOutboundCommTelemetryMemberBucket(targetName, byMember, maxTrackedMembers)
    local resolvedTarget = NormalizeCharacterKey(targetName)
    byMember = type(byMember) == "table" and byMember or {}
    if resolvedTarget == "" or type(byMember[resolvedTarget]) == "table" then
      return resolvedTarget, false
    end
    local trackedCount = 0
    for _ in pairs(byMember) do
      trackedCount = trackedCount + 1
    end
    if trackedCount >= math.max(1, tonumber(maxTrackedMembers) or 24) then
      return "__other__", true
    end
    return resolvedTarget, false
  end

  local function RecordOutboundCommMemberTelemetry(item, eventName)
    local telemetry = type(stats.memberTelemetry) == "table" and stats.memberTelemetry or {}
    stats.memberTelemetry = telemetry
    local byMember = type(telemetry.byMember) == "table" and telemetry.byMember or {}
    telemetry.byMember = byMember
    local targetName = ResolveOutboundCommTelemetryTarget(item)
    local bucketName, overflowed = SelectOutboundCommTelemetryMemberBucket(targetName, byMember, telemetry.maxTrackedMembers)
    local bucket
    if bucketName == "" then
      bucket = type(telemetry.group) == "table" and telemetry.group or {}
      telemetry.group = bucket
    elseif overflowed then
      bucket = type(telemetry.other) == "table" and telemetry.other or {}
      telemetry.other = bucket
    else
      bucket = type(byMember[bucketName]) == "table" and byMember[bucketName] or {}
      byMember[bucketName] = bucket
    end
    local payloadBytes = #(type(item) == "table" and tostring(item.payload or "") or "")
    if eventName == "attempted" then
      bucket.attempted = math.max(0, tonumber(bucket.attempted) or 0) + 1
      bucket.bytesAttempted = math.max(0, tonumber(bucket.bytesAttempted) or 0) + payloadBytes
    elseif eventName == "sent" then
      bucket.sent = math.max(0, tonumber(bucket.sent) or 0) + 1
      bucket.bytesSent = math.max(0, tonumber(bucket.bytesSent) or 0) + payloadBytes
    elseif eventName == "throttled" then
      bucket.throttled = math.max(0, tonumber(bucket.throttled) or 0) + 1
    elseif eventName == "failed" then
      bucket.failed = math.max(0, tonumber(bucket.failed) or 0) + 1
    end
    return targetName, overflowed
  end

  local function GetOutboundCommMemberTelemetry()
    local telemetry = type(stats.memberTelemetry) == "table" and stats.memberTelemetry or {}
    local function buildSnapshot(entry)
      entry = type(entry) == "table" and entry or {}
      return {
        attempted = math.max(0, tonumber(entry.attempted) or 0),
        sent = math.max(0, tonumber(entry.sent) or 0),
        throttled = math.max(0, tonumber(entry.throttled) or 0),
        failed = math.max(0, tonumber(entry.failed) or 0),
        bytesAttempted = math.max(0, tonumber(entry.bytesAttempted) or 0),
        bytesSent = math.max(0, tonumber(entry.bytesSent) or 0),
      }
    end
    local members = {}
    for memberName, entry in pairs(type(telemetry.byMember) == "table" and telemetry.byMember or {}) do
      local snapshot = buildSnapshot(entry)
      snapshot.member = NormalizeCharacterKey(memberName)
      if snapshot.member ~= "" then
        members[#members + 1] = snapshot
      end
    end
    table.sort(members, function(left, right)
      if left.bytesSent ~= right.bytesSent then
        return left.bytesSent > right.bytesSent
      end
      if left.attempted ~= right.attempted then
        return left.attempted > right.attempted
      end
      return string.lower(left.member) < string.lower(right.member)
    end)
    return {
      maxTrackedMembers = math.max(1, tonumber(telemetry.maxTrackedMembers) or 24),
      members = members,
      group = buildSnapshot(telemetry.group),
      other = buildSnapshot(telemetry.other),
    }
  end

  return {
    ResolveOutboundCommTelemetryLane = ResolveOutboundCommTelemetryLane,
    RecordOutboundCommLaneTelemetry = RecordOutboundCommLaneTelemetry,
    GetOutboundCommLaneTelemetry = GetOutboundCommLaneTelemetry,
    ResolveOutboundCommTelemetryTarget = ResolveOutboundCommTelemetryTarget,
    SelectOutboundCommTelemetryMemberBucket = SelectOutboundCommTelemetryMemberBucket,
    RecordOutboundCommMemberTelemetry = RecordOutboundCommMemberTelemetry,
    GetOutboundCommMemberTelemetry = GetOutboundCommMemberTelemetry,
  }
end
