import mongoose from "mongoose";
import { IMessageRecord, MessageRecord } from "../../src/models/messageRecordModel";
import { User } from "../../src/models/userModel";
import { FCMService } from "../../src/services/fcmService";
import { filterEmptyProps } from "../../src/libs/utils";

const fcmService = FCMService.getInstance();

/**
 * 消息发送任务：
 * 1. 查询所有状态为0（未发送）且计划发送时间已到的消息记录。
 * 2. 遍历这些消息，为每个消息找到对应的用户和设备令牌。
 * 3. 调用 FCMService 发送消息。
 * 4. 根据发送结果更新 messageRecord 的状态和相关字段。
 *
 * 注意：数据库连接由外部的调度器（例如 index.ts）统一管理。
 */
export const run = async () => {
  console.log("Starting message sender cron job...");

  try {
    // 检查连接状态，确保在执行查询前数据库已连接
    if (mongoose.connection.readyState !== 1) {
      console.error("[Message Sender] Database connection is not ready. Skipping execution.");
      return;
    }

    // 查找状态为0且计划发送时间小于或等于当前时间的消息记录
    const recordsToSend: IMessageRecord[] = await MessageRecord.find({
      status: 0,
      plannedSendAt: { $lte: new Date() },
    }).limit(100);

    console.log(`Found ${recordsToSend.length} messages to send.`);

    for (const record of recordsToSend) {
      try {
        const user = await User.findOne({ uid: record.uid });
        if (!user || !user.fmToken) {
          console.warn(`User ${record.uid} not found or no FCM token, updating record status to failed.`);
          await MessageRecord.findByIdAndUpdate(record._id, {
            status: -1,
            actualSendAt: new Date(),
            errno: "User not found or no FCM token",
          });
          continue;
        }

        const messageData = filterEmptyProps({
          msgid: record._id.toString(),
          title: record.title,
          content: record.content,
          image: record.image || "",
          bigger: record.bigger?.toString() || "false",
          action: record.action || "",
          param: record.param || "",
          extend: record.extend || "",
        });

        const result = await fcmService.sendMessage(user.fmToken, messageData);

        if (result instanceof Error) {
          // 检查是否是由于无效的FCM Token导致的失败
          const isTokenInvalid =
            result.message.includes("messaging/invalid-argument") || result.message.includes("messaging/registration-token-not-registered") || result.message.includes("messaging/unregistered");

          let updateOps: any = {
            status: -1,
            actualSendAt: new Date(),
            errno: result.message,
          };

          if (isTokenInvalid) {
            // 如果是Token无效，则从用户文档中移除fcmToken
            console.warn(`[Message Sender] Invalid FCM Token for user ${record.uid}. Clearing token.`);
            await User.findOneAndUpdate({ uid: record.uid }, { fmToken: null });
            updateOps.errno = `Invalid FCM Token. Token has been cleared. Original error: ${result.message}`;
          }

          await MessageRecord.findByIdAndUpdate(record._id, updateOps);
        } else {
          // 成功发送，更新记录
          await MessageRecord.findByIdAndUpdate(record._id, {
            status: 1,
            actualSendAt: new Date(),
            fcmReceipt: result,
            errno: null,
          });
        }
      } catch (error) {
        console.error(`Failed to process message record ${record._id}:`, error);
        await MessageRecord.findByIdAndUpdate(record._id, {
          status: -1,
          actualSendAt: new Date(),
          errno: "Internal server error while processing message",
        });
      }
    }
    console.log("Message sender cron job finished.");
  } catch (err) {
    console.error("Error in message sender cron job:", err);
  }
};
