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

export class ServerInfo {
  @prop({ required: true })
  id: number;                // 小区id

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

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

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

  @prop({ required: true })
  host: string;               // pinus连接地址

  @prop({ required: false })
  port: number;               // pinus端口

  @prop({ required: true })
  serverStatus: number;       // 服务器状态
  
  public get status() {
    let now = new Date();
    if( now > this.openTime) {
      return this.serverStatus;
    } else {
      return 3; // 未开服
    }
  }

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

  @prop({ required: true })
  createTime: Date;

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

  constructor(id: number, name: string, groupId: number, groupName: string, host: string, port: number, serverStatus: number, serverType: string, openTime?: Date) {
    this.id = id;
    this.name = name;
    this.groupId = groupId;
    this.groupName = groupName;
    this.host = host;
    this.port = port;
    this.serverStatus = serverStatus;
    this.serverType = serverType;
    this.openTime = openTime||new Date();
    this.createTime = new Date();
  }
}
                                                            
export class ServerEnv {
  @prop({ required: true })
  env: string;                // 服务器环境，一台物理机一个
  
  @prop({ required: true })
  envName: string;          // 环境名 正式服 开发服 测试服 等

  @prop({ required: true })
  serverType: string;          // serverlist表中的serverType

  @prop({ required: true })
  gmHost: string;              // 后台地址

  @prop({ required: true })
  webHost: string;              // web服地址

  @prop({ required: true })
  gameHost: string;             // pinus长链接地址
}

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

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

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

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

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

  @prop({ required: true, type: ServerInfo, default: [], _id: false })
  serverList: Array<ServerInfo>;

  @prop({ required: true, type: ServerEnv, default: [], _id: false })
  serverEnv: Array<ServerEnv>;

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

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

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

  public static async getAllServerList() {
    let game: GameType = await GameModel.findOne().lean();
    if(game) {
      return game.serverList;
    } else {
      return []
    }
  }

  public static async getServerList() {
    let game: GameType = await GameModel.findOne().lean({ getter: true, virtuals: true });
    if (!game) {
      const serverInfo = new ServerInfo(1, '常山少年', 1, '逍遥津', 'pinus_test.trgame.cn', 3014, 1, 'official');
      const iconUrl = `https://download.tgamebox.cn/avatar/${APP_ID}/1.png`;
      game = await GameModel.findOneAndUpdate(
        {},
        { id: 1, name: '赵云传', nameEn: 'zyz', des: '牛逼的战棋', iconUrl, version: '0.0.1', versionCode: 1, $push: { serverList: serverInfo } },
        { upsert: true, new: true },
      ).lean({ getter: true, virtuals: true });
    }
    let serverList: Array<ServerInfo> = game ? game.serverList : [];
    return serverList;
  }


  public static async getServerEnvList() {
    let game: GameType = await GameModel.findOne().lean({ getter: true, virtuals: true });
    let serverList: ServerEnv[] = game ? game.serverEnv : [];
    return serverList;
  }

  public static async newServer(serverId: number, serverType: string, name: string, host: string, port: number, status: number, lean = true) {
    let serverInfo = new ServerInfo(serverId, name, 1, '逍遥津', host, port, status, serverType);
    let game: GameType = await GameModel.findOneAndUpdate({}, {$push: {serverList: serverInfo}}, {new: true}).lean(lean);
    return game;
  }
}

export const GameModel = getModelForClass(Game);

export interface GameType extends Pick<DocumentType<Game>, keyof Game>{
  id: number;
};
