import dayjs from "dayjs";
import { clickhouseService } from "../services/clients";
import mongoose, { Model } from "mongoose";
import DoneRate, { IDoneRate } from "../models/doneRateModel";
// 导入 DoneRate 模型

// ClickHouse 表名
const CLICKHOUSE_EVENTS_TABLE = "events";

// =========================================================================
// !!! 必须修改这里以设置回填的起始日期 (YYYY-MM-DD 格式) !!!
// 示例: 如果您的 tipCount 追踪是从 2024 年 1 月 1 日开始的，则设置为 "2024-01-01"
const BACKFILL_START_DATE = "2025-10-08";
// =========================================================================

/**
 * ClickHouse 查询结果接口：每日每个作品的使用道具数 (tipCount)
 */
interface ClickHouseTipCountResult {
  res: string; // 作品 ID (ObjectId 字符串形式)
  tip_count: number; // 道具使用次数
}

/**
 * 遍历指定日期范围，从 ClickHouse 提取 tipCount 并回填到 DoneRate 记录中。
 * @returns Promise<string> - 返回回填结果的摘要信息。
 */
export async function runBackfill(): Promise<string> {
  console.log(`[TipCount Backfill] Starting tipCount initialization for DoneRate model.`);

  // 设置日期范围：从 BACKFILL_START_DATE 到昨天
  let startDate = dayjs(BACKFILL_START_DATE).startOf("day");
  const endDate = dayjs().subtract(1, "day").startOf("day");

  if (!startDate.isValid() || startDate.isAfter(endDate)) {
    const errorMsg = `[TipCount Backfill] Invalid start date ${BACKFILL_START_DATE} or date range is empty. Aborting.`;
    console.error(errorMsg);
    return errorMsg;
  }

  console.log(`[TipCount Backfill] Date Range: ${startDate.format("YYYY-MM-DD")} to ${endDate.format("YYYY-MM-DD")}`);

  let totalDaysProcessed = 0;
  let totalDoneRateUpdated = 0;

  // 循环遍历历史数据中的每一天
  for (let currentDay = startDate; currentDay.isBefore(endDate) || currentDay.isSame(endDate); currentDay = currentDay.add(1, "day")) {
    const currentYYYYMMDD = currentDay.format("YYYYMMDD");
    const currentStartString = currentDay.format("YYYY-MM-DD HH:mm:ss");
    const currentEndString = currentDay.endOf("day").format("YYYY-MM-DD HH:mm:ss");

    console.log(`\n--- [TipCount Backfill] Processing date: ${currentYYYYMMDD} ---`);
    totalDaysProcessed++;

    try {
      // 1. 从 ClickHouse 中提取当天的 tipCount
      const tipCountsQuery = `
        SELECT
            res,
            count() AS tip_count
        FROM ${CLICKHOUSE_EVENTS_TABLE}
        WHERE event = 'color_tip'
          AND time >= toDateTime('${currentStartString}')
          AND time < toDateTime('${currentEndString}')
        GROUP BY res
        HAVING res IS NOT NULL
      `;
      const tipResults = await clickhouseService.queryEvents<ClickHouseTipCountResult>(tipCountsQuery);

      console.log(`[TipCount Backfill] Retrieved ${tipResults.length} records with 'color_tip' event.`);

      if (tipResults.length === 0) {
        // 如果当天没有 tip 事件，但可能存在 DoneRate 记录，我们仍然需要更新它们 (如果它们是 null 或 undefined)
        // 但由于 DoneRateModel 默认 tipCount: 0，所以我们只需要处理有 tip 事件的记录。
        console.log(`[TipCount Backfill] No 'color_tip' events found for ${currentYYYYMMDD}. Skipping MongoDB update.`);
        continue;
      }

      // 2. 批量更新 MongoDB 中的 DoneRate 记录
      const bulkOps = tipResults
        .filter((row) => row.res && mongoose.Types.ObjectId.isValid(row.res)) // 过滤掉无效的 res ID
        .map((row) => ({
          updateOne: {
            // 查找条件：日期 + 作品ID (唯一复合索引)
            filter: { date: currentYYYYMMDD, res: new mongoose.Types.ObjectId(row.res) },
            // 更新操作：设置 tipCount 字段
            // 注意：我们只更新 tipCount，不影响 startCount 和 doneCount
            update: { $set: { tipCount: row.tip_count } },
            // 如果 DoneRate 记录不存在，则忽略。因为 DoneRate 记录通常由 color_start/color_done 事件创建。
            upsert: false,
          },
        }));

      if (bulkOps.length > 0) {
        const updateResult = await DoneRate.bulkWrite(bulkOps, { ordered: false });

        const modifiedCount = updateResult.modifiedCount || 0;
        totalDoneRateUpdated += modifiedCount;

        console.log(`[TipCount Backfill] Successfully updated ${modifiedCount} DoneRate documents for ${currentYYYYMMDD}.`);
      }
    } catch (error) {
      console.error(`[TipCount Backfill] Fatal error processing date ${currentYYYYMMDD}:`, error);
    }
  }

  const summary = `[TipCount Backfill] DoneRate tipCount backfill completed. Total days processed: ${totalDaysProcessed}. Total DoneRate documents updated: ${totalDoneRateUpdated}.`;
  console.log(`\n${summary}`);
  return summary;
}
