import { RandomInt } from "../script/util";

export class NetworkHelper {

  _eventListeners: any = {};
  ctor() { }

  on(eventName, func) {
    this._eventListeners[eventName] = func;
  }

  async init(roomType: string, maxPlayers: number) {
    this.initRoom();

    try {
      return await this.joinRoom(roomType, maxPlayers);
    } catch (e) {
      await this.initListener();
      this.initRoom();
      return await this.joinRoom(roomType, maxPlayers);
    }
  }


  async startGame() {
    await this.startFrameSync();
    await this.closeRoom();
  }

  async stopGame() {
    await this.stopFrameSync();
    await this.leaveRoom();
  }

  getRoomInfo() {
    return this.room.roomInfo;
  }

  initListener() {
    return new Promise((resolve, reject) => {
      const gameId = "obg-i4ql53h1"; //替换为控制台上的 游戏 ID
      const secretKey = "060d81c7abaf24c8ce2afc5a725c152062676d35"; //替换为控制台上的 游戏 Key
      const serverUrl = "i4ql53h1.wxlagame.com"; //替换为控制台上的 域名

      const gameInfo = {
        gameId: gameId,
        openId: "openid_test" + Math.random(), //自定义的用户唯一ID
        secretKey: secretKey
      };
      const config = {
        url: serverUrl,
        reconnectMaxTimes: 5,
        reconnectInterval: 1000,
        resendInterval: 1000,
        resendTimeout: 10000,
        cacertNativeUrl: ""
      };

      MGOBE.DebuggerLog.enable = false;
      // 如果是原生平台，则加载 Cert 证书，否则会提示 WSS 错误
      if (cc.sys.isNative) {

        let cacertFile;
        const cacertNode = cc.find('cacertNode');
        if (cacertNode) {
          cacertFile = cacertNode.getComponent('cacert').cacertFile;
        }

        if (!cacertFile) {
          this.log('没有cacertFile!!!');
        }
        config.cacertNativeUrl = cc.loader.md5Pipe && cc.ENGINE_VERSION < "2.4.0" ?
          cc.loader.md5Pipe.transformURL(cacertFile.nativeUrl) :
          cacertFile.nativeUrl;
      }

      MGOBE.Listener.init(gameInfo, config, event => {
        this.log(JSON.stringify(event));
        if (event.code !== 0) {
          this.log("初始化失败: " + event.code);
          reject();
          return;
        }
        this.log("初始化成功");
        resolve(null);
      });
    });
  }

  room: MGOBE.Room;
  initRoom() {
    this.room = new MGOBE.Room();
    MGOBE.Listener.add(this.room);
    this.room.onJoinRoom = this.onJoinRoom.bind(this);
    this.room.onLeaveRoom = this.onLeaveRoom.bind(this);
    this.room.onRecvFromClient = this.onRecvFromClient.bind(this);
    this.room.onRecvFrame = this.onRecvFrame.bind(this);
    this.room.onStartFrameSync = this.onStartFrameSync.bind(this);
    this.room.onStopFrameSync = this.onStopFrameSync.bind(this);
    this.room.onRecvFromGameSvr = this.onRecvFromGameSvr.bind(this);
    this.log('this.room = ' + JSON.stringify(this.room.roomInfo));
  }
  
  joinRoom(roomType: string, maxPlayers: number, customData: string = '') {
    return new Promise((resolve, reject) => {
      const playerName = "Player-" + Math.round( Math.random() * 1000);
      const playerInfo = {
        name: playerName,
        customPlayerStatus: 0,
        customProfile: customData,
      };

      const matchRoomPara = {
        playerInfo,
        maxPlayers: maxPlayers,
        roomType: roomType
      };

      this.room.matchRoom(matchRoomPara, event => {
        console.log(event);
        if (event.code === 0) {
          cc.log("匹配成功");
          const player = event.data.roomInfo.playerList.find(player => player.name == playerName);
          resolve(player.id);
        } else {
          cc.log("匹配失败");
          reject();
        }
      });
    });
  }

  leaveRoom() {
    return new Promise((resolve, reject) => {
      this.room.leaveRoom({}, event => {
        console.log(event);
        if (event.code === 0) {
          cc.log("退房成功", this.room.roomInfo.id);
          this.room.initRoom();
          resolve(null);
        }
      });
    });
  }

  closeRoom() {
    return new Promise((resolve, reject) => {
      this.room.changeRoom({ isForbidJoin: true }, (event) => {
        console.log('关门')
        console.log(event);
        resolve(null);
      });
    });
  }

  sendMessage(msg) {

    if (!msg) {
      return;
    }

    if (typeof (msg) == 'object') {
      msg = JSON.stringify(msg);
    }

    const sendToClientPara = {
      recvType: MGOBE.ENUM.RecvType.ROOM_ALL,
      recvPlayerList: [],
      msg: msg
    };
    this.room.sendToClient(sendToClientPara, event => console.log(event));
  }

  startFrameSync() {
    return new Promise((resolve, reject) => {
      this.room.startFrameSync({}, event => {
        console.log(event);
        if (event.code === 0) {
          cc.log("开始帧同步成功，请到控制台查看具体帧同步信息");
          resolve(null);
        } else {
          reject();
        }
      });
    });
  }

  stopFrameSync() {
    return new Promise((resolve, reject) => {
      this.room.stopFrameSync({}, event => {
        console.log(event);
        if (event.code === 0) {
          cc.log("停止帧同步成功");
          resolve(null);
        } else {
          reject(event.code);
        }
      });
    });
  }

  sendToServer() {
    const sendToGameServerPara = {
      data: {
        cmd: 1
      }
    };
    this.room.sendToGameSvr(sendToGameServerPara, event => console.log(event));
  }

  sendFrame(data: any) {
    this.room.sendFrame({ data }, err => {
      if (err.code != 0) {
        console.log("err", err)
      }
    });
  }

  

  sendEvent(key: String, data: Object) {
    this.sendFrame({key, data});
  }

  onJoinRoom(event) {
    if (this._eventListeners['playerJoin']) {
      this._eventListeners['playerJoin'](event);
    }

    this.room.roomInfo = event.data.roomInfo;
    console.log("新玩家加入", event.data.joinPlayerId);
  }
  onLeaveRoom(event) {
    if (this._eventListeners['playerLeave']) {
      this._eventListeners['playerLeave'](event);
    }
    this.room.roomInfo = event.data.roomInfo;
    console.log("玩家退出", event.data.leavePlayerId);
  }
  onRecvFromClient() { }

  onRecvFrame(event) {
    if (this._eventListeners['frameEvent']) {
      this._eventListeners['frameEvent'](event);
    }
  }
  onStartFrameSync(event) {
    if (this._eventListeners['gameStart']) {
      this._eventListeners['gameStart'](event);
    }
  }
  onStopFrameSync(event) { }
  onRecvFromGameSvr() { }

  log(str) {
    const node = cc.find('middleLayer');
    if (node) {
      node.getComponent('middleLayer').log(str);
    } else {
      cc.log(str);
    }
  }

  async onDestroy() {
    try {
      this.log('onDestroy1')
      MGOBE.Listener.clear();
      await this.stopGame();
      this.log('onDestroy2')
    } catch (e) {
      this.log(JSON.stringify(e));
    }
  }
}