// oms/src/services/fcmService.ts

import * as admin from "firebase-admin";
import path from "path";
import { BatchResponse, MulticastMessage, MessagingTopicManagementResponse, SendResponse } from "firebase-admin/messaging";

// 从配置文件加载服务账号
// 服务账号文件路径在 oms/config/fcm-service-account.json
const serviceAccount = require(path.join(__dirname, "../../config/fcm-service-account.json"));

/**
 * FCMService 类，用于处理 Firebase Cloud Messaging 的消息发送逻辑。
 * 使用单例模式确保 Firebase app 只初始化一次。
 */
export class FCMService {
  private static instance: FCMService;

  private constructor() {
    // 检查 Firebase 是否已初始化，避免重复初始化
    if (!admin.apps.length) {
      admin.initializeApp({
        credential: admin.credential.cert(serviceAccount),
      });
      console.log("Firebase Admin SDK initialized successfully.");
    }
  }

  /**
   * 获取 FCMService 的单例实例。
   * @returns FCMService 实例
   */
  public static getInstance(): FCMService {
    if (!FCMService.instance) {
      FCMService.instance = new FCMService();
    }
    return FCMService.instance;
  }

  /**
   * 发送 FCM 消息。
   * @param deviceToken 接收消息的设备令牌
   * @param data 消息数据，用于客户端解析
   * @returns 成功则返回消息 ID，失败则返回错误信息
   */
  public async sendMessage(deviceToken: string, data: any): Promise<string | Error> {
    const message: admin.messaging.Message = {
      data: data,
      token: deviceToken,
    };

    try {
      const response = await admin.messaging().send(message);
      console.log("Successfully sent message:", response);
      return response; // response is the message ID
    } catch (error) {
      console.error("Error sending message:", error);
      return error as Error;
    }
  }

  /**
   * 批量发送 FCM 消息给多个设备令牌。
   * @param tokens 接收消息的设备令牌数组
   * @param data 消息数据，用于客户端解析
   * @returns 批量发送结果，包含每个令牌的成功/失败信息
   */
  public async sendBatch(tokens: string[], data: any): Promise<BatchResponse> {
    const message: MulticastMessage = {
      data: data,
      tokens: tokens,
    };

    try {
      const response = await admin.messaging().sendEachForMulticast(message);
      console.log(`Successfully sent batch message: ${response.successCount} succeeded, ${response.failureCount} failed.`);
      return response;
    } catch (error) {
      console.error("Error sending message batch:", error);

      // 构建一个符合 FirebaseError 类型的对象来满足类型要求
      const firebaseError = {
        code: "messaging/unknown-error",
        message: `Failed to send batch: ${(error as Error).message}`,
        toJSON: () => ({ code: "messaging/unknown-error", message: `Failed to send batch: ${(error as Error).message}` }),
      } as admin.FirebaseError;

      return {
        successCount: 0,
        failureCount: tokens.length,
        responses: tokens.map(() => ({
          success: false,
          error: firebaseError,
        })),
      };
    }
  }
}
