import { Injectable, NestMiddleware } from '@nestjs/common';
import type { Request, Response, NextFunction } from 'express';
import { PinoLogger } from 'nestjs-pino';
import { extractClientIp } from 'src/common/utils/client-ip.util';

@Injectable()
export class RequestContextMiddleware implements NestMiddleware {
  constructor(private readonly logger: PinoLogger) {
    this.logger.setContext(RequestContextMiddleware.name);
  }

  use(req: Request, res: Response, next: NextFunction) {
    // client ip
    const clientIp = extractClientIp(req);

    req.clientIp = clientIp;

    const requestId =
      typeof req.id === 'string' || typeof req.id === 'number'
        ? req.id.toString()
        : undefined;

    if (requestId) {
      req.requestId = requestId;
      res.setHeader('x-request-id', requestId);
    }

    this.logger.debug(
      {
        event: 'http.request.in',
        requestId: requestId ?? '',
        method: req.method,
        path: req.originalUrl ?? req.url,
        clientIp,
      },
      'http request in',
    );

    next();
  }
}
