import { Injectable, OnModuleInit } from '@nestjs/common';
import * as client from 'prom-client';
import { ITelemetryMetricsService } from '../../domain/ports/telemetry-metrics.service.interface';

@Injectable()
export class TelemetryMetricsService implements ITelemetryMetricsService, OnModuleInit {
  private readonly onlineUsers: client.Gauge;
  private readonly dau: client.Gauge;
  private readonly heartbeatTotal: client.Counter;
  private readonly eventsTotal: client.Counter;
  private readonly eventBatchDuration: client.Histogram;

  constructor() {
    this.onlineUsers = new client.Gauge({
      name: 'genex_online_users',
      help: 'Current online user count',
    });

    this.dau = new client.Gauge({
      name: 'genex_dau',
      help: 'Daily active users',
      labelNames: ['date'],
    });

    this.heartbeatTotal = new client.Counter({
      name: 'genex_heartbeat_total',
      help: 'Total heartbeat count',
      labelNames: ['app_version'],
    });

    this.eventsTotal = new client.Counter({
      name: 'genex_events_total',
      help: 'Total telemetry events',
      labelNames: ['event_name'],
    });

    this.eventBatchDuration = new client.Histogram({
      name: 'genex_event_batch_duration',
      help: 'Batch event processing duration in seconds',
      buckets: [0.01, 0.05, 0.1, 0.25, 0.5, 1, 2.5],
    });
  }

  onModuleInit() {
    client.collectDefaultMetrics();
  }

  // ── ITelemetryMetricsService interface methods ──

  incEventsTotal(eventName: string): void {
    this.eventsTotal.inc({ event_name: eventName });
  }

  incHeartbeatTotal(appVersion: string): void {
    this.heartbeatTotal.inc({ app_version: appVersion });
  }

  setOnlineUsers(count: number): void {
    this.onlineUsers.set(count);
  }

  setDau(date: string, count: number): void {
    this.dau.set({ date }, count);
  }

  startBatchTimer(): () => void {
    return this.eventBatchDuration.startTimer();
  }

  async getMetrics(): Promise<string> {
    return client.register.metrics();
  }

  getContentType(): string {
    return client.register.contentType;
  }
}
