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",
  ];

  jumpList = [
    // { from: 2, to: 11 },
    // { from: 3, to: 7 },
    // { from: 8, to: 18 },
    // { from: 9, to: 2 },
    // { from: 12, to: 15 },
    // { from: 13, to: 1 },
    // { from: 21, to: 5 },
    // { from: 24, to: 16 },
  ];

  private _totalStep: any;
  randomList = [];
  private _useAI: boolean;

  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 ? "Blue" : "Red",
      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,
    step: 0,
    current: "Blue",
    jump: 0,
  };
  startGame() {
    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: "Red",
            };
            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 (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 nowStep = this.gameStatus[this.gameStatus.current];
        let index = Math.floor(Math.random() * this.randomList.length)
        let step = this.randomList[index];
        step = Math.min(step, this._totalStep - nowStep);

        console.log("random step ===" + step);
        this.gameStatus.step = step;
        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 nowStep = this.gameStatus[this.gameStatus.current];
      const jump = this.jumpList.find(jump => parseInt(jump.from) == parseInt(data.idx));
      this.gameStatus[this.gameStatus.current] = jump ? parseInt(jump.to) : nowStep + this.gameStatus.step;
      if (this.gameStatus[this.gameStatus.current] < this._totalStep) {
        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.networkHelper.sendFrame({
          type: "SERVER_playerWin",
          status: this.gameStatus,
        });
        this.gameStatus['gameOver'] = true;
      }

    } else if (data.type == "wrong") {
      console.log("data = " + JSON.stringify(data));
      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;
        }
        this.networkHelper.sendFrame({
          type: "SERVER_updateStatus",
          status: this.gameStatus,
        });
        this.gameStatus.jump = null;
      }

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

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


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