/**
 * Performance Monitoring Interceptor
 *
 * Tracks request duration and logs metrics
 */

import { Injectable, NestInterceptor, ExecutionContext, CallHandler, Logger } from '@nestjs/common';
import { Observable } from 'rxjs';
import { tap, catchError } from 'rxjs/operators';
import * as Sentry from '@sentry/node';

@Injectable()
export class PerformanceMonitoringInterceptor implements NestInterceptor {
  private readonly logger = new Logger(PerformanceMonitoringInterceptor.name);

  intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
    const request = context.switchToHttp().getRequest();
    const { method, url, user } = request;
    const startTime = Date.now();

    return next.handle().pipe(
      tap(_data => {
        const duration = Date.now() - startTime;
        const response = context.switchToHttp().getResponse();

        // Log performance
        if (duration > 1000) {
          this.logger.warn(
            `Slow request: ${method} ${url} took ${duration}ms (userId: ${
              user?.sub || 'anonymous'
            })`
          );
        }

        // Log successful request
        this.logger.log(`${method} ${url} - ${response.statusCode} - ${duration}ms`);
      }),
      catchError(error => {
        const duration = Date.now() - startTime;

        // Log error
        this.logger.error(
          `Request error: ${method} ${url} (${duration}ms) - ${error.message}`,
          error.stack
        );

        // Capture exception in Sentry
        Sentry.withScope(scope => {
          scope.setContext('request', {
            method,
            url,
            userId: user?.sub,
            duration,
          });
          Sentry.captureException(error);
        });

        throw error;
      })
    );
  }
}
