// Prometheus Metrics Collection
// Request duration, error rates, database performance

import { logger } from './logger';

// In production, this would use prom-client
// For now, we'll create a simple metrics interface

export interface Metrics {
  requestDuration: Map<string, number[]>;
  errorCount: Map<string, number>;
  dbQueryDuration: Map<string, number[]>;
}

class MetricsService {
  private metrics: Metrics = {
    requestDuration: new Map(),
    errorCount: new Map(),
    dbQueryDuration: new Map(),
  };

  /**
   * Record request duration
   */
  recordRequestDuration(path: string, method: string, duration: number): void {
    const key = `${method}:${path}`;
    if (!this.metrics.requestDuration.has(key)) {
      this.metrics.requestDuration.set(key, []);
    }
    this.metrics.requestDuration.get(key)?.push(duration);
  }

  /**
   * Record error
   */
  recordError(path: string, method: string, statusCode: number): void {
    const key = `${method}:${path}:${statusCode}`;
    const current = this.metrics.errorCount.get(key) || 0;
    this.metrics.errorCount.set(key, current + 1);
  }

  /**
   * Record database query duration
   */
  recordDbQuery(operation: string, duration: number): void {
    if (!this.metrics.dbQueryDuration.has(operation)) {
      this.metrics.dbQueryDuration.set(operation, []);
    }
    this.metrics.dbQueryDuration.get(operation)?.push(duration);
  }

  /**
   * Get average request duration for a path
   */
  getAverageRequestDuration(path: string, method: string): number {
    const key = `${method}:${path}`;
    const durations = this.metrics.requestDuration.get(key) || [];
    if (durations.length === 0) return 0;
    return durations.reduce((a, b) => a + b, 0) / durations.length;
  }

  /**
   * Get error count for a path
   */
  getErrorCount(path: string, method: string, statusCode: number): number {
    const key = `${method}:${path}:${statusCode}`;
    return this.metrics.errorCount.get(key) || 0;
  }

  /**
   * Get metrics summary
   */
  getSummary(): {
    requestDurations: Record<string, number>;
    errorCounts: Record<string, number>;
    dbQueryDurations: Record<string, number>;
  } {
    const requestDurations: Record<string, number> = {};
    for (const [key, durations] of this.metrics.requestDuration.entries()) {
      if (durations.length > 0) {
        requestDurations[key] = durations.reduce((a, b) => a + b, 0) / durations.length;
      }
    }

    const errorCounts: Record<string, number> = {};
    for (const [key, count] of this.metrics.errorCount.entries()) {
      errorCounts[key] = count;
    }

    const dbQueryDurations: Record<string, number> = {};
    for (const [operation, durations] of this.metrics.dbQueryDuration.entries()) {
      if (durations.length > 0) {
        dbQueryDurations[operation] = durations.reduce((a, b) => a + b, 0) / durations.length;
      }
    }

    return {
      requestDurations,
      errorCounts,
      dbQueryDurations,
    };
  }

  /**
   * Reset metrics (useful for testing)
   */
  reset(): void {
    this.metrics = {
      requestDuration: new Map(),
      errorCount: new Map(),
      dbQueryDuration: new Map(),
    };
  }
}

export const metricsService = new MetricsService();

