import { asyncDelay, asyncLoadDragonBoneAnime, asyncTweenBy, asyncTweenTo, onHomeworkFinish } from "../script/util";
import { MyCocosSceneComponent } from "../script/MyCocosSceneComponent";
import Cake from "../prefabs/Cake";
import AudioButton from "../script/AudioButton";
import { defaultData } from "../script/defaultData";
import ChoseNode from "../prefabs/choseNode";
import CakeBar from "../prefabs/CakeBar";
import AudioBar from "../prefabs/AudioBar";
import Candle from "../prefabs/Candle";
import { delayCall } from "../../../form_angular/src/app/play/Unit";

const { ccclass, property } = cc._decorator;
@ccclass
export default class SceneComponent extends MyCocosSceneComponent {

    @property(cc.Prefab)
    candlePrefab: cc.Prefab = null;

    @property(cc.Prefab)
    cakePrefab: cc.Prefab = null;

    @property(cc.Prefab)
    chosePrefab: cc.Prefab = null;

    @property(cc.Prefab)
    cakeRatePrefab: cc.Prefab = null;

    @property(cc.Prefab)
    audioPrefab: cc.Prefab = null;


    @property(cc.Node)
    cover: cc.Node = null

    @property(cc.Label)
    title: cc.Label = null

    @property(AudioButton)
    startNode: AudioButton = null

    @property(cc.Node)
    audioRoot: cc.Node = null

    @property(AudioButton)
    answerNode: AudioButton = null

    @property(cc.Node)
    cakrBarRoot: cc.Node = null

    @property(cc.Node)
    cakeRoot: cc.Node = null

    @property(cc.Node)
    candleRoot: cc.Node = null

    @property(cc.Node)
    endRoot: cc.Node = null

    @property(cc.Node)
    tvRoot: cc.Node = null
    @property(cc.Node)
    tvCenter: cc.Node = null
    @property(AudioButton)
    tvCenterBtn: AudioButton = null

    @property(dragonBones.ArmatureDisplay)
    excellent: dragonBones.ArmatureDisplay = null;

    @property(cc.Node)
    nictTry: cc.Node = null;

    @property(cc.Label)
    lb_word: cc.Label = null

    @property(cc.Node)
    choseARoot: cc.Node = null

    @property(cc.Node)
    choseBRoot: cc.Node = null;

    @property(cc.Node)
    cakePiece: cc.Node = null;

    private _defaultFadeIn = 0.5;
    private _defaultFadeOut = 0.5;

    private _cake: Cake;
    private _audioBar: AudioBar;
    private _questionIndex: number;
    private _nowRightLetter: string;
    private _nowRightIndex: number;
    private _canAnswer: boolean;
    private _choseNodeA: ChoseNode;
    private _choseNodeB: ChoseNode;
    private _totalQuestion: number;
    private _cakeBar: CakeBar;
    private _nowData: { text: string; audio: string; dragonBoneData: { skeJsonData: { url: string; name: string; }; texJsonData: { url: string; name: string; }; texPngData: { url: string; name: string; }; }; waitTime: number; choosewaitTime: number; testWaitTime: number; rightLetter: string; wrongLetter: string; } | { text: string; audio: string; dragonBoneData: { skeJsonData: { url: string; name: string; }; texJsonData: { url: string; name: string; }; texPngData: { url: string; name: string; }; }; choosewaitTime: number; testWaitTime: number; rightLetter: string; wrongLetter: string; waitTime?: undefined; };
    private _txtAni: cc.Node;
    private _candle: Candle;
    private _coursewareDone: boolean;
    private _wrongQuestion: number;



    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() {

    }

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

    _cantouch = null;
    async initData() {
        // 所有全局变量 默认都是null 
        this._cantouch = true;
        this._totalQuestion = defaultData.questions.length;
        this._wrongQuestion = 0;

        await new Promise((resolve) => {
            cc.assetManager.loadBundle("cake_template_test", (ero) => {
                console.log("budle loaded");
                !ero && resolve(null);
            });
        })


        console.log("init data");
    }

    initView() {
        this.initBg();
        this.initPic();
        this.initBtn();
        // this.initIcon();
    }

    initBg() {
        const bgNode = cc.find('Canvas/bg');
        bgNode.scale = this._mapScaleMax;
        this.cover.active = true;
        this.cakeRoot.active = false;
        this.cakePiece.active = false
        this.title.string = defaultData.title;
        this.tvRoot.active = false;
        this.candleRoot.active = false;
        this.excellent.node.active = false;
        this.nictTry.active = false;
        this.answerNode.node.active = false;
    }

    pic1 = null;
    pic2 = null;
    initPic() {
        let choseA = cc.instantiate(this.chosePrefab);
        choseA.parent = this.choseARoot;
        choseA.x = 0;
        choseA.y = 0;
        this._choseNodeA = choseA.getComponent(ChoseNode)

        let choseB = cc.instantiate(this.chosePrefab);
        choseB.parent = this.choseBRoot;
        choseB.x = 0;
        choseB.y = 0;
        this._choseNodeB = choseB.getComponent(ChoseNode)

        let cakeBar = cc.instantiate(this.cakeRatePrefab);
        cakeBar.parent = this.cakrBarRoot;
        cakeBar.y = 0;
        cakeBar.x = 0;
        this._cakeBar = cakeBar.getComponent(CakeBar);
        this._cakeBar.init(this._totalQuestion);

        let audioNode = cc.instantiate(this.audioPrefab);
        audioNode.parent = this.audioRoot;
        audioNode.y = 0;
        audioNode.x = 0;
        this._audioBar = audioNode.getComponent(AudioBar);

        let candleNode = cc.instantiate(this.candlePrefab);
        candleNode.parent = this.candleRoot;
        audioNode.y = 0;
        audioNode.x = 0;
        this._candle = candleNode.getComponent(Candle);
    }

    initIcon() {
        // const iconNode = this.getSprNode('icon');
        // iconNode.zIndex = 5;
        // iconNode.anchorX = 1;
        // iconNode.anchorY = 1;
        // iconNode.parent = cc.find('Canvas');
        // iconNode.x = iconNode.parent.width / 2 - 10;
        // iconNode.y = iconNode.parent.height / 2 - 10;

        // iconNode.on(cc.Node.EventType.TOUCH_START, () => {
        //     this.playAudioByUrl(this.data.audio_url);
        // })
    }

    //  游戏结束时需要调用这个方法通知系统作业完成
    // onHomeworkFinish();
    curPage = null;
    initBtn() {
        this.startNode.onceClick(this._startAndRemoveCover, this);
        this.tvCenterBtn.onClick(this._replayAni, this);
        this.answerNode.onClick(this._answerNow, this);
    }
    async _startAndRemoveCover() {
        cc.tween(this.startNode.node).delay(0.2).hide().start();

        await asyncTweenTo(this.cover, this._defaultFadeOut, { opacity: 0 });
        this.startNode.node.active = false;
        this._questionIndex = 0;
        this._initQuestionByIndex();
    }

    _replayAni() {

        console.log("_replayAni");
        if (this._txtAni) {
            this._txtAni.getComponent(dragonBones.ArmatureDisplay).playAnimation("newAnimation", 1);
        }

    }

    _initQuestionByIndex() {
        this._canAnswer = false;
        if (this._txtAni) {
            this._txtAni.parent = null;
            this._txtAni.destroy();
            this._txtAni = null;
        }

        this._nowData = defaultData.questions[this._questionIndex];
        this.initNodes(this._nowData);

        // this.testDragonB();
    }


    updateCakeBar() {

    }

    async initNodes(data: any) {

        this.cover.active = true;
        this.candleRoot.x = - cc.winSize.width;
        this.candleRoot.active = true;
        this._candle.setSkin(0);
        this.audioRoot.x = cc.winSize.width + 400;
        this.audioRoot.active = false;
        let word: string = data.text;
        let rightLetter: string = data.rightLetter;
        let wrongLetter: string = data.wrongLetter;
        this._nowRightLetter = rightLetter;
        this.answerNode.node.x = cc.winSize.width

        this.lb_word.string = word;
        if (!this._cake) {
            let cake = cc.instantiate(this.cakePrefab);
            cake.parent = this.cakeRoot;
            cake.y = 100;
            cake.x = 0;
            this._cake = cake.getComponent(Cake);
        }
        this._nowRightIndex = word.indexOf(rightLetter);
        let cakeWords = word.split("")
        cakeWords.splice(this._nowRightIndex, 1);
        console.log(cakeWords);
        this._cake.init(cakeWords);

        this.cakeRoot.y = -this._designSize.height / 2
        this.cakeRoot.x = cc.winSize.width;
        this.cakeRoot.active = true;

        let rigthTop = Math.random() > 0.5;

        this.choseARoot.x = 1.5 * cc.winSize.width - 200;
        this.choseARoot.y = 200;
        this._choseNodeA.init(rigthTop ? rightLetter : wrongLetter, rigthTop, this._onClickAnswer.bind(this));

        this.choseBRoot.x = 1.5 * cc.winSize.width - 200;
        this.choseBRoot.y = 0;
        this._choseNodeB.init(!rigthTop ? rightLetter : wrongLetter, !rigthTop, this._onClickAnswer.bind(this));

        asyncTweenBy(this.choseARoot, 1, { x: -cc.winSize.width })
        asyncTweenBy(this.choseBRoot, 1, { x: -cc.winSize.width })
        await asyncTweenTo(this.cakeRoot, 1, { x: 0 })


        this._audioBar.url = this._nowData.audio;
        this.playAudioByUrl(this._nowData.audio, async () => {
            this._canAnswer = true;
            this.audioRoot.active = true;
            cc.tween(this.audioRoot).to(0.5, { x: 550, y: 30 }).start();

            this.setCandelBar(0)

            cc.tween(this.candleRoot).to(0.5, { x: -550 }).call(() => {
                this._candle.fireOn(this._nowData.choosewaitTime, this._choseTimeOut.bind(this));
                this.cover.active = false;
            }).start();
        })
    }
    async _choseTimeOut() {

        if (!this._canAnswer) return;
        this._canAnswer = false;

        this.cakePiece.active = true;
        this.setCandelBar(2);

        asyncTweenTo(this.candleRoot, 0.5, { x: -cc.winSize.width })
        asyncTweenTo(this.audioRoot, 0.5, { x: cc.winSize.width })
        asyncTweenTo(this.choseARoot, 0.5, { x: cc.winSize.width })
        await asyncTweenTo(this.choseBRoot, 0.5, { x: cc.winSize.width })

        this.nextStep(false)
    }

    async _onClickAnswer(node, isAnswer: boolean) {

        if (!this._canAnswer) return;
        this._canAnswer = false;

        if (isAnswer) {
            this._candle.fireStop();
            await this.playLocalAudio("effect_chose_right", true);
            await asyncTweenTo(node.parent, 0.3, { x: 0, y: -100 })
            node.active = false;
            this._cake.insert(this._nowRightLetter, this._nowRightIndex);
            await asyncDelay(1);
        } else {

            this._candle.fireStop();
            await this.playLocalAudio("effect_cake_drop", true);
            // await asyncTweenTo(node.parent, 0.18, { x: 200, y: -300 })
            node.active = false;
            this.cakePiece.active = true;
            this.setCandelBar(2);
            await asyncDelay(1);
        }

        this.nextStep(isAnswer)

    }

    setCandelBar(state: number) {
        this._cakeBar.updateUI(this._questionIndex, state);

        console.log("setCandelBar");
        if (state == 2) {
            this._wrongQuestion++;
        }
    }

    async nextStep(isAnswer) {


        if (isAnswer) {

            console.log("start evolution");

            asyncTweenTo(this.candleRoot, 0.5, { x: -cc.winSize.width })
            asyncTweenTo(this.choseARoot, 0.5, { x: cc.winSize.width })
            asyncTweenTo(this.choseBRoot, 0.5, { x: cc.winSize.width })
            await Promise.all([asyncTweenTo(this.audioRoot, 0.5, { x: cc.winSize.width }),
            await this._setDragonTxt()
            ])

            this.tvRoot.y = -cc.winSize.height;
            this.tvRoot.x = 0;
            this.tvRoot.active = true;
            await asyncTweenTo(this.tvRoot, 0.5, { y: -this._designSize.height / 2 });
            this._txtAni.getComponent(dragonBones.ArmatureDisplay).playAnimation("newAnimation", 1);

            this.playAudioByUrl(defaultData.guideAudio)

            this.candleRoot.x = - cc.winSize.width;
            this.candleRoot.active = true;
            this._candle.setSkin(1);

            this.answerNode.node.active = true;
            asyncTweenTo(this.candleRoot, 0.5, { x: -550 });
            await asyncTweenTo(this.answerNode.node, 0.5, { x: 500 });

            this._startCourseware();

        } else {


            this.cakePiece.active = false;
            asyncTweenTo(this.candleRoot, 0.5, { x: -cc.winSize.width })
            asyncTweenTo(this.choseARoot, 0.5, { x: cc.winSize.width })
            asyncTweenTo(this.choseBRoot, 0.5, { x: cc.winSize.width })
            asyncTweenTo(this.audioRoot, 0.5, { x: cc.winSize.width })
            await asyncTweenTo(this.cakeRoot, 0.5, { x: cc.winSize.width })
            this._toNextQueston();
        }

    }
    _toNextQueston() {
        this._questionIndex++;
        if (this._questionIndex >= this._totalQuestion) {
            this.endQuestion();
        } else {
            this._initQuestionByIndex()
        }
    }
    async _startCourseware() {

        this._coursewareDone = false;
        if (window["courseware"]?.startTest) {

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

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

        this._candle.fireOn(this._nowData.testWaitTime, this._coursewareStoped.bind(this))

        await asyncDelay(this._nowData.testWaitTime);

        this._coursewareStoped();

    }

    _answerNow() {
        this._coursewareStoped();
    }

    async _coursewareStoped() {

        if (this._coursewareDone) return;
        this._coursewareDone = true;

        this._candle.fireStop();
        asyncTweenTo(this.candleRoot, 0.5, { x: -cc.winSize.width });
        asyncTweenTo(this.answerNode.node, 0.5, { x: cc.winSize.width });

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

        if (window["courseware"]?.stopTest) {
            window["courseware"]?.stopTest((res, b) => {

                if (typeof res == "string") {
                    res = JSON.parse(res);
                }
                console.log("++++++++++++ _coursewareEnd  +++++++++++++++");
                this._coursewareEnd(res.result?.pronunciation || 0)
                console.log("pronunciation=== " + res.result?.pronunciation);
                // console.log("++++++++++++  res  +++++++++++++++");
                // console.log(res);
                // console.log("++++++++++  res.result  +++++++++++++++++");
                // console.log(res.result);
                // console.log("+++++++++++++  res.dtLastResponse  ++++++++++++++");
                // console.log(res.dtLastResponse);
                // console.log("+++++++++++++++++++++++++++");
                // console.log("111=== " + res.pronunciation);
                // console.log("222=== " + res.overall);
                console.log("333=== " + res.result?.pronunciation);

            });
        } else {
            await asyncDelay(3);
            console.log("web 模拟录音评测 结果");
            this._coursewareEnd(Math.random() > 0.5 ? 100 : 70)
        }

    }
    async _coursewareEnd(score: number) {

        if (score >= 80) {


            console.log("good");
            this.excellent.node.active = true;
            this.excellent.playAnimation("newAnimation", 1);
            this.playLocalAudio("effect_evaluation_excellent")
            await asyncDelay(1);

            this.excellent.node.active = false;
            cc.tween(this.cover).to(0.5, { opacity: 0 }).start();
            this.setCandelBar(1)
            await asyncDelay(0.5);
            this.cover.active = false;

            asyncTweenTo(this.cakeRoot, 0.5, { x: cc.winSize.width })
            await asyncTweenTo(this.tvRoot, 0.5, { x: -cc.winSize.width })

            this._toNextQueston();

        } else {

            this.setCandelBar(2)
            this.nictTry.y = cc.winSize.height;
            this.nictTry.active = true;
            cc.tween(this.nictTry).
                to(0.5, { y: -cc.winSize.height / 10 }, { easing: "bounceIn" }).
                call(() => {
                    this.playLocalAudio("effect_evaluation_nicetry")
                }).
                to(0.3, { y: 0 }, { easing: "bounceOut" }).
                delay(1).
                to(0.5, { y: -cc.winSize.height }).call(async () => {

                    console.log("come on");

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

                    asyncTweenTo(this.cakeRoot, 0.5, { x: cc.winSize.width })
                    await asyncTweenTo(this.tvRoot, 0.5, { x: -cc.winSize.width })

                    this._toNextQueston();

                }).start();

            console.log("come on");

        }

    }
    async _setDragonTxt() {

        console.log(this._nowData);
        this._txtAni =
            await asyncLoadDragonBoneAnime(this.tvCenter,
                {
                    skeJsonData: { url: this._nowData.dragonBoneData.skeJsonData.url },
                    texJsonData: { url: this._nowData.dragonBoneData.texJsonData.url },
                    texPngData: { url: this._nowData.dragonBoneData.texPngData.url }
                }
            )
    }



    async endQuestion() {
        console.log("endQuestion this._wrongQuestion = " + this._wrongQuestion);

        this.cover.active = true;
        this.cover.opacity = 0;
        cc.tween(this.cover).to(0.5, { opacity: 255 }).start();

        this.endRoot.active = true;
        if (this._wrongQuestion == 0) {

            this.endRoot.active = true;
            this.endRoot.getChildByName("flower").active = true;
            this.playLocalAudio("effect_all_right");

            await asyncDelay(3);
            onHomeworkFinish();

        } else {
            if (this._wrongQuestion / this._totalQuestion <= 0.2) {

                let node = this.endRoot.getChildByName("nicetry")
                node.y = cc.winSize.height;
                node.active = true;
                cc.tween(node).
                    to(0.5, { y: -cc.winSize.height / 10 }, { easing: "bounceIn" }).
                    call(() => {
                        this.playLocalAudio("effect_nicetry")
                    }).
                    to(0.3, { y: 0 }, { easing: "bounceOut" }).
                    delay(1).
                    to(0.5, { y: -cc.winSize.height }).call(async () => {
                        onHomeworkFinish();
                    }).start();


            } else {
                let node = this.endRoot.getChildByName("comeon")
                node.y = cc.winSize.height;
                node.active = true;
                cc.tween(node).
                    to(0.5, { y: -cc.winSize.height / 10 }, { easing: "bounceIn" }).
                    call(() => {
                        this.playLocalAudio("effect_final_report")
                    }).
                    to(0.3, { y: 0 }, { easing: "bounceOut" }).
                    delay(1).
                    to(0.5, { y: -cc.winSize.height }).call(async () => {
                        onHomeworkFinish();
                    }).start();

            }
        }
    }

    initListener() {

    }

    playLocalAudio(audioName, notWaitDone?: boolean) {
        return new Promise((resolve, reject) => {
            cc.assetManager.getBundle("cake_template_test").load("/audios/" + audioName, (ero: Error, asset: cc.AudioClip) => {
                if (!ero) {
                    let id = cc.audioEngine.playEffect(asset, false);
                    if (notWaitDone) {
                        resolve(null)
                    } else {
                        cc.audioEngine.setFinishCallback(id, () => {
                            resolve(null);
                        });
                    }
                } else {
                    cc.error(ero);
                }
            })
        })
    }
}
