import BaseModel from './BaseModel';
import { index, getModelForClass, prop, DocumentType, modelOptions } from '@typegoose/typegoose';
import { COUNTER } from '../consts'
import { CounterModel } from './Counter';

/**
  * 游戏字段接口
*/
@modelOptions({schemaOptions: {id: false}})
@index({ id: 1 })
export default class Notice extends BaseModel {

  @prop({ required: true })
  id: number;                 // 公告id
  @prop({ required: true })
  title: string;              // 公告标题
  @prop({ required: true })
  tag: number;                // 公告显示标签，在系统参数表中配了
  @prop({ required: true })
  type: number;               // 类型 1-公告 2-活动
  @prop({ required: true })
  content: string;            // 公告内容

  @prop({ required: true })
  time: string;             // 时间显示

  @prop({ required: true, select: false  })
  sort: number;

  @prop({ required: true, select: false  })
  showStartTime: Date;
  @prop({ required: true, select: false  })
  showEndTime: Date;

  @prop({ required: true, select: false  })
  isEnable: boolean;


  public static async getAllNotice() {
    let curTime = new Date();
    let notices: NoticeType[] = await NoticeModel.find({ showStartTime: { $lte: curTime }, showEndTime: { $gte: curTime }, isEnable: true })
    .sort({ sort: -1, createTime: -1 })
    .lean({ virtuals: true });
    return notices;
  }

  public static async updateNotice(id: number|string, values: NoticeTypeParam, uid = 1) {
    if(id == 'new') {
        id = await CounterModel.getNewCounter(COUNTER.NOTICE);
    }
    delete values.id;
    let rec: NoticeType = await NoticeModel.findOneAndUpdate({ id }, { $set: {...values, updatedBy: uid}, $setOnInsert: { createdBy: uid } },
        { new: true, upsert: true }).lean(true);
    return rec;
  }

  public static async delNotice(id: number) {
    let rec: NoticeType = await NoticeModel.findOneAndDelete({ id }).lean();
    return rec
  }

  private static getSearchObj(form: { type?: number, content?: string }) {
    let searchObj = {};
    if(form['content']) searchObj['content'] = { $regex: new RegExp(form.content.toString(), 'i') };
    return searchObj
  }

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

    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: NoticeType[] = await NoticeModel.find(searchObj).limit(pageSize).skip((page - 1) * pageSize).sort(sort).select('+sort +showStartTime +showEndTime +isEnable').lean({ getters: true, virtuals: true });
    return result;

  }

  public static async countByCondition(form: { type?: number, content?: string } = {}) {

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

export const NoticeModel = getModelForClass(Notice);

export interface NoticeType extends Pick<DocumentType<Notice>, keyof Notice>{
  id: number;
};
export type NoticeTypeParam = Partial<NoticeType>; // 将所有字段变成可选项