
import { asyncDelay, exchangeNodePos, getSprNode, onHomeworkFinish, playAudio, RandomInt } from "../script/JJ_Game_09_util";
import { MyCocosSceneComponent } from "../script/JJ_Game_09_MyCocosSceneComponent";
import Game, { Item } from "./JJ_Game_09_Game";
import pg from "./JJ_Game_09_pg";

enum ItemType {
    PIC = "img",
    RIGHT_TXT = "right_txt",
    LOWER_TXT = "lower_txt"
}
const { ccclass, property } = cc._decorator;

@ccclass
export default class SceneComponent extends MyCocosSceneComponent {

    addPreloadImage() {
        this._imageResList.push(...this.data.pages.map(question => {
            return { url: question.pic_url };
        }));
    }

    addPreloadAudio() {
        this._audioResList.push(...this.data.pages.map(question => {
            return { url: question.audio_url };
        }));
    }

    addPreloadAnima() {

    }

    isDestroy;
    protected onDestroy(): void {
        this.isDestroy = true;
        clearTimeout(this.timeOut);
        clearInterval(this.intervalId);
        cc.audioEngine.setEffectsVolume(1);
    }
    onLoadEnd() {
        // TODO 加载完成后的逻辑写在这里, 下面的代码仅供参考

        this.initData();
        this.initView();
        this.initEvent();
        this.loadingAction();
    }
    protected onDisable(): void {
        cc.Tween.stopAll();
    }
    @property(cc.Node)
    page_view: cc.Node = null;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    private page: number;
    initData() {

        this.log(`initData:${JSON.stringify(this.data)}`)
        this.autoPlay = 0;
        this.page = 0;
        Game.getIns().init(this.data);
        Game.getIns().reset();
    }
    initView() {
        this.btn_back.active = true;
        cc.find(`title`, this.btn_back).getComponent(cc.Label).string = this.data.title || " ";
        this.nextPage();
    }
    onEnable() {
        this.randomPopo();
    }
    async randomPopo() {
        const createPopo = async () => {
            await asyncDelay(RandomInt(0, 20));
            if (this.isDestroy) {
                return;
            }
            const rType = Math.random()<0.5?1:2; // 1: 小泡泡，2：大泡泡
            const node = getSprNode(rType==1?"popo_sm":"popo_big");
            node.y = 0-(this.node.height / 2) - 260;
            const randomX = RandomInt(this.node.width) - (this.node.width/2);
            node.x = randomX;
            node.parent = cc.find("popo_cup", this.node);
            const speed = 30-(rType*5); // 大泡泡飘得快，小泡泡飘得慢
            cc.tween(node).to(speed, {y: (this.node.height/2)+400, x: randomX + (Math.tan(0.6) * this.node.height)}).call(() => {
                cc.find("popo_cup", this.node).removeChild(node);
                node.destroy();
            }).start();
            cc.tween(node).by(1.5, {scaleY: -0.05, scaleX: 0.05}).to(1.5, {scaleY: 1.05, scaleX: 1}).union().repeatForever().start();
        }
        const num = RandomInt(1, 3);
        const ppArr = [];
        for (let i = 0; i <= num; i++) {
            ppArr.push(createPopo());
        }
        await Promise.all(ppArr);
        if (this.isDestroy) {
            return;
        }
        await this.randomPopo();
        if (this.isDestroy) {
            return;
        }
    }
    initEvent() {
        this.btn_laba.on(cc.Node.EventType.TOUCH_END, this.onLaba, this);
        this.btn_record.on(cc.Node.EventType.TOUCH_END, this.onRecord, this);
        this.btn_play.on(cc.Node.EventType.TOUCH_END, this.onPlayRecord, this);
        this.btn_stop.on(cc.Node.EventType.TOUCH_END, this.onStopRecord, this);
        // this.btn_off.on(cc.Node.EventType.TOUCH_END, this.onReadOff, this);
        // this.btn_on.on(cc.Node.EventType.TOUCH_END, this.onReadOpen, this);
        this.btn_back.on(cc.Node.EventType.TOUCH_END, this.onBack, this);
        this.btn_left.on(cc.Node.EventType.TOUCH_END, this.onLeft, this);
        this.btn_right.on(cc.Node.EventType.TOUCH_END, this.onRight, this);
        this.page_view.on("scroll-ended", this.scrollEnd, this);
    }
    private loadingAction() {
        let icon_review = cc.find("icon_review", this.layout_loading);
        cc.tween(icon_review).repeatForever(cc.tween().by(0.5, { angle: -360 })).start();
    }
    private onLeft() {
        if (this.page <= 0) return;
        this.page_view.getComponent(cc.PageView).scrollToPage(this.page - 1, 0.1);
    }
    private onRight() {
        let index = this.page_view.getComponent(cc.PageView).getCurrentPageIndex();
        if (index + 1 >= Game.getIns().len) return;
        this.page_view.getComponent(cc.PageView).scrollToPage(this.page + 1, 0.1);
    }
    private scrollEnd() {
        clearTimeout(this.timeOut);
        let index = this.page_view.getComponent(cc.PageView).getCurrentPageIndex();
        if (this.page == index) {
            if (index + 1 == Game.getIns().len) {
                this.showTip("已经是最后一页了")
            }
            return;
        }
        this.resetAudio();
        this.page = index;
        this.updateTop();
        this.playLocalAudio("fanye", 0.2).then(() => {
            if (this.isDestroy) {
                return;
            }
            this.playQuestionAudio();
        });
        console.log("idx:" + index);
    }
    private resetAudio() {
        this.cleanRecord();
        cc.audioEngine.stopAll();
        this.stop = true;
        let data: Item = Game.getIns().getDataByPage(this.page);

        this.btn_play.active = data.recordAudio;
        this.btn_stop.active = false;
        this.btn_laba.active = !!data.audio_url;
    }
    private intervalId;
    private stop;
    private onLaba() {
        this.playTitleAudio(Game.getIns().lists[this.page].audio_url);
    }
    private playTitleAudio(audio, cb = null) {
        this.resetAudio();
        let btn_laba1 = this.btn_laba.getChildByName("btn_laba1");
        let btn_laba2 = this.btn_laba.getChildByName("btn_laba2");
        btn_laba1.active = true;
        btn_laba2.active = true;
        let count = 0;
        if (this.intervalId) clearInterval(this.intervalId);
        this.stop = false;
        this.intervalId = setInterval(() => {
            if (this.isDestroy) {
                return;
            }
            count++;
            // btn_laba1.active = count % 2 == 0;
            btn_laba2.active = count % 2 == 1;
            if (this.stop) {
                btn_laba1.active = true;
                btn_laba2.active = true;
                clearInterval(this.intervalId);
            }
        }, 150)
        pg.audio.playAudioByUrl(audio).then((audioId) => {
            if (this.isDestroy) {
                return;
            }
            this.stop = true;
            btn_laba1.active = true;
            btn_laba2.active = true;
            cb && cb(audioId);
        });
    }

    isRecording = false;
    private onRecord() {
        let recording_count = cc.find("btn_recording/recording_count", this.btn_record).getComponent(cc.Sprite);
        let btn_recording = cc.find("btn_recording", this.btn_record);
        if (recording_count.fillRange != 0) {
            cc.Tween.stopAllByTarget(recording_count);
            recording_count.fillRange = 0;
            btn_recording.active = false;
            this.recordStop();
        } else {
            this.resetAudio();
            this.isRecording = true;
            btn_recording.active = true;
            recording_count.fillRange = 0;
            cc.tween(recording_count).to(120, { fillRange: -1 }).call(() => { 
                if (this.isDestroy) {
                    return;
                }
                recording_count.fillRange = 0; this.recordStop(); }).start();

            let text = "";
            if (Game.getIns().lists[this.page].text) {
                text += Game.getIns().lists[this.page].text;
            }
            if (window['courseware']) {
                window['courseware'].startTest(text);
            }
        }
    }
    private cleanRecord() {
        let recording_count = cc.find("btn_recording/recording_count", this.btn_record).getComponent(cc.Sprite);
        let btn_recording = cc.find("btn_recording", this.btn_record);
        cc.Tween.stopAllByTarget(recording_count);
        recording_count.fillRange = 0;
        btn_recording.active = false;
    }
    private recordAudioId;
    private onPlayRecord() {
        this.resetAudio();

        let recording_count = cc.find("recording_count", this.btn_stop).getComponent(cc.Sprite);
        if (recording_count.fillRange != 0) {
            cc.Tween.stopAllByTarget(recording_count);
            recording_count.fillRange = 0;
        }

        this.btn_stop.active = true;
        this.btn_play.active = false;
        pg.audio.playAudioByUrl(Game.getIns().lists[this.page].recordAudio, (audioId) => {
            this.recordAudioId = audioId;
            const time = cc.audioEngine.getDuration(audioId);
            cc.tween(recording_count).to(time, { fillRange: -1 }).call(() => { recording_count.fillRange = 0; }).start();
        }).then(() => {
            if (this.isDestroy) {
                return;
            }
            this.btn_stop.active = false;
            this.btn_play.active = true;
        });

    }
    private onStopRecord() {
        let recording_count = cc.find("recording_count", this.btn_stop).getComponent(cc.Sprite);
        cc.Tween.stopAllByTarget(recording_count);
        recording_count.fillRange = 0;
        
        if (this.recordAudioId) {
            cc.audioEngine.stopEffect(this.recordAudioId)
        }
        this.btn_stop.active = false;
        this.btn_play.active = true;
    }
    private onBack() {
        const middleLayer = global["middleLayer"];
        if (middleLayer) {
            // 有些模板需要在返回时上报数据，直接把数据作为参数传入就可以了
            middleLayer.exitGame({});
        } else {
            console.log("==触发返回事件==");
        }
    }
    private onHideEnd() {
        this.recordEndView.active = false;

        if (this.autoPlay == 0) return;

        if (this.timeOut) clearTimeout(this.timeOut);

        this.timeOut = setTimeout(() => {
            if (this.isDestroy) {
                return;
            }
            let index = this.page_view.getComponent(cc.PageView).getCurrentPageIndex();
            this.page_view.getComponent(cc.PageView).scrollToPage(index + 1, 0.1);
        }, 2000);
    }
    private onReadOff() {
        // this.btn_off.active = false;
        // this.btn_on.active = true;
        this.autoPlay = 1;
        console.log("open");
        this.showTip("已开启自动阅读");
        this.updateTop();
        this.playQuestionAudio();
    }
    private onReadOpen() {
        // this.btn_on.active = false;
        // this.btn_off.active = true;
        this.autoPlay = 0;
        console.log("off");
        this.showTip("已关闭自动阅读");
        this.updateTop();
    }
    private timeOut;
    private playQuestionAudio() {
        this.playTitleAudio(Game.getIns().lists[this.page].audio_url, (audioId) => {
            if (this.autoPlay == 0) return;
            let time = audioId ? 1000 : 3000;
            this.timeOut = setTimeout(() => {
                if (this.isDestroy) {
                    return;
                }
                let index = this.page_view.getComponent(cc.PageView).getCurrentPageIndex();
                this.page_view.getComponent(cc.PageView).scrollToPage(index + 1, 0.1);
            }, time);
        })
    }
    private nextPage() {
        this.createCrads();
        this.updateTop();
        this.resetAudio();
    }

    private async createCrads() {
        let list = Game.getIns().lists;
        for (let index = 0; index < list.length; index++) {
            let question = list[index]
            const group = cc.instantiate(this.layout_pic);
            let pic = cc.find("pic", group);
            await pg.view.setNetImg(pic, question.pic_url, { w: 943, h: 1024 }, true);
            if (this.isDestroy) {
                return;
            }
            cc.find("pic2", group).active = false;
            // 等首图加载完成后 隐藏加载进度条
            if (index == 0) {
                this.hideMiddleLayerLoading();
            }
            group.active = true;
            if (this.page_view) {
                this.page_view.getComponent(cc.PageView).addPage(group);
            }
        }

    }
    private hideMiddleLayerLoading() {
        // 图片资源加载完成后隐藏加载条
        if (window && window["air"]) {
            window["air"].hideAirClassLoading();
        }
    }

    private autoPlay;
    private updateTop() {
        let data: Item = Game.getIns().getDataByPage(this.page);
        this.round.getComponent(cc.Label).string = `${data.page + 1}/${Game.getIns().len}`
        // cc.find("hand_ske", this.node).active = data.page == 0 && this.autoPlay == 0;
        let bg_excellent = cc.find("top/bg_excellent-small", this.node);
        let bg_tryagain = cc.find("top/bg_tryagain-small", this.node);
        let bg_good = cc.find("top/bg_good-small", this.node);


        bg_excellent.active = data.recordScore > 80;
        bg_good.active = data.recordScore >= 50 && data.recordScore <= 80;
        bg_tryagain.active = data.recordScore >= 0 && data.recordScore < 50;
        // this.btn_off.active = this.autoPlay == 0;
        // this.btn_on.active = this.autoPlay == 1;
        this.btn_record.active = true;
        this.btn_noplay.active = !data.recordAudio;
        this.btn_play.active = data.recordAudio;
        this.btn_left.active = this.page > 0 && this.autoPlay == 0;
        this.btn_right.active = this.page >= 0 && this.page < Game.getIns().len - 1 && this.autoPlay == 0;
    }

    private showRecordEnd(res) {
        this.layout_loading.active = false;
        this.recordEndView.active = true;
        asyncDelay(2).then(() => {
            if (this.isDestroy) {
                return;
            }
            this.onHideEnd();
        });
        let overall = res.result.overall;
        Game.getIns().getDataByPage(this.page).recordScore = overall;
        let bg_excellent = cc.find("bg_excellent", this.recordEndView);
        let bg_good = cc.find("bg_good", this.recordEndView);
        let bg_tryagain = cc.find("bg_tryagain", this.recordEndView);
        bg_excellent.active = overall > 80;
        bg_good.active = overall >= 50 && overall <= 80;
        bg_tryagain.active = overall < 50;
        if (overall > 80) {
            this.playLocalAudio("excellent");
            // bg_excellent.getComponent(dragonBones.ArmatureDisplay).playAnimation("newAnimation", 1);
        }
        if (overall >= 50 && overall <= 80) {
            this.playLocalAudio("good");
            // bg_good.getComponent(dragonBones.ArmatureDisplay).playAnimation("newAnimation", 1);
        }
        if (overall < 50) {
            this.playLocalAudio("tryagain");
            // bg_tryagain.getComponent(dragonBones.ArmatureDisplay).playAnimation("newAnimation", 1);
        }
        this.updateTop();
    }
    private recordStop() {
        this.layout_loading.active = true;

        if (window['courseware']) {
            window['courseware'].stopTest((res) => {
                this.isRecording = false;
                res = JSON.parse(res);

                let list = Game.getIns().lists
                if (res && res.audioUrl) {
                    list[this.page].recordAudio = res.audioUrl;
                    list[this.page].recordScore = res.overall;
                    // this.resetRecord();
                }
                this.showRecordEnd(res);
                for (let i = 0; i < list.length; i++) {
                    if (!list[i].recordAudio || list[i].recordAudio == "") return;
                }

                let send: any = {};
                send.details = list;
                onHomeworkFinish(send);
            });
        } else {

            let res = { "audioUrl": "https://staging-teach.cdn.ireadabc.com/bea0ba87bcf8bc09815f34b4790ffac9.mp3", "eof": 1, "file": "/storage/emulated/0/Android/data/com.example.oxford/cache/shengtong/gradeVoice.mp3", "result": { "duration": "2.670", "fluency": 86, "integrity": 50, "kernel_version": "3.7.1", "overall": 28, "pronunciation": 28, "resource_version": "2.3.11", "rhythm": 28, "sentences": [{ "beginIndex": 0, "details": [{ "charType": 0, "end": 0, "overall": 56, "prominence": 0, "start": 0, "word": "Good" }, { "charType": 0, "end": 0, "overall": 0, "prominence": 0, "start": 0, "word": "morning" }], "end": 0, "endIndex": 0, "overall": 28, "sentence": "Good morning", "start": 0 }], "speed": 28 }, "tokenId": "62d7a2343327934258000009" }

            let list = Game.getIns().lists
            // 模拟测试
            list[this.page].recordAudio = 'http://staging-teach.cdn.ireadabc.com/92ddbc65e9af775f7a8450a5bef1a732.mp3';
            this.showRecordEnd(res);
        }
    }

    private showTip(str) {
        const mdler = global["middleLayer"];
        if (mdler) {
            mdler.showTips(str);
        } else {
            console.log("tips===", str);
        }
    }
    playLocalAudio(audioName, volume = 1) {
        const audio = cc.find(`Canvas/res/audio/${audioName}`).getComponent(cc.AudioSource);
        cc.audioEngine.setEffectsVolume(volume);
        return new Promise((resolve, reject) => {
            const id = cc.audioEngine.playEffect(audio.clip, false);
            cc.audioEngine.setFinishCallback(id, () => {
                resolve(id);
            });
        })
    }

    log (str) {
        const node = cc.find('middleLayer');
        // if(node){
        //     node.getComponent('middleLayer').log(str);
        // }else{
            console.log(str);
        // }
    }
    
}
