function cmd::logs::show_fw_events() {
  local filter_ip="${1:-}" filter_name="${2:-}" filter_type="${3:-}" \
        limit="${4:-50}" net_file="${5:-}" collapse="${6:-1}" \
        since="${7:-}" filter_dest_ip="${8:-}" filter_dest_port="${9:-}" \
        sort_order="${10:-desc}" resolved_only="${11:-false}"

  [[ ! -f "$FW_EVENTS_LOG" ]] && return 0

  local data
  data=$(json::fw_events \
    "$FW_EVENTS_LOG" "$filter_ip" "$filter_type" \
    "$(ctx::clients)" "${net_file:-}" \
    "$limit" "$collapse" "$since" \
    "$filter_dest_ip" "$filter_dest_port" \
    "$sort_order" \
    2>/dev/null)

  [[ -z "$data" ]] && return 0

  # ── Pass 1: resolve endpoints and measure widths ──
  local w_client=16 w_dest=20 w_endpoint=0
  local resolved_data=""

  while IFS='|' read -r ts client dest_ip dest_port proto svc count src_endpoint; do
    [[ -z "$ts" ]] && continue

    # Measure client
    (( ${#client} > w_client )) && w_client=${#client}

    # Build svc_display (for w_dest measurement)
    local svc_display=""
    if [[ -n "$svc" ]]; then
      [[ -n "$dest_port" ]] && svc_display="${svc}/${proto}" \
                            || svc_display="${svc} (${proto})"
    else
      [[ -n "$dest_port" ]] && svc_display="${dest_ip}:${dest_port}/${proto}" \
                            || svc_display="${dest_ip} (${proto})"
    fi

    # Build raw_suffix plain (no ANSI) for w_dest measurement
    local raw_plain=""
    if [[ -n "$svc" ]]; then
      [[ -n "$dest_port" ]] && raw_plain=" (${dest_ip}:${dest_port})" \
                            || raw_plain=" (${dest_ip})"
    fi

    local measure_len
    if $resolved_only; then
      measure_len=${#svc_display}
    else
      local raw_plain=""
      [[ -n "$svc" && -n "$dest_port" ]] && raw_plain=" (${dest_ip}:${dest_port})"
      [[ -n "$svc" && -z "$dest_port" ]] && raw_plain=" (${dest_ip})"
      measure_len=$(( ${#svc_display} + ${#raw_plain} ))
    fi
    (( measure_len > w_dest )) && w_dest=$measure_len

    # Resolve endpoint once
    local src_resolved=""
    if [[ -n "$src_endpoint" ]]; then
      src_resolved=$(resolve::ip "$src_endpoint" 2>/dev/null || true)
      [[ "$src_resolved" == "$src_endpoint" ]] && src_resolved=""
      # Measure endpoint column: raw IP + " → resolved"
      local ep_display_len=${#src_endpoint}
      [[ -n "$src_resolved" ]] && ep_display_len=$(( ep_display_len + 4 + ${#src_resolved} ))
      (( ep_display_len > w_endpoint )) && w_endpoint=$ep_display_len
    fi

    if [[ -n "$src_endpoint" ]]; then
    local ep_measure_len
    if $resolved_only; then
      ep_measure_len=${#src_resolved}
      [[ -z "$src_resolved" ]] && ep_measure_len=${#src_endpoint}
    else
      ep_measure_len=${#src_endpoint}
      [[ -n "$src_resolved" ]] && \
        ep_measure_len=$(( ${#src_endpoint} + 4 + ${#src_resolved} ))
    fi
    (( ep_measure_len > w_endpoint )) && w_endpoint=$ep_measure_len
  fi

    resolved_data+="${ts}|${client}|${dest_ip}|${dest_port}|${proto}|${svc}|${count}|${src_endpoint}|${src_resolved}"$'\n'
  done <<< "$data"

  (( w_client   += 2 ))
  (( w_dest     += 2 ))
  [[ "$w_endpoint" -gt 0 ]] && (( w_endpoint += 2 ))

  # ── Pass 2: render ──
  ui::logs::fw_section_header
  while IFS='|' read -r ts client dest_ip dest_port proto svc count src_endpoint src_resolved; do
    [[ -z "$ts" ]] && continue
    ui::logs::fw_row "$ts" "$client" "$dest_ip" "$dest_port" \
      "$proto" "$svc" "$count" "$w_client" "$w_dest" \
      "$src_endpoint" "$src_resolved" "$w_endpoint" "$resolved_only"
  done <<< "$resolved_data"
  printf "\n"
}
function cmd::logs::show_wg_events() {
  local filter_ip="${1:-}" filter_name="${2:-}" filter_type="${3:-}" \
        limit="${4:-50}" collapse="${5:-1}" \
        since="${6:-}" filter_event="${7:-}" sort_order="${8:-desc}" \
        resolved_only="${9:-false}"

  [[ ! -f "$WG_EVENTS_LOG" ]] && return 0

  local data
  data=$(json::wg_events \
    "$WG_EVENTS_LOG" "$filter_name" "$filter_type" \
    "$limit" "$collapse" "$since" "$filter_event" \
    "$(ctx::endpoint_cache)" "$sort_order" \
    2>/dev/null)

  [[ -z "$data" ]] && return 0

  local w_client=16 w_endpoint=16
  local resolved_data=""

  while IFS='|' read -r ts client endpoint event count gap_seconds; do
    [[ -z "$ts" ]] && continue
    (( ${#client} > w_client )) && w_client=${#client}

    local resolved=""
    [[ -n "$endpoint" ]] && resolved=$(resolve::ip "$endpoint" 2>/dev/null || true)
    [[ "$resolved" == "$endpoint" ]] && resolved=""

    # In resolved_only mode, use resolved name as display (or raw if unresolved)
    local ep_display
    if $resolved_only; then
      ep_display="${resolved:-$endpoint}"
      [[ -z "$ep_display" ]] && ep_display="-"
    else
      ep_display="${endpoint:--}"
    fi

    (( ${#ep_display} > w_endpoint )) && w_endpoint=${#ep_display}
    # Extra width for annotation when not resolved_only
    $resolved_only || {
      [[ -n "$resolved" && -n "$endpoint" ]] && \
        w_endpoint=$(( w_endpoint > ${#endpoint} + 4 + ${#resolved} \
          ? w_endpoint : ${#endpoint} + 4 + ${#resolved} ))
    }

    resolved_data+="${ts}|${client}|${endpoint}|${event}|${count}|${gap_seconds}|${resolved}|${ep_display}"$'\n'
  done <<< "$data"

  (( w_client   += 2 ))
  (( w_endpoint += 2 ))
  $resolved_only || (( w_endpoint += 4 ))  # space for annotation

  ui::logs::wg_section_header
  while IFS='|' read -r ts client endpoint event count gap_seconds resolved ep_display; do
    [[ -z "$ts" ]] && continue
    if $resolved_only; then
      ui::logs::wg_row "$ts" "$client" "$ep_display" "$event" \
        "$count" "$w_client" "$w_endpoint" "$gap_seconds" ""
    else
      ui::logs::wg_row "$ts" "$client" "$endpoint" "$event" \
        "$count" "$w_client" "$w_endpoint" "$gap_seconds" "$resolved"
    fi
  done <<< "$resolved_data"
  printf "\n"
}
