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";
import { count } from "console";

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.startAudio });
        // 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();
    }
    protected onDestroy(): void {
        pg.event.clear();
    }

    @property(cc.Node)
    layout_game: cc.Node = null;
    @property(cc.Node)
    layout_box: cc.Node = null;
    @property(cc.Node)
    layout_start: cc.Node = null;
    @property(cc.Node)
    layout_finish: cc.Node = null;
    @property(cc.Node)
    layout_card: cc.Node = null;

    public isCanClick: boolean;
    public isFinish: boolean;
    private tryData: Array<Option>;
    private timeSecond;
    private assessCount;
    initData() {
        Game.getIns().init(this.data);
        Game.getIns().reset();
        this.tryData = [];
        // 所有全局变量 默认都是null 
        this.timeSecond = 0;
        this.assessCount = 0;
        this.isCanClick = false;
        this.isFinish = false;
    }
    private audioId: any;
    async initView() {
        // cc.audioEngine.stopAllEffects();
        this.initStart();
        this.gameStart(false);

    }
    initEvent() {
        let btn_again = cc.find("layout_finish/btn_again", this.node);
        let btn_next = cc.find("layout_finish/btn_next", this.node);
        btn_again.on(cc.Node.EventType.TOUCH_END, this.onAgain, this);
        btn_next.on(cc.Node.EventType.TOUCH_END, this.onNext, this);
        pg.event.on("game_start", () => {
            this.gameStart();
        });
        pg.event.on("check_next_question", () => {
            // this.checkClickEnd();
        });
        pg.event.on("mouse_num_game_end", () => {
            if (this.checkOver()) {
                this.showFind();
            }
        });
    }
    private onAgain() {
        this.layout_finish.active = false;
        this.onLoadEnd();
    }
    private onNext() {

    }

    private intervalId;
    private playLaba() {

        // this.btn_laba.active = false;
        // this.play_laba.active = true;
        // let btn_laba1 = this.play_laba.getChildByName("btn_laba1");
        // let btn_kaba2 = this.play_laba.getChildByName("btn_laba2");
        // let btn_kaba3 = this.play_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;
        //         this.btn_laba.active = true;
        //         this.play_laba.active = false;
        //     }
        // }, 150)
        // pg.audio.playAudioByUrl(Game.getIns().getCurrentPage().audioUrl, (() => {
        //     stop = true;
        // }))
    }


    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(isPlayAudio = true) {
        Game.getIns().state = GAME_STATE.RUNNING;
        this.showQuestion();
        isPlayAudio && this.playLaba();
    }
    private wordItams: cc.Node[];
    private chipPos = [];
    private showQuestion() {
        this.chipPos = [
            { x: -260, y: -44, angle: 130 }, { x: -190, y: -24, angle: 130 }, { x: 17, y: 104, angle: 120 },
            { x: 35, y: 39, angle: 65 }, { x: -172, y: 43, angle: 130 }, { x: -64, y: -6, angle: 130 },
            { x: 208, y: 112, angle: 50 }, { x: -26, y: 28, angle: 120 }, { x: 245, y: -18, angle: 55 },
            { x: 190, y: -15, angle: 60 }, { x: 130, y: -18, angle: 65 }, { x: 112, y: 83, angle: 65 }
        ];
        this.layout_card.removeAllChildren();
        let chipNode = cc.find("chips", this.layout_game);
        this.wordItams = [];
        let chips = Game.getIns().getCardInfo();
        chips.forEach((ch, idx) => {
            let chip = cc.instantiate(chipNode); //cc.find("chips_" + (idx + 1), this.layout_card);
            chip.active = true;
            let word = cc.find("word", chip);
            word.getComponent(cc.Label).string = ch.txt;
            chip.data = ch;
            chip.data.zIndex = idx;
            chip.x = this.chipPos[idx].x;
            chip.y = this.chipPos[idx].y;
            chip.angle = this.chipPos[idx].angle;
            this.layout_card.addChild(chip, idx);

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

            chip.on(cc.Node.EventType.TOUCH_START, this.onItemTouchStart, this);
            chip.on(cc.Node.EventType.TOUCH_MOVE, this.onItemTouchMove, this);
            chip.on(cc.Node.EventType.TOUCH_END, this.onItemTouchEnd, this);
        })
        let list = Game.getIns().getList();
        list.forEach((questio, idx) => {
            let box = this.layout_box.children[idx];
            if (!box) return;
            let bg_box = cc.find("bg_box", box);
            bg_box.removeAllChildren();
            let word = cc.find("word", box);
            word.getComponent(cc.Label).string = questio.text;
            box.active = true;
            this.wordItams.push(box);
            box.pageIdx = questio.page;
        })
        this.isCanClick = false;
    }

    onItemTouchStart(e) {
        this.playLocalAudio("click");
        // if (this.checkRoundOver()) return;
        let target: cc.Node = e.target;
        let data = target.data;
        //已经成功的方块要拒绝掉
        // if (this.checkSuccess(target, data)) return;
        target.parent = this.node;
        // target.setPosition(AP);
        this.setTouchPos(e);
    }
    onItemTouchMove(e) {
        // if (this.checkRoundOver()) return;
        let target: cc.Node = e.target;
        let data = target.data;
        //已经成功的方块要拒绝掉
        this.setTouchPos(e);
    }
    onItemTouchEnd(e) {
        // 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 + 20 && bg.pageIdx == data.page) {
                return bg;
            }
            return null;
        })

        if (!itemBg) {
            target.parent = null;
            this.layout_card.addChild(target, data.zIndex);
            target.x = this.chipPos[data.zIndex].x;
            target.y = this.chipPos[data.zIndex].y;
            target.angle = this.chipPos[data.zIndex].angle;
            this.playLocalAudio("error");
            return;
        }
        let bg_box = cc.find("bg_box", itemBg);
        let pos = this.getBoxPos(bg_box.children.length);
        target.parent = bg_box;
        target.x = pos.x;
        target.y = pos.y;
        target.angle = pos.angle;
        this.playLocalAudio("right");
        pg.event.emit("mouse_add");
    }

    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)
        }
    }
    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 getBoxPos(idx) {
        let box1 = [{ x: 90, y: 88, angle: 65 }, { x: -95, y: 90, angle: 110 }, { x: 24, y: 120, angle: 80 }, { x: -40, y: 80, angle: 95 }]
        return box1[idx];
    }
    private checkOver() {
        let count = 0;
        this.layout_box.children.forEach((box) => {
            let bg_box = cc.find("bg_box", box);
            count += bg_box.children.length;
        })
        return count >= Game.getIns().getCardInfo().length;
    }

    private checkRoundEnd() {
        Game.getIns().addPage();
        if (!Game.getIns().getCurrentPage()) {
            // this.gameOver();
            this.showFind();
        } else {
            this.playLocalAudio("next");
            this.gameStart();
        }

    }

    private showFind() {
        if (this.isFinish) return;
        this.isFinish = true;
        this.playLocalAudio("finish");
        let layout_finish = cc.find("layout_finish", this.node);
        layout_finish.active = true;
        let finish_db = cc.find("finish_db", layout_finish);
        let btn_again = cc.find("btn_again", layout_finish);
        let btn_next = cc.find("btn_next", layout_finish);
        this.playLocalAudio("finish").then(() => {
            finish_db.active = false;
            btn_again.active = true;
            btn_next.active = true;
        });
    }

    private initStart() {
        this.layout_start.active = true;
        cc.find("layout_top/label_title", this.node).getComponent(cc.Label).string = Game.getIns().title;
        pg.event.emit("mouse_num", Game.getIns().getCardInfo().length);
        let start_ske = cc.find("layout_start/start_ske", this.node);
        pg.load.loadDB(start_ske, { ske: Game.getIns().aniEnter.ske.url, tex: Game.getIns().aniEnter.tex.url, png: Game.getIns().aniEnter.png.url }).then((animationName) => {
            if (animationName && animationName != "") {
                let db = start_ske.getComponent(dragonBones.ArmatureDisplay);
                let anis = db.getAnimationNames("armatureName");
                db.playAnimation(anis[0], 0);
                cc.tween(start_ske).by(1, { x: -500 }).call(() => {
                    pg.audio.playAudioByUrl(Game.getIns().startAudio).then(() => {
                        cc.tween(start_ske).delay(1).by(1, { x: 500 }).call(() => {
                            this.layout_start.active = false;
                            this.playLaba();
                        }).start();
                    });
                }).start();
            } else {
                this.layout_start.active = false;
                this.playLaba();
            }
        })
    }

    update(dt) {

    }

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


