// oms/src/services/messageActivityService.ts

import { MessageActivity, IMessageActivity } from "../models/messageActivityModel";
import { IMessageTemplate, MessageTemplate } from "../models/messageTemplateModel";
import { MessageRecord, IMessageRecord } from "../models/messageRecordModel";
import { UserTargetingService } from "./userTargetingService";
import rabbitmqService from "./rabbitmqService";
import { addHours, isPast, differenceInHours } from "date-fns";

// 语言映射，用于根据国家代码确定语言
const ccToLangMap: { [key: string]: string } = {
  US: "en",
  GB: "en",
  CA: "en",
  AU: "en",
  CN: "zh-cn",
  TW: "zh-tw",
  JP: "ja",
  KR: "ko",
  FR: "fr",
  DE: "de",
  ES: "es",
  PT: "pt",
  RU: "ru",
  IT: "it",
};

// 检查传入的语言是否在消息模板中定义
const getLocalizedText = (template: IMessageTemplate, lang: string, key: "messageTitle" | "messageContent"): string => {
  if (template[key][lang]) {
    return template[key][lang];
  }
  return template[key]["en"] || ""; // 如果找不到语言，则默认使用 'en'
};

export class MessageActivityService {
  private userTargetingService: UserTargetingService;

  constructor() {
    this.userTargetingService = new UserTargetingService();
  }

  /**
   * 创建一个新的消息活动
   * @param activityData 消息活动数据
   * @returns 新创建的消息活动对象
   */
  public async createMessageActivity(activityData: IMessageActivity): Promise<IMessageActivity> {
    const { templateId } = activityData;

    // 验证消息模板是否存在
    if (templateId) {
      const templateExists = await MessageTemplate.findById(templateId);
      if (!templateExists) {
        throw new Error("Associated message template not found.");
      }
    }

    const newActivity = new MessageActivity(activityData);
    return await newActivity.save();
  }

  /**
   * 获取所有消息活动
   * @returns 消息活动列表
   */
  public async getAllActivities(): Promise<IMessageActivity[]> {
    return await MessageActivity.find().populate("templateId");
  }

  /**
   * 根据ID获取单个消息活动
   * @param activityId 消息活动ID
   * @returns 消息活动对象或null
   */
  public async getSingleActivity(activityId: string): Promise<IMessageActivity | null> {
    return await MessageActivity.findById(activityId).populate("templateId");
  }

  /**
   * 根据ID更新消息活动
   * @param activityId 消息活动ID
   * @param updateData 更新数据
   * @returns 更新后的消息活动对象
   */
  public async updateMessageActivity(activityId: string, updateData: Partial<IMessageActivity>): Promise<IMessageActivity | null> {
    const { templateId } = updateData;

    // 验证消息模板是否存在
    if (templateId) {
      const templateExists = await MessageTemplate.findById(templateId);
      if (!templateExists) {
        throw new Error("Associated message template not found.");
      }
    }

    const updatedActivity = await MessageActivity.findByIdAndUpdate(activityId, updateData, { new: true });
    return updatedActivity;
  }

  /**
   * 根据ID删除消息活动
   * @param activityId 消息活动ID
   * @returns 删除后的消息活动对象
   */
  public async deleteMessageActivity(activityId: string): Promise<IMessageActivity | null> {
    return await MessageActivity.findByIdAndDelete(activityId);
  }

  /**
   * 根据消息活动生成消息记录。
   *
   * @param activityId 要生成记录的消息活动ID
   * @returns 成功生成的记录数量
   */
  public async generateRecordsForActivity(activityId: string): Promise<number> {
    try {
      // 1. 获取消息活动和模板
      const activity = await MessageActivity.findById(activityId);
      if (!activity || !activity.templateId) {
        console.error(`Message activity or template not found for id: ${activityId}`);
        return 0;
      }

      // 更新activity的lastPubDate字段
      activity.lastPubDate = new Date();
      await activity.save();

      const template = await MessageTemplate.findById(activity.templateId);
      if (!template) {
        console.error(`Message template not found for id: ${activity.templateId}`);
        return 0;
      }

      // 2. 查找所有目标用户
      const targetUsers = await this.userTargetingService.findTargetUsers(activity.filter || []);
      if (targetUsers.length === 0) {
        console.log(`No users found for activity: ${activity.name}`);
        return 0;
      }

      // 3. 找出最近3天内（以 plannedSendAt 计）已收到过消息的用户
      // 先取消这个策略
      // const threeDaysAgo = addHours(new Date(), -72);
      // const recentMessages = await MessageRecord.aggregate([
      //   { $match: { uid: { $in: targetUsers.map((u) => u.uid) } } },
      //   { $sort: { plannedSendAt: -1 } },
      //   { $group: { _id: "$uid", lastPlannedSendAt: { $first: "$plannedSendAt" } } },
      // ]);
      // const lastPlannedSendMap = new Map<string, Date>();
      // recentMessages.forEach((item) => {
      //   if (item.lastPlannedSendAt >= threeDaysAgo) {
      //     lastPlannedSendMap.set(item._id, item.lastPlannedSendAt);
      //   }
      // });

      const recordsToInsert = [];

      // 4. 遍历目标用户，生成消息记录
      for (const user of targetUsers) {
        // 检查用户是否在最近3天内收到过消息
        // if (lastPlannedSendMap.has(user.uid)) {
        //   console.log(`User ${user.uid} has a recent message scheduled. Skipping.`);
        //   continue;
        // }

        // 5. 确定消息语言
        let userLang = "en"; // 默认语言
        if (user.lang) {
          userLang = user.lang;
        } else if (user.cc) {
          userLang = ccToLangMap[user.cc] || "en";
        }

        // 6. 从模板中获取本地化文本
        const messageTitle = getLocalizedText(template, userLang, "messageTitle");
        const messageContent = getLocalizedText(template, userLang, "messageContent");

        if (!messageTitle || !messageContent) {
          console.error(`No message title or content found for user ${user.uid} with lang/cc: ${userLang}/${user.cc}. Skipping.`);
          continue;
        }

        // 7. 计算 plannedSendAt
        let baseDate = activity.scheduleAt || new Date();
        // 如果活动计划时间已过期，则使用当前日期作为基础
        if (isPast(baseDate) && !activity.everyday) {
          baseDate = new Date();
        }

        let plannedSendAt = baseDate;
        if (user.lastActiveAt) {
          // 获取用户上次活跃时间的小时和分钟
          const lastActiveHour = user.lastActiveAt.getHours();
          const lastActiveMinute = user.lastActiveAt.getMinutes();

          // 将基础日期的时间调整为用户上次活跃时间的前一小时
          plannedSendAt = new Date(baseDate.getFullYear(), baseDate.getMonth(), baseDate.getDate(), lastActiveHour - 1, lastActiveMinute, 0, 0);

          // 如果调整后的时间在过去，则将日期推到第二天
          if (isPast(plannedSendAt) && differenceInHours(new Date(), plannedSendAt) > 2) {
            plannedSendAt = addHours(plannedSendAt, 24);
          }
        }

        // 8. 创建消息记录对象
        recordsToInsert.push({
          uid: user.uid,
          activityId: activity._id,
          templateId: template._id,
          title: messageTitle,
          content: messageContent,
          image: activity.image,
          bigger: activity.bigger,
          action: activity.action,
          param: activity.param,
          extend: activity.extend,
          status: 0, // 0: 未发送
          plannedSendAt: plannedSendAt,
        });
      }

      // 9. 批量插入消息记录
      let count = 0;
      if (recordsToInsert.length > 0) {
        const result = await MessageRecord.insertMany(recordsToInsert);
        console.log(`Successfully generated ${result.length} message records.`);
        count = result.length;
      } else {
        console.log("No new message records to generate.");
      }

      return count;
    } catch (error) {
      console.error("Error generating message records for activity:", error);
      return 0;
    }
  }
}
