import { asyncDelay, RandomInt } from "../script/util_L5R3_GuessingGame";
import { AI } from "./AI_L5R3_GuessingGame";
import MsgData from "./msgDate_L5R3_GuessingGame";
import { MsgType, PlayerData, resultType } from "./msgType_L5R3_GuessingGame";
import { NetworkHelper } from "./NetworkHelper_L5R3_GuessingGame";

export class GameServer {
  playerList = [];
  playerMaxNumber = 0;
  networkHelper: NetworkHelper;
  nameList = [
    "Chris",
    "Benny",
    "Leslie",
    "Devin",
    "Sam",
    "Kerry",
    "Joey",
    "Hailey",
    "Fred",
    "Arrow",
    "Tony",
    "Michael",
  ];
  headUrls = [
    "http://staging-teach.cdn.ireadabc.com/0751c28419a0e8ffb1f0e84435b081ce.png",
    "http://staging-teach.cdn.ireadabc.com/f596e586a31ac2813b1702557941c022.png",
    "http://staging-teach.cdn.ireadabc.com/f0f396c52c42239913fd94523db979fa.png",
    "http://staging-teach.cdn.ireadabc.com/9f2d2ef622fa33d4e2abcbdc4b40ab6a.png",
    "http://staging-teach.cdn.ireadabc.com/f40ce4a8630039c4cf48a63fc1399c52.png",
  ];

  _checkList = [
    [0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11], [12, 13, 14, 15],
    [0, 4, 8, 12], [1, 5, 9, 13], [2, 6, 10, 14], [3, 7, 11, 15],
    [0, 5, 10, 15], [3, 6, 9, 12]
  ]

  private _totalStep: any;
  randomList = [];
  wordList = [];
  _answerList = []
  private _useAI: boolean;
  private _timer: number;
  private _round1Time: number = 10;
  private _round2Time: number = 90;
  private _gameData: MsgData;
  private _userPrepareCount: number;
  private _lastTime: number;
  private _nowAnswerIndex: number;
  private _round_1_cardList: any[] = [];
  private _nowStepAnswerIndex: number;
  private _round2OutIndex;
  private _gameOver: boolean = false;

  constructor(playerMaxNumber, networkHelper) {
    this.playerMaxNumber = playerMaxNumber;
    this.networkHelper = networkHelper;

    this._timeoutIds = [];
    this._intervalIds = [];

    this.headUrls = this.headUrls.sort((a, b) => RandomInt(2) - 1);
    this.nameList = this.nameList.sort((a, b) => RandomInt(2) - 1);

    this._userPrepareCount = 0;
    this._gameData = new MsgData();
    this._gameData.Time = this._round1Time;
    this._gameData.Round = 1;
    this._gameOver = false;

    this.networkHelper.startFrameSync();
  }

  async addPlayer(player: PlayerData) {
    console.log("addPlayer");

    this._gameData.addPlayer({
      playerId: player.uuid,
      name: this.nameList.splice(0, 1)[0],
      uuid: player.uuid,
      side:
        player.uuid == this.networkHelper.room.roomInfo.owner ? "Red" : "Blue",
      isAI: player.isAI,
      headUrl: this.headUrls.splice(0, 1)[0],
    })

    this._senMsg({
      type: MsgType.USER_JOIN_EV,
      data: this._gameData.Msg
    });

    if (player.isAI) {
      this._useAI = true;
      await asyncDelay(1);
      if (this._gameData.PlayerList.length == this.playerMaxNumber) {
        this.networkHelper.closeRoom();
        await asyncDelay(0.5);
        this.startGame();
        this.startAI();
      }
    }
  }


  startGame() {

    console.log("========start game===========");
    this._senMsg({
      type: MsgType.ROOM_INIT_DONE,
      data: this._gameData.Msg
    });

    //this._senMsg({
    //   type: "SERVER_updateStatus",
    //   status: this.gameStatus,
    // });
  }

  onPlayerJoin(event) {
    // this.addPlayer({
    //   uuid: event.data.joinPlayerId,
    //   isAI: false,
    // });
  }

  _aiPlayerList = [];
  startMatch() {
    for (let i = 0; i < this.playerMaxNumber; i++) {
      this._timeoutIds.push(
        setTimeout(() => {
          let playerList = this._gameData.PlayerList;
          const count = this.playerMaxNumber - playerList.length;
          if (count > 0) {
            const playerInfo = {
              uuid: "ai_" + i,
              isAI: true,
              times: 3
            };
            this._aiPlayerList.push(new AI(this.networkHelper, playerInfo, this.wordList));
            this.addPlayer(playerInfo);
          }
        }, RandomInt(10000, 15000))
      );
    }
  }


  _senMsg(data: { type: MsgType, data: any }) {

    this.networkHelper.sendFrame({
      type: data.type,
      data: data.data
    });

    this._aiPlayerList.forEach((ai: AI) => {
      ai.onFrameEvent(data);
    });
  }

  _shecduleTimer() {

    let now = Date.now()
    this._gameData.Time -= (now - this._lastTime) / 1000;

    if (this._gameData.Time <= 0) {
      if (this._gameData.Round == 1) {

        clearInterval(this._timer)
        this._senMsg({
          type: MsgType.ROUND_END_EV,
          data: this._gameData.Msg
        });

        this._gameData.Round = 2;

      } else {

        clearInterval(this._timer)

        this._gameData.Time = 0;
        this._senMsg({
          type: MsgType.ROOM_ST,
          data: this._gameData.Msg
        });

        this._senMsg({
          type: MsgType.ROUND_END_EV,
          data: { round: 2, uuid: "none", isWin: false, list: this._gameData.getAnswerList() }
        })
      }


    } else {

      this._lastTime = now;
      this._senMsg({
        type: MsgType.ROOM_ST,
        data: this._gameData.Msg
      }

      );
    }
  }



  async onFrameEvent(data) {
    // if (this.gameStatus['gameOver']) {
    //   return;
    // }
    let type: MsgType = data.type;
    let msgDate = data.data;

    if (type == MsgType.USER_JOIN_ERQ) {
      this.addPlayer(<PlayerData>msgDate)
    }
    else if (type == MsgType.USER_PREPARE_REQ) {

      if (this._gameData.Round == 1) {
        this._userPrepareCount++;
        if (this._userPrepareCount == this.playerMaxNumber - (this._useAI ? 1 : 0)) {
          this._senMsg({
            type: MsgType.ROUND_START_EV,
            data: { round: this._gameData.Round }
          });
          this._userPrepareCount = 0;
          this._lastTime = Date.now();
          this._shecduleTimer();
          this._timer = setInterval(this._shecduleTimer.bind(this), 1000)
        }
      } else {
        this._userPrepareCount++;
        if (this._userPrepareCount == this.playerMaxNumber - (this._useAI ? 1 : 0)) {
          this._gameData.Time = this._round2Time;
          this._userPrepareCount = 0;
          this._lastTime = Date.now();
          this._shecduleTimer();
          this._timer = setInterval(this._shecduleTimer.bind(this), 1000);

          this._senMsg({
            type: MsgType.ROUND_START_EV,
            data: { round: this._gameData.Round, list: this._gameData.getAnswerList() }
          });

        }
      }

    }
    else if (type == MsgType.USER_REQ_ADD_WOED) {

      let userId = msgDate.uuid;
      let word = msgDate.word;
      cc.log("uuid=" + userId + " input words =" + word);
      this._gameData.addAnswerList({ uuid: userId, word: word, time: 3 });

    }
    else if (type == MsgType.USER_REQ_WOED) {

      let userId = msgDate.uuid;
      let word = msgDate.word;
      this._gameData.getAnswerList().forEach((val) => {
        if (val.uuid != userId) {
          if (word == val.word) {
            clearInterval(this._timer)
            console.log("被猜中了");
            this._senMsg({
              type: MsgType.ROUND_END_EV,
              data: { round: 2, uuid: userId, isWin: true, list: this._gameData.getAnswerList() }
            })

          } else {
            console.log("没猜中了 次数-1");
            let time = val.time - 1;
            val.time = time;
            if (time > 0) {
              this._senMsg({
                type: MsgType.USER_REQ_EV,
                data: { round: 2, uuid: userId, time: time }
              })
            } else {
              clearInterval(this._timer)
              this._senMsg({
                type: MsgType.ROUND_END_EV,
                data: { round: 2, uuid: userId, isWin: false, list: this._gameData.getAnswerList() }
              })
            }

          }
        }
      })

    }

  }

  set TotalStep(step) {
    this._totalStep = step;
  }

  startAI() {
    this.playerList
      .filter((player) => player.isAI == true)
      .forEach((player) => { });
  }

  _timeoutIds = null;
  _intervalIds = null;
  // 生命周期
  onDestroy() {
    this._timeoutIds.forEach((id) => {
      clearTimeout(id);
    });
    this._intervalIds.forEach((id) => {
      clearInterval(id);
    });
  }
}
