import BaseModel from './BaseModel';
import { index, getModelForClass, prop, DocumentType, modelOptions, ReturnModelType, mongoose } from '@typegoose/typegoose';
import { CounterAllModal } from './CounterAll';
import { COUNTER, SERVER_STATUS } from '../consts';
import { CreateServerParam } from '../domain/backEndField/params';
import { RegionType } from './Region';
import { nowSeconds } from '../pubUtils/timeUtil';
import { gameData } from '../pubUtils/data';

export class Maintenance {

  @prop({ required: true })
  batchCode: string;       // 批次，如果是从大区列表维护就是一批的，小区列表上就是一服一个
  
  @prop({ required: true })
  isOpen: boolean;       // 维护是否使用

  @prop({ required: true })
  startTime: number;       // 维护开始时间

  @prop({ required: true })
  endTime: number;       // 维护结束时间

  @prop({ required: true })
  hasNotify: boolean;       // 是否有维护通知

}

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

  @prop({ required: true, default: 1 })
  regionId: number;            // 大区id

  @prop({ required: true })
  env: string;                // 环境变量

  @prop({ required: true })
  isReview: boolean;                // 是否是审核服

  @prop({ required: true })
  prefix: string;                // 前缀

  @prop({ required: true })
  id: number;                // 小区id 自增，全大区共用自增counter，玩家role表中存的就是这个serverId

  @prop({ required: true })
  serverId: number;              // 相同serverType下的id，不同serverType下id一定不同，但是serverId可能相同

  @prop({ required: true })
  name: string;              // 小区区名

  @prop({ required: true })
  groupId: number;           // 战区id

  @prop({ required: true })
  groupName: string;          // 战区区名

  @prop({ required: true, default: 1, enum: SERVER_STATUS })
  serverStatus: number;       // 服务器状态

  // @prop({ required: true, type: Number })
  // activityGroupId: number[];  // 活动组

  public get status() {
    let now = nowSeconds();
    if (now < this.openTime) {
      return SERVER_STATUS.WILL_OPEN;
    } else if (this.maintenance && this.maintenance.isOpen && this.maintenance.startTime < now && this.maintenance.endTime > now) {
      return SERVER_STATUS.MAINTENANCE;
    } else {
      return this.serverStatus; // 未开服
    }
  }

  @prop({ required: true })
  openTime: number;

  @prop({ required: true })
  stopRegisterTime: number;

  @prop({ required: true, default: true })
  canRegister: boolean;

  @prop({ required: true, default: 0 })
  playerCnt: number;          // 当前玩家人数

  @prop({ required: true, type: Maintenance, _id: false })
  maintenance: Maintenance

  public static async getAllServerList() {
    let id = await CounterAllModal.getCounter(COUNTER.SERVER);
    let result: ServerlistType[] = [];
    let n = Math.ceil(id/1000); 
    for(let i = 0; i < n; i++) {
      let servers: ServerlistType[] = await ServerlistModel.find().limit(1000).skip(i * 1000).lean({ getters: true, virtuals: true });
      result.push(...servers);
    }
    return result;
  }

  public static async findByServerId(serverId: number) {
    let server: ServerlistType = await ServerlistModel.findOne({ id: serverId }).lean({ getters: true, virtuals: true });
    return server;
  }

  public static async findByServerIds(serverIds: number[], select?: string) {
    let servers: ServerlistType[] = await ServerlistModel.find({ id: { $in: serverIds } }).select(select).lean({ getters: true, virtuals: true });
    return servers;
  }

  public static async updateByServerId(serverId: number, update: ServerlistUpdate) {
    let server: ServerlistType = await ServerlistModel.findOneAndUpdate({ id: serverId }, { $set: update }, {new: true}).lean({ getters: true, virtuals: true });
    return server;
  }

  public static async updateByServerIds(serverIds: number[], update: ServerlistUpdate) {
    const result = await ServerlistModel.updateMany({ id: { $in: serverIds } }, { $set: update });
    return result;
  }

  public static async newServer(params: CreateServerParam, region: RegionType, serverId: number, uid = 1 ) {
    let dicServerName = gameData.serverNames.get(serverId);
    let { prefix, id: regionId, env } = region;
    // 分大区
    let id = await CounterAllModal.getNewCounter(COUNTER.SERVER);
    let { openTime, stopRegisterTime: hour, activityGroupId } = params;
    let { sname: name, groupId, groupName } = dicServerName;
    let stopRegisterTime = openTime + hour * 60 * 60;

    const doc = new ServerlistModel();
    const update = Object.assign(doc.toJSON(), { 
      id, regionId, env, prefix, 
      serverId, name, groupId, groupName, activityGroupId, 
      openTime, stopRegisterTime,
      createdBy: uid, updatedBy: uid 
    });
    // 旧服修改状态
    await ServerlistModel.updateMany({ env, serverStatus: SERVER_STATUS.NEW }, { $set: { serverStatus: SERVER_STATUS.HOT } })
    let server: ServerlistType = await ServerlistModel.findOneAndUpdate({ id }, { $setOnInsert: update }, { new: true, upsert: true }).lean({ getters: true, virtuals: true });
    return server;
  }

  public static async findByEnv(env?: string, isReview = false) {
    if(isReview) {
      let server: ServerlistType[] = await ServerlistModel.find({ env, serverStatus: { $gt: 0 }, isReview }).sort({ id: -1 }).lean({ getters: true, virtuals: true });
      return server;
    } else {
      let server: ServerlistType[] = await ServerlistModel.find({ env, serverStatus: { $gt: 0 } }).sort({ id: -1 }).lean({ getters: true, virtuals: true });
      return server;
    }
  }

  //根据多个活动id查询活动数据
  public static async findServerByIds(ids: number[]) {
    let result: ServerlistType[] = await ServerlistModel.find({ id: { $in: ids } }).lean();
    return result;
  }

  // public static async updateActivityGroup(id: string, pushArr: number[], pullArr: number[]) {
  //   // console.log(id, pushArr, pullArr)
  //   let update = {};
  //   if(pushArr.length > 0) update['$push'] = { activityGroupId: { $each: pushArr } };
  //   if(pullArr.length > 0) update['$pull'] = { activityGroupId: { $in: pullArr } };
  //   let result: ServerlistType[] = await ServerlistModel.findOneAndUpdate({ _id: id }, update).lean();
  //   return result;
  // }

  // public static async pullByGroupId(groupId: number) {
  //   let result = await ServerlistModel.updateMany({ activityGroupId: { $elemMatch: { $eq: groupId } }}, { $pull: { activityGroupId: groupId } }, { new: true }).lean(true);
  //   return result;
  // }

  public static async incRoleCnt(serverId: number) {
    let server: ServerlistType = await ServerlistModel.findOneAndUpdate({ id: serverId }, { $inc: { playerCnt: 1 } });
    return server;
  }

}

export let ServerlistModel: ReturnModelType<typeof Serverlist, {}>;
export function loadServerlistModel(connect: mongoose.Connection) {
    ServerlistModel = getModelForClass(Serverlist, {
        existingConnection: connect
    });
}

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