import { asyncDelay, onHomeworkFinish } from "../script/util";
import { MyCocosSceneComponent } from "../script/MyCocosSceneComponent";
import pg from "./pg";
import Game from "./Game";

const { ccclass, property } = cc._decorator;

@ccclass
export default class SceneComponent extends MyCocosSceneComponent {

    private upArr: Array<any>;
    private downArr: Array<any>;
    private _colors: Array<string> = [];
    private _drawIndex: number = 0;
    private ani_flower;
    private rightClip;
    private wrongClip;
    private roundIdx: number = 0;
    private questIdx: number = 0;


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

    }

    onLoadEnd() {
        // TODO 加载完成后的逻辑写在这里, 下面的代码仅供参考
        this.initData();
        this.initView();
        this.initListener();
        pg.event.emit("mouse_start_play", { voice: Game.getIns().aniEnter.audioUrl, time: Game.getIns().aniEnter.time });
    }

    _cantouch = null;
    initData() {
        // 所有全局变量 默认都是null 
        Game.getIns().aniEnter = this.data.aniEnter;
        this._cantouch = true;
        this._colors = ["#4ab222", "#e6223f", "#5f63e8", "#f28c20", "#dc43ff", "#f851bc", "#00aec9", "#a766ec"];
    }
    initView() {

        this.ani_flower = cc.find("particle_star", this.node);
        this.rightClip = cc.find('Canvas/res/audio/right').getComponent(cc.AudioSource).clip;
        this.wrongClip = cc.find('Canvas/res/audio/wrong').getComponent(cc.AudioSource).clip;
        pg.event.emit("mouse_num", this.data.item.length);
        this.updateRound();
        this.showGame();



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

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

    pic1 = null;
    pic2 = null;
    initPic() {
        const canvas = cc.find('Canvas');
        const maxW = canvas.width * 0.7;

        this.getSprNodeByUrl(this.data.pic_url, (sprNode) => {
            const picNode1 = sprNode;
            picNode1.scale = maxW / picNode1.width;
            picNode1.baseX = picNode1.x;
            canvas.addChild(picNode1);
            this.pic1 = picNode1;

            const labelNode = new cc.Node();
            labelNode.color = cc.Color.YELLOW;
            const label = labelNode.addComponent(cc.Label);
            label.string = this.data.text;
            label.fontSize = 60;
            label.lineHeight = 60;
            label.font = cc.find('Canvas/res/font/BRLNSDB').getComponent('cc.Label').font;
            picNode1.addChild(labelNode);
        });

        this.getSprNodeByUrl(this.data.pic_url_2, (sprNode) => {
            const picNode2 = sprNode;
            picNode2.scale = maxW / picNode2.width;
            canvas.addChild(picNode2);
            picNode2.x = canvas.width;
            picNode2.baseX = picNode2.x;
            this.pic2 = picNode2;

            const labelNode = new cc.Node();
            const label = labelNode.addComponent(cc.RichText);
            const size = 60
            label.font = cc.find('Canvas/res/font/BRLNSDB').getComponent(cc.Label).font;
            label.string = `<outline color=#751e00 width=4><size=${size}><color=#ffffff>${this.data.text}</color></size></outline>`
            label.lineHeight = size;
            picNode2.addChild(labelNode);
        });

    }

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

    curPage = null;
    initBtn() {

        this.curPage = 0;
        const bottomPart = cc.find('Canvas/bottomPart');
        bottomPart.zIndex = 5; // 提高层级

        bottomPart.x = bottomPart.parent.width / 2;
        bottomPart.y = -bottomPart.parent.height / 2;

        const leftBtnNode = bottomPart.getChildByName('btn_left');
        //节点中添加了button组件 则可以添加click事件监听
        leftBtnNode.on('click', () => {
            if (!this._cantouch) {
                return;
            }
            if (this.curPage == 0) {
                return;
            }
            this.curPage = 0
            this.leftMove();

            this.playLocalAudio('btn');
        })

        const rightBtnNode = bottomPart.getChildByName('btn_right');
        //节点中添加了button组件 则可以添加click事件监听
        rightBtnNode.on('click', () => {
            if (!this._cantouch) {
                return;
            }
            if (this.curPage == 1) {
                return;
            }

            this.curPage = 1
            this.rightMove();

            // 游戏结束时需要调用这个方法通知系统作业完成
            onHomeworkFinish();

            this.playLocalAudio('btn');
        })
    }

    leftMove() {
        this._cantouch = false;
        const len = this.pic1.parent.width;
        cc.tween(this.pic1)
            .to(1, { x: this.pic1.baseX }, { easing: 'cubicInOut' })
            .start();

        cc.tween(this.pic2)
            .to(1, { x: this.pic2.baseX }, { easing: 'cubicInOut' })
            .call(() => {
                this._cantouch = true;
            })
            .start();
    }

    rightMove() {
        this._cantouch = false;
        const len = this.pic1.parent.width;
        cc.tween(this.pic1)
            .to(1, { x: this.pic1.baseX - len }, { easing: 'cubicInOut' })
            .start();

        cc.tween(this.pic2)
            .to(1, { x: this.pic2.baseX - len }, { easing: 'cubicInOut' })
            .call(() => {
                this._cantouch = true;
            })
            .start();
    }
    // update (dt) {},


    initListener() {

    }

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



    private rotateShake(item, rate = 1) {

        const time = 0.9;
        cc.tween(item)
            .to(time / 6 / 2, { angle: -20 * rate }, { easing: 'sineInOut' })
            .to(time / 6, { angle: 12 * rate }, { easing: 'sineInOut' })
            .to(time / 6, { angle: -7 * rate }, { easing: 'sineInOut' })
            .to(time / 6, { angle: 4 * rate }, { easing: 'sineInOut' })
            .to(time / 6, { angle: -2 * rate }, { easing: 'sineInOut' })
            .to(time / 6, { angle: 1 * rate }, { easing: 'sineInOut' })
            .to(time / 6, { angle: 0 * rate }, { easing: 'sineInOut' })
            .start();

    }


    private randomData() {
        this.upArr = [];
        this.downArr = [];
        let dt = this.data.item[this.roundIdx];
        if (!dt) return;
        let data = dt.group;
        data.forEach((dt, idx) => {
            if (dt.up) {
                dt.up.id = idx;
                this.upArr.push(dt.up);
            }
            if (dt.down) {
                dt.down.id = idx;
                this.downArr.push(dt.down);
            }
        });
        this.downArr.sort(() => Math.random() - 0.5);
    }

    private updateRound() {
        let label_round = cc.find("bg/page/lable", this.node);
        let round = this.roundIdx + 1;
        if (round > this.data.item.length) round = this.data.item.length;
        label_round.getComponent(cc.Label).string = round + "/" + this.data.item.length;
    }

    private showGame() {
        if (this.roundIdx >= this.data.item.length) {
            this.gameOver();
            return;
        }

        this.randomData();

        this.showQuestion();
        this.showLayout();
    }
    private checkisPicOrText() {
        if (this.upArr.length == 5) return false;
        let t1 = this.upArr[0].type == 1;
        let t2 = this.downArr[0].type == 1;
        return t1 && t2;
    }
    private showLayout() {
        let data = this.data.item.group;
        let lift = cc.find("lift", this.node);
        let right = cc.find("right", this.node);
        lift.removeAllChildren();
        right.removeAllChildren();
        let isSpY = this.checkisPicOrText();
        right.getComponent(cc.Layout).spacingY = isSpY ? this.upArr.length == 3 ? 60 : 30 : 10;
        lift.getComponent(cc.Layout).spacingY = isSpY ? this.upArr.length == 3 ? 60 : 30 : 10;
        right.getComponent(cc.Layout).paddingTop = isSpY ? this.upArr.length == 3 ? 30 : 10 : 0;
        lift.getComponent(cc.Layout).paddingTop = isSpY ? this.upArr.length == 3 ? 30 : 10 : 0;

        this.upArr.forEach((item) => {
            if (item.type == 1) {
                let textItem = this.getItemNode(1, isSpY);
                let size = this.getHeadSize(1);
                this.initTextItem(textItem, item, 1);
                textItem.parent = lift;
            } else if (item.type == 0) {
                let textItem = this.getItemNode(1);
                let size = this.getHeadSize(1);
                this.initPicItem(textItem, item, size);
                textItem.parent = lift;
            }
        });

        this.downArr.forEach((item) => {
            if (item.type == 1) {
                let textItem = this.getItemNode(2, isSpY);
                let size = this.getHeadSize(2);
                this.initTextItem(textItem, item);
                textItem.parent = right;
            } else if (item.type == 0) {
                let textItem = this.getItemNode(2);
                let size = this.getHeadSize(2);
                this.initPicItem(textItem, item, size);
                textItem.parent = right;
            }
        });
        setTimeout(() => {
            this.updateItemWidth(lift);
            this.updateItemWidth(right);
        }, 60);
    }

    private showQuestion() {
        // if (this._questionIdx >= data.questionArr.length) {
        // 	this._questionIdx = 0;
        // 	this._roundIdx++;
        // 	this.showGame();
        // 	// this.updataMouse();
        // 	return;
        // }
        let quest = this.data.item[this.roundIdx];
        // this.showCheckGroup(quest);

        let question = cc.find("question", this.node);
        let img_laba02 = question.getChildByName("img_close");
        let desc = question.getChildByName("desc");
        let head = question.getChildByName("head");

        // if (quest.type == "text") {
        head.active = false;
        desc.active = true;
        desc.getComponent(cc.Label).string = quest.title;
        // } else if (quest.questionType == "pic") {
        //     desc.active = false;
        //     head.active = true;
        //     pg.view.setNetImg(head, quest.pic_url, { w: 550, h: 95 });
        // }
        img_laba02.opacity = quest.audio_title ? 255 : 0;
        if (quest.audio_title) {
            this.playLaba(img_laba02, question);
            cc.assetManager.loadRemote(quest.audio_title, (err, audioClip) => {
                question.audioClip = audioClip;
            });
        }
    }

    private initTextItem(item, data, type = 2) {
        item.data = data;
        let img_laba02 = item.getChildByName("img_close");
        let desc = item.getChildByName("desc");
        desc.getComponent(cc.Label).string = data.text;
        setTimeout(() => {
            if (desc.width - item.width > -15 && item.name != "type4") {
                item.width = desc.width + 60;
                img_laba02.opacity = data.audio_url ? 255 : 0;
            }
        }, 30);
        item.on(cc.Node.EventType.TOUCH_END, () => {
            setTimeout(() => {
                this.checkLing();
                this.showAniFlower(item);
            }, 60);
        })
        if (data.audio_url) {
            this.playLaba(img_laba02, item);
            cc.assetManager.loadRemote(data.audio_url, (err, audioClip) => {
                item.audioClip = audioClip;
            });
        }
        item.x = 0;
        item.opacity = 0.1;
    }

    private initPicItem(item, data, size) {
        item.data = data;
        let img_laba02 = item.getChildByName("img_close");
        let desc = item.getChildByName("desc");
        let head = item.getChildByName("head");
        pg.view.setNetImg(head, data.pic_url, size);

        // if (desc) desc.getComponent(cc.Label).string = data.text;

        item.on(cc.Node.EventType.TOUCH_END, () => {
            setTimeout(() => {
                this.checkLing();
                this.showAniFlower(item);
            }, 60);
        })
        img_laba02.opacity = data.audio_url ? 255 : 0;
        if (data.audio_url) {
            this.playLaba(img_laba02, item);
            cc.assetManager.loadRemote(data.audio_url, (err, audioClip) => {
                item.audioClip = audioClip;
            });
        }
        item.x = 0;
        item.opacity = 0.1;
    }

    private checkLing() {
        let liftLayout = cc.find("lift", this.node);
        let rightLayout = cc.find("right", this.node);
        let lift = null;
        let right = null;
        let liftIdx = -1;
        let rightIdx = -1;
        liftLayout.children.forEach((ch, idx) => {
            let circle_right = ch.getChildByName("circle_right");
            let t = ch.getComponent(cc.Toggle);
            if (t.isChecked) {
                liftIdx = idx;
                lift = ch;
                if (circle_right) circle_right.opacity = 255;
            } else {
                if (circle_right) circle_right.opacity = 0;
            }
        });
        rightLayout.children.forEach((ch, idx) => {
            let circle_lift = ch.getChildByName("circle_lift");
            let t = ch.getComponent(cc.Toggle);
            if (t.isChecked) {
                right = ch;
                rightIdx = idx;
                if (circle_lift) circle_lift.opacity = 255;
            } else {
                if (circle_lift) circle_lift.opacity = 0;
            }
        });
        if (!lift || !right) return;

        if (lift.data.id == right.data.id) {
            console.log("匹配成功！···")
            lift.getComponent(cc.Toggle).interactable = false;
            right.getComponent(cc.Toggle).interactable = false;
            this.drawLine(lift, right);
        } else {
            pg.audio.playAudio(this.wrongClip, () => {
            });
            this.rotateShake(lift, 0.5);
            this.rotateShake(right, 0.5);
            this.resetLayout();
        }

    }
    private resetLayout() {
        let liftLayout = cc.find("lift", this.node);
        let rightLayout = cc.find("right", this.node);
        liftLayout.children.forEach((ch) => {
            let t = ch.getComponent(cc.Toggle);
            t.isChecked = false;
            let circle_right = ch.getChildByName("circle_right");
            if (circle_right) circle_right.opacity = 0;
        });
        rightLayout.children.forEach((ch) => {
            let t = ch.getComponent(cc.Toggle);
            t.isChecked = false;
            let circle_lift = ch.getChildByName("circle_lift");
            if (circle_lift) circle_lift.opacity = 0;
        });
    }
    private showAniFlower(target) {
        if (!target.getComponent(cc.Toggle).interactable) return;
        let pos = target.convertToWorldSpaceAR(cc.Vec2.ZERO);
        let pos2 = this.node.convertToNodeSpaceAR(pos);
        let ani_flower = cc.instantiate(this.ani_flower);
        this.node.addChild(ani_flower);
        ani_flower.x = pos2.x;
        ani_flower.y = pos2.y;
        ani_flower.active = true;

        cc.audioEngine.playEffect(this.rightClip, false);
        setTimeout(() => {
            ani_flower && (ani_flower.parent = null);
        }, 3000);
    }
    private playLaba(btn, item) {
        let img_laba01 = item.getChildByName("img_open");
        btn.on(cc.Node.EventType.TOUCH_END, () => {
            if (item.audioClip) {
                img_laba01.opacity = 255;
                pg.audio.playAudio(item.audioClip, () => {
                    // cc.audioEngine.stopAllEffects();
                    img_laba01.opacity = 0;
                    // anim.stop();
                });
            }
        }, this)
    }



    private drawLine(lift, right) {
        let pos1 = null;
        let pos2 = null;

        let circle_right = lift.getChildByName("circle_right");

        let circle_lift = right.getChildByName("circle_lift");
        pos1 = circle_right.convertToWorldSpaceAR(cc.v2(- 10, 0));
        pos2 = circle_lift.convertToWorldSpaceAR(cc.v2(10, 0));


        let graphics = cc.find("graphics", this.node).getComponent(cc.Graphics);


        let color = this._colors[this._drawIndex];
        graphics.strokeColor = new cc.Color().fromHEX(color);
        // let line = [point1, point2, color];
        // this.lined.push(line);

        let deltaY = pos1.y - pos2.y;
        let drawX = pos1.x + 1;
        let drawY = pos1.y + 1;
        this.schedule(
            () => {
                // graphics.moveTo(drawX, drawY);
                // drawY = drawY - deltaY / 30;
                // let a = ((drawY - pos2.y) * (pos1.x - pos2.x));
                // let b = (pos1.y - pos2.y) + pos2.x;
                // drawX = Math.abs(a / b);
                // drawX = drawX - deltaY / 30;
                // drawY = ((drawY - pos2.y) * (pos1.x + pos2.x)) / (pos1.y - pos2.y) + pos2.y;

                // graphics.lineTo(drawX, drawY);
                graphics.moveTo(pos1.x, pos1.y);
                graphics.lineTo(pos2.x, pos2.y);
                graphics.stroke();
            },
            0.3 / 30,
            30
        );
        this.scheduleOnce(() => {
            this.resetLayout();
        }, 0.15);
        this._drawIndex++;
        if (this._drawIndex >= this.data.item[this.roundIdx].group.length) {
            this.scheduleOnce(() => {
                this._drawIndex = 0;
                graphics.clear();
                this.roundIdx++;
                this.showGame();
                this.updateRound();
                pg.event.emit("mouse_add");
            }, 1);
        }
    }
    private gameOver() {
        setTimeout(() => {
            let mouse_end = pg.view.find(this, "mouse_end");
            mouse_end.active = true;
            mouse_end.getComponent("mouse_end").play().then(() => {
                onHomeworkFinish();
            })
        }, 1800);
    }
    private updateItemWidth(layout: cc.Node) {
        let width = 0;
        layout.children.forEach((ch) => {
            if (ch.width > width) width = ch.width;
        });
        layout.children.forEach((ch) => {
            ch.width = width;
            ch.opacity = 255;
        });
    }

    private getItemNode(type, isSpY = false) {
        let item;
        if (this.upArr.length == 5) {
            if (type == 1) {
                item = cc.instantiate(cc.find("items/type1", this.node));
            } else {
                item = cc.instantiate(cc.find("items/type4", this.node));
            }
        } else if (this.upArr.length == 4) {
            if (type == 1) {
                if (isSpY) item = cc.instantiate(cc.find("items/type1", this.node));
                else item = cc.instantiate(cc.find("items/type5", this.node));
            } else {
                if (isSpY) item = cc.instantiate(cc.find("items/type1", this.node));
                else item = cc.instantiate(cc.find("items/type5", this.node));
            }
        } else if (this.upArr.length == 3) {
            if (type == 1) {
                if (isSpY) item = cc.instantiate(cc.find("items/type1", this.node));
                else item = cc.instantiate(cc.find("items/type6", this.node));
            } else {
                if (isSpY) item = cc.instantiate(cc.find("items/type1", this.node));
                else item = cc.instantiate(cc.find("items/type6", this.node));
            }
        }
        return item;
    }
    private getHeadSize(type) {
        let size = {};
        if (this.upArr.length == 5) {
            if (type == 1) {
                size = { w: 50, h: 50 }
            } else {
                size = { w: 400, h: 60 }
            }
        } else if (this.upArr.length == 4) {
            if (type == 1) {
                size = { w: 90, h: 90 }
            } else {
                size = { w: 255, h: 80 }
            }
        } else if (this.upArr.length == 3) {
            if (type == 1) {
                size = { w: 120, h: 115 }
            } else {
                size = { w: 255, h: 120 }
            }
        }
        return size;
    }







}
