import {
  Inject,
  Injectable,
  Logger,
  OnApplicationBootstrap,
} from "@nestjs/common";
import { ClientProxy } from "@nestjs/microservices";
import { SendEmailDto } from "./dtos/email.dto";
import { isBrokerConnected, publishConfirmed } from "./broker.util";

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

  constructor(
    @Inject("EMAIL_SERVICE")
    private readonly emailClient: ClientProxy,
  ) {}

  private readonly enabled = process.env.RABBITMQ_ENABLED !== "false";

  async onApplicationBootstrap() {
    if (!this.enabled) return;
    this.emailClient
      .connect()
      .then(() => this.logger.log("connected to Email service"))
      .catch((err) => {
        console.error("Error happened at Email service", err);
      });
  }

  async sendEmail(dto: SendEmailDto): Promise<{ queued: boolean }> {
    if (!this.enabled) {
      this.logger.warn(`RABBITMQ disabled — skipped EMAIL to=${dto.to}`);
      return { queued: false };
    }
    const queued = await publishConfirmed(
      this.emailClient,
      "send-email",
      {
        to: dto.to,
        subject: dto.subject,
        text: dto.text,
        html: dto.html,
        appKey: "IFHCRS-LICENSE-MANAGEMENT",
      },
      this.logger,
    );
    // Publisher-confirmed: RabbitMQ has taken ownership of the message. Still NOT
    // delivery — the consumer and the SMTP hop are downstream and invisible here.
    this.logger.log(
      `EMAIL publish to RabbitMQ [${process.env.EMAIL_QUEUE ?? "email_queue"}] pattern='send-email' confirmed=${queued}`,
    );
    // Recipient + content are PII — debug only.
    this.logger.debug(`EMAIL payload to=${dto.to} subject="${dto.subject}"`);
    return { queued };
  }

  /**
   * Connection state for the health endpoint. `null` means the broker client did
   * not expose its manager — reported as "unknown" rather than assumed healthy.
   */
  get brokerConnected(): boolean | null {
    if (!this.enabled) return false;
    return isBrokerConnected(this.emailClient);
  }
}
