import {
  asyncDelay,
  asyncPlayDragonBoneAnimation,
  asyncTweenTo,
  onHomeworkFinish,
  RandomInt,
} from "../script/util";
import { MyCocosSceneComponent } from "../script/MyCocosSceneComponent";
import { NetworkHelper } from "../script/NetworkHelper";
import { GameServer } from "../script/Server";

const { ccclass, property } = cc._decorator;
const RED = "red";
const BLUE = "blue";

// 所有消息列表
const MSG_TEST = "msg_test";
const MSG_SWITCHSIDE = "msg_switch_side";
const MSG_ROLLING = "msg_rolling";
const MSG_PROFIX_END = "__END__"

@ccclass
export default class SceneComponent extends MyCocosSceneComponent {
  @property(cc.Prefab)
  loadingLayerPrefab = null; // 等待其他小伙伴加入页面

  @property(cc.Prefab)
  playerOffLineLayerPrefab = null; // 其他人掉线页面

  @property(cc.Prefab)
  endLayerPrefab = null; // 结束页面

  server: GameServer;
  networkHelper: NetworkHelper;
  playerId; // 当前玩家ID
  isRoomOwner; // 是否为房主
  recordWaitCount; // 录音等待倒计时
  asyncToken: ""; // 同步令牌 消息发送发会把令牌一同传给其他客户端，当客户端执行异步动作完毕以后 会把同步令牌

  addPreloadImage() {
    // TODO 根据自己的配置预加载图片资源
    // this._imageResList.push({ url: this.data.pic_url });
    // this._imageResList.push({ url: this.data.pic_url_2 });
  }

  addPreloadAudio() {
    // TODO 根据自己的配置预加载音频资源
    // this._audioResList.push({ url: this.data.audio_url });
  }

  addPreloadAnima() {}

  onLoadEnd() {
    // TODO 加载完成后的逻辑写在这里, 下面的代码仅供参考
    this.initData();
    this.initView();
    this.initListener();
    this.initEvents();
  }

  // 初始化数据
  async initData() {
    this.networkHelper = new NetworkHelper();
    this.initNetworkListener();
    do {
      this.playerId = await this.networkHelper.init("l2_boardgame2_tree", 2);
      if (this.playerId === null) {
        console.log("onDestroy");
        this.networkHelper.onDestroy();
      }
      console.log("this.playerId = " + this.playerId);
    } while (this.playerId === null);

    const room = this.networkHelper.room;
    if (this.playerId == room.roomInfo.owner) {
      console.log("房主");
      this.isRoomOwner = true;
      this.server = new GameServer(2, this.networkHelper);
      //   this.server.jumpList = this.getJumpList();
      await this.networkHelper.startFrameSync();
      this.server.addPlayer({
        uuid: this.playerId,
        isAI: false,
      });
      this.server.startMatch();
    }
    await this.initHeadImgAndName();
    this.recordWaitCount = 0;
  }

  // 获取用户头像
  async initHeadImgAndName() {
    const playerInfo: any = {
      playerHeadUrl:
        "http://staging-teach.cdn.ireadabc.com/0751c28419a0e8ffb1f0e84435b081ce.png",
      playerName: "test",
    };

    // 从中间层获取用户信息
    const middleLayer = cc.find("middleLayer");
    if (middleLayer) {
      const middleLayerComponent = middleLayer.getComponent("middleLayer");
      if (middleLayerComponent.getUserInfo && middleLayerComponent.getHeadUrl) {
        const kidInfo = await middleLayerComponent.getUserInfo();
        const playerHeadUrl = middleLayerComponent.getHeadUrl(
          kidInfo.avatar_url || kidInfo.id
        );
        playerInfo.playerHeadUrl = playerHeadUrl;
        playerInfo.playerName = kidInfo.nick_name || "拼读达人";
      }
    }
    this.networkHelper.sendFrame({
      type: "playerInfo",
      playerId: this.playerId,
      playerName: playerInfo.playerName,
      playerHeadUrl: playerInfo.playerHeadUrl,
    });
  }

  // 把卡片数据附加到节点上
  addComponents() {
    // cc.find('Canvas/bg/chessBoard/boardItems').children.forEach(node => {
    //   let itemData = node.getComponent("BoardGame2_ItemData");
    //   if (!itemData) {
    //     itemData = node.addComponent('BoardGame2_ItemData');
    //     let name = node.name;
    //     console.log(name);
    //     if (name == 'start' || name == 'end') {
    //     } else {
    //       let arr = name.split('_');
    //       itemData.letter = arr[1];
    //       itemData.idx = Number(arr[0]);
    //       itemData.word = arr[1];
    //       itemData.jump = 0;
    //     }
    //   }
    // });
  }

  initView() {
    // 初始化界面
    this.initLoadingLayer();
    this.initOfflineLayer();
    this.initTurntable();
    this.initGemstone();
  }

  // update (dt) {},

  initListener() {
    // 初始化时间监听
  }

  playLocalAudio(audioName) {
    const audio = cc
      .find(`Canvas/res/audio/${audioName}`)
      .getComponent(cc.AudioSource);
    return new Promise((resolve, reject) => {
      const id = cc.audioEngine.playEffect(audio.clip, false);
      cc.audioEngine.setFinishCallback(id, () => {
        resolve(id);
      });
    });
  }

  // 等待游戏开始加入
  loadingLayer;
  initLoadingLayer() {
    cc.log("[Function]initLoadingLayer");
    const loadingLayerBase = cc.find("Canvas/loadingLayerBase");
    const loadingLayerNode = cc.instantiate(this.loadingLayerPrefab);
    loadingLayerBase.addChild(loadingLayerNode);

    this.loadingLayer = loadingLayerNode.getComponent("LoadingLayer");
    this.loadingLayer.setMaxPlayerNumber(2);
    this.loadingLayer.onLoadFinished(() => {
      this.initSide();
    });
  }

  // 初始化掉线提示组件
  offlineLayer;
  initOfflineLayer() {
    cc.log("[Function]initOfflineLayer");
    const offlineLayerBase = cc.find("Canvas/offlineLayerBase");
    const offlineLayerNode = cc.instantiate(this.playerOffLineLayerPrefab);
    offlineLayerBase.addChild(offlineLayerNode);

    this.offlineLayer = offlineLayerNode.getComponent("PlayerOffLineLayer");
  }

  // 异步游戏核心事件控制
  allPlayerList;
  initNetworkListener() {
    this.networkHelper.on("playerJoin", (event) => {
      if (this.server) {
        this.server.onPlayerJoin({ data: { joinPlayerId: event.playerId } });
      }
      console.log("playerJoin");
    });
    this.networkHelper.on("playerLeave", (event) => {
      cc.log("playerLeave" + JSON.stringify(event));
      this.offlineLayer.show();
      this.networkHelper.leaveRoom();
    });
    this.networkHelper.on("playerOffLine", (event) => {
      cc.log("playerOffLine" + JSON.stringify(event));
      this.offlineLayer.show();
      this.networkHelper.leaveRoom();
    });
    this.networkHelper.on("gameStart", (event) => {
      console.log("游戏开始")
    });
    this.networkHelper.on("frameEvent", (event) => {
      cc.log("Frame event");
      event.data.frame.items.forEach(async (item) => {
        if (this.server) {
          this.server.onFrameEvent(item.data);
        }

        if (item.data.type == "SERVER_allPlayerInfo") {
          cc.log(
            "SERVER_allPlayerInfo: " + JSON.stringify(item.data.playerData)
          );
          item.data.playerData.forEach((player) => {
            // 如果所有玩家列表为空 则初始化
            if (!this.allPlayerList) {
              this.allPlayerList = [];
            }

            // 若果当前用户第一次进入房间 则存储用户信息
            if ( !this.allPlayerList.find(listPlayer=> listPlayer.uuid == player.uuid)) {
              this.allPlayerList.push({
                uuid: player.uuid,
                name: player.name,
                color: player.color,
                headUrl: player.headUrl,
              });
            }

            // this.loadPlayerHeadImage();

            // 把当前用户信息显示在页面上
            this.loadingLayer.addPlayer(
              player.name,
              player.uuid == this.playerId,
              player.headUrl,
              player.uuid
            );
          });
        } else {
          // 遍历自定义消息
          for(let key in this.eventsMap) {
            // 找到对应的消息类型 并且发消息的人不是自己
            if(item.data.type == key && item.data.sender != this.playerId) {
              this.runServerEvent(key, item.data.param)
            }
          }
        }
      });
    });
  }

  // 用户自定义事件
  eventsMap = {};
  registerEvent(name, callback, endCallback?) {
    if(this.eventsMap[name] != undefined) {
      cc.log("该事件已经注册过，将会覆盖原有注册")
    }
    this.eventsMap[name] = {
      fn: callback,
      pending: false,
      isRequireEnd: endCallback?true:false,
    }

    if(endCallback) {
      this.eventsMap[name + MSG_PROFIX_END] = {
        fn: endCallback,
        pending: false,
        isRequireEnd: false,
      }
    }
  }

  // 注册全局游戏事件，需要玩家之间同步执行的方法
  // 无论是自己方 还是对方，只需要调用即可，方法内处理消息发送和执行
  runEvent(eventName, param) {
    if(this.eventsMap[eventName] == undefined) {
      cc.log("该事件没有注册过");
      return;
    }
    this.eventsMap[eventName].fn(param, ()=>{
      this.eventsMap[eventName].pending = false;
      
    });
    this.eventsMap[eventName].pending = true;
    this.networkHelper.sendFrame({
      type: eventName,
      sender: this.playerId,
      param: param,
    });
  }

  // 执行服务器发来的消息广播 和runEvent不同的地方只是 这个方法不会再次转发消息
  runServerEvent(eventName, param) {
    if(this.eventsMap[eventName] == undefined) {
      cc.log("该事件没有注册过");
      return;
    }
    this.eventsMap[eventName].fn(param, ()=>{
      this.eventsMap[eventName].pending = false;
      if(this.eventsMap[eventName].isRequireEnd) {
        this.networkHelper.sendFrame({
          type: eventName + MSG_PROFIX_END,
          sender: this.playerId
        });
      }
    });
    this.eventsMap[eventName].pending = true;
  }

  // 初始化转盘
  turntable: null;
  initTurntable() {
    this.turntable = cc.find("Canvas/Turntable").getComponent("Turntable");
    cc.find("Canvas/Turntable").on("Rolling_Start", ()=>{
      this.turntable.stopBlink();
      this.runEvent(MSG_ROLLING, {num:1});
    })
    // this.turntable.initTurntable(true);
    // this.turntable.blink()
    // setTimeout(() => {
    //   this.turntable.stopBlink()
    // }, 5000);
    // this.turntable.disable()
    // setTimeout(() => {
    //   this.turntable.enable();
    // }, 6000);
    // setTimeout(() => {
    //   cc.log("ABCDE")
    //   this.turntable.rollNum(0);
    // }, 7000);
  }

  // 初始化宝石
  gemstones = [[], [], []]
  initGemstone() {
    const gemstoneGroup = cc.find("Canvas/center_map/gemstone");
    gemstoneGroup.children.forEach(gem=>{
      let itemData = gem.addComponent('OPW_BoardGame_L5R4_word_dataitem');
      itemData.word = gem.name.split("_")[0];
      itemData.score = Number(gem.name.split("_")[1]);
      itemData.word = gem.name.split("_")[0];
      itemData.beforeNode = cc.find("before", gem);
      itemData.afterNode = cc.find("after", gem);
      if(itemData.score == 1) {
        this.gemstones[0].push(gem);
      } else if(itemData.score == 2) {
        this.gemstones[1].push(gem);
      } else if(itemData.score == 3) {
        this.gemstones[2].push(gem);
      }

      itemData.afterNode.active = false;
    })
  }

  // 选边初始化
  side = RED; // 标记自己阵营颜色
  currentGameSide = RED; // 当前游戏轮次的颜色
  initSide() {
    if(this.isRoomOwner) {
      this.side = RED;
      // 初始化红色阵营 先手 开始闪烁
      this.turntable.blink();
    } else {
      this.side = BLUE;
      // 蓝色阵营 后手 禁止点击
      this.turntable.disable()
    }
  }

  // 注册自定义消息事件
  initEvents() {
    this.registerEvent(MSG_TEST, (param, next)=>{
      console.log("测试消息")
      next();
    })

    this.registerEvent(MSG_SWITCHSIDE, (param, next)=>{
      this.currentGameSide = param.side;
      this.handleSwitchSide();
      next();
    })

    this.registerEvent(MSG_ROLLING, (param, next)=>{
      this.turntable.stopBlink();
      this.turntable.rollNum(param.num).then(()=>{
        // 异步操作执行完成后调用
        next();
      });
    }, ()=>{
      console.log(`执行${MSG_ROLLING}结束`)
      if(this.side == this.currentGameSide) {
        if(this.currentGameSide == RED) {
          this.currentGameSide = BLUE;
        } else {
          this.currentGameSide = RED;
        }
        let side = this.currentGameSide;
        this.runEvent(MSG_SWITCHSIDE, {side});
      }
    })
  }





  // 处理换边
  handleSwitchSide() {
    if(this.side == this.currentGameSide) {
      this.turntable.enable();
      this.turntable.blink();
    } else {
      this.turntable.disable();
      this.turntable.stopBlink();
    }
  }
}
