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

/**
  * GM用户组接口
*/
@index({ id: 1 })
@index({ group: 1 })
@modelOptions({schemaOptions: {id: false}})
export default class GMGroup extends BaseModel {
  @prop({ required: true })
  id: number;

  @prop({ required: true })
  group: string;

  @prop({ required: true })
  name: string;

  @prop({ required: true })
  desc: string;

  @prop({ required: true })
  apis: Array<number>;

   
  public static async createGroup(group: string, name: string, desc: string, lean = true) {
    const id = await CounterModel.getNewCounter(COUNTER.GM_GROUP);
    const result: GMGroupType = await GMGroupModel.findOneAndUpdate({id}, {group, desc, name, apis: []}, {upsert: true, new: true}).select('uid username name').lean(lean);
    return result;
  }

  public static async editGroup(groupId: number, group: string, name: string, desc: string, lean = true) {
    const result: GMGroupType = await GMGroupModel.findOneAndUpdate({ id: groupId }, {$set: {group, desc, name}}).select('uid username name').lean(lean);
    return result;
  }

  public static async getAllGroup(lean = true) {
    const list: GMGroupType[] = await GMGroupModel.find().lean(lean);
    return list;
  }

  public static async getGroup(group: string, lean = true) {
    const result: GMGroupType = await GMGroupModel.findOne({ group }).lean(lean);
    return result;
  }
  
  public static async getGroupById(id: number, lean = true) {
    const result: GMGroupType = await GMGroupModel.findOne({ id }).lean(lean);
    return result;
  }

  public static async saveApiToGroup(id: number, apis: Array<number>, lean = true) {
    let group: GMGroupType = await GMGroupModel.getGroupById(id);
    if(group) {
      let originApi = group.apis||[];
      let addArr = new Array(), removeArr = new Array();
      for(let i = 0; i < apis.length; i++) {
        let api = apis[i];
        if(originApi.indexOf(api) == -1) addArr.push(api);
      }
      for(let i = 0; i < originApi.length; i++) {
        let api = originApi[i];
        if(apis.indexOf(api) == -1) removeArr.push(api);
      }
      await GMGroupModel.findOneAndUpdate({ id }, { $push: {apis: {$each: addArr}} }).lean(lean);
      const result: GMGroupType = await GMGroupModel.findOneAndUpdate({ id }, { $pull: {apis: {$in: removeArr}} }).lean(lean);
      return result;
    }
  }
  
  
}

export let GMGroupModel: ReturnModelType<typeof GMGroup, {}>;
export function loadGMGroupModel(connect: mongoose.Connection) {
  GMGroupModel = getModelForClass(GMGroup, {
        existingConnection: connect
    });
}
export interface GMGroupType extends Pick<DocumentType<GMGroup>, keyof GMGroup>{
  id: number;
};
