import { Injectable } from '@nestjs/common';
import { InjectMetric } from '@willsoto/nestjs-prometheus';
import { type Counter, type Gauge, type Histogram } from 'prom-client';
import {
  GOODGO_LISTINGS_CREATED_TOTAL,
  GOODGO_PAYMENTS_PROCESSED_TOTAL,
  GOODGO_ACTIVE_SUBSCRIPTIONS,
  GOODGO_SEARCH_QUERIES_TOTAL,
  GOODGO_API_REQUEST_DURATION,
  HTTP_REQUESTS_TOTAL,
} from '../metrics.constants';

@Injectable()
export class MetricsService {
  constructor(
    @InjectMetric(GOODGO_LISTINGS_CREATED_TOTAL)
    private readonly listingsCreatedCounter: Counter,
    @InjectMetric(GOODGO_PAYMENTS_PROCESSED_TOTAL)
    private readonly paymentsProcessedCounter: Counter,
    @InjectMetric(GOODGO_ACTIVE_SUBSCRIPTIONS)
    private readonly activeSubscriptionsGauge: Gauge,
    @InjectMetric(GOODGO_SEARCH_QUERIES_TOTAL)
    private readonly searchQueriesCounter: Counter,
    @InjectMetric(GOODGO_API_REQUEST_DURATION)
    private readonly requestDurationHistogram: Histogram,
    @InjectMetric(HTTP_REQUESTS_TOTAL)
    private readonly httpRequestsCounter: Counter,
  ) {}

  /** Record a new listing creation. */
  recordListingCreated(category: string): void {
    this.listingsCreatedCounter.inc({ category });
  }

  /** Record a payment processing event. */
  recordPaymentProcessed(status: string, method: string): void {
    this.paymentsProcessedCounter.inc({ status, method });
  }

  /** Set the current number of active subscriptions for a plan tier. */
  setActiveSubscriptions(plan: string, count: number): void {
    this.activeSubscriptionsGauge.set({ plan }, count);
  }

  /** Record a search query. */
  recordSearchQuery(collection: string, type: string): void {
    this.searchQueriesCounter.inc({ collection, type });
  }

  /** Record HTTP request duration and count (used by interceptor). */
  recordHttpRequest(
    method: string,
    route: string,
    statusCode: number,
    durationSeconds: number,
  ): void {
    const labels = {
      method,
      route,
      status_code: String(statusCode),
    };
    this.requestDurationHistogram.observe(labels, durationSeconds);
    this.httpRequestsCounter.inc(labels);
  }
}
