/**
 * Centralized IP extraction utility for consistent client IP logging
 * across all API routes.
 *
 * Priority order:
 * 1. X-Forwarded-For header (takes first IP from comma-separated list)
 * 2. X-Real-IP header (direct proxy IP)
 * 3. CF-Connecting-IP header (Cloudflare)
 * 4. Fallback to localhost for development or 'unavailable' for server contexts
 */

import { headers } from 'next/headers';

/**
 * Extracts the client IP address from request
 * Prioritizes platform-provided IP (Vercel/Next.js) which cannot be spoofed,
 * falls back to headers only when platform IP is unavailable.
 *
 * @param request - Next.js Request object
 * @returns Client IP address string
 */
export function getClientIp(request: Request): string {
  // Prefer platform-provided IP (Vercel/Next.js) - cannot be spoofed by clients
  if ('ip' in request && typeof (request as { ip?: string }).ip === 'string') {
    return (request as { ip: string }).ip;
  }

  // Fallback to forwarded headers (less trusted, can be spoofed)
  const forwarded = request.headers.get('x-forwarded-for');
  const realIp = request.headers.get('x-real-ip');

  if (forwarded) {
    return forwarded.split(',')[0].trim();
  }

  if (realIp) {
    return realIp.trim();
  }

  return '127.0.0.1';
}

/**
 * Extracts client IP from Next.js headers() function (for server components/actions)
 *
 * This is an async function that uses the headers() API which may not be available
 * in all contexts (e.g., some server actions). Returns 'unavailable' on failure.
 *
 * @returns Promise<string> - Client IP address or 'unavailable'
 */
export async function getClientIpFromHeaders(): Promise<string> {
  try {
    const headersList = await headers();
    return headersList.get('x-forwarded-for')?.split(',')[0]?.trim() ||
      headersList.get('x-real-ip') ||
      headersList.get('cf-connecting-ip') ||
      'unavailable';
  } catch {
    // headers() not available in this context
    return 'unavailable';
  }
}
