import { asyncDelay, asyncTweenTo } from "../script/util";
import { MyCocosSceneComponent } from "../script/MyCocosSceneComponent";

const { ccclass, property } = cc._decorator;

@ccclass
export default class Playing extends MyCocosSceneComponent {

    @property(cc.AudioClip)
    bgMusic1: cc.AudioClip = null;

    addPreloadImage() {
    }

    addPreloadAudio() {
        this._audioResList.push({ url: this.data.audio_url });
    }

    addPreloadAnima() {

    }

    onLoadEnd() {
        this.initData();
        this.initView();
        this.initListener();
    }

    initView() {
        cc.tween(cc.find(`Canvas/people_a/arr1`))
            .to(.4, { x: -58, y: 120 })
            .to(.4, { x: -68, y: 130 })
            .union().repeatForever().start();

        cc.tween(cc.find(`Canvas/people_b/arr2`))
            .to(.4, { x: 51, y: 125 })
            .to(.4, { x: 61, y: 135 })
            .union().repeatForever().start();

        cc.audioEngine.setMusicVolume(0.5);
        cc.audioEngine.playMusic(this.bgMusic1, true);
        // this.openBan();
    }

    _cantouch = null;
    spllingFlag = null;
    initData() {
        // 所有全局变量 默认都是null 
        this._cantouch = true;
        this.spllingFlag = false;

        // 倒计时
        this.djsTimes = {
            "readaloud": 20,
            "spelling": 50
        };

        // 练习
        let arr = [];
        // 单词做一下乱序
        this.data.sort(() => {
            return Math.random() - 0.5;
        });
        arr = arr.concat(this.data);
        this.data.sort(() => {
            return Math.random() - 0.5;
        });
        arr = arr.concat(this.data);
        this.data = arr;
    }

    closeBan(callback) {
        this.playLocalAudio(`banzi`);
        const ban = cc.find(`Canvas/man/word_ban`);
        cc.tween(ban)
            .to(.2, { angle: 90, scale: 0.1 })
            .call(() => {
                cc.find(`Canvas/min_down`).active = true;
                cc.find(`Canvas/man`).active = false;
                callback && callback();
            })
            .start();
    }
    openBan(text_cn, callback = null) {
        this.playLocalAudio(`banzi`);
        cc.find(`Canvas/min_down`).active = false;
        cc.find(`Canvas/man`).active = true;

        if (this.gameType === 'spelling') {
            cc.find(`Canvas/man/word_ban/text`).active = true;
            cc.find(`Canvas/man/word_ban/text_small`).getComponent(cc.Label).string = "";
            cc.find(`Canvas/man/word_ban/spelling`).getComponent(cc.Label).string = "";
            cc.find(`Canvas/man/word_ban/text_small`).active = false;
            cc.find(`Canvas/man/word_ban/spelling`).active = false;
        }

        const ban = cc.find(`Canvas/man/word_ban`);
        cc.tween(ban)
            .to(.2, { angle: 0, scale: 1 })
            .call(() => {
                cc.find(`Canvas/man/word_ban/text`).getComponent(cc.Label).string = text_cn;
                cc.find(`Canvas/people_a/arr1`).active = true;
                cc.find(`Canvas/people_a/tips`).active = true;
                cc.find(`Canvas/people_b/arr2`).active = true;
                cc.find(`Canvas/people_b/tips`).active = true;
                
                this._cantouch = true;
                callback && callback();
            })
            .start();

    }

    gameType = null; // readaloud: 看中文说单词； spelling: 看中文拼读单词
    currentIndex = null;
    beginSpelling(evt, data) {
        this.playLocalAudio(`btn`);
        if (!this._cantouch) {
            return;
        }
        this._cantouch = false;
        this.gameType = data;
        cc.find(`Canvas/choseLevel`).active = false;
        this.startGame();
    }

    restartGame() {
        if (!this._cantouch) {
            return;
        }
        this._cantouch = false;

        cc.find(`Canvas/restartNode`).active = false;
        this.currentIndex = 0;
        cc.find(`Canvas/score_a/score`).getComponent(cc.Label).string = `0`;
        cc.find(`Canvas/score_b/score`).getComponent(cc.Label).string = `0`;

        this.startGame();
    }

    // 倒计时
    djsAudio = null;
    djsTimes = null;
    djs(callback) {
        const timeLen = this.djsTimes[this.gameType];
        cc.find(`Canvas/quan`).active = true;
        this.djsAudio = this.playLocalAudio(`clock`);
        cc.tween(cc.find(`Canvas/quan/zz`))
            .to(timeLen, { angle: -405 })
            .start();
        cc.tween(cc.find(`Canvas/quan`))
            .delay(timeLen - 3)
            .to(.1, { scale: 1.05 })
            .to(.1, { scale: 1 })
            .delay(0.8)
            .to(.1, { scale: 1.05 })
            .to(.1, { scale: 1 })
            .delay(0.8)
            .to(.1, { scale: 1.05 })
            .to(.1, { scale: 1 })
            .call(() => {
                this.stopDjs();
                callback && callback();
            })
            .start();
    }
    stopDjs() {
        cc.Tween.stopAllByTarget(cc.find(`Canvas/quan/zz`));
        cc.Tween.stopAllByTarget(cc.find(`Canvas/quan`));
        cc.find(`Canvas/quan`).scale = 1;
        cc.find(`Canvas/quan/zz`).angle = 0;

        cc.audioEngine.stop(this.djsAudio);
        cc.find(`Canvas/quan`).active = false;
    }


    doAsk(e, data) {
        if (!this._cantouch) {
            return;
        }
        this._cantouch = false;

        cc.tween(this.node).delay(0.3).call(()=>{
            cc.find(`Canvas/people_a/arr1`).active = false;
            cc.find(`Canvas/people_a/tips`).active = false;
            cc.find(`Canvas/people_b/arr2`).active = false;
            cc.find(`Canvas/people_b/tips`).active = false;

            cc.find(`Canvas/han_${data}`).active = true;
            cc.find(`Canvas/people_${data}`).active = false;
        }).start();

        this.djs(() => {
            this.playLocalAudio(`pi`);
            this.spllingFlag = false;
            if (window["courseware"]) {
                window["courseware"].stopRealtimeRecord();
                window["courseware"].stopWordSpell();
            }
            this.closeBan(async () => {
                cc.find(`Canvas/bishi`).active = true;
                cc.find(`Canvas/min_down`).active = false;
                cc.find(`Canvas/xiukui_${data}`).active = true;
                cc.find(`Canvas/han_${data}`).active = false;
                await asyncDelay(3);
                cc.find(`Canvas/xiukui_${data}`).active = false;
                cc.find(`Canvas/people_${data}`).active = true;
                cc.find(`Canvas/bishi`).active = false;
                cc.find(`Canvas/min_down`).active = true;

                this.nextWord();
            });
        });
        this.exe(() => {
            const nd = cc.find(`Canvas/score_${data}`);
            this.playLocalAudio(`getscore`);
            cc.find(`score`, nd).getComponent(cc.Label).string = `${parseInt(cc.find(`score`, nd).getComponent(cc.Label).string) + 1}`;
            cc.tween(nd).to(.1, { scale: 1.05 }).to(.1, { scale: 1 }).start();
            this.stopDjs();

            this.closeBan(() => {
                // 庆祝等反馈动作
                this.playLocalAudio(`kinglaugh`);
                const king = cc.find(`Canvas/king_${data}`);
                cc.find(`Canvas/han_${data}`).active = false;
                king.active = true;
                const anim = king.getComponent(cc.Animation);
                anim.once('finished', () => {
                    cc.find(`Canvas/people_${data}`).active = true;
                    king.active = false;

                    this.nextWord();
                });
                anim.play();
            });
        });
    }

    nextWord() {
        this.currentIndex++;
        const item = this.data[this.currentIndex];
        if (!item) {
            cc.find(`Canvas/restartNode`).active = true;
            this._cantouch = true;
            return;
        }
        this.openBan(item.text_cn);
    }

    async startGame() {
        await asyncDelay(1);
        this.currentIndex = 0;
        const item = this.data[this.currentIndex];
        this.closeBan(() => {
            this.openBan(item.text_cn);
        });
    }

    exe(callback) {
        if (this.gameType == 'readaloud') {
            this.readaloud(callback);
        }
        if (this.gameType == 'spelling') {
            this.spelling(callback);
        }
    }

    readaloud(callback) {
        if (!window["courseware"]) {
            return;
        }

        const ch = this.data[this.currentIndex].text_en;
        window["air"].recordRealtimeCallBack = (res) => {
            if (!this.spllingFlag) {
                return;
            }
            if (res) {
                let arr = [];
                try {
                    arr = JSON.parse(res).result.words.map(item => {
                        return { word: item.word, pronunciation: item.scores.pronunciation };
                    });
                } catch (error) {
                }
                if (arr.length === 0) {
                    return;
                }

                if (arr[0].pronunciation > 60) {
                    this.spllingFlag = false;
                    window["courseware"].stopRealtimeRecord();
                    callback();
                }
            }
        }
        this.spllingFlag = true;
        window["courseware"].startRealtimeRecord({ params: ch });
    }

    spelling(callback) {
        if (!window["courseware"]) {
            return;
        }

        const zh = this.data[this.currentIndex].text_cn;
        const ch = this.data[this.currentIndex].text_en.trim();
        const textNode = cc.find(`Canvas/man/word_ban/text`);
        const textSmallNode = cc.find(`Canvas/man/word_ban/text_small`);
        const spellingNode = cc.find(`Canvas/man/word_ban/spelling`);
        const textSmallNodeComponent = textSmallNode.getComponent(cc.Label);
        const spellingNodeComponent = spellingNode.getComponent(cc.Label);

        const debugLabelComponent = cc.find(`Canvas/log`).getComponent(cc.Label);
        debugLabelComponent.string = "";

        let isSpelled = false;
        const charArr = ch.split('');
        const filterArr = [];
        let spellingIndex = 0;
        window["air"].recordWordSpellCallBack = (res) => {

            if (!this.spllingFlag) {
                return;
            }
            if (res) {
                let arr = [];
                try {
                    arr = JSON.parse(res).result.details;
                } catch (error) {
                }
                if (arr.length === 0) {
                    return;
                }

                // 调试用
                // debugLabelComponent.string = arr.map(item => `${item.word}: ${item.confidence}`).join("\n");

                const newChar = arr[spellingIndex].word;
                if (!newChar) {
                    return;
                }

                const fillChar = (c) => {
                    if (!c) {
                        return;
                    }
                    if (c.charCodeAt() < 65 || c.charCodeAt() > 122 || (c.charCodeAt() > 90 && c.charCodeAt() < 97)) {
                        filterArr.push(c);
                        fillChar(charArr[filterArr.length]);
                    }
                }
                fillChar(charArr[filterArr.length]);
                // 调试用
                // debugLabelComponent.string = `${newChar}===${charArr[filterArr.length]}`;
                if (newChar == charArr[filterArr.length]) {
                    filterArr.push(newChar);
                }
                fillChar(charArr[filterArr.length]);
                spellingIndex ++;
                
                if (filterArr.length === 0) {
                    return;
                }

                if (isSpelled === false) {
                    isSpelled = true;
                    textNode.active = false;
                    textSmallNode.active = true;
                    spellingNode.active = true;
                    textSmallNodeComponent.string = zh;
                }
                spellingNodeComponent.string = filterArr.join("");

                if (filterArr.join("") == ch) {
                    this.spllingFlag = false;
                    window["courseware"].stopWordSpell();
                    callback();
                }
            }
        }
        this.spllingFlag = true;
        window["courseware"].startWordSpell({params: ch});
    }

    initListener() {

    }

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

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