import {
  CallHandler,
  ExecutionContext,
  Injectable,
  NestInterceptor,
} from '@nestjs/common';
import { Observable } from 'rxjs';
import { tap } from 'rxjs/operators';
import { Request } from 'express';

/** Clés à masquer dans les logs (corps de requête) */
const SENSITIVE_KEYS = [
  'password',
  'smtp_password',
  'token',
  'accessToken',
  'refreshToken',
  'secret',
];

function maskBody(body: unknown): unknown {
  if (body === null || body === undefined) return body;
  if (typeof body !== 'object') return body;
  const out: Record<string, unknown> = {};
  for (const [key, value] of Object.entries(body)) {
    const lower = key.toLowerCase();
    const isSensitive = SENSITIVE_KEYS.some((s) => lower.includes(s));
    out[key] = isSensitive ? '***' : value;
  }
  return out;
}

@Injectable()
export class LogRequestInterceptor implements NestInterceptor {
  private readonly enabled: boolean;

  constructor() {
    this.enabled =
      process.env.LOG_API_REQUESTS === 'true' ||
      process.env.LOG_API_REQUESTS === '1';
  }

  intercept(context: ExecutionContext, next: CallHandler): Observable<unknown> {
    if (!this.enabled) return next.handle();

    const http = context.switchToHttp();
    const req = http.getRequest<Request>();
    const { method, url, body, query } = req;
    const hasBody = body && Object.keys(body).length > 0;

    const logLine = [
      `[API] ${method} ${url}`,
      Object.keys(query || {}).length ? `query=${JSON.stringify(query)}` : '',
      hasBody ? `body=${JSON.stringify(maskBody(body))}` : '',
    ]
      .filter(Boolean)
      .join(' ');

    console.log(logLine);

    return next.handle().pipe(
      tap({
        next: () => {
          // Optionnel: log du statut en fin de requête (si besoin plus tard)
        },
      }),
    );
  }
}
