import { CallHandler, ExecutionContext, Injectable, NestInterceptor } from '@nestjs/common';
import { CustomLogger } from './custom-logger';
import { Observable, tap } from 'rxjs';

@Injectable()
export class LoggingInterceptor implements NestInterceptor {

  private readonly logger = new CustomLogger(LoggingInterceptor.name);
  private readonly excludedPaths = ['/health'];

  public intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
    const req = context.switchToHttp().getRequest();
    if (this.excludedPaths.includes(req.path)) {
      return next.handle();
    }

    if (!req.id) {
      req.id = this.generateRequestId();
    }
    const userId = req.user?.userId ?? '';

    this.logger.log(`[Request ${req.id}] ${req.method} ${req.url} by user ${userId} with body ${JSON.stringify(req.body, null, 2)}`);

    const startOfRequest = Date.now();
    return next
      .handle()
      .pipe(
        tap(() => this.logger.log(`[Request ${req.id}] Completed after... ${Date.now() - startOfRequest}ms`))
      );
  }

  private generateRequestId(): string {
    const randomString = Math.random().toString(36).substring(2, 8);
    return `${Date.now()}-${randomString}`;
  }
}
