import { Injectable, Logger } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { HttpService } from '@nestjs/axios';
import { firstValueFrom } from 'rxjs';
import { MetricSnapshotRepository } from '../repositories/metric-snapshot.repository';
import { MetricSnapshot } from '../../domain/entities/metric-snapshot.entity';

@Injectable()
export class PrometheusCollector {
  private readonly logger = new Logger(PrometheusCollector.name);
  private readonly prometheusUrl: string;

  constructor(
    private readonly metricRepo: MetricSnapshotRepository,
    private readonly configService: ConfigService,
    private readonly httpService: HttpService,
  ) {
    this.prometheusUrl = this.configService.get<string>(
      'PROMETHEUS_URL',
      'http://localhost:9090',
    );
  }

  async collect(
    server: { id: string },
    queries: string[],
  ): Promise<MetricSnapshot[]> {
    const snapshots: MetricSnapshot[] = [];
    const now = new Date();

    for (const query of queries) {
      try {
        const response = await firstValueFrom(
          this.httpService.get(`${this.prometheusUrl}/api/v1/query`, {
            params: { query },
            timeout: 10_000,
          }),
        );

        const result = response.data;
        if (result?.status !== 'success' || !result.data?.result?.length) {
          this.logger.debug(`No results for Prometheus query: ${query}`);
          continue;
        }

        for (const series of result.data.result) {
          const [, valueStr] = series.value ?? [];
          const value = parseFloat(valueStr);
          if (isNaN(value)) continue;

          const metricType = series.metric?.__name__ ?? query.split('{')[0].trim();
          const snap = new MetricSnapshot();
          snap.serverId = server.id;
          snap.metricType = metricType;
          snap.value = value;
          snap.recordedAt = now;

          await this.metricRepo.save(snap);
          snapshots.push(snap);
        }
      } catch (error: any) {
        this.logger.error(
          `Prometheus query failed (${query}): ${error.message}`,
        );
      }
    }

    this.logger.debug(
      `Collected ${snapshots.length} metrics from Prometheus for server ${server.id}`,
    );
    return snapshots;
  }
}
