import BoardCardItem from "../scene/boardCardItem";
import { asyncDelay, RandomInt } from "../script/util";
import { AI } from "./AI";
import { NetworkHelper } from "./NetworkHelper";

export class GameServer {
  playerList = [];
  playerMaxNumber = 0;
  networkHelper: NetworkHelper = null;
  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",
  ];

  private _totalStep: any;
  randomList = [];
  private _useAI: boolean;
  private _timer: number;
  private _totalTime: number = 150;

  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.networkHelper.startFrameSync();
  }

  async addPlayer(player) {
    console.log("addPlayer");
    this.playerList.push({
      name: this.nameList.splice(0, 1)[0],
      uuid: player.uuid,
      color:
        player.uuid == this.networkHelper.room.roomInfo.owner ? "Red" : "Blue",
      isAI: player.isAI,
      headUrl: this.headUrls.splice(0, 1)[0],
    });

    if (player.isAI) {
      this._useAI = true;
      await asyncDelay(1);
      this.networkHelper.sendFrame({
        type: "SERVER_allPlayerInfo",
        playerData: this.playerList,
      });
      if (this.playerList.length == this.playerMaxNumber) {
        this.networkHelper.closeRoom();
        await asyncDelay(0.5);
        this.startGame();
        this.startAI();
      }
    }
  }

  gameStatus = {
    state: 0,// -1:未开始 0 准备阶段  1 roll 2 判定
    Red: 0,
    Blue: 0,
    RedTime: 0,
    BlueTime: 0,
    step: 0,
    current: "Red",
    time: "0"
  };
  startGame() {


    this.openTimerCounter();

    console.log("startGame set time ------");
    this.networkHelper.sendFrame({
      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(() => {
          const count = this.playerMaxNumber - this.playerList.length;
          if (count > 0) {
            const playerInfo = {
              uuid: "ai_" + i,
              isAI: true,
              color: "Blue",
            };
            this._aiPlayerList.push(new AI(this.networkHelper, playerInfo));
            this.addPlayer(playerInfo);
          }
        }, RandomInt(10000, 15000))
      );
    }
  }

  async onFrameEvent(data) {
    if (this.gameStatus['gameOver']) {
      return;
    }

    let sender = this.playerList.find(p => p.uuid == data.uuid);
    if (sender) {
      sender.name = data.playerName;
      sender.headUrl = data.playerHeadUrl;
    }


    if (data.type == "playerInfo") {

      this.networkHelper.sendFrame({
        type: "SERVER_allPlayerInfo",
        playerData: this.playerList,
        status: this.gameStatus,
      });
      if (this.playerList.length == this.playerMaxNumber) {
        this.networkHelper.closeRoom();
        await asyncDelay(0.5);
        this.startGame();
        this.startAI();
      }
    }
    else if (data.type == "roll") {
      if (!data.uuid) {
        console.warn("data no uuid");
        return;
      }

      if (sender.color == this.gameStatus.current) {

        let i = Math.floor(Math.random() * this.randomList.length)
        let index = this.randomList[i];

        console.log("random index ===" + index);
        this.gameStatus.step = index;
        this.gameStatus.state = 1;


        this.networkHelper.sendFrame({
          type: "SERVER_playerRoll",
          status: this.gameStatus,
        });


      } else {
        console.warn("data  uuid not match");
      }
    }
    else if (data.type == "right") {

      let posIndex = this.gameStatus.step
      this.gameStatus[this.gameStatus.current]++;
      let lastTime = +this.gameStatus.time;
      console.log("lasttime  = " + lastTime);
      let costTime = (Math.floor(Date.now() / 1000) - lastTime).toFixed(1)
      console.log("=right===cost time = " + costTime);
      if (this.gameStatus.current == "Red") {
        this.gameStatus.RedTime += +costTime
      } else {
        this.gameStatus.BlueTime += +costTime
      }

      let i = this.randomList.indexOf(posIndex);
      this.randomList[i] = this.randomList[this.randomList.length - 1];
      this.randomList.length--;

      if (this.gameStatus[this.gameStatus.current] < 10) {
        this.gameStatus.step = null;
        this.gameStatus.state = 2;
        this.networkHelper.sendFrame({
          type: "SERVER_playerRight",
          status: this.gameStatus,
        });
        this.changeSide();
      } else {
        this.gameStatus.state = 2;
        this.gameStatus.step = null;
        this.networkHelper.sendFrame({
          type: "SERVER_playerWin",
          status: this.gameStatus,
        });
        this.gameStatus['gameOver'] = true;
        clearTimeout(this._timer);
      }

    } else if (data.type == "wrong") {

      let lastTime = +this.gameStatus.time;
      let costTime = (Math.floor(Date.now() / 1000) - lastTime).toFixed(1)
      console.log("=wrong and ===cost time = " + costTime);
      if (this.gameStatus.current == "Red") {
        this.gameStatus.RedTime += +costTime
      } else {
        this.gameStatus.BlueTime += +costTime
      }

      this.gameStatus.step = null;
      this.gameStatus.state = 2;

      this.networkHelper.sendFrame({
        type: "SERVER_playerWrong",
        status: this.gameStatus,
      });
      this.changeSide();

    } else if (data.type == "stateUpdate") {

      if (this._useAI || sender.color == this.gameStatus.current) {

        if (this.gameStatus.state == 2) {
          this.gameStatus.state = 0;
        }

        if (this.gameStatus.state == 0) {
          this.openTimerCounter();
        }

        this.networkHelper.sendFrame({
          type: "SERVER_updateStatus",
          status: this.gameStatus,
        });

      }

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

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

  openTimerCounter() {

    let prepareTime = 4;
    // AI 无准备时间
    if (this._useAI && this.gameStatus.current == "Blue") {
      prepareTime = 0
    }
    this.gameStatus.time = "" + (Math.floor(Date.now() / 1000) + prepareTime);
    console.log(" openTimerCounter set time ------");
    clearTimeout(this._timer)
    let leftTime = this.gameStatus.BlueTime
    if (this.gameStatus.current == "Red") {
      leftTime = this.gameStatus.RedTime;
    }
    leftTime = this._totalTime - leftTime + prepareTime;

    console.log(`${this.gameStatus.current} left time  ${leftTime}, now time ${Date.now() / 1000}`)

    this._timer = setTimeout(this.timeOver.bind(this), leftTime * 1000);
  }
  timeOver() {

    let lastTime = +this.gameStatus.time;
    let costTime = (Math.floor(Date.now() / 1000) - lastTime).toFixed(1)
    console.log(`time over and time now ${Date.now() / 1000}`);
    console.log("=wrong and ===cost time = " + costTime);
    if (this.gameStatus.current == "Red") {
      this.gameStatus.RedTime += +costTime
    } else {
      this.gameStatus.BlueTime += +costTime
    }

    if (this.gameStatus.current == "Red") {
      this.gameStatus.current = "Blue"
    }
    this.gameStatus.state = 2;
    this.gameStatus.step = null;
    this.networkHelper.sendFrame({
      type: "SERVER_playerWin",
      status: this.gameStatus,
    });
    this.gameStatus['gameOver'] = true;

  }

  changeSide() {

    console.log("=====changeSide=======");

    console.log("=====old =======" + this.gameStatus.current);

    if (this.gameStatus.current == "Red") {
      this.gameStatus.current = "Blue";
    } else {
      this.gameStatus.current = "Red";
    }

    console.log("=====now =======" + this.gameStatus.current);
  }

  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);
    });
  }
}
