import * as amqp from 'amqplib';

import { TTaskEnvelope } from '../microservice/task-envelope.type';

const { NODE_ENV } = process.env;

export class RabbitService {
  private connection: amqp.ChannelModel | null = null;
  private channel: amqp.Channel | null = null;

  async init() {
    const rabbitMQApi = NODE_ENV === 'development' ? 'localhost' : 'rabbitmq';

    this.connection = await amqp.connect(`amqp://${rabbitMQApi}`, { heartbeat: 10 });

    this.connection.on('error', (err) => {
      console.error('RabbitMQ connection error', err);
    });

    this.connection.on('close', () => {
      console.warn('RabbitMQ connection closed. Reconnecting...');
      setTimeout(() => this.init(), 5000);
    });

    this.channel = await this.connection.createChannel();

    console.log('RabbitMQ connected');
  }

  publish(exchange: string, routingKey: string, payload: TTaskEnvelope<unknown>) {
    if (!this.channel) {
      throw new Error('RabbitMQ channel is not initialized');
    }

    this.channel.publish(
      exchange,
      routingKey,
      Buffer.from(JSON.stringify(payload)),
      { persistent: true },
    );
  }
}
