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

const { ccclass, property } = cc._decorator;

export function getDegree(p1, p2) {
    let vector = p2.sub(p1);
    let degree = Math.atan(vector.y / vector.x) / Math.PI * 180;
    if (vector.x >= 0) {
        if (vector.y < 0) {
            degree += 360;
        }
    } else {
        if (vector.y > 0) {
            degree += 180;
        } else {
            degree = 180 + degree;
        }
    }
    return -(-degree + 90);//角度计算方法
}
let win: any = window;
let courseware = win.courseware;
enum GUN_STATE {
    WAIT = 1,
    SHUT_MIDDLE,
    SHUT_LEFT,
    SHUT_RIGHT
}
enum FISH_STATE {
    NORMAL = 1,
    BREAK,
    FALL,
}
enum TIPS_STATE {
    GOOD = 1,
    TRY,
    COM,
}
@ccclass
export default class SceneComponent extends MyCocosSceneComponent {

    addPreloadImage() {
        // TODO 根据自己的配置预加载图片资源
        this._imageResList.push(...this.data.questions.map(question => {
            return { url: question.image };
        }));
    }

    addPreloadAudio() {
        // TODO 根据自己的配置预加载音频资源
        this._audioResList.push({ url: this.data.questionTextAudio });
        this._audioResList.push({ url: this.data.bgAudio });
        this._audioResList.push(...this.data.questions.map(question => {
            return { url: question.audio };
        }));
    }

    addPreloadAnima() {

    }

    onLoadEnd() {
        // TODO 加载完成后的逻辑写在这里, 下面的代码仅供参考
        this.initData();
        this.initView();
        this.initEvent();
        this.startTime();
        this.updateTop();
    }
    protected onDestroy(): void {
        pg.event.clear();
    }

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

    private tryData: Array<Option>;
    private timeSecond;
    private assessCount;
    private isClick = true;
    initData() {
        Game.getIns().init(this.data);
        Game.getIns().reset();
        this.tryData = [];
        // 所有全局变量 默认都是null 
        this.startSecond = false;
        this.timeSecond = 0;
        this.assessCount = 0;
        this.isClick = true;
    }
    private layout_start: cc.Node;
    private audioId: any;

    async initView() {
        cc.audioEngine.stopAllEffects();
        this.layout_start = pg.view.find(this, "layout_start");

        this.layout_start.active = true;

        if (Game.getIns().title) {
            cc.find("layout_info/label_title", this.node).getComponent(cc.Label).string = Game.getIns().title;
        }
    }
    initEvent() {
        this.btn_laba.on(cc.Node.EventType.TOUCH_END, this.playLaba, this);
        // this.btn_record.on(cc.Node.EventType.TOUCH_END, this.onTouchRecord, this);
        // this.btn_recording.on(cc.Node.EventType.TOUCH_END, this.onTouchRecordEnd, this);
        cc.find("btn_close", this.layout_final).on(cc.Node.EventType.TOUCH_END, this.onCloseFinal, this);
        cc.find("btn_restart", this.layout_final).on(cc.Node.EventType.TOUCH_END, this.onRestart, this);
        pg.event.on("game_start", () => {
            this.gameStart();
        });
        pg.event.on("check_next_question", () => {
            this.roundEnd();
        });
    }
    private onRestart() {
        this.playLocalAudio("btn");
        this.layout_final.active = false;
        this.label_time.getComponent(cc.Label).string = "00:00";
        pg.event.clear();
        this.cleanBridge();
        this.onLoadEnd();
    }
    private onCloseFinal() {
        this.playLocalAudio("btn");
        this.layout_final.active = false;
    }
    private cleanBridge() {
        // let bridge_4 = cc.find("bridge_4", this.layout_game);
        // bridge_4.active = false;
        // bridge_4.children.forEach((ch) => {
        //     let word = cc.find("word", ch);
        //     word.getComponent(cc.Label).string = "";
        // })
        // let bridge_8 = cc.find("bridge_8", this.layout_game);
        // bridge_8.children.forEach((ch) => {
        //     let word = cc.find("word", ch);
        //     word.getComponent(cc.Label).string = "";
        // })
        // let bridge_12 = cc.find("bridge_12", this.layout_game);
        // bridge_12.children.forEach((ch) => {
        //     let word = cc.find("word", ch);
        //     word.getComponent(cc.Label).string = "";
        // })
        // bridge_8.active = false;
        // bridge_12.active = false;

        this.layout_game.children.forEach((ch) => {
            ch.active = false;
        })
    }

    private gameOver() {
        Game.getIns().state = GAME_STATE.OVER;
        let data: any = {};
        data.total = Game.getIns().total;
        data.right = Game.getIns().player.right;
        data.scores = Game.getIns().player.voices;
        data.stone = Math.floor(10 * data.right / data.total);
        this.log("total: " + data.total + "      right: " + data.right + "   stone: " + data.stone);
        onHomeworkFinish(data)
    }

    gameStart() {
        Game.getIns().state = GAME_STATE.RUNNING;
        this.startSecond = true;
        this.layout_start.active = false;
        let qiao1 = cc.find("bg/qiao1", this.node);
        qiao1.active = false;
        this.showQuestion();
        this.updateTop();
    }
    private wordItams: cc.Node[];
    private showQuestion() {
        this.playLaba();
        this.wordItams = [];
        let data = Game.getIns().getCurrentPage();
        this.layout_game.children.forEach((ch, idx) => {
            ch.active = false;
        });
        let layout_cloud = this.getLayoutCloud();
        let layout_bridge = this.getLayoutBridge();

        layout_cloud.active = true;
        layout_bridge.active = true;
        data.wordArr.sort(function () {
            return (0.5 - Math.random());
        });
        layout_cloud.children.forEach((ch, idx) => {
            let c_d = data.wordArr[idx];
            if (!c_d) ch.active = false;
            this.initCloudItem(ch, c_d);
            let iData: any = {};
            iData.x = ch.x;
            iData.y = ch.y;
            ch.data = iData;
            this.floatForeverAction(ch);
        });
        layout_bridge.children.forEach((item, idx) => {
            let c_d = data.wordArr[idx];
            if (!c_d) item.active = false;
            let iData: any = {};
            iData.x = item.x;
            iData.y = item.y;
            item.data = iData;
            let word = cc.find("word", item);
            word.getComponent(cc.Label).string = c_d;
            word.active = false;
            this.wordItams.push(item);
            let bData: any = {};
            bData.text = c_d;
            bData.parent = word.parent;
            bData.startPos = word.getPosition();
            word.data = bData;
            word.on(cc.Node.EventType.TOUCH_START, this.onBridgeStart, this);
            word.on(cc.Node.EventType.TOUCH_MOVE, this.onBridgeMove, this);
            word.on(cc.Node.EventType.TOUCH_END, this.onBridgeEnd, this);
        });
        this.isClick = true;
    }
    private initCloudItem(item, text) {
        let word = cc.find("word", item);
        if (!text) {
            word.active = false;
            return;
        }

        word.getComponent(cc.Label).string = text;
        let data: any = {};
        data.text = text;
        data.parent = word.parent;
        data.startPos = word.getPosition();
        word.data = data;
        word.active = true;

        word.off(cc.Node.EventType.TOUCH_START, this.onItemTouchStart, this);
        word.off(cc.Node.EventType.TOUCH_MOVE, this.onItemTouchMove, this);
        word.off(cc.Node.EventType.TOUCH_END, this.onItemTouchEnd, this);

        word.on(cc.Node.EventType.TOUCH_START, this.onItemTouchStart, this);
        word.on(cc.Node.EventType.TOUCH_MOVE, this.onItemTouchMove, this);
        word.on(cc.Node.EventType.TOUCH_END, this.onItemTouchEnd, this);
    }
    private getLayoutCloud() {
        let data = Game.getIns().getCurrentPage();
        let length = data.wordArr.length;
        let count = length > 4 ? length > 8 ? 12 : 8 : 4;
        let layout_cloud = cc.find("cloud_" + count, this.layout_game);
        return layout_cloud;

    }
    private getLayoutBridge() {
        let data = Game.getIns().getCurrentPage();
        let length = data.wordArr.length;
        let count = length > 4 ? length > 8 ? 12 : 8 : 4;
        let layout_bridge = cc.find("bridge_" + count, this.layout_game);
        return layout_bridge;
    }

    private setTouchPos(e) {
        let location = e.getLocation();
        let size = cc.view.getCanvasSize();
        let scale = (size.width / size.height) / (1920 / 1080);
        if (scale > 1) {
            let width = size.width / size.height * 1080;
            let pos = location.sub(cc.v2(width / 2, 1080 / 2))
            e.target.setPosition(pos)
        } else {
            let height = size.height / size.width * 1920;
            let pos = location.sub(cc.v2(1920 / 2, height / 2))
            e.target.setPosition(pos)
        }
    }

    onItemTouchStart(e) {
        if (!this.isClick) return;
        if (e.target.getComponent(cc.Label).string == "") return;
        this.playLocalAudio("takeout");
        // if (this.checkRoundOver()) return;
        let target: cc.Node = e.target;
        let data = target.data;
        this.floatAction(target.parent);
        //已经成功的方块要拒绝掉
        // if (this.checkSuccess(target, data)) return;
        target.parent = this.node;
        // target.setPosition(AP);
        this.setTouchPos(e);
    }
    onItemTouchMove(e) {
        if (!this.isClick) return;
        // if (this.checkRoundOver()) return;
        let target: cc.Node = e.target;
        let data = target.data;
        //已经成功的方块要拒绝掉
        this.setTouchPos(e);
    }
    onItemTouchEnd(e) {
        if (!this.isClick) return;
        // if (this.checkRoundOver()) return;
        let target: cc.Node = e.target;
        let data = target.data;
        let itemBg = this.wordItams.find((bg) => {
            // let dis = this.getDistances(target.getPosition(), bg.getPosition());
            let dis = this.getDistances(target, bg);
            // if (dis < 100 && bg.sortId == data.id) {
            if (dis < bg.width / 2 && !cc.find("word", bg).active && bg.active) {
                return bg;
            }
            return null;
        })
        target.parent = data.parent;
        target.setPosition(data.startPos);
        target.active = false;

        if (!itemBg) {
            target.active = true;
            this.floatForeverAction(target.parent);
            return
        }
        this.floatAction(itemBg);

        let word = cc.find("word", itemBg);
        word.active = true;
        // word.getComponent(cc.Label).string = data.text;
        word.data.CParent = data.parent;

        this.playLocalAudio("move")
        if (this.checkRoundOver()) {
            if (this.checkMoveRight()) {
                this.playLocalAudio("right");
                let qiao2 = cc.find("bg/qiao2", this.node);
                qiao2.active = true;
                qiao2.opacity = 0;
                cc.tween(qiao2)
                    .to(0.5, { opacity: 100 }).to(0.5, { opacity: 0 })
                    .to(0.5, { opacity: 100 }).to(0.5, { opacity: 0 })
                    .call(() => {
                        let qiao1 = cc.find("bg/qiao1", this.node);
                        qiao1.active = true;
                    })
                    .delay(1)
                    .call(() => {
                        this.roundEnd();
                    })
                    .start();

            } else {
                Game.getIns().failCount++;
                this.isClick = false;
                this.playLocalAudio("error").then(() => {
                    this.showQuestion();
                });
            }
        }

    }

    private onBridgeStart(e) {
        if (!this.isClick) return;
        let target: cc.Node = e.target;
        this.floatAction(target.parent);
        target.parent = this.node;
        this.setTouchPos(e);
    }
    private onBridgeMove(e) {
        if (!this.isClick) return;
        let target: cc.Node = e.target;
        this.setTouchPos(e);
    }
    private onBridgeEnd(e) {
        if (!this.isClick) return;
        let target: cc.Node = e.target;
        let data = target.data;
        let itemBg = this.wordItams.find((bg) => {
            // let dis = this.getDistances(target.getPosition(), bg.getPosition());
            let dis = this.getDistances(target, bg);
            // if (dis < 100 && bg.sortId == data.id) {
            if (dis > bg.width) {
                return bg;
            }
            return null;
        })
        target.parent = data.parent;
        target.setPosition(data.startPos);
        if (!itemBg) return;
        target.active = false;
        let cloud = data.CParent;
        if (cloud) {
            this.floatForeverAction(cloud);
            let word = cc.find("word", cloud);
            if (word) {
                word.active = true;
                // word.getComponent(cc.Label).string = data.text;
            }

        }
    }

    private checkRoundOver() {
        let count = 0;
        let layout = this.getLayoutCloud();
        layout.children.forEach((item) => {
            let word = cc.find("word", item);
            if (word && word.active) count++;
        })
        return count == 0;
    }

    private checkMoveRight() {
        let word = Game.getIns().getCurrentPage().txt;
        let str = "";
        let layout = this.getLayoutBridge();
        layout.children.forEach((item) => {
            let word = cc.find("word", item);
            str += word.getComponent(cc.Label).string;
        })
        return word == str;
    }

    private floatAction(target) {
        cc.Tween.stopAllByTarget(target);
        let data = target.data;
        target.x = data.x;
        target.y = data.y;
        let y1 = target.y - 20;
        let y2 = target.y;
        cc.tween(target).to(0.15, { y: y1 }).to(0.3, { y: y2 }).start();

    }
    private floatForeverAction(target) {
        cc.Tween.stopAllByTarget(target);
        let data = target.data;
        target.x = data.x;
        target.y = data.y;
        let y1 = target.y - 10;
        let y2 = target.y;
        cc.tween(target).repeatForever(cc.tween().to(0.5 + Math.random() * 1.5, { y: y1 }).to(0.5 + Math.random() * 1.5, { y: y2 })).start();
    }





    //根据两点获取距离
    private getDistance(p1, p2) {
        let temp = p1.sub(p2);
        let dis = Math.abs(temp.mag());
        return dis;
    }
    private getDistances(p1, p2) {
        //转换世界坐标查看距离
        let ps2 = p2.convertToWorldSpaceAR(cc.v2(0, 0));
        let ps1 = p1.convertToWorldSpaceAR(cc.v2(0, 0));
        let temp = ps1.sub(ps2);
        let dis = Math.abs(temp.mag());
        return dis;
    }







    private roundEnd() {
        Game.getIns().addPage();
        if (!Game.getIns().getCurrentPage()) {
            this.showFind();
        } else {
            this.playLocalAudio("next").then(() => {
                // this.startTime();
                this.gameStart();
            });
        }

    }


    // private nextstar(isRight = true) {
    //     this.starData = Game.getIns().getCurrentPage();
    //     if (this.starData) {
    //         this.star_node.active = true;
    //         this.gameStart(isRight)
    //     } else {
    //         this.startSecond = false;
    //         this.gameOver();
    //         this.showFind();
    //     }
    // }


    private updateTop() {
        let round = cc.find("layout_info/bg_number/round", this.node);
        round.getComponent(cc.Label).string = `${Game.getIns().getCurrentPage().page}/${Game.getIns().total}`;
    }
    private startSecond: boolean;

    update(dt) {
        if (Game.getIns().state != GAME_STATE.RUNNING) return;
        if (!this.startSecond) return;
        this.timeSecond = this.timeSecond + dt;
        let count = Math.ceil(this.timeSecond);
        let str = this.formatSeconds(count);
        this.label_time.getComponent(cc.Label).string = str;
    }
    private formatSeconds(value) {
        var secondTime = parseInt(value);// 秒
        var minuteTime = 0;// 分
        var hourTime = 0;// 小时
        if (secondTime > 59) {//如果秒数大于60，将秒数转换成整数
            //获取分钟，除以60取整数，得到整数分钟
            minuteTime = Math.floor(secondTime / 60);
            //获取秒数，秒数取佘，得到整数秒数
            secondTime = Math.floor(secondTime % 60);
            //如果分钟大于60，将分钟转换成小时
            // if (minuteTime > 60) {
            //     //获取小时，获取分钟除以60，得到整数小时
            //     hourTime = minuteTime / 60;
            //     //获取小时后取佘的分，获取分钟除以60取佘的分
            //     minuteTime = minuteTime % 60;
            // }
        }
        var result = (secondTime < 10 ? "0" + secondTime : secondTime) + "";

        if (minuteTime > 0) {
            result = "" + (minuteTime < 10 ? "0" + minuteTime : minuteTime) + ":" + result;
        } else {
            result = "00:" + result
        }
        // if (hourTime > 0) {
        //     result = "" + hourTime + "小时" + result;
        // }
        return result;
    }


    private async startTime() {
        this.layout_start.active = true;
        for (let i = 3; i >= 0; i--) {
            let target = cc.find("layout_start/text_" + i, this.node);
            if (i == 0) this.playLocalAudio("go")
            else this.playLocalAudio("count")
            await this.startTextAction(target);
        }
        this.gameStart();
    }
    private startTextAction(target) {
        return new Promise((resolve, reject) => {
            target.scale = 1;
            target.active = true;
            target.opacity = 255;
            cc.tween(target).to(1, { scale: 0.5, opacity: 0 }).call(() => { target.active = false; return resolve("") }).start();
        })
    }
    private showFind() {
        this.playLocalAudio("wancheng");
        this.startSecond = false;
        this.layout_final.scale = 0.3;
        this.layout_final.active = true;
        let count = cc.find("count", this.layout_final);
        let time = cc.find("time", this.layout_final);
        time.getComponent(cc.Label).string = this.formatSeconds(this.timeSecond);
        count.getComponent(cc.Label).string = "" + Game.getIns().failCount;
        cc.tween(this.layout_final).to(0.3, { scale: 1 }).start();
    }





    private intervalId;
    private playLaba() {
        // let btn_kaba2 = this.btn_laba.getChildByName("btn_laba2");
        let btn_kaba3 = this.btn_laba.getChildByName("btn_laba3");
        // 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_kaba3.active = count % 3 == 2;
            if (stop && count % 3 == 2) {
                clearInterval(this.intervalId);
                // btn_kaba2.active = false;
                btn_kaba3.active = false;
            }
        }, 150)

        pg.audio.playAudioByUrl(Game.getIns().getCurrentPage().audioUrl, (() => {
            stop = true;
        }))
    }



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



    async showOneFirework(pos, parentNode, nodeList) {

        for (let i = 0; i < 3; i++) {
            this.showFirework(pos, parentNode, nodeList, 200, 200, 25);
            await asyncDelay(0.1);
        }
    }

    showFirework(pos, parentNode, nodeList, width = 200, height = 500, 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(0.5 + 1 * Math.random(), { opacity: 0 })
                .start();
        }
    }

    createQuads(pos, parentNode, nodeList) {
        const quadBase = cc.instantiate(nodeList[RandomInt(nodeList.length)]);
        // console.log('nodeList', nodeList);
        // console.log('quadBase', quadBase);
        quadBase.x = pos.x;
        quadBase.y = pos.y + 30;
        quadBase.z = pos.z;
        quadBase.angle = RandomInt(180);
        quadBase.parent = parentNode;

        const quad = quadBase.getChildByName('quad');
        quad.x = 0;
        quad.y = 0;
        quad.angle = RandomInt(180);

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

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


