import BaseModel from './BaseModel';
import { index, getModelForClass, prop, DocumentType } from '@typegoose/typegoose';
import { nowSeconds } from '../pubUtils/timeUtil';
import { isArray } from 'util';

/**
  * 累计充值活动 
*/
@index({ type: 1, id: -1 })
@index({ refTime: 1 })

export default class HiddenDataById extends BaseModel {

  @prop({ required: true })
  type: number;		    // 1-武将 2-道具

  @prop({ required: true })
  id: number;		    // 武将id or 道具id

  @prop({ required: false })
  publishTime: number;		    // 结束隐藏时间

  public static async checkHasInit(type: number, ids: number[]) {
    return await HiddenDataByIdModel.exists({ type, id: ids });
  }
  
  private static getSearchObj(form: any) {
    let searchObj = {};
    let orData = [];
    if(form.heroes && isArray(form.heroes) && form.heroes.length > 0) {
      orData.push({ type: 1, id: { $in: form.heroes }});
    }
    if(form.goods && isArray(form.goods) && form.goods.length > 0) {
      orData.push({ type: 2, id: { $in: form.goods }});
    }
    if(orData.length > 0) {
      searchObj['$or'] = orData;
    }
    return searchObj
  }

  public static async findByCondition(page: number, pageSize: number, sortField: string = 'updatedAt', sortOrder: string = 'descend', form: any = {}) {

    let searchObj = this.getSearchObj(form);
    let sort = {};
    if(sortField && sortOrder) {
        if(sortOrder == 'ascend') {
            sort[sortField] = 1;
        } else if (sortOrder == 'descend') {
            sort[sortField] = -1;
        }
    }
    const result: HiddenDataByIdModelType[] = await HiddenDataByIdModel.find(searchObj).limit(pageSize).skip((page - 1) * pageSize).sort(sort).lean({ getters: true, virtuals: true });
    return result;

  }

  public static async countByCondition(form: any = {}) {

      let searchObj = this.getSearchObj(form);
      const result = await HiddenDataByIdModel.count(searchObj);
      return result;
  }

  public static async createDatas(datas: HiddenDataByIdModelTypeParam[]) {
    await HiddenDataByIdModel.insertMany(datas);
  }

  public static async findAllData() {
    let result: { _id: number, ids: {type: number, id: number }[]}[] = await HiddenDataByIdModel.aggregate([
      { $match: { publishTime: { $gte: nowSeconds() } } },
      { $group: { _id: '$publishTime', ids: { $push: { type: '$type', id: '$id' } }} },
      { $sort: { _id: -1 } }
    ]);
    return result;
  }

  public static async findExistData(type: number) {
    let result: { type: number, id: number }[] = await HiddenDataByIdModel.aggregate([ 
      { $match: { type } },
      { $project: { id: 1 } } 
    ]);
    return result;
  }

  public static async checkById(type: number, ids: number[], publishTime: number) {
    let now = nowSeconds();
    if (publishTime >= now) { // 设为隐藏，不可有原来公开着的
      let result = await HiddenDataByIdModel.exists({ type, id: { $in: ids }, publishTime: { $lt: now } });
      return !result
    }
    return true;
  }

  public static async updateData(type: number, id: number, publishTime: number, uid: number) {
    await HiddenDataByIdModel.findOneAndUpdate({ type, id }, { $set: { publishTime, updatedBy: uid }, $setOnInsert: { createdBy: uid } }, { new: true, upsert: true }).lean();
  }
}

export const HiddenDataByIdModel = getModelForClass(HiddenDataById);

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