import mongoose, { Schema, Document } from "mongoose";
import { User, IUser } from "../../../src/models/userModel";
import { IMessageTemplate, MessageTemplate } from "../../../src/models/messageTemplateModel";
import { MessageStrategy, IMessageStrategy } from "../../../src/models/messageStrategyModel";
import { MessageRecord, IMessageRecord } from "../../../src/models/messageRecordModel";
import Art, { IArt } from "../../../src/models/artModel";
import { TimezoneService } from "../../../src/services/timezoneService";
// import { connectToDatabase } from "../../../src/database";

// 确保模型已被注册
mongoose.model("MessageTemplate", MessageTemplate.schema);
mongoose.model("MessageStrategy", MessageStrategy.schema);

// 国家代码到语言的映射表
const countryCodeToLanguageMap: { [key: string]: string } = {
  CN: "zh-cn",
  US: "en",
  JP: "ja",
  FR: "fr",
  DE: "de",
  ES: "es", // Spain
  MX: "es", // Mexico
  CL: "es", // Chile
  BR: "pt", // Brazil
  RU: "ru", // Russia
  IN: "hi", // India
  ID: "id", // Indonesia
  IT: "it",
  KR: "ko",
  TH: "th",
  TR: "tr",
  VN: "vi",
};

// 新增：每日推送策略的配置
const dailyStrategies = [
  // { name: "local-morning-notify", hour: 8 }, // 早上8点
  { name: "local-midday-notify", hour: 12 }, // 中午12点
  // { name: "local-evening-notify", hour: 20 }, // 晚上8点
];

/**
 * 根据用户的 lang 或 cc 字段推断其语言。
 * @param user 用户对象
 * @returns 推断出的语言代码
 */
function getUserLanguage(user: IUser): string {
  if (user.lang) {
    return user.lang;
  }
  if (user.cc && countryCodeToLanguageMap[user.cc]) {
    return countryCodeToLanguageMap[user.cc];
  }
  return "en";
}

/**
 * 将多语言模板转换为 FCM 消息数据格式。
 * @param template 消息模板
 * @param userLang 用户的语言代码
 * @param artworkId 画作ID
 */
function getMessageDataFromTemplate(template: IMessageTemplate, userLang: string, artworkId: string): { [key: string]: string } {
  const lang = template.messageContent[userLang] ? userLang : "en";
  const imageUrl = `https://d1e6q48ob2nxw1.cloudfront.net/thumbs/v2/page/640/${artworkId}.png`;

  return {
    title: template.messageTitle[lang] || template.messageTitle["en"] || "",
    content: template.messageContent[lang] || template.messageContent["en"] || "",
    image: template.image || imageUrl, // 如果template指定了图片则用template的，没有则使用随机分配的今日新图
    bigger: "true",
    action: "go/art",
    param: template.param || artworkId,
    extend: template.extend || "",
  };
}

/**
 * 获取今日的用于消息推送的8幅最新画作。
 * @returns 包含八个画作 ID 的数组
 */
async function getTodaysArtworksForFCM(): Promise<string[]> {
  try {
    const artworks = await Art.find({}).sort({ publishTime: -1 }).limit(8).lean<IArt[]>();
    return artworks.map((art) => art._id.toString());
  } catch (error) {
    console.error("查询今日画作失败:", error);
    return [];
  }
}

/**
 * 记录消息，不再立即发送。
 * 此函数仅创建数据库记录。
 * @param uid 用户ID
 * @param cc 用户国家代码
 * @param template 消息模板
 * @param messageData 消息数据
 * @param strategyId 消息策略ID
 * @param strategyName 消息策略名称
 * @param plannedSendAt 计划发送时间
 */
const recordMessage = async (
  uid: string,
  cc: string | undefined,
  template: IMessageTemplate,
  messageData: { [key: string]: string },
  strategyId: mongoose.Types.ObjectId,
  strategyName: string,
  plannedSendAt: Date
) => {
  try {
    await MessageRecord.create({
      uid: uid,
      cc: cc,
      templateId: template._id,
      templateName: template.templateName,
      strategyId: strategyId,
      strategyName: strategyName,
      title: messageData.title,
      content: messageData.content,
      image: messageData.image,
      bigger: messageData.bigger === "true",
      action: messageData.action,
      param: messageData.param,
      extend: messageData.extend,
      plannedSendAt: plannedSendAt, // 使用计算出的计划时间
      status: 0,
    });

    console.log(`成功为用户 ${uid} 创建消息记录。计划发送时间: ${plannedSendAt.toISOString()}`);
  } catch (error) {
    console.error(`创建消息记录失败，用户 ${uid}:`, error);
  }
};

/**
 * 脚本的入口方法，用于筛选用户并创建每日三条消息的推送任务。
 * @returns {Promise<void>}
 */
export async function run(): Promise<void> {
  console.log("脚本开始：创建活跃用户每日通知任务...");

  // await connectToDatabase();

  try {
    const sevenDaysAgo = new Date(Date.now() - 7 * 24 * 60 * 60 * 1000);

    const activeUsers = await User.find({
      lastActiveAt: { $gte: sevenDaysAgo },
      // $or: [{ lastActiveAt: { $gte: sevenDaysAgo } }, { lastActiveAt: { $in: [null, "", undefined] } }],
      fmToken: { $nin: [null, ""] },
      versionCode: { $gte: 347 },
    })
      .select("_id uid fmToken lang cc")
      .lean<IUser[]>();

    if (activeUsers.length === 0) {
      console.log("未找到符合条件的用户，脚本结束。");
      return;
    }
    console.log(`找到 ${activeUsers.length} 位活跃用户。`);

    const todaysArtworks = await getTodaysArtworksForFCM();
    if (todaysArtworks.length === 0) {
      console.warn("今日用于FCM消息推送的画作数量不足。脚本结束。");
      return;
    }
    console.log(`今日获取到 ${todaysArtworks.length} 幅最新画作。`);

    // 加载所有需要的策略和模板
    const strategies = await MessageStrategy.find({ name: { $in: dailyStrategies.map((s) => s.name) } }).populate("templates");
    if (strategies.length !== dailyStrategies.length) {
      console.error("未找到所有必需的消息策略。");
      return;
    }

    const strategyMap = new Map(strategies.map((s) => [s.name, s]));

    // 实例化 TimezoneService
    const timezoneService = TimezoneService.getInstance();

    // 遍历用户，创建每日三条消息任务
    console.log("\n开始为用户创建每日任务...");
    for (const user of activeUsers) {
      const userLang = getUserLanguage(user);

      // 为每个预设的时间点创建一条消息记录
      for (const config of dailyStrategies) {
        const strategy = strategyMap.get(config.name);
        if (!strategy || !strategy.templates || strategy.templates.length === 0) {
          console.error(`策略 '${config.name}' 或其绑定的模板缺失，跳过此任务。`);
          continue;
        }
        const templates = strategy.templates as IMessageTemplate[];

        // 随机选择一个模板
        const randomIndex = Math.floor(Math.random() * templates.length);
        const template = templates[randomIndex];

        // 从获取的8幅画作中随机选择一个
        const randomArtworkIndex = Math.floor(Math.random() * todaysArtworks.length);
        const artworkId = todaysArtworks[randomArtworkIndex];

        const messageData = getMessageDataFromTemplate(template, userLang, artworkId);

        // **核心改动：直接调用 TimezoneService 中的方法**
        const plannedSendAt = timezoneService.getPlannedSendTime(user.cc, config.hour);

        await recordMessage(user.uid, user.cc, template, messageData, strategy._id, strategy.name, plannedSendAt);
      }
    }

    console.log("所有每日任务创建完成。");
  } catch (error) {
    console.error("脚本执行过程中发生致命错误:", error);
    throw error;
  }
}

// 确保只有在直接运行时才调用 run() 函数
if (require.main === module) {
  run()
    .then(() => {
      console.log("脚本执行完毕，退出进程。");
      process.exit(0);
    })
    .catch((err) => {
      console.error("脚本执行失败:", err);
      process.exit(1);
    });
}
