import BaseModel from './BaseModel';
import { index, getModelForClass, prop, DocumentType, Ref, mongoose } from '@typegoose/typegoose';
import Guild from './Guild';
import Role, { } from './Role';

/**
  * 活动系统 - 限时排行榜
*/
@index({ activityId: 1 })

export default class Activity_Time_Limit_Rank extends BaseModel {
  @prop({ required: true })
  serverId: number;				// 区Id
  
  @prop({ required: true })
  activityId: number;				// 活动Id

  @prop({ required: false })
  guildCode: string;			    // 军团

  @prop({ ref: () => Guild, type: mongoose.Schema.Types.ObjectId })
  guild: Ref<Guild>;

  @prop({ required: false })
  roleId: string;			    // 军团

  @prop({ ref: () => Role, type: mongoose.Schema.Types.ObjectId })
  role: Ref<Role>;

  @prop({ required: true })
  score: number;			       // 活动期间内的积分

  @prop({ required: true })
  time: number;			       // 更新时间

  public static async addGuildScore(serverId: number, activityId: number, rankType: number, guildCode: string, fund: number, guild?: string) {
    let rec: ActivityTimeLimitRankModelType = await ActivityTimeLimitRankModel.findOneAndUpdate({
      serverId, activityId, guildCode
    }, {
      $setOnInsert: { guild }, $set: { time: Date.now(), rankType }, $inc: { score: fund }
    }, { new: true, upsert: true }).lean();
    return rec;
  }

  public static async findByCode(serverId: number, activityId: number, guildCode: string) {
    let rec: ActivityTimeLimitRankModelType = await ActivityTimeLimitRankModel.findOne({ serverId, activityId, guildCode }).lean();
    return rec;
  }

  public static async insertRanks(insertInfos: ActivityTimeLimitRankModelTypeParam[]) {
    await ActivityTimeLimitRankModel.insertMany(insertInfos);
    return <ActivityTimeLimitRankModelType[]>insertInfos;
  }

  public static async getRank(serverId: number, activityId: number) {
    let rec: ActivityTimeLimitRankModelType[] = await ActivityTimeLimitRankModel.find({ serverId, activityId })
    .populate('role')
    .populate({
      path: 'guild',
      select: 'code icon name lv memberCnt leader ceLimit',
      model: 'Guild',
      populate: {
          path: 'leader',
          model: 'Role'
      }
    }).sort({ score: -1, time: 1 }).lean({ getters: true, virtuals: true });
    return rec;
  }
}

export const ActivityTimeLimitRankModel = getModelForClass(Activity_Time_Limit_Rank);

export interface ActivityTimeLimitRankModelType extends Pick<DocumentType<Activity_Time_Limit_Rank>, keyof Activity_Time_Limit_Rank> { }
export type ActivityTimeLimitRankModelTypeParam = Partial<ActivityTimeLimitRankModelType>; // 将所有字段变成可选项