import { Injectable, Inject, Logger } from '@nestjs/common';
import { ClientKafka } from '@nestjs/microservices';
import { DomainEvent } from '../../domain/events/domain-event.base';

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

  constructor(
    @Inject('KAFKA_SERVICE')
    private readonly kafkaClient: ClientKafka,
  ) {}

  async publish(event: DomainEvent): Promise<void> {
    const topic = this.getTopicForEvent(event);
    const message = {
      key: event.aggregateId,
      value: JSON.stringify({
        eventId: event.eventId,
        eventType: event.eventType,
        aggregateId: event.aggregateId,
        aggregateType: event.aggregateType,
        occurredAt: event.occurredAt.toISOString(),
        version: event.version,
        payload: event.toPayload(),
      }),
    };

    try {
      this.kafkaClient.emit(topic, message);
      this.logger.log(`Published event ${event.eventType} to topic ${topic}`);
    } catch (error) {
      this.logger.error(`Failed to publish event ${event.eventType}:`, error);
      throw error;
    }
  }

  async publishAll(events: DomainEvent[]): Promise<void> {
    for (const event of events) {
      await this.publish(event);
    }
  }

  private getTopicForEvent(event: DomainEvent): string {
    switch (event.eventType) {
      case 'RewardCreated':
        return 'reward.created';
      case 'RewardClaimed':
        return 'reward.claimed';
      case 'RewardExpired':
        return 'reward.expired';
      case 'RewardSettled':
        return 'reward.settled';
      default:
        return 'reward.events';
    }
  }
}
