// ABOUTME: Express middleware for correlation ID tracking and structured request/response logging
// ABOUTME: correlationIdMiddleware extracts or generates correlation IDs; requestLoggingMiddleware logs completed requests

import { Request, Response, NextFunction } from 'express';
import { randomUUID } from 'crypto';
import logger from '../utils/logger';

declare global {
  namespace Express {
    interface Request {
      correlationId?: string;
      startTime?: number;
    }
  }
}

/**
 * Middleware that extracts or generates a correlation ID for each request.
 *
 * - Reads the `x-correlation-id` header from the incoming request if present.
 * - Falls back to generating a new UUID.
 * - Sets `req.correlationId` for downstream use.
 * - Sets the `X-Correlation-Id` response header for client-side tracing.
 */
export function correlationIdMiddleware(req: Request, res: Response, next: NextFunction): void {
  const correlationId = (req.headers['x-correlation-id'] as string) || randomUUID();
  req.correlationId = correlationId;
  res.setHeader('X-Correlation-Id', correlationId);
  next();
}

/**
 * Middleware that logs structured information about every completed request.
 *
 * Records the following on response `finish`:
 * - HTTP method, path, status code
 * - Response duration (ms)
 * - Correlation ID
 * - User-Agent header
 *
 * Must be registered after `correlationIdMiddleware` so that `req.correlationId`
 * is available on every request.
 */
export function requestLoggingMiddleware(req: Request, res: Response, next: NextFunction): void {
  req.startTime = Date.now();

  res.on('finish', () => {
    const duration = Date.now() - (req.startTime || Date.now());

    logger.info({
      msg: 'Request completed',
      correlationId: req.correlationId,
      method: req.method,
      path: req.path,
      statusCode: res.statusCode,
      durationMs: duration,
      userAgent: req.headers['user-agent'],
    });
  });

  next();
}
