import { Request } from 'express';

/**
 * 클라이언트의 실제 IP 주소를 추출합니다.
 *
 * @description
 * Proxy, Load Balancer, CDN 뒤에 있어도 실제 클라이언트 IP를 정확하게 가져옵니다.
 * 다음 순서로 IP를 확인합니다:
 * 1. X-Forwarded-For 헤더 (Proxy/Load Balancer)
 * 2. X-Real-IP 헤더 (Nginx)
 * 3. req.ip (Express 기본)
 * 4. req.socket.remoteAddress (직접 연결)
 * 5. 'unknown' (IP를 찾을 수 없는 경우)
 *
 * @param req - Express Request 객체
 * @returns 클라이언트 IP 주소
 *
 * @example
 * const ip = getClientIp(req);
 * console.log(ip);  // '203.123.45.67' or 'unknown'
 */
export function getClientIp(req: Request): string {
  // 1. X-Forwarded-For 헤더 확인 (Proxy/Load Balancer 환경)
  // 형식: "client IP, proxy1 IP, proxy2 IP"
  const forwardedFor = req.headers['x-forwarded-for'];
  if (forwardedFor) {
    // 배열이면 첫 번째 요소, 문자열이면 콤마로 split
    const ips = Array.isArray(forwardedFor)
      ? forwardedFor[0]
      : forwardedFor.split(',')[0];
    return ips.trim();
  }

  // 2. X-Real-IP 헤더 확인 (Nginx 환경)
  const realIp = req.headers['x-real-ip'];
  if (realIp && typeof realIp === 'string') {
    return realIp.trim();
  }

  // 3. Express가 제공하는 req.ip
  if (req.ip) {
    return req.ip;
  }

  // 4. Socket의 remoteAddress
  if (req.socket?.remoteAddress) {
    return req.socket.remoteAddress;
  }

  // 5. IP를 찾을 수 없는 경우
  return 'unknown';
}
