
import { delayCall } from "../../../form/src/app/play/Unit";
import EndView from "../prefabs/endView/EndView";
import Keyboard from "../prefabs/keyboards/Keyboard";
import LoadingLayer from "../script/BoardGame_yyh_LoadingLayer";
import MsgData from "../script/msgDate";
import { MsgType, PlayerData, resultType } from "../script/msgType";
import { MyCocosSceneComponent } from "../script/MyCocosSceneComponent";
import { NetworkHelper } from "../script/NetworkHelper";
import { GameServer } from "../script/Server";
import { asyncTweenTo, asyncDelay, onHomeworkFinish, asyncPlayDragonBoneAnimation } from "../script/util";
import BoardCardItem from "./boardCardItem";

const DOLOG = false;

const { ccclass, property } = cc._decorator;

@ccclass
export default class SceneComponent extends MyCocosSceneComponent {
    @property(cc.Prefab)
    loadingLayerPrefab = null;
    @property(cc.Prefab)
    keyboardLayerPrefab = null
    @property(cc.Prefab)
    endViewPrefab = null
    @property(cc.Node)
    cat = null
    @property(cc.Node)
    bfly: cc.Node = null
    @property(cc.Node)
    cover = null
    @property(cc.Node)
    recordCat = null
    @property(cc.Node)
    btn_keyboard: cc.Node = null

    _cardList: Array<cc.Node> = [];

    private _isRolling: any;

    _gameWordList = [];
    excellent: any;
    _nowData: any;
    private _myData: any;
    private _loadingDone: boolean = false;
    private _loadingCall: Function
    private _playingAudio: boolean;
    private _canClick: any;
    private _recordBefore: boolean = false;
    private _coinNode: cc.Node;
    private _springNode: cc.Node;
    private _leftTime: number;
    private _redLb: cc.Label;
    private _blueLb: cc.Label;
    private _redDot: cc.Node;
    private _blueDot: cc.Node;
    private _lastIndex: any;
    private _checkLast: boolean;
    private _keyboard: Keyboard;
    private _blueHeadIcon: cc.Node;
    private _redHeadIcon: cc.Node;
    private _clockNode: any;
    private _clockTime: any;
    private _wordCardRoot: cc.Node;
    private _redLightList: any;
    private _blueLightList: any;
    private _round2WordList: Array<{ word: string, uuid: string }>;
    private _stepWord: string;
    private _birdsRoot: cc.Node;
    private _redUrl: any;
    private _blueUrl: any;
    lb_round2: cc.Node;
    private _localAudioRoot: cc.Node;
    private _round: number;


    onLoad() {
        super.onLoad();

        this._localAudioRoot = this.node.getChildByName("audio")
        this.addLoadingLayer();
    }
    addLoadingLayer() {
        const loadingLayerNode = cc.instantiate(this.loadingLayerPrefab);
        loadingLayerNode.parent = this.node;
        loadingLayerNode.zIndex = 100;
        this.loadingLayer = loadingLayerNode.getComponent(LoadingLayer);
    }
    addKeyboard() {

        const keyboard = cc.instantiate(this.keyboardLayerPrefab);
        keyboard.parent = this.node;
        keyboard.zIndex = 100;
        this._keyboard = keyboard.getComponent(Keyboard);
        this._keyboard.setNormalData(-cc.winSize.height / 2)
        this._keyboard.InputEndCall = this._inputWords.bind(this);
    }

    _inputWords(word) {
        this._sendMsg(MsgType.USER_REQ_ERQ, { word: word, uuid: this.playerId })
    }
    addPreloadImage() {
        // TODO 根据自己的配置预加载图片资源
        // this._imageResList.push({ url: this.data.pic_url });
    }

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

    addPreloadAnima() { }

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

    }
    loadingLayer: LoadingLayer;
    initLoadingLayer() {
        this.loadingLayer.setMaxPlayerNumber(2);
        this.loadingLayer.onLoadFinished(() => {
            this.playAudioByUrl(this.data.gameStartAudio);
            this._loadingDone = true;
            if (this._loadingCall) {
                this._loadingCall();
                this._loadingCall = null;
            }
        });

        this.playAudioByUrl(this.data.gameLoadingAudio);
    }
    initView() {
        this.initProtory();
        this.addKeyboard();
        this.initLoadingLayer();
    }

    initProtory() {
        const bgNode = cc.find('Canvas/bg');
        bgNode.scale = this._mapScaleMax;

        this.cover.width = cc.winSize.width;
        this.cover.height = cc.winSize.height;
        this.cover.getChildByName("bg").scale = this._mapScaleMax;

        let topRoot = cc.find("Canvas/topRoot");

        this._redLightList = topRoot.getChildByName("lights").getChildByName("red");
        this._blueLightList = topRoot.getChildByName("lights").getChildByName("blue");
        this._blueHeadIcon = topRoot.getChildByName("blue").getChildByName("headIcon");
        this._redHeadIcon = topRoot.getChildByName("red").getChildByName("headIcon");
        this._redLb = topRoot.getChildByName("lb_red").getComponent(cc.Label)
        this._blueLb = topRoot.getChildByName("lb_blue").getComponent(cc.Label)

        this._clockNode = this.cat.parent.getChildByName("clock");
        this._clockTime = this._clockNode.getChildByName("lb").getComponent(cc.Label);

        this._wordCardRoot = cc.find("Canvas/center/wordBgRoot");

        this._birdsRoot = cc.find("Canvas/center/birdsRoot");


        this.lb_round2 = cc.find("Canvas/lb_round2");

        this.cat.getComponent(dragonBones.ArmatureDisplay).addEventListener(dragonBones.EventObject.COMPLETE, () => {

            console.log("ani complite");
            this.catAni();
        });

        this.bfly.getComponent(dragonBones.ArmatureDisplay).addEventListener(dragonBones.EventObject.COMPLETE, () => {
            this.bfly.getComponent(dragonBones.ArmatureDisplay).playAnimation("normal", 0);
        });


        this.cat.getChildByName("btn").on("click", () => {
            if (this._playingAudio) {
                return;
            }
            this._playingAudio = true;
            this.catAni(true);
        })
    }

    loadPlayerHeadImage() {
        this._playerList.forEach((player) => {
            this.getSpriteFrimeByUrl(player.headUrl, (sf) => {
                if (player.side == "Red") {
                    this._redHeadIcon.getComponent(cc.Sprite).spriteFrame = sf;
                    this._redUrl = player.headUrl
                } else {
                    this._blueHeadIcon.getComponent(cc.Sprite).spriteFrame = sf;
                    this._blueUrl = player.headUrl
                }
            });
        });
    }

    catAni(playAudio?) {

        if (this._round == 1) {
            asyncPlayDragonBoneAnimation(this.cat, "begin", 0);
            this.playLocalAudio("catRoud1", -1, () => {
                asyncPlayDragonBoneAnimation(this.cat, "normal", 0);
                this._playingAudio = false;
            })

        } else if (this._round == 2) {
            asyncPlayDragonBoneAnimation(this.cat, "begin", 0);
            this.playLocalAudio("catRound2", -1, () => {
                asyncPlayDragonBoneAnimation(this.cat, "normal", 0);
                this._playingAudio = false;
            })
        }
    }
    _status = {
        state: 0,// -1:未开始 0 准备阶段  1 roll 2 判定
        Red: 0,
        Blue: 0,
        RedTime: 0,
        BlueTime: 0,
        step: 0,
        current: "Red",
        time: 0
    };
    playerId;
    isRoomOwner;
    server: GameServer;
    networkHelper: NetworkHelper;
    async initNetSever() {

        this._initGameData()

        this.networkHelper = new NetworkHelper();
        this.initNetworkListener();
        do {
            this.playerId = await this.networkHelper.init("op_L5_R1_bingo", 2);
            if (this.playerId === null) {
                this.log("onDestroy");
                this.networkHelper.onDestroy();
            }
            this.log("this.playerId = " + this.playerId);
        } while (this.playerId === null);

        const room = this.networkHelper.room;
        if (this.playerId == room.roomInfo.owner) {
            this.log("房主");
            this.isRoomOwner = true;
            this.server = new GameServer(2, this.networkHelper);

            this.server.wordList = this._gameWordList;

            await this.networkHelper.startFrameSync();

            this.server.startMatch();
        }
        await this.initHeadImgAndName();
    }

    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");
            middleLayerComponent.log("这里 打log?");
            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 || '拼读达人';
            }
        }

        let playData: PlayerData = {
            playerId: this.playerId,
            uuid: this.playerId,
            name: playerInfo.playerName,
            headUrl: playerInfo.playerHeadUrl,
            side: "",
            isAI: false,
        };
        this._sendMsg(MsgType.USER_JOIN_ERQ, playData);
    }

    _initGameData() {
        let cardRoot = cc.find("Canvas/center/cardRoot");
        let cards = cardRoot.children;
        for (let i = 0; i < cards.length; ++i) {
            let card = cards[i];
            this._gameWordList.push(card.name)
        }

    }
    _sendMsg(type: MsgType, data: any) {
        this.networkHelper.sendFrame({
            type: type,
            data: data
        });
    }
    _isSeverMsgType(type) {
        return type == MsgType.USER_JOIN_ERQ ||
            type == MsgType.USER_REQ_ERQ ||
            type == MsgType.USER_PREPARE_REQ;
    }
    _playerList;
    initNetworkListener() {
        this.networkHelper.on("playerJoin", (event) => {
            // if (this.server) {

            //     this.server.onPlayerJoin({ data: { joinPlayerId: event.playerId } });
            // }
            this.log("playerJoin" + JSON.stringify(event, null, 2));
        });
        this.networkHelper.on("playerLeave", (event) => {
            cc.log("playerLeave" + JSON.stringify(event));
            cc.find("Canvas/PlayerOffLineLayer").active = true;
            this.networkHelper.leaveRoom();
        });
        this.networkHelper.on("playerOffLine", (event) => {
            cc.find("Canvas/PlayerOffLineLayer").active = true;
            this.networkHelper.leaveRoom();
            this.log("playerOffLine" + JSON.stringify(event));
        });
        this.networkHelper.on("gameStart", (event) => { });
        this.networkHelper.on("frameEvent", (event) => {
            event.data.frame.items.forEach(async (item) => {
                let type: MsgType = item.data.type;
                let msgData: MsgData = item.data.data;
                console.log("msg type: " + MsgType[item.data.type]);
                DOLOG && console.log("msg data :\n" + item.data.data);
                DOLOG && this.log("msg type: " + item.data.type);
                DOLOG && this.log("msg data :\n" + item.data.data)
                // 服务器只处理用户消息， 用户只处理广播消息
                if (this.server && this._isSeverMsgType(item.data.type)) {
                    this.server.onFrameEvent(item.data);
                } else {
                    let msg = typeof msgData == "string" ? JSON.parse(msgData) : msgData
                    this._onSeverMsg(type, msg);
                }

            });
        });
    }

    _onSeverMsg(type: MsgType, data: any) {

        if (type == MsgType.USER_JOIN_EV) {
            this._updateUserJoin(new MsgData(data));
        } else if (type == MsgType.ROOM_INIT_DONE) {

            this._doStartGameAni(new MsgData(data));

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

            this._updateRootSt(new MsgData(data));
        }
        else if (type == MsgType.ROUND_START_EV) {
            if (data.round == 1) {

                this._round = 1
            } else {
                this._round = 2
                let index = data.index;
                this._stepWord = this._round2WordList[index].word;

                this.playLocalAudio(this._stepWord);

                this.unschedule(this._cyclePlayAudio)
                this.schedule(this._cyclePlayAudio, 2.5, 3, 2.2)

                // this.lb_round2.getComponent(cc.Label).string = "当前发音单词：" + this._stepWord
                console.log("========setp word ===========" + this._stepWord);

            }
        }
        else if (type == MsgType.USER_REQ_EV) {
            this._checkUserAnswer(data)
        } else if (type == MsgType.ROUND_END_EV) {
            this._round = -1
            this._roundEndCheck(data);
        }
    }

    _cyclePlayAudio() {
        this.playLocalAudio(this._stepWord);
    }

    _updateUserJoin(data: MsgData) {
        data.PlayerList.forEach((player) => {
            if (!this._playerList) {
                this._playerList = [];
            }

            if (
                !this._playerList.find(
                    (listPlayer) => listPlayer.uuid == player.uuid
                )
            ) {
                this._playerList.push({
                    uuid: player.uuid,
                    name: player.name,
                    side: player.side,
                    headUrl: player.headUrl,
                });
            }

            this.loadPlayerHeadImage();

            this.loadingLayer.addPlayer(
                player.name,
                player.uuid == this.playerId,
                player.headUrl,
                player.uuid
            );
        });
    }

    _cardsAni() {

        let cardRoot = cc.find("Canvas/center/cardRoot");
        let cards = cardRoot.children;
        for (let i = 0; i < cards.length; ++i) {
            cc.tween(cards[i]).delay(0.25 * i).by(0.3, { scale: 1.05 }).to(0.1, { scale: 1 }).start();

        }

    }
    _doStartGameAni(data: MsgData) {

        cc.log("_doStartGameAni")
        this._updateClock(data.Time);


        let aniCall = () => {
            let wp1 = this.bfly.convertToWorldSpaceAR(cc.Vec2.ZERO);
            let wp2 = this.btn_keyboard.convertToWorldSpaceAR(cc.Vec2.ZERO)
            let offsetX = wp2.x - wp1.x;
            console.log("offset  x =" + offsetX)
            cc.tween(this.bfly).by(1, { x: offsetX }).call(() => {
                this.bfly.getComponent(dragonBones.ArmatureDisplay).playAnimation("begin", 1);
            }).delay(1.5).call(() => {
                this.playLocalAudio("flyd")
            }).delay(1.5).call(() => {

                this._sendMsg(MsgType.USER_PREPARE_REQ, {});
                this._keyboard.showIn();
            }).by(1, { x: -offsetX }).start();
        }

        let doneLoadCall = async () => {

            this._cardsAni();
            if (this.data.gameStartAudio) {
                asyncPlayDragonBoneAnimation(this.cat, "begin", 0)
                this.playAudioByUrl(this.data.gameStartAudio, () => {
                    aniCall();
                    asyncPlayDragonBoneAnimation(this.cat, "normal", 0)
                })
            } else {
                asyncPlayDragonBoneAnimation(this.cat, "begin", 0)
                this.playLocalAudio("gameStart", -1, () => {
                    aniCall();
                    asyncPlayDragonBoneAnimation(this.cat, "normal", 0)
                })

            }
        }

        if (this._loadingDone) {
            doneLoadCall();
        } else {
            this._loadingCall = doneLoadCall;
        }
    }
    _updateRootSt(data: MsgData) {
        DOLOG && console.log(data);
        if (data.Round == 1) {

            this._updateCards(data.getAnswerList())

        } else {
            this._updateRound2Cards(data.getAnswerList())
        }
        this._updateClock(data.Time);
        this._updateProgrss(data.RedScore, data.BuleSocre, data.Round)
    }
    _roundEndCheck(data) {

        if (data.round == 1) {
            this._round2WordList = data.answerList
            console.log("====_round2WordList====");
            console.log(this._round2WordList);
            // resaon 1 全部完成， 2 时间到了
            this._keyboard.showOut(true);
            this._clockTime.string = "0";

            console.log("_roundEndCheck");
            console.log(data);
            if (data.resaon == 1) {
                asyncPlayDragonBoneAnimation(this.cat, "begin", 0)
                this.playLocalAudio("allDone", -1, () => {
                    this._reInitCards();
                    this.playLocalAudio("round2begin", -1, () => {
                        asyncPlayDragonBoneAnimation(this.cat, "normal", 0)
                        aniCall();
                    })
                })

            } else {
                asyncPlayDragonBoneAnimation(this.cat, "begin", 0)
                this.playLocalAudio("timeDone", -1, async () => {
                    await this._updateCards(data.answerList, true)
                    this._reInitCards();
                    this.playLocalAudio("round2begin", -1, () => {
                        asyncPlayDragonBoneAnimation(this.cat, "normal", 0)
                        aniCall();
                    })

                })
            }



            let aniCall = () => {


                let wp1 = this.bfly.convertToWorldSpaceAR(cc.Vec2.ZERO);
                let wp2 = this.btn_keyboard.convertToWorldSpaceAR(cc.Vec2.ZERO)
                let offsetX = wp2.x - wp1.x;
                console.log("offset  x =" + offsetX)
                cc.tween(this.bfly).by(1, { x: offsetX }).call(() => {
                    this.bfly.getComponent(dragonBones.ArmatureDisplay).playAnimation("begin", 1);
                }).delay(1.5).call(() => {
                    this.playLocalAudio("flyd")
                }).delay(1.5).call(() => {
                    this._sendMsg(MsgType.USER_PREPARE_REQ, {});

                    this._initCardClickEvent();

                }).by(1, { x: -offsetX }).start();
            }


        } else {


            this.unschedule(this._cyclePlayAudio)
            // 鸟飞走



            let endview = cc.instantiate(this.endViewPrefab);
            endview.parent = this.node;
            endview.zIndex = 1000;
            let endViewCom: EndView = endview.getComponent(EndView);

            let realRedScore = (Math.floor(data.redScore / 100) + data.redScore % 100);
            let realBlueScore = (Math.floor(data.blueScore / 100) + data.blueScore % 100);

            if (this.playerId == data.uuid) {

                this.playLocalAudio("bingoWin");
            } else {
                this.playLocalAudio("bingoLose");
            }

            endViewCom.showView(
                this.playerId == data.uuid,
                realRedScore,
                realBlueScore,
                this._redUrl,
                this._blueUrl
            )

        }
    }
    _initCardClickEvent() {
        this._wordCardRoot.children.forEach((card, index) => {
            if (!card.getComponent(cc.Button)) {
                card.addComponent(cc.Button)
            }
            card.on("click", () => {

                console.log("===click birds===");
                this._sendMsg(
                    MsgType.USER_REQ_ERQ,
                    {
                        uuid: this.playerId,
                        index: index,
                    }
                )

            })

        })
    }
    _updateProgrss(redScore, blueScore, round) {

        let realRedScore = (Math.floor(redScore / 100) + redScore % 100);
        let realBlueScore = (Math.floor(blueScore / 100) + blueScore % 100);
        this._redLb.string = "" + realRedScore;
        this._blueLb.string = "" + realBlueScore;

        if (round == 1) {
            this._redLightList.children.forEach((node) => {
                node.active = +node.name <= redScore % 100
            })
            this._blueLightList.children.forEach((node) => {
                node.active = +node.name <= blueScore % 100
            })
        } else {
            this._redLightList.children.forEach((node) => {
                node.active = +node.name <= Math.floor(redScore / 100)
            })
            this._blueLightList.children.forEach((node) => {
                node.active = +node.name <= Math.floor(blueScore / 100)
            })
        }
    }
    async _updateCards(list, delay?) {

        for (let i = 0; i < list.length; ++i) {
            let data = list[i];
            let word = data.word;
            let uuid = data.uuid;
            let cardBg = this._wordCardRoot.children[i];

            if (cardBg.getChildByName("word")) {
                continue;
            } else {

                if (delay) {
                    await asyncDelay(0.2)
                }
                let wordNode = this.getSprNode(word)
                wordNode.parent = cardBg;
                wordNode.name = "word";
                wordNode.x = 0;
                wordNode.y = 0;
                wordNode.zIndex = 10;
                let side = this._getSideByUuid(uuid);

                if (side == "Red") {

                    let coverBg = this.getSprNode("RedBox");
                    coverBg.parent = cardBg;
                    coverBg.name = "cover"
                    coverBg.x = 0;
                    coverBg.y = 0;

                } else if (side == "Blue") {
                    let coverBg = this.getSprNode("BlueBox");
                    coverBg.parent = cardBg;
                    coverBg.name = "cover"
                    coverBg.x = 0;
                    coverBg.y = 0;
                }
            }
        }

    }

    async _reInitCards() {
        for (let i = 0; i < 16; ++i) {
            let cardBg = this._wordCardRoot.children[i];
            let cover = cardBg.getChildByName("cover");
            cover && (cover.parent = null);
        }
    }
    async _updateRound2Cards(list) {

        list.forEach((val) => {
            let index = val.index;
            let uuid = val.uuid;
            let cardBg = this._wordCardRoot.children[index];
            if (cardBg.getChildByName("cover1")) {

            } else {
                let side = this._getSideByUuid(uuid);
                if (side == "Red") {
                    let coverBg = this.getSprNode("RedBox");
                    coverBg.parent = cardBg;
                    coverBg.name = "cover1"
                    coverBg.zIndex = 5;
                    coverBg.x = 0;
                    coverBg.y = 0;

                } else if (side == "Blue") {
                    let coverBg = this.getSprNode("BlueBox");
                    coverBg.parent = cardBg;
                    coverBg.name = "cover1";
                    coverBg.zIndex = 5
                    coverBg.x = 0;
                    coverBg.y = 0;
                }
            }

        })

    }
    _getSideByUuid(uuid) {
        let side = "";
        this._playerList.forEach((player) => {
            if (player.uuid == uuid) {
                side = player.side
            }
        });
        return side;
    }
    _updateClock(time: number) {

        if (this._leftTime == time) return
        this._leftTime = time;
        this._clockTime.string = "" + Math.round(time);
        cc.tween(this._clockTime.node).to(0.3, { scale: 1.2 }).to(0.7, { scale: 1 }).start();
    }
    _checkUserAnswer(data: { round: number, uuid: string, index: number, result: resultType }) {

        if (data.round == 1) {
            if (this.playerId == data.uuid) {

                if (data.result == resultType.REPEAT) {
                    cc.log("这个单词已经存在了");

                    this.playLocalAudio("wordhas")

                } else if (data.result == resultType.WRONG) {
                    cc.log("抱歉 你答错了");
                    this.playLocalAudio("wordCardwrong")
                } else if (data.result == resultType.RIGHT) {
                    this.playLocalAudio("wordRight")
                    cc.log("恭喜你答对了");
                }
            }
        } else {

            let bird = this._birdsRoot.children[data.index]
            if (this.playerId == data.uuid) {
                if (data.result == resultType.WRONG) {
                    cc.log("抱歉 你答错了");
                    this.playLocalAudio("birdwrong")

                    asyncPlayDragonBoneAnimation(bird, "wrong").then(() => {
                        bird.getComponent(dragonBones.ArmatureDisplay).playAnimation("normal", 0);
                    })

                } else if (data.result == resultType.RIGHT) {

                    this.playLocalAudio("birdHappy")
                    asyncPlayDragonBoneAnimation(bird, "right").then(() => {
                        bird.getComponent(dragonBones.ArmatureDisplay).playAnimation("normal", 0);
                    })
                    cc.log("恭喜你答对了");
                }
            }
        }
    }

    async openCoursView(node, word) {
        this.cover.active = true;
        this.cat.active = false;
        this._clockNode.active = false;
        let probar = this.cover.getChildByName("bg").getChildByName("probar");
        let pass = this.cover.getChildByName("bg").getChildByName("pass");
        let loss = this.cover.getChildByName("bg").getChildByName("loss");
        this.cover.getChildByName("bg").getChildByName("bar").removeAllChildren();
        let icon = cc.instantiate(node);
        icon.parent = this.cover.getChildByName("bg").getChildByName("bar");
        icon.x = 0;
        icon.y = 0;
        icon.scale = Math.min(600 / icon.width, 600 / icon.height);
        pass.active = false;
        loss.active = false;

        probar.getComponent(cc.ProgressBar).unscheduleAllCallbacks();
        let total = 1;
        probar.getComponent(cc.ProgressBar).progress = total;

        if (!this._recordBefore && this.data.recordWait) {//
            this._recordBefore = true;
            await new Promise((resolve) => {
                this.recordCat.getComponent(dragonBones.ArmatureDisplay).playAnimation("normal", 0);
                this.playAudioByUrl(this.data.recordWait, () => {
                    this.recordCat.getComponent(dragonBones.ArmatureDisplay).playAnimation("record", 0);
                    console.log("record audio done==============");
                    resolve("")
                });
            })
        } else {
            this.recordCat.getComponent(dragonBones.ArmatureDisplay).playAnimation("record", 0);
        }

        this._startCourseware(word);
        await asyncDelay(0.5);
        // 6s 
        probar.getComponent(cc.ProgressBar).schedule(() => {
            probar.getComponent(cc.ProgressBar).progress = total;
            total -= 1 / 30;
            if (total < 0) {
                probar.getComponent(cc.ProgressBar).unscheduleAllCallbacks();
                this._coursewareStoped();
            }
        }, 0.1, 61, 0.1)
    }

    async _startCourseware(word) {
        if (!cc.sys.isBrowser && window["courseware"]?.startTest) {

            this.log("录音开始 单词：" + word);
            window["courseware"]?.startTest(word);
        } else {

            console.log("web 模拟录音开始");
        }
    }
    async _coursewareStoped() {

        // this.cover.active = false;
        // cc.tween(this.cover).to(0.5, { opacity: 255 }).start();
        // await asyncDelay(0.5);

        if (!cc.sys.isBrowser && window["courseware"]?.stopTest) {
            window["courseware"]?.stopTest((res, b) => {

                if (typeof res == "string") {
                    res = JSON.parse(res);
                }
                this.log("++++++++++++ _coursewareEnd  +++++++++++++++");
                this.log("发音分数： pronunciation=== " + res.result?.pronunciation);
                this._coursewareEnd(res.result?.pronunciation || 0,)
            });
        } else {
            await asyncDelay(3);
            this.log("web 模拟录音评测 结果");
            this._coursewareEnd(Math.random() > 0.7 ? 90 : 60)
        }

    }
    async _coursewareEnd(score: number) {

        // if (this._status.Blue + this._status.step > 4 || this._status.Red + this._status.step > 4) {
        //     score = 50
        // }

        this.log("测评分数：" + score);
        if (score >= 70) {

            let pass = this.cover.getChildByName("bg").getChildByName("pass");
            pass.active = true;
            pass.scale = 0;
            cc.tween(pass).to(0.3, { scale: 0.5 }, { easing: "cubicIn" }).start();
            this.playLocalAudio("right");
            await asyncDelay(1);

            this.cover.active = false;
            this.cat.active = true;
            this._clockNode.active = true;
            this.log("====评测通过=====");
            // this.networkHelper.sendFrame({
            //     type: "right",
            //     uuid: this.myData.uuid,
            // });


        } else {

            let loss = this.cover.getChildByName("bg").getChildByName("loss");
            loss.active = true;
            loss.scale = 0;
            cc.tween(loss).to(0.3, { scale: 0.5 }, { easing: "cubicIn" }).start();
            this.playLocalAudio("wrong");
            await asyncDelay(1);
            this.cover.active = false;
            this.cat.active = true;
            this._clockNode.active = true;
            this.log("====评测不通过=====");
            // this.networkHelper.sendFrame({
            //     type: "wrong",
            //     uuid: this.myData.uuid,
            // });

        }

    }


    roundEndCheck(isRight?) {

        const blueHead = cc.find("Canvas/road/blueHead");
        const redHead = cc.find("Canvas/road/redHead");

        blueHead.getChildByName("tree").getComponent(cc.ProgressBar).progress = this._status.Blue / 10;
        redHead.getChildByName("tree").getComponent(cc.ProgressBar).progress = this._status.Red / 10;

        if (isRight) {

            // if (this.isMySide) {
            //     this._checkLast = true
            //     this.cat.getComponent(dragonBones.ArmatureDisplay).playAnimation("right", 1);
            // }

            if (this._status.current == "Red") {
                redHead.getChildByName("spine").getComponent(dragonBones.ArmatureDisplay).playAnimation("normal", 1);
            } else {
                blueHead.getChildByName("spine").getComponent(dragonBones.ArmatureDisplay).playAnimation("normal", 1)
            }
        } else {

            // if (this.isMySide) {
            //     this._checkLast = true
            //     this.cat.getComponent(dragonBones.ArmatureDisplay).playAnimation("wrong", 1);
            // }
        }


        // this.networkHelper.sendFrame({
        //     type: "stateUpdate",
        //     uuid: this.myData.uuid,
        // });
    }

    showYourTurn() {
        this.log("=====showYourTurn===========");
        return new Promise((resolve, reject) => {
            const yourTurn = cc.find("Canvas/yourturn");
            yourTurn.active = true;
            this.playLocalAudio("youturnTip")
            cc.tween(yourTurn)
                .set({ opacity: 0, scale: 5 })
                .to(1, { opacity: 255, scale: 2 })
                .delay(0.5)
                .to(0.5, { opacity: 0 })
                .call(() => {
                    resolve(null);
                })
                .start();
        });
    }

    async toEnd() {

        const blueHead = cc.find("Canvas/road/blueHead");
        const redHead = cc.find("Canvas/road/redHead");
        blueHead.getChildByName("tree").getComponent(cc.ProgressBar).progress = this._status.Blue / 10;
        redHead.getChildByName("tree").getComponent(cc.ProgressBar).progress = this._status.Red / 10;

        this._redLb.string = `${this._status.Red}/10`;
        this._blueLb.string = `${this._status.Blue}/10`;

        let node = cc.find(`Canvas/road/root/piece${this._status.current}`);
        // let pos = this._bluePointRoot.getChildByName("19").position;

        // if (this._status.current == "Red") {
        //     pos = this._redPointRoot.getChildByName("19").position;
        // }

        // await asyncTweenTo(
        //     node,
        //     0.7,
        //     { x: pos.x, y: pos.y },
        //     { easing: "cubicOut" }
        // );
        // if (this.isMySide) {
        //     this.cat.getComponent(dragonBones.ArmatureDisplay).playAnimation("finish", 1);
        // } else {

        // }
        // await asyncDelay(0.2);

    }

    showWin() {
        let endRoot = cc.find("Canvas/endRoot")
        endRoot.active = true;
        endRoot.opacity = 0;
        cc.tween(endRoot).to(1, { opacity: 255 }).start();
        const win = cc.find("Canvas/endRoot/win");
        win.active = true;
        this.playLocalAudio("win");
    }
    showLoss() {
        let endRoot = cc.find("Canvas/endRoot")
        endRoot.active = true;
        endRoot.opacity = 0;
        cc.tween(endRoot).to(1, { opacity: 255 }).start();
        const loss = cc.find("Canvas/endRoot/loss");
        loss.active = true;
        this.playLocalAudio("loss");
    }


    finish() {
        // onHomeworkFinish();
    }

    async rollTheDice(num) {
        if (this._isRolling) {
            return;
        }

        this._springNode.getComponent(cc.Animation).play();

        cc.tween(this._coinNode).by(0.14, { y: -10 }).start();

        await asyncDelay(0.14);
        this._coinNode.getChildByName("coinA").active = false;
        this._coinNode.getChildByName("coinB").active = true;

        cc.tween(this._coinNode).by(0.5, { y: 400 }).start();
        await asyncDelay(0.5);
        this._coinNode.parent = this._cardList[num].parent;
        this._coinNode.position = cc.v3(this._cardList[num].x, this._cardList[num].y + 1000, 0)

        cc.tween(this._coinNode).by(0.5, { y: -1000 }, { easing: cc.easeBounceIn.name }).start();
        await asyncDelay(0.5);
        this._coinNode.getChildByName("coinA").active = true;
        this._coinNode.getChildByName("coinB").active = false;
        return Promise.resolve();
    }

    async playLocalAudio(audioName, time = -1, callback = null) {

        let audioNode = this._localAudioRoot.getChildByName(audioName);
        if (audioNode) {
            let realTime = audioNode.getComponent(cc.AudioSource).getDuration();
            audioNode.getComponent(cc.AudioSource).play();
            if (time > 0) realTime = time;
            await asyncDelay(realTime);
            callback && callback();

        } else {

            console.warn("no local audio with name " + audioName);
        }


    }



    // 生命周期
    onDestroy() {
        this.networkHelper.onDestroy();
    }
}

