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

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

  constructor(
    @Inject("SMS_SERVICE")
    private smsClient: ClientProxy,
  ) { }

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

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

  async sendSms(dto: SingleMessageDto): Promise<{ queued: boolean }> {
    if (!this.enabled) {
      this.logger.warn(`RABBITMQ disabled — skipped SMS`);
      return { queued: false };
    }
    const queued = await publishConfirmed(
      this.smsClient,
      "send-sms",
      {
        to: dto.to,
        text: dto.message,
        appKey: "IFHCRS-LICENSE-MANAGEMENT",
      },
      this.logger,
    );
    // Publisher-confirmed: RabbitMQ has taken ownership of the message. Still NOT
    // delivery — the consumer, the SMS gateway and the carrier are all downstream
    // of this and invisible from here.
    this.logger.log(
      `SMS publish to RabbitMQ [${process.env.SMS_QUEUE ?? "sms_queue"}] pattern='send-sms' confirmed=${queued}`,
    );
    // Recipient + content are PII — debug only.
    this.logger.debug(`SMS payload to=${dto.to} text="${dto.message}"`);
    return { queued };
  }

  async sendBulkMessages(dto: BulkMessagesDto): Promise<{ queued: boolean }> {
    if (!this.enabled) {
      this.logger.warn(
        `RABBITMQ disabled — skipped BULK SMS (${dto.messages?.length ?? 0} messages)`,
      );
      return { queued: false };
    }
    const messages = (dto.messages ?? []).map((m) => ({
      to: m.to,
      text: m.message,
      from: m.from,
    }));
    const queued = await publishConfirmed(
      this.smsClient,
      "ozeking-bulk-sms",
      {
        messages,
        appKey: "IFHCRS-LICENSE-MANAGEMENT",
      },
      this.logger,
    );
    this.logger.log(
      `BULK SMS publish to RabbitMQ [${process.env.SMS_QUEUE ?? "sms_queue"}] pattern='ozeking-bulk-sms' count=${messages.length} confirmed=${queued}`,
    );
    this.logger.debug(`BULK SMS payload messages=${JSON.stringify(messages)}`);
    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.smsClient);
  }
}
