import { asyncDelay, callMiddleLayerFunction, onHomeworkFinish, playAudio } from "../script/util";
import { MyCocosSceneComponent } from "../script/MyCocosSceneComponent";

const { ccclass, property } = cc._decorator;

@ccclass
export default class SceneComponent extends MyCocosSceneComponent {

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

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

    addPreloadAnima() {

        console.log('this.data: ', this.data);
        this._animaResList.push({ url: this.data.skeJsonData.url || '' });
        this._animaResList.push({ url: this.data.texJsonData.url || ''});
        this._animaResList.push({ url: this.data.texPngData.url || ''});
    }

    onLoadEnd() {
        // TODO 加载完成后的逻辑写在这里, 下面的代码仅供参考

        this.initData();

        let isDataLoaded = false;
        let isAnimLoaded = false;
        const checkStart = () => {
            
            console.log( ' in checkStart: ', isDataLoaded)
            console.log( ' in isAnimLoaded: ', isAnimLoaded)
            if (isDataLoaded && isAnimLoaded) {
                    
                window["air"].hideAirClassLoading();
                this.initView();
            }
        } 

      
        this.getState(() => {
            isDataLoaded = true;
            checkStart();
        })

        this.setOneAnima(this.data, () => {
            isAnimLoaded = true;
            checkStart();
        });

    }

    isFirst;
    isLast;
    playTimes;
    jumpData;
    getState(cb) {


        // this.isFirst = this.checkIsFirst();
        // this.isLast = this.checkIsLast();
        // this.playTimes =  this.checkPlayTimes();
        // this.jumpData =  this.getJumpData();

        // cb && cb();
        // return;
        callMiddleLayerFunction('PSQS_get_course_info', {}, (data) => {

            this.isFirst = data.first; //this.checkIsFirst();
            this.isLast = data.last // this.checkIsLast();
            this.playTimes = data.playTime // this.checkPlayTimes();
            this.jumpData = data.saveData // this.getJumpData();

            cb && cb();
        })

    }

    checkIsFirst() {
        return true;
    }

    checkIsLast() {
        return true;
    }

    checkPlayTimes() {
        return 0;
    }

    getJumpData() {
        return //{step: 2};
    }


    _cantouch = null;
    canvas;
    initData() {
        // 所有全局变量 默认都是null 
        this._cantouch = true;
        this.canvas = cc.find("Canvas");


        this.initLocalAudio();
        this.initLyrics();
    }

    textArr;
    textArrIndex;
    initLyrics() {
        this.textArr = [];
        this.textArrIndex = 0;

        const lyrics = this.data?.lrcData?.lyrics;
        if (!lyrics) {
            return;
        }

        for (let i=0; i<lyrics.length; i++) {

            const data = lyrics[i].data;
            if (!data) {
                continue;
            }

            const time = lyrics[i].time;

            let duration = 0;
            if (i != lyrics.length - 1) {
                duration = lyrics[i+1].time - lyrics[i].time;
            }

            this.textArr.push({data, time, duration});
        }
    }

    readyClip;
    goClip;
    goodjobClip;
    initLocalAudio() {

        const getLocalAudio = (name) => {
            const audioNode = cc.find("Canvas/res/audio/" + name);
            return audioNode.getComponent(cc.AudioSource).clip;
        }

        this.readyClip = getLocalAudio('ready');
        this.goClip = getLocalAudio('go');
        this.goodjobClip = getLocalAudio('goodjob');
    }

    initView() {

        console.log( ' in initView')

        if (this.jumpData) {
            this.junpAnim();
            return;
        }


        if (this.isFirst) {
            this.initStartView();
            return;
        }

        this.startAnim();


        return;
 
    }


    junpAnim() {
        const jumpFrame = this.getJumpFrame();
        this.dragonDisplay.timeScale = jumpFrame;
        this.dragonDisplay.playAnimation(this.animaNode.animationNames[0], 1);
    }

    getJumpFrame() {

        const maxDisFrame = this.data.frame * 2;

        const arr = this.data.stepArr;
        if (arr.length <= 1) {
            return maxDisFrame;
        }

        let disFrame = maxDisFrame;
        for (let i=1; i<arr.length; i++) {

            const curDis = (arr[i].text - arr[i-1].text) / 2;
            if (disFrame > curDis) {
                disFrame = curDis;
            }
        }

        return disFrame;
    }

    initStartView() {

        this.showStartLight();
        if (this.playTimes > 0) {
            this.showStartTitleGo();
        } else {
            this.showStartTitleReady();
        }
    }
    

    lightBg;
    lightLeft;
    lightRight
    showStartLight() {

        const lightBg = this.getSprNode('black');
        lightBg.scaleX = this.canvas.width / lightBg.width;
        lightBg.scaleY = this.canvas.height / lightBg.height;
        lightBg.opacity = 180;
        this.canvas.addChild(lightBg, 10);
        

        const lightLeft = this.getSprNode('light');
        lightLeft.anchorY = 0.9;
        lightLeft.x = -this.canvas.width / 2;
        lightLeft.y = this.canvas.height / 2;
        lightLeft.scale = this._mapScaleMin;
        lightLeft.zIndex = 10;
        lightLeft.parent = this.canvas;
        lightLeft.rotation = 45;
        lightLeft.opacity = 0;
        cc.tween(lightLeft)
            .to(1, {rotation: -45}, {easing: "cubicOut"})
            .start();
        cc.tween(lightLeft)
            .to(0.5, {opacity: 255})
            .start();
        
        const lightRight = this.getSprNode('light');
        lightRight.anchorY = 0.9;
        lightRight.x = this.canvas.width / 2;
        lightRight.y = this.canvas.height / 2;
        lightRight.scale = this._mapScaleMin;
        lightRight.zIndex = 10;
        lightRight.parent = this.canvas;
        lightRight.rotation = -45;
        lightRight.opacity = 0;
        cc.tween(lightRight)
            .to(1, {rotation: 45}, {easing: "cubicOut"})
            .start();
        cc.tween(lightRight)
            .to(0.5, {opacity: 255})
            .start();


        this.lightBg = lightBg;
        this.lightLeft = lightLeft;
        this.lightRight = lightRight;
    }




    title;
    showStartTitleReady() {
        const title = this.getSprNode('start_title');
        title.scale = this._mapScaleMin;
        title.y = this.canvas.height / 2 + title.height * title.scaleY;
        title.parent = this.canvas;
        title.zIndex = 11;

        cc.tween(title)
            .delay(0.3)
            .call(() => {
                playAudio(this.readyClip, (() => {
                    this.startAudioEnd();
                }));
            })
            .to(1.5, {y: 0}, {easing: "elasticOut"})
            .start();

        this.title = title
    }


    async showStartTitleGo() {


        const title = new cc.Node();
        title.parent = this.canvas;
        title.zIndex = 11;
        title.scale = this._mapScaleMin;
        this.title = title


        playAudio(this.goClip, (() => {
            this.startAudioEnd();
        }));

        const popNum = (name, time = 1) => {
            const sprNode = this.getSprNode(name);
            title.addChild(sprNode);
            sprNode.scale = 0;

            cc.tween(sprNode)
                .to(0.5 * time, {scale: 1}, {easing: 'elasticOut'})
                .delay(0.4 * time)
                .to(0.1 * time, {opacity: 0})
                .start();
        }


        await asyncDelay(2);

        popNum('go_1');
        await asyncDelay(1);
        popNum('go_2');
        await asyncDelay(1);
        popNum('go_3', 0.8);
        await asyncDelay(0.8);
        popNum('go_0');
        await asyncDelay(1);

        // cc.tween(title)
        //     .delay(0.3)
        //     .call(() => {
        //         playAudio(this.readyClip, (() => {
        //             this.startAudioEnd();
        //         }));
        //     })
        //     .to(1.5, {y: 0}, {easing: "elasticOut"})
        //     .start();

    }

    startAudioEnd() {
        this.hideStartView();
    }

    async hideStartView() {
        const hideSpr = (sprNode, cb=null) => {
            cc.tween(sprNode)
                .to(0.3, {opacity: 0})
                .call(() => {
                    sprNode.active = false;
                    cb && cb();
                })
                .start();
        }

        hideSpr(this.lightLeft);
        hideSpr(this.lightRight);
        hideSpr(this.title);

        await asyncDelay(0.2)
        hideSpr(this.lightBg, () => {
            this.startAnim();
        });
    }

    audioId;
    startAnim() {

        this.dragonDisplay.playAnimation(this.animaNode.animationNames[0], 1);
        this.dragonDisplay.timeScale = 1;


        this.playAudioByUrl(this.data.lrcData.audio_url);

        cc.assetManager.loadRemote(this.data.lrcData.audio_url, (err, audioClip) => {
            this.audioId = cc.audioEngine.play(audioClip, false, 0.8);
        });
    }

    showHand(id) {

        const stepData = this.data.stepArr[Number(id) - 1];

        if (stepData['X'] == 0 && stepData['Y'] == 0) {
            console.log('stepData: ', stepData);
            callMiddleLayerFunction('PSQS_jump_to_question', {step: id}, null)
            return;
        }


        const handBase = cc.find("Canvas/hand");
        const hand = cc.instantiate(handBase);
        hand.parent = this.animaNode;
        hand.active = true;
        // hand.scale = this._mapScaleMin;
        hand.x = stepData['X'];
        hand.y = stepData['Y'];

        const dragonDisplay = hand.getComponent(dragonBones.ArmatureDisplay);
        dragonDisplay.playAnimation('normal', -1);


        const boxLen = 300;

        const clickBox = new cc.Node();
        clickBox.width = clickBox.height = boxLen;
        clickBox.parent = hand;
        // const ctx = clickBox.addComponent(cc.Graphics);
        // ctx.fillColor = cc.Color.RED.setA(100);
        // ctx.fillRect(-boxLen/2, -boxLen/2, boxLen, boxLen);
        // ctx.fill();

        clickBox.on('touchstart', () => {

            console.log('PSQS_show_rabbit 1');
            // callMiddleLayerFunction('PSQS_show_rabbit', null, () => {
                
                console.log('PSQS_show_rabbit 2')
                callMiddleLayerFunction('PSQS_jump_to_question', {step: id}, null)
            // })
        })
    }


    jumpAudio(id) {
        const stepData = this.data.stepArr[id-1];
        const time = stepData.text / this.data.frame;

        cc.assetManager.loadRemote(this.data.lrcData.audio_url, (err, audioClip) => {
            const audioId = cc.audioEngine.play(audioClip, false, 0.8);
            cc.audioEngine.setCurrentTime(audioId, time);
            this.audioId = audioId;
        });
        
    }

    continueAnim(id) {

        console.log(' in continueAnim')
     
        callMiddleLayerFunction('PSQS_hide_rabbit', null, () => {

            this.jumpAudio(id);
            this.dragonDisplay.timeScale = 1;
        });
    }

    animChangeStep(stepName) {

        console.log('stepName: ', stepName);
        const id = stepName.split('step')[1];

        if (this.jumpData) {
            console.log('this.jumpData: ', this.jumpData);
            if (id == this.jumpData.step) {
                this.continueAnim(id);
                this.jumpData = null;
            }
            return 
        }

        console.log('id: ', id);
        this.dragonDisplay.timeScale = 0;
        cc.audioEngine.pauseAllEffects();

        this.showHand(id);
    }


    showGoodjob() {
        const goodjob = cc.find("Canvas/goodjob");
        goodjob.zIndex = 15;
        goodjob.active = true;
        goodjob.scale = this._mapScaleMin;

        const dragonDisplay = goodjob.getComponent(dragonBones.ArmatureDisplay);
        dragonDisplay.playAnimation('normal', 1);

        playAudio(this.goodjobClip);

        dragonDisplay.on(dragonBones.EventObject.COMPLETE, (e) => {
            this.animPlayEnd();
        })
    }

    animPlayEnd() {

        console.log(' in animPlayEnd 1')
        // callMiddleLayerFunction('PSQS_show_rabbit', null, () => {

            console.log(' in animPlayEnd 2')
            callMiddleLayerFunction('PSQS_play_animate_over', this.animaNode, () => {})
        // })
        
    }


    dragonDisplay;
    animaNode;
	setOneAnima(data, cb) {


		const animaNode = new cc.Node();
		this.canvas.addChild(animaNode);


		const dragonDisplay = animaNode.addComponent(dragonBones.ArmatureDisplay);
		if (!data.texPngData) {
			return
		}
		const image = data.texPngData.url//"http://staging-teach.cdn.ireadabc.com/5a0c5af3e952acd0ac83a6e5c6f03ff1.png";
		const ske = data.skeJsonData.url//"http://staging-teach.cdn.ireadabc.com/bd825dcceea298d1146be8067ae3d17f.json";
		const atlas = data.texJsonData.url//"http://staging-teach.cdn.ireadabc.com/246f8991b729fa3e5a7f4802de828efa.json";
		cc.loader.load(image, (error, texture) => {

			cc.loader.load({url: atlas, type: 'txt'}, (error, atlasJson) => {

				cc.loader.load({url: ske, type: 'txt'}, (error, dragonBonesJson) => {

					const atlas = new dragonBones.DragonBonesAtlasAsset();
					atlas.atlasJson = atlasJson;
					atlas.texture = texture;

					const asset = new dragonBones.DragonBonesAsset();
					asset.dragonBonesJson = dragonBonesJson;

					dragonDisplay.dragonAtlasAsset = atlas;
					dragonDisplay.dragonAsset = asset;

					let json = JSON.parse(asset.dragonBonesJson);
					let armatures = json["armature"];
					console.log('armatures: ', armatures);
					let armatureNames = [];
					for (let i = 0; i < armatures.length; i++) {
						armatureNames.push(armatures[i].name);
					}
					// console.log('armatureNames: ', armatureNames);
					if (armatureNames.length > 0) {
						let defaultArmatureName = armatureNames[0];
						dragonDisplay.armatureName = defaultArmatureName;
						// let animationNames = dragonDisplay.getAnimationNames(defaultArmatureName);
						let defaultArmature = armatures[0];
						let animations = defaultArmature.animation;
						let animationNames = [];
						for (let i = 0; i < animations.length; i++) {
							animationNames.push(animations[i].name);
						}

                        animaNode['animationNames'] = animationNames;
					}

                    animaNode.scale = this._mapScaleMin;

                    // dragonDisplay.timeScale = 50;

                    dragonDisplay.playAnimation(animaNode['animationNames'][0], 1);
                    dragonDisplay.timeScale = 0;

                    dragonDisplay.on(dragonBones.EventObject.FRAME_EVENT, (e) => {
                        if (this.playTimes > 0) {
                            this.animChangeStep(e['name']);
                        }
                    })
                    dragonDisplay.on(dragonBones.EventObject.COMPLETE, (e) => {
                        if (this.isLast && this.playTimes > 0) {
                            this.showGoodjob();
                        } else {
                            this.animPlayEnd();
                        }
                    })
                  
                    animaNode.on('touchstart', (e) => {

                        const pos = e.getLocation();
                        const x = pos.x// - e.currentTarget.width / 2;
                        const y = pos.y// - e.currentTarget.height / 2;

                        const newPos = animaNode.convertToNodeSpaceAR(cc.v2(x, y));
                        console.log('X: ', Math.round( newPos.x ));
                        console.log('Y: ', Math.round( newPos.y ));
                    })

                    this.dragonDisplay = dragonDisplay;
                    this.animaNode = animaNode;

                    cb && cb();
                    console.log("animaNode: ", animaNode);

				});
			});
		});

	}

    curTextObj;
    checkShowText() {
        if (this.audioId == null) {
            return;
        }

        if (!this.curTextObj) {
            this.curTextObj = this.getCurTextObj();
        }

        if (!this.curTextObj) {
            return;
        }

        const currentTime = cc.audioEngine.getCurrentTime(this.audioId);
        const startTime = this.curTextObj.time;

        if (currentTime >= startTime) {
            this.showText(this.curTextObj, currentTime);
        }


    }

    getCurTextObj() {
        const data = this.textArr[this.textArrIndex];
        if (data) {
            this.textArrIndex ++;
        }
        return data;
    }

    textLabel;
    showText(textObj, currentTime) {
        if (textObj.isShow) {
            return;
        }
        textObj.isShow = true;

        if (currentTime > Number(textObj.time) + Number(textObj.duration)) {
            this.curTextObj = null;
            return;
        }

        console.log('textObj: ', textObj);


        if (!this.textLabel) {
            this.textLabel = this.getTextLabel();
        }

        if (this.textLabel.curTween) {
            this.textLabel.curTween.stop();
        }

        
        this.textLabel.string = `<outline color=white width=4>${textObj.data}</outline>`

        if (textObj.duration ) {
            this.textLabel.curTween = cc.tween(this.textLabel.node)
            .to(0.1, {opacity: 0})
            .to(0.2, {opacity: 255}, {easing: 'sineOut'})
            .delay(textObj.duration - 0.4)
            .call(() => {
                this.curTextObj = null;
            })
            .to(0.1, {opacity: 0})
            .start();
        } else {
            this.textLabel.curTween = cc.tween(this.textLabel.node)
            .to(0.1, {opacity: 0})
            .to(0.2, {opacity: 255}, {easing: 'sineOut'})
            .start();
        }
      
    }

    getTextLabel() {
        const richTextNode = new cc.Node();
        richTextNode.y = -this.canvas.height / 2 + 20 * this._mapScaleMin ;
        richTextNode.opacity = 0;
        richTextNode.anchorY = 0;
        richTextNode.scale = this._mapScaleMin;

        richTextNode.color = cc.Color.BLACK;
        const richText = richTextNode.addComponent(cc.RichText);
        const font = this.getFont('Muli_1GDlj');
        richText.font = font;
        richText.fontSize = 50;
        richText.lineHeight = 60;
        richText.maxWidth = this.canvas.width * 0.9;
        richText.horizontalAlign = cc.macro.TextAlignment.CENTER;


        this.canvas.addChild(richTextNode, 14);
        return richText
    }

    getFont(name) {

        const fontNode = cc.find("Canvas/res/font/" + name);
        const font = fontNode.getComponent(cc.Label).font;
        return font
    }







    update (dt) {
        this.checkShowText();
    }


    initListener() {

    }

}
