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

enum touchState {
    NORMAL,
    SELECT,
    FINISH
}


const { ccclass, property } = cc._decorator;

@ccclass
export default class SceneComponent extends MyCocosSceneComponent {
    @property(cc.Node)
    item2_left: cc.Node = null;
    @property(cc.Node)
    item2_right: cc.Node = null;
    @property(cc.Node)
    item3_pic: cc.Node = null;
    @property(cc.Node)
    item3_text: cc.Node = null;
    @property(cc.Node)
    item4_text: cc.Node = null;
    @property(cc.Node)
    item4_pic: cc.Node = null;
    @property(cc.Node)
    item5_pic: cc.Node = null;
    @property(cc.Node)
    item5_left: cc.Node = null;
    @property(cc.Node)
    item5_right: cc.Node = null;

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

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

    private _colors: Array<string> = [];
    private upArr: Array<any>;
    private downArr: Array<any>;
    private _drawIndex: number = 0;
    private roundIdx: number = 0;
    private logs: Array<any>;
    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();
    }

    _cantouch = null;
    initData() {
        // 所有全局变量 默认都是null 
        this.logs = [];
        this._cantouch = true;
        Game.getIns().init(this.data);
        // this._colors = ["#f87b8e", "#fdb652", "#4acfe0", "#30ff6d", "#848cff"];
    }


    // update (dt) {},

    initView() {
        let topTitle = cc.find("top/topTitle", this.node);
        pg.view.touchOn(topTitle, this.playTopLaba, this);
        // let btn_check = cc.find("btn_check", this.node);
        // pg.view.touchOn(btn_check, this.touchOver, this);
        this.showQuestion();
        this.showGame();
    }
    private touchOver() {
        this.playLocalAudio("finish");
        let data: any = {};
        let questions = this.logs.concat();
        let score = 0;
        questions.forEach(q => {
            score += q.score;
        })
        data.questions = questions;
        data.score = score;
        console.log(data);
        onHomeworkFinish(data);
    }
    private gameOver() {
        setTimeout(() => {
            let btn_check = cc.find("btn_check", this.node);
            btn_check.getComponent(cc.Button).interactable = true;
            this.playLocalAudio("sahua");

            // const bg = cc.find('Canvas/group_item', this.node);
            this.showAllFirework(this.node, cc.find('Canvas/petal').children);
            // let mouse_end = pg.view.find(this, "mouse_end");
            // mouse_end.active = true;
            // mouse_end.getComponent("mrbr04_mouse_end").play().then(() => {
            //结算

            // })
        }, 1);
    }
    private showGame() {
        if (this.roundIdx >= this.data.questions.length) {
            this.gameOver();
            return;
        }

        this.randomData();

        this.showLayout();
    }
    private showQuestion() {
        let quest = this.data.top;
        let desc = cc.find("top/topTitle/title", this.node);
        let img = cc.find("top/boy", this.node);
        desc.active = true;
        desc.getComponent(cc.Label).string = quest.text;
        if (quest.audio) {
            this.playTopLaba()
        }
        pg.view.setNetImg(img, quest.image, { w: 70, h: 70 });
    }
    private intervalId;
    private playTopLaba() {
        let btn_laba = cc.find("top/topTitle/laba", this.node);
        let btn_kaba2 = btn_laba.getChildByName("laba_1");
        let btn_kaba3 = btn_laba.getChildByName("laba_2");
        btn_kaba2.active = true;
        btn_kaba3.active = true;
        cc.audioEngine.stopAllEffects();
        let count = 0;
        if (this.intervalId) clearInterval(this.intervalId);
        let stop = false;
        this.intervalId = setInterval(() => {
            count++;
            // btn_kaba2.active = count % 2 == 1;
            btn_kaba3.active = count % 2 == 1;
            if (stop && count % 2 == 0) {
                btn_kaba2.active = false;
                clearInterval(this.intervalId);
            }
        }, 150)

        let quest = this.data.top;
        quest.audio && pg.audio.playAudioByUrl(quest.audio).then(() => { stop = true; })
    }

    private randomData() {
        this.upArr = [];
        this.downArr = [];
        let dt = this.data.questions[this.roundIdx];
        if (!dt) return;
        let data = dt.options;
        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);
            }
        });
        do {
            this.downArr.sort(() => Math.random() - 0.5);
        } while (this.downArr[0].id == this.upArr[0].id);
        this._colors = [].concat(["#f87b8e", "#fdb652", "#4acfe0", "#30ff6d", "#848cff"]);
        this._colors.sort(() => Math.random() - 0.5);
    }

    private getItemLeftNode(type) {
        let item;
        // let isText = this.upArr[0].type == 1;
        let isText = type == "txt";
        if (this.upArr.length == 5) {
            item = isText ? cc.instantiate(this.item5_right) : cc.instantiate(this.item5_pic);
        }
        else if (this.upArr.length == 4) {
            item = isText ? cc.instantiate(this.item4_text) : cc.instantiate(this.item4_pic);
        }
        else if (this.upArr.length == 3) {
            item = isText ? cc.instantiate(this.item3_text) : cc.instantiate(this.item3_pic);
        }
        else if (this.upArr.length == 2) {
            item = cc.instantiate(this.item2_left);
        }
        return item;
    }
    private getItemRightNode(type) {
        let item;
        let isText = type == "txt";
        // let isText = this.downArr[0].type == 1;
        if (this.upArr.length == 5) {
            item = isText ? cc.instantiate(this.item5_right) : cc.instantiate(this.item5_pic);
        }
        else if (this.upArr.length == 4) {
            item = isText ? cc.instantiate(this.item4_text) : cc.instantiate(this.item4_pic);
        }
        else if (this.upArr.length == 3) {
            item = isText ? cc.instantiate(this.item3_text) : cc.instantiate(this.item3_pic);
        }
        else if (this.upArr.length == 2) {
            item = cc.instantiate(this.item2_right);
        }
        return item;
    }
    private getlayoutSpacing() {
        if (this.upArr.length == 2) return { sY: 100, top: 100 };
        if (this.upArr.length == 3) return { sY: 0, top: 40 };
        if (this.upArr.length == 4) return { sY: 0, top: 40 };
        if (this.upArr.length == 5) return { sY: -9, top: 30 };
    }

    private showLayout() {
        let data = this.data.questions.options;
        this.layout_left.removeAllChildren();
        this.layout_right.removeAllChildren();
        let spacing = this.getlayoutSpacing();
        this.layout_right.getComponent(cc.Layout).spacingY = spacing.sY
        this.layout_left.getComponent(cc.Layout).spacingY = spacing.sY
        this.layout_right.getComponent(cc.Layout).paddingTop = spacing.top;
        this.layout_left.getComponent(cc.Layout).paddingTop = spacing.top;

        this.upArr.forEach((item) => {
            if (item.type == "txt") {
                let textItem = this.getItemLeftNode("txt");
                this.initTextItem(textItem, item);
                textItem.parent = this.layout_left;
            } else if (item.type == "img") {
                let textItem = this.getItemLeftNode("img");
                let size = this.getHeadSize(1);
                this.initPicItem(textItem, item, size);
                textItem.parent = this.layout_left;
            }
        });
        this.downArr.forEach((item) => {
            if (item.type == "txt") {
                let textItem = this.getItemRightNode("txt");
                this.initTextItem(textItem, item);
                textItem.parent = this.layout_right;
            } else if (item.type == "img") {
                let textItem = this.getItemRightNode("img");
                let size = this.getHeadSize(2);
                this.initPicItem(textItem, item, size);
                textItem.parent = this.layout_right;
            }
        });
    }

    private initTextItem(item, data) {
        item.data = data;
        let nText = cc.find("normal/text", item);
        let sText = cc.find("select/text", item);
        let fText = cc.find("finish/text", item);

        nText.getComponent(cc.Label).string = data.text;
        sText.getComponent(cc.Label).string = data.text;
        fText.getComponent(cc.Label).string = data.text;

        if (data.audio_url) {
            cc.assetManager.loadRemote(data.audio_url, (err, audioClip) => {
                item.audioClip = audioClip;
            });
        }
        item.on(cc.Node.EventType.TOUCH_END, () => {
            // if (item.touch == touchState.FINISH) return;
            this.playLocalAudio("btn");
            this.playLaba(item);
            this.updateClickImg(item.parent, data.id);
            this.checkLing();
            // this.showAniFlower(item);
        })
        item.touch = touchState.NORMAL;
        item.x = 0;
        item.y = 0;
        // item.opacity = 0.1;
    }

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

        if (data.audio_url) {
            cc.assetManager.loadRemote(data.audio_url, (err, audioClip) => {
                item.audioClip = audioClip;
            });
        }
        item.x = 0;
        item.y = 0;
        // item.opacity = 0.1;
        item.on(cc.Node.EventType.TOUCH_END, () => {
            // if (item.touch == touchState.FINISH) return;
            this.playLocalAudio("btn");
            this.playLaba(item);
            this.updateClickImg(item.parent, data.id);
            this.checkLing();
            // this.showAniFlower(item);
        })
        item.touch = touchState.NORMAL;
    }

    private updateClickImg(layout, id) {
        layout.children.forEach((item) => {
            if (!item.data) return;
            // if (item.touch == touchState.FINISH) return;
            let select = cc.find("select", item);
            let normal = cc.find("normal", item);
            let finish = cc.find("finish", item);
            if (item.data.id == id) {
                item.touch = touchState.SELECT;
                select.active = true;
                normal.active = false;
                finish.active = false;
            } else {
                item.touch = item.touch == touchState.FINISH ? touchState.FINISH : touchState.NORMAL;
                select.active = false;
                normal.active = true;
            }
        })
    }





    private checkLing() {
        let lift = null;
        let right = null;
        let liftIdx = -1;
        let rightIdx = -1;
        this.layout_left.children.forEach((ch, idx) => {
            let circle_right = ch.getChildByName("circle_right");
            if (ch.touch == touchState.SELECT) {
                liftIdx = idx;
                lift = ch;
                if (circle_right) circle_right.opacity = 255;
            } else {
                if (circle_right) circle_right.opacity = 0;
            }
        });
        this.layout_right.children.forEach((ch, idx) => {
            let circle_lift = ch.getChildByName("circle_lift");
            if (ch.touch == touchState.SELECT) {
                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) {
        let isRight = lift.data.id == right.data.id;
        this.playLocalAudio("check")
        console.log("匹配成功！···")
        lift.getComponent(cc.Button).interactable = false;
        right.getComponent(cc.Button).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() {
        this.layout_left.children.forEach((item) => {
            let select = cc.find("select", item);
            let normal = cc.find("normal", item);
            let finish = cc.find("finish", item);
            if (item.touch != touchState.FINISH) {
                normal.active = true;
                select.active = false;
                item.touch = touchState.NORMAL;
            }
            finish.active = item.touch == touchState.FINISH;
            let circle_right = item.getChildByName("circle_right");
            if (circle_right) circle_right.opacity = 0;
        });
        this.layout_right.children.forEach((item) => {
            let select = cc.find("select", item);
            let normal = cc.find("normal", item);
            let finish = cc.find("finish", item);
            if (item.touch != touchState.FINISH) {
                normal.active = true;
                select.active = false;
                item.touch = touchState.NORMAL;
            }
            finish.active = item.touch == touchState.FINISH;
            let circle_lift = item.getChildByName("circle_lift");
            if (circle_lift) circle_lift.opacity = 0;
        });
    }
    private resetLeftCardStateById(id) {
        this.layout_left.children.forEach((item) => {
            if (item.data.id == id) {
                item.touch = touchState.NORMAL;
                let select = cc.find("select", item);
                let normal = cc.find("normal", item);
                let finish = cc.find("finish", item);
                normal.active = true;
                select.active = false;
                finish.active = false;
                return;
            }
        });
    }

    private resetRightCardStateById(id) {
        this.layout_right.children.forEach((item) => {
            if (item.data.id == id) {
                item.touch = touchState.NORMAL;
                let select = cc.find("select", item);
                let normal = cc.find("normal", item);
                let finish = cc.find("finish", item);
                normal.active = true;
                select.active = false;
                finish.active = false;
                return;
            }
        });
    }

    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 cleanLine(id, type) {
        this.graphicsArr.forEach((gs, idx) => {
            if (type == 1 && gs.data.left == id) {
                gs.getComponent(cc.Graphics).clear();
                this.graphicsArr.splice(idx, 1);
                gs.parent = null;
                gs.destroy();
                this.resetLeftCardStateById(gs.data.left);
                this.resetRightCardStateById(gs.data.right);
                this._colors.push(gs.data.color);
            }
            if (type == 0 && gs.data.right == id) {
                gs.getComponent(cc.Graphics).clear();
                this.graphicsArr.splice(idx, 1);
                gs.parent = null;
                gs.destroy();
                this.resetRightCardStateById(gs.data.right);
                this.resetLeftCardStateById(gs.data.left);
                this._colors.push(gs.data.color);
            }
        })
    }
    private graphicsArr = [];
    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));


        this.cleanLine(lift.data.id, 1);
        this.cleanLine(right.data.id, 0);

        lift.touch = touchState.FINISH;
        right.touch = touchState.FINISH;
        let graphicsNode = cc.instantiate(cc.find("graphics", this.node));
        let graphics = graphicsNode.getComponent(cc.Graphics);
        let color = this._colors.splice(0, 1)[0];
        graphics.strokeColor = new cc.Color().fromHEX(color);

        graphicsNode.data = { left: lift.data.id, right: right.data.id, color: color };

        // let line = [point1, point2, color];
        // this.lined.push(line);
        this.graphicsArr.push(graphicsNode);
        this.node.addChild(graphicsNode, 5);
        let group_item = cc.find("group_item", this.node);
        group_item.zIndex = 99;
        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.graphicsArr.length >= this.data.questions[this.roundIdx].options.length) {
            this.scheduleOnce(() => {
                this.addSendData();
                this._drawIndex = 0;
                this.roundIdx++;
                if (this.roundIdx < this.data.questions.length) {
                    this.graphicsArr.forEach((gs, idx) => {
                        gs.getComponent(cc.Graphics).clear();
                        gs.parent = null;
                        gs.destroy();
                    })
                    this.graphicsArr.length = 0;
                }
                this.showGame();
                // this.updateRound();
                // pg.event.emit("mouse_add");
            }, 1);
        }
    }

    private addSendData() {
        let score = 0;
        this.graphicsArr.forEach((item) => {
            if (item.data.right == item.data.left) score += Game.getIns().score;
        })
        this.logs.push({
            option: Game.getIns().getDataByPage(this.roundIdx),
            // submit: datas,
            isRight: true,
            score: score
        })
    }




    //撒花 ------------------------------------------
    async showOneFirework(pos, parentNode, nodeList) {
        for (let i = 0; i < 3; i++) {
            this.showFirework(pos, parentNode, nodeList, 200, 200, 15);
            await asyncDelay(0.1);
        }
    }

    async showAllFirework(parentNode, nodeList) {
        for (let i = 0; i < 6; i++) {
            this.showFirework(cc.v2(0, -parentNode.height / 2), parentNode, nodeList, parentNode.width * 2 / 3, parentNode.height * 1.3);
            await asyncDelay(0.1);
        }
    }

    showFirework(pos, parentNode, nodeList, width = 200, height = 200, number = 30) {
        for (let i = 0; i < number; i++) {
            const quad = this.createQuads(pos, parentNode, nodeList);
            const targetX = RandomInt(width / 2, -width / 2);
            const targetY = RandomInt(height);

            cc.tween(quad)
                .by(0.5, { x: targetX })
                .by(3, { x: targetX * 2 })
                .start();

            cc.tween(quad)
                .by(0.5, { y: targetY }, { easing: 'quadOut' })
                .to(4, { y: -parentNode.height * 2 }, { easing: 'quadIn' })
                .removeSelf()
                .start();

            cc.tween(quad)
                .delay(1)
                .to(1.5, { opacity: 0 })
                .start();
        }
    }

    createQuads(pos, parentNode, nodeList) {
        const quadBase = cc.instantiate(nodeList[RandomInt(nodeList.length)]);
        quadBase.x = pos.x;
        quadBase.y = pos.y;
        quadBase.z = pos.z;
        quadBase.angle = RandomInt(180);
        // quadBase.parent = parentNode;
        parentNode.addChild(quadBase, 999);
        const quad = quadBase.getChildByName('quad');
        quad.x = 0;
        quad.y = 0;
        quad.angle = RandomInt(180);

        const paper = quad.getChildByName('petal');
        paper.scaleX = Math.random() * 0.5 + 0.5;
        paper.scaleY = Math.random() * 0.5 + 0.5;

        quadBase.scaleX = Math.random();
        cc.tween(quadBase)
            .to((1 - quadBase.scaleX) * 0.3, { scaleX: 1 })
            .call(() => {
                const time = Math.random() * 0.2;
                cc.tween(quadBase)
                    .to(0.1 + time, { scaleX: -1 })
                    .to(0.1 + time, { scaleX: 1 })
                    .union()
                    .repeatForever()
                    .start();
            })
            .start();


        return quadBase;
    }






    private playLaba(item) {
        if (item.audioClip) {
            pg.audio.playAudio(item.audioClip, () => {
                // cc.audioEngine.stopAllEffects();
                // anim.stop();
            });
        }
    }
    private getHeadSize(type) {
        let size = {};
        if (this.upArr.length == 5) {
            size = { w: 55, h: 55 }
        } else if (this.upArr.length == 4) {
            size = { w: 68, h: 68 }
        } else if (this.upArr.length == 3) {
            size = { w: 98, h: 98 }
        }
        return size;
    }
    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);
            });
        })
    }
}
