// oms/src/services/doneRateService.ts
import DoneRate, { IDoneRate } from "../models/doneRateModel"; // 导入 DoneRate 模型和 IDoneRate 接口
import mongoose, { FilterQuery } from "mongoose"; // 导入 mongoose 类型，如 FilterQuery

class DoneRateService {
  /**
   * 创建或更新单条作品每日完成率记录。
   * 如果记录已存在 (由 date 和 res 唯一确定)，则更新其统计字段；否则创建新记录。
   * 会自动计算 completionRate。
   *
   * @param date - 日期 (yyyyMMdd 字符串格式)。
   * @param resId - 作品 ID (mongoose.Types.ObjectId)。
   * @param startCount - 今日该作品点击进入填色的次数。
   * @param doneCount - 今日该作品的完成数。
   * @returns 创建或更新后的 DoneRate 文档。
   */
  public async createOrUpdateDoneRate(date: string, resId: mongoose.Types.ObjectId, startCount: number, doneCount: number): Promise<IDoneRate> {
    try {
      if (startCount < 0 || doneCount < 0) {
        throw new Error("startCount and doneCount cannot be negative.");
      }

      // 计算完成率
      const completionRate = startCount > 0 ? (doneCount / startCount) * 100 : 0;

      const filter: FilterQuery<IDoneRate> = { date, res: resId };
      const update = {
        $set: {
          startCount: startCount,
          doneCount: doneCount,
          completionRate: completionRate,
        },
        $setOnInsert: {
          // 如果是新插入，确保这些字段也设置
          date: date,
          res: resId,
        },
      };
      const options = { upsert: true, new: true, setDefaultsOnInsert: true }; // 插入或更新，返回新文档，并在插入时应用默认值

      const doneRate = await DoneRate.findOneAndUpdate(filter, update, options);

      if (!doneRate) {
        throw new Error("Failed to create or update DoneRate record unexpectedly.");
      }
      return doneRate;
    } catch (error) {
      console.error(`创建或更新 DoneRate (date: ${date}, res: ${resId}) 时出错:`, error);
      throw new Error("无法创建或更新作品完成率记录。");
    }
  }

  /**
   * 根据作品 ID 获取该作品的所有历史完成率数据。
   * 结果按日期升序排列。
   *
   * @param resId - 作品 ID (mongoose.Types.ObjectId)。
   * @returns DoneRate 文档数组。
   */
  public async getDoneRatesByArtwork(resId: mongoose.Types.ObjectId): Promise<IDoneRate[]> {
    try {
      const doneRates = await DoneRate.find({ res: resId }).sort({ date: 1 }).exec();
      return doneRates;
    } catch (error) {
      console.error(`获取作品 (ID: ${resId}) 的完成率历史数据时出错:`, error);
      throw new Error("无法检索作品完成率历史数据。");
    }
  }

  /**
   * 根据特定日期获取该日所有作品的完成率数据。
   *
   * @param date - 日期 (yyyyMMdd 字符串格式)。
   * @returns DoneRate 文档数组。
   */
  public async getDoneRatesByDate(date: string): Promise<IDoneRate[]> {
    try {
      // 验证日期格式
      if (!/^\d{8}$/.test(date)) {
        throw new Error("Invalid date format. Expected YYYYMMDD.");
      }
      const doneRates = await DoneRate.find({ date: date }).exec();
      return doneRates;
    } catch (error) {
      console.error(`获取日期 (date: ${date}) 的完成率数据时出错:`, error);
      throw new Error("无法检索指定日期的完成率数据。");
    }
  }

  /**
   * 更新现有作品每日完成率记录的统计字段。
   *
   * @param date - 日期 (yyyyMMdd 字符串格式)。
   * @param resId - 作品 ID (mongoose.Types.ObjectId)。
   * @param updateData - 包含要更新字段的对象 (Partial<IDoneRate>)。
   * @returns 更新后的 DoneRate 文档，如果未找到则为 null。
   */
  public async updateDoneRate(date: string, resId: mongoose.Types.ObjectId, updateData: Partial<IDoneRate>): Promise<IDoneRate | null> {
    try {
      // 避免更新 date 和 res 字段，因为它们是复合索引的一部分
      const mutableUpdateData: Partial<IDoneRate> = { ...updateData };
      delete mutableUpdateData.date;
      delete mutableUpdateData.res;

      // 如果提供了 startCount 或 doneCount，重新计算 completionRate
      if ((mutableUpdateData.startCount !== undefined && mutableUpdateData.startCount >= 0) || (mutableUpdateData.doneCount !== undefined && mutableUpdateData.doneCount >= 0)) {
        // 先获取现有记录，以计算正确的完成率
        const existingRecord = await DoneRate.findOne({ date, res: resId }).lean().exec();
        if (existingRecord) {
          const currentStartCount = mutableUpdateData.startCount !== undefined ? mutableUpdateData.startCount : existingRecord.startCount;
          const currentDoneCount = mutableUpdateData.doneCount !== undefined ? mutableUpdateData.doneCount : existingRecord.doneCount;
          mutableUpdateData.completionRate = currentStartCount > 0 ? (currentDoneCount / currentStartCount) * 100 : 0;
        } else {
          // 如果记录不存在，则尝试更新时，完成率应基于传入数据或默认0
          const currentStartCount = mutableUpdateData.startCount || 0;
          const currentDoneCount = mutableUpdateData.doneCount || 0;
          mutableUpdateData.completionRate = currentStartCount > 0 ? (currentDoneCount / currentStartCount) * 100 : 0;
        }
      }

      const updatedDoneRate = await DoneRate.findOneAndUpdate(
        { date, res: resId },
        { $set: mutableUpdateData },
        { new: true, runValidators: true } // 返回更新后的文档，并运行 Schema 验证器
      );
      return updatedDoneRate;
    } catch (error) {
      console.error(`更新 DoneRate (date: ${date}, res: ${resId}) 时出错:`, error);
      throw new Error("无法更新作品完成率记录。");
    }
  }

  /**
   * 根据 date 和 res 删除单条完成率记录。
   *
   * @param date - 日期 (yyyyMMdd 字符串格式)。
   * @param resId - 作品 ID (mongoose.Types.ObjectId)。
   * @returns 如果删除成功则为 true，否则为 false。
   */
  public async deleteDoneRate(date: string, resId: mongoose.Types.ObjectId): Promise<boolean> {
    try {
      const result = await DoneRate.deleteOne({ date, res: resId }).exec();
      return result.deletedCount === 1; // 如果删除了一条记录，则返回 true
    } catch (error) {
      console.error(`删除 DoneRate (date: ${date}, res: ${resId}) 时出错:`, error);
      throw new Error("无法删除作品完成率记录。");
    }
  }
}

export default new DoneRateService();
