import BoardCardItem from "../scene/boardCardItem_PK_Game";
import { asyncDelay, RandomInt } from "../script/util_PK_Game";
import { AI } from "./AI_PK_Game";
import { NetworkHelper } from "./NetworkHelper_PK_Game";

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

  lvData = {
    0: { min: 0, max: 999, questionNun: 5, tiket: 5, award: 10 },
    1: { min: 1000, max: 5000 - 1, questionNun: 5, tiket: 10, award: 20 },
    2: { min: 5000, max: 20000 - 1, questionNun: 10, tiket: 20, award: 40 },
    3: { min: 20000, max: 50000 - 1, questionNun: 10, tiket: 40, award: 80 },
    4: { min: 50000, max: 2000000 - 1, questionNun: 10, tiket: 60, award: 120 },
    5: { min: 2000000, max: 5000000 - 1, questionNun: 20, tiket: 120, award: 240 },
  }



  private _totalStep: any;
  randomList = [];
  private _useAI: boolean;
  answerIndex: number;
  prepareNum: number;
  questionData: any;
  answerData: any[];
  matchLv: any;
  answerCount: number;
  settleTimer: number;
  startTime: number;

  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],
      score: player.score,
      lv: player.lv,
    });

    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 开始
    index: 0,
    blueRight: 0,
    redRight: 0,
    total: 0,
    addRedScore: 0,
    addBlueScore: 0,
  };
  startGame() {

    this.answerIndex = 0;
    this.prepareNum = 0;
    this.answerCount = 0
    this.gameStatus.index = 0;
    this.gameStatus.state = 0;
    this.gameStatus.blueRight = 0;
    this.gameStatus.redRight = 0;
    this.gameStatus.total = this.lvData[this.matchLv].questionNun;
    this.networkHelper.sendFrame({
      type: "SERVER_updateStatus",
      status: this.gameStatus,
    });
  }

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

  _aiPlayerList = [];
  startMatch(matchLv) {
    this.matchLv = matchLv;
    for (let i = 0; i < this.playerMaxNumber; i++) {
      this._timeoutIds.push(
        setTimeout(() => {
          const count = this.playerMaxNumber - this.playerList.length;
          if (count > 0) {
            const playerInfo = this.randomAiPlayer(i, matchLv);
            this._aiPlayerList.push(new AI(this.networkHelper, playerInfo));
            this.addPlayer(playerInfo);
          }
        }, RandomInt(5000, 1000))
      );
    }
  }

  randomAiPlayer(index, matchLv) {

    let matchInfo = this.lvData[matchLv];
    let randomScore = matchInfo.min + Math.floor(Math.random() * matchInfo.max - matchInfo.min);

    let data = {
      uuid: "ai_" + index,
      isAI: true,
      color: "Red",
      lv: matchLv,
      score: randomScore,
    }
    return data;
  }

  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 == "gamePrepare") {
      if (!data.uuid) {
        console.warn("data no uuid");
        return;
      }

      this.prepareNum++;
      if (this.prepareNum == 2) {

        this.prepareNum = 0
        this.gameStatus.index = 0;
        this.gameStatus.state = 1;
        this.gameStatus.addBlueScore = 0;
        this.gameStatus.addRedScore = 0;
        this.answerIndex = 0;
        this.answerCount = 0;
        this.answerData = [];
        let question = this.questionData[this.answerIndex];


        this.networkHelper.sendFrame({
          type: "SERVER_gameEv",
          status: this.gameStatus,
          question: question
        });
        // 开始计时11秒
        this.countToSettle(11);
      }

    }
    else if (data.type == "anserQues") {
      console.log("data = " + JSON.stringify(data));
      this.answerCount++;
      let quetion = this.questionData[this.answerIndex]
      this.answerData = this.answerData || [];
      this.answerData.push(data);

      if (quetion.rightIndex == data.index) {
        if (sender.color == "Red") {
          this.gameStatus.redRight += 1;
          this.gameStatus.addRedScore = 10 - Math.floor((Date.now() - this.startTime) / 1000);
          this.gameStatus.addRedScore = Math.max(0, this.gameStatus.addRedScore)
        } else {
          this.gameStatus.blueRight += 1;
          this.gameStatus.addBlueScore = 10 - Math.floor((Date.now() - this.startTime) / 1000);
          this.gameStatus.addBlueScore = Math.max(0, this.gameStatus.addBlueScore)
        }
      }

      if (this.answerCount == 2) {

        clearTimeout(this.settleTimer)
        this.networkHelper.sendFrame({
          type: "SERVER_gameSettle",
          status: this.gameStatus,
          ans: this.answerData
        });

        if (this.answerIndex == this.gameStatus.total - 1) {

          await asyncDelay(1);

          this.networkHelper.sendFrame({
            type: "SERVER_gameSettleEnd",
            status: this.gameStatus,
            ans: this.answerData
          });

        } else {

          await asyncDelay(1);
          this.prepareNum = 0
          this.answerIndex++;
          this.gameStatus.state = 1;
          this.gameStatus.addBlueScore = 0;
          this.gameStatus.addRedScore = 0;
          this.gameStatus.index = this.answerIndex;
          this.answerCount = 0;
          this.answerData = [];
          let question = this.questionData[this.answerIndex];
          this.networkHelper.sendFrame({
            type: "SERVER_gameEv",
            status: this.gameStatus,
            question: question
          });
          // 开始计时11秒
          this.countToSettle(11);

        }

      }

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

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


  countToSettle(time) {

    this.startTime = Date.now();
    clearTimeout(this.settleTimer)
    this.settleTimer = setTimeout(async () => {

      if (this.answerIndex == this.gameStatus.total - 1) {


        this.networkHelper.sendFrame({
          type: "SERVER_gameSettle",
          status: this.gameStatus,
          ans: this.answerData
        });

        await asyncDelay(1);

        this.networkHelper.sendFrame({
          type: "SERVER_gameSettleEnd",
          status: this.gameStatus,
          ans: this.answerData
        });

      } else {
        this.networkHelper.sendFrame({
          type: "SERVER_gameSettle",
          status: this.gameStatus,
          ans: this.answerData
        });

        await asyncDelay(1);
        this.prepareNum = 0
        this.answerIndex++;
        this.gameStatus.state = 1;
        this.gameStatus.addBlueScore = 0;
        this.gameStatus.addRedScore = 0;
        this.gameStatus.index = this.answerIndex;
        this.answerCount = 0;
        this.answerData = [];
        let question = this.questionData[this.answerIndex];
        this.networkHelper.sendFrame({
          type: "SERVER_gameEv",
          status: this.gameStatus,
          question: question
        });
        // 开始计时11秒
        this.countToSettle(11);
      }

    }, time * 1000)



  }


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

  initQuestion(data) {

    this.questionData = data;

  }
}
