import { Injectable, Logger, OnModuleInit } from '@nestjs/common';
import { RedisEventBus } from '@it0/events';
import { EventPatterns } from '@it0/common';
import { MetricSnapshotRepository } from '../repositories/metric-snapshot.repository';
import { MetricSnapshot } from '../../domain/entities/metric-snapshot.entity';

interface AgentMetricsPayload {
  serverId: string;
  metrics: Array<{
    metricType: string;
    value: number;
    recordedAt?: string;
  }>;
}

@Injectable()
export class AgentCollector implements OnModuleInit {
  private readonly logger = new Logger(AgentCollector.name);

  constructor(
    private readonly metricRepo: MetricSnapshotRepository,
    private readonly eventBus: RedisEventBus,
  ) {}

  async onModuleInit(): Promise<void> {
    this.logger.log('Subscribing to AGENT_METRICS events...');

    await this.eventBus.subscribe(
      EventPatterns.AGENT_METRICS,
      'monitor-agent-collector',
      `collector-${crypto.randomUUID().slice(0, 8)}`,
      async (event) => {
        await this.handleMetrics(event.payload ?? event);
      },
    );
  }

  async handleMetrics(data: AgentMetricsPayload): Promise<void> {
    if (!data?.serverId || !Array.isArray(data.metrics)) {
      this.logger.warn('Received invalid AGENT_METRICS payload, skipping');
      return;
    }

    const now = new Date();
    const snapshots: MetricSnapshot[] = [];

    for (const metric of data.metrics) {
      const snap = new MetricSnapshot();
      snap.serverId = data.serverId;
      snap.metricType = metric.metricType;
      snap.value = metric.value;
      snap.recordedAt = metric.recordedAt ? new Date(metric.recordedAt) : now;

      await this.metricRepo.save(snap);
      snapshots.push(snap);
    }

    this.logger.debug(
      `Processed ${snapshots.length} agent metrics for server ${data.serverId}`,
    );
  }
}
