import { randomUUID } from "crypto"

/**
 * Generates a unique request ID for tracing requests across the application
 * Uses UUID v4 for uniqueness and includes timestamp for better debugging
 */
export function generateRequestId(): string {
  return randomUUID()
}

/**
 * Generates a trace ID for distributed tracing
 * Shorter format for better performance in logs
 */
export function generateTraceId(): string {
  return randomUUID().replace(/-/g, "").substring(0, 16)
}

/**
 * Creates a correlation ID that can be used across services
 * Format: service-timestamp-random
 */
export function generateCorrelationId(service: string = "cf-api"): string {
  const timestamp = Date.now().toString(36)
  const random = Math.random().toString(36).substring(2, 8)
  return `${service}-${timestamp}-${random}`
}

/**
 * Extracts or generates a single request ID for all tracing needs
 *
 * SIMPLIFIED APPROACH: This ID serves as both correlation ID and trace ID
 * This is a simplified approach that works well for most applications.
 *
 * Priority: x-correlation-id > x-request-id > x-trace-id > generate new
 *
 * BENEFITS OF SINGLE ID:
 * - Simpler to understand and maintain
 * - Reduces complexity for developers
 * - Still supports distributed tracing via header inheritance
 * - Sufficient for most microservices architectures
 *
 * WHEN TO USE INDUSTRY STANDARD (separate IDs):
 * - Complex microservices with 10+ services
 * - High-volume tracing requiring different granularity
 * - Compliance requirements for detailed audit trails
 * - Need to distinguish between intra-service vs cross-service operations
 *
 * @param req Express request object
 * @returns Single request ID that serves all tracing purposes
 */
export function extractOrGenerateRequestId(req: any): string {
  return (
    req.headers["x-correlation-id"] ||
    req.headers["x-request-id"] ||
    req.headers["x-trace-id"] ||
    generateCorrelationId()
  )
}

/**
 * @deprecated Use extractOrGenerateRequestId instead
 *
 * DEPRECATION REASON: Simplified to use single ID approach
 * This function is kept for backward compatibility but now delegates to extractOrGenerateRequestId
 *
 * TO REVERT TO INDUSTRY STANDARD:
 * 1. Restore original implementation that only checks x-correlation-id and x-request-id
 * 2. Use generateCorrelationId() instead of generateRequestId()
 * 3. Update enhanced-logging.ts to use separate correlation and trace IDs
 *
 * Original implementation was:
 * return req.headers["x-correlation-id"] || req.headers["x-request-id"] || generateCorrelationId()
 */
export function extractOrGenerateCorrelationId(req: any): string {
  return extractOrGenerateRequestId(req)
}

/**
 * @deprecated Use extractOrGenerateRequestId instead
 *
 * DEPRECATION REASON: Simplified to use single ID approach
 * This function is kept for backward compatibility but now delegates to extractOrGenerateRequestId
 *
 * TO REVERT TO INDUSTRY STANDARD:
 * 1. Restore original implementation that only checks x-trace-id
 * 2. Use generateTraceId() instead of generateCorrelationId()
 * 3. Update enhanced-logging.ts to use separate correlation and trace IDs
 *
 * Original implementation was:
 * return req.headers["x-trace-id"] || generateTraceId()
 */
export function extractOrGenerateTraceId(req: any): string {
  return extractOrGenerateRequestId(req)
}

/**
 * Extracts request ID from headers or generates a new one
 * Useful for maintaining request context across service boundaries
 * @deprecated Use extractOrGenerateCorrelationId instead for better distributed tracing
 */
export function getOrCreateRequestId(req: any): string {
  return extractOrGenerateCorrelationId(req)
}

/**
 * Adds request tracing headers to response
 * Useful for maintaining trace context across service boundaries
 */
export function addTracingHeaders(
  res: any,
  requestId: string,
  traceId?: string,
  correlationId?: string,
): void {
  res.setHeader("X-Request-ID", requestId)
  res.setHeader("X-Correlation-ID", correlationId || requestId)
  if (traceId) {
    res.setHeader("X-Trace-ID", traceId)
  }
}
