import {
    CallHandler,
    ExecutionContext,
    Injectable,
    NestInterceptor,
} from '@nestjs/common';
import { Observable } from 'rxjs';
import { finalize } from 'rxjs/operators';
import { MetricsService } from './metrics.service';

@Injectable()
export class HttpMetricsInterceptor implements NestInterceptor {
    constructor(private readonly metrics: MetricsService) { }

    intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
        const req = context.switchToHttp().getRequest();
        const res = context.switchToHttp().getResponse();

        const method = req.method;
        const route = req.route?.path || req.url;

        const start = Date.now();
        this.metrics.activeRequests.inc();

        return next.handle().pipe(
            finalize(() => {
                const duration = (Date.now() - start) / 1000;
                const status = res.statusCode;

                this.metrics.activeRequests.dec();

                this.metrics.requestCounter.inc({
                    method,
                    route,
                    status: String(status),
                });

                this.metrics.requestDuration.observe(
                    { method, route },
                    duration,
                );
            }),
        );
    }
}
