import { Injectable, Logger } from "@nestjs/common";
import { ConfigService } from "@nestjs/config";
import axios, { isAxiosError } from "axios";

import { NotificationStrategy } from "./notification.strategy";

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

  constructor(private readonly configService: ConfigService) {}

  async send(recipient: string, message: string): Promise<boolean> {
    const url =
      this.configService.get<string>("OZIKING_SMS_URL") ??
      "https://notification-dev.license.aafda.gov.et/api/sms-services/ozeking/sms";

    const appKey = this.configService.get<string>("OZIKING_APP_KEY") ?? "";
    if (!appKey) {
      this.logger.warn("OZIKING_APP_KEY is not set — SMS may be rejected by the API");
    }

    this.logger.debug(`Sending SMS to ${recipient} via ${url}`);

    // axios defaults to no timeout — a hanging gateway would block the caller
    // (and any transaction it sits in) indefinitely. Always bound the wait.
    const timeout = Number(this.configService.get<string>("SMS_TIMEOUT_MS") ?? 8000);

    try {
      const response = await axios.post(
        url,
        {
          to: recipient,
          sourceId: this.configService.get<string>("OZIKING_SOURCE_ID") ?? "EDR",
          sourceName: this.configService.get<string>("OZIKING_SOURCE_NAME") ?? "EDR Freight",
          appKey,
          text: message,
          callbackUrl: "",
        },
        {
          timeout,
          headers: {
            accept: "*/*",
            "Content-Type": "application/json",
          },
        },
      );

      this.logger.debug(`SMS API response: ${response.status} ${JSON.stringify(response.data)}`);
      return true;
    } catch (err) {
      if (isAxiosError(err)) {
        this.logger.error(
          `SMS API error: ${err.message} | status=${err.response?.status} | body=${JSON.stringify(err.response?.data)}`,
        );
      } else {
        this.logger.error(`SMS send failed: ${String(err)}`);
      }
      throw err;
    }
  }
}
