import StartSceneBase from "../../libs/new_wx/components/StartSceneBase";
import PanelCtrl from "../../libs/new_wx/ctrls/panelCtrl";
import { ABNetManager } from "../../libs/tc/manager/ABNetManager";
import { GDispatcher } from "../../libs/tc/util/GDispatcher";
import EgretRender from "../physics/EgretRender";
import check from "./check";
import { bubble, bubbleGroup, bubbleMask, award } from "./collisionConfig";
import createBox from "./createBox";
import createBtns from "./createBtns";
import createBubblePic from "./createBubblePic";
import createItems, { rollbackIcon } from "./createItems";
import { getCurrentPercent, onLvBoom, getCurrentLevel, getLevelAniTag, setLevelAniTag, addCurrentScore, toNextLevel, getLevelData, getCurrentScore } from "./levels";
import random from "./random";
import { startStandbyBubblesLeft, startStandbyBubblesRight, stopStandbyBubblesLeft, stopStandbyBubblesRight } from "./standbyBubbles";
import updateLVProgress from "./updateLVProgress";
import Panel from "../../libs/new_wx/components/Panel";
import { ModuleTypes } from "../../libs/new_wx/types/sceneTypes";
import initScoreTxt from "./initScoreTxt";

export default class StartScene extends StartSceneBase {
    _engine: Matter.Engine;
    _egretRender: EgretRender;
    private _lastTimestamp = 0;
    _startStandbyBubblesLeft: number;
    _startStandbyBubblesRight: number;
    egretRenderContainer: egret.Sprite;

    onPanelRemoved(e: egret.Event) {
        const { panel, closeType } = e.data;
        const c1 = panel.type == ModuleTypes.PRIZE_PANEL;
        const c3 = panel.type == ModuleTypes.NO_PRIZE_PANEL;
        const c2 = closeType == 'closeByClick';
        if (!c1 && !c2 && !c3) return;
        if (toNextLevel()) {
            this.initLevelView();
            this.playLevelAni();
            this.clearAwardBody();
            createItems(this);
        }
    }

    clearAwardBody() {
        const bodies = Matter.Composite.allBodies(this._engine.world);
        const isAward = (i: Matter.Body) => { return i.collisionFilter.group == award }
        bodies.forEach(i => {
            if (isAward(i)) this._egretRender.remove(i);
        })
    }

    onNetError() {

    }

    update() {

    }

    initLevelView() {
        const lv = getCurrentLevel();
        updateLVProgress(this, lv);
        this.updateProgress();
        this['lvLayer'].touchChildren = this['lvLayer'].touchEnabled = false;
    }

    playLevelAni() {
        if (!getLevelAniTag()) {
            const lv = getCurrentLevel();
            setLevelAniTag();
            this['lvbg'].visible = true;
            this['lvbg'].alpha = 1;
            this[`lv${lv}`].visible = true;
            egret.Tween.get(this[`lv${lv}`]).set({ y: 166.26 - 1624 }).to({ y: 166.26 }, 700, egret.Ease.backOut)
                .wait(1000).to({ y: 1624 + 166.26 }, 500, egret.Ease.backIn);
            egret.Tween.get(this['lvbg']).wait(700 + 1000).to({ alpha: 0 }, 500);
        } else {

        }
    }

    updateProgress() {
        const percent = getCurrentPercent();
        const maxwidth = this.progressfront.width;
        egret.Tween.removeTweens(this.progressfront.mask);
        egret.Tween.get(this.progressfront.mask).to({ width: percent * maxwidth }, 200);
        this.updateScoreTxt();
    }

    onBoom(): any {
        rollbackIcon(getCurrentScore(), this);
        onLvBoom();
        this.updateProgress();
    }

    addScore(): any {
        addCurrentScore();
        this.updateProgress();
    }

    async start(data?) {
        super.start();
        toNextLevel();
        GDispatcher.addEvent(ABNetManager.NET_ERROR, this.onNetError, this);
        PanelCtrl.instance.addEventListener('onPanelRemoved', this.onPanelRemoved, this)
        egret.lifecycle.onPause = () => {
            console.log("app 进入后台");
            egret.ticker.pause(); // 关闭渲染与心跳
        }
        egret.lifecycle.onResume = () => {
            console.log("app 进入前台");
            this._lastTimestamp = 0;
            egret.ticker.resume(); // 打开渲染与心跳
        }

        this.addChild(this['basket_bottom']);

        //创建引擎
        const engine = Matter.Engine.create();
        this._engine = engine;
        this._engine.world.gravity.y = 0.2;

        //创建egret渲染
        this.egretRenderContainer = new egret.Sprite();
        this.addChild(this.egretRenderContainer);
        this._egretRender = new EgretRender(this.egretRenderContainer, this._engine);

        this.addChild(this['basket_top']);
        this.addChild(this['glass']);
        this.addChild(this['lvLayer']);

        [this['basket_bottom'], this['basket_top'], this['glass']].forEach(item =>
            egret.Tween.get(item).set({ alpha: 0 }).to({ alpha: 1 }, 500));

        // run the engine
        this.runEngine();

        const options: any = {
            width: 750,
            height: 1624,
            wireframes: !1,
        };

        const render = Matter.Render.create({
            element: document.getElementById('debugCanvas'),
            engine: engine,
            options: options
        });
        Matter.Render.run(render);

        this.runGame();
    }

    addForce = false;
    stageX = 0;
    stageY = 0;
    async runGame() {
        createBox(this);

        const rect = new egret.Rectangle(0, 0, 380, 28);
        rect.width = 0;
        this.progressfront.mask = rect;

        this.initLevelView();
        this.playLevelAni();

        const reslist = ['boom', 'gift', 'candy', 'coin', 'egg']
        await Promise.all(
            reslist.map(res => RES.getResAsync(`${res}_json`))
        );

        RES.getResAsync('success_json');
        RES.getResAsync('fail_json');

        createItems(this);

        Matter.Events.on(this._engine, 'beforeUpdate', () => {
            if (!this.addForce) return
            this.addForce = false;
            const isleft = this.stageX < 375;
            const start = isleft ? { x: 208, y: 821 } : { x: 549, y: 821 };
            const scale = 2.2;
            for (let i = 0; i < 15; i++) {
                setTimeout(() => {
                    const r = random(10, 14);
                    let bubblePic;
                    bubblePic = createBubblePic(r);//默认球的尺寸100
                    const basex = 0.02;
                    const xoffset = 0.007;
                    const fx = isleft ? random(-basex, basex) : random(-basex, basex);
                    const padding = 50;
                    const startx = random(start.x - padding, start.x + padding);
                    if (fx < -xoffset || fx > xoffset) bubblePic = null;
                    const body = this._egretRender.circle(startx, start.y, r, bubblePic,
                        {
                            density: 0.001 * 3,
                            restitution: 1,
                            force: { x: fx * scale, y: -0.02 * scale },
                            collisionFilter: { group: bubbleGroup, category: bubble, mask: bubbleMask }
                        }
                    );

                    setTimeout(() => {
                        this._egretRender.remove(body);
                    }, 1000);
                }, Math.random() * 200);
            }
            for (let j = 0; j < 1; j++) {
                const start = isleft ? { x: 208 + 50, y: 821 + 30 } : { x: 549 - 50, y: 821 + 30 };
                const r = random(10, 14);
                const body = this._egretRender.circle(start.x, start.y, r, null,
                    {
                        density: 0.001 * 3,
                        restitution: 1,
                        force: { x: (isleft ? 1 : -1) * 0.02 * 1.7, y: 0 },
                        collisionFilter: { group: bubbleGroup, category: bubble, mask: bubbleMask }
                    }
                );

                setTimeout(() => {
                    this._egretRender.remove(body);
                }, 1000);
            }
        });

        [this['leftBtn'], this['rightBtn']].forEach(btn => {
            btn.addEventListener(egret.TouchEvent.TOUCH_TAP, (e: egret.TouchEvent) => {
                // createNewBubble(this,LabelType.candy)
                this.addForce = true;
                this.stageX = e.stageX;
                if (this.stageX < 375) {
                    stopStandbyBubblesLeft();
                    clearTimeout(this._startStandbyBubblesLeft);
                    this._startStandbyBubblesLeft = setTimeout(() => {
                        startStandbyBubblesLeft(this._egretRender);
                    }, 1000);
                } else {
                    stopStandbyBubblesRight();
                    clearTimeout(this._startStandbyBubblesRight);
                    this._startStandbyBubblesRight = setTimeout(() => {
                        startStandbyBubblesRight(this._egretRender);
                    }, 1000);
                }
            }, this);
        });

        createBtns(this);

        startStandbyBubblesLeft(this._egretRender);
        startStandbyBubblesRight(this._egretRender);

        initScoreTxt(this);
        this.updateProgress();
    }

    runEngine() {
        egret.startTick(this.onTick, this);
    }

    private onTick(timestamp: number) {
        if (this._lastTimestamp === 0) {
            this._lastTimestamp = timestamp;
            return;
        }
        let delta = timestamp - this._lastTimestamp;
        if (delta > 20)
            delta = 20;
        this._lastTimestamp = timestamp;
        Matter.Engine.update(this._engine, delta);
        // console.log(delta);
        this._egretRender.run();
        check(this);
        return false;
    }

    updateScoreTxt() {
        this.scoreTxt.text = `得分:${getCurrentScore()}`;
    }

    initEvents() {
        super.initEvents();
        if (this.treasureBtn)
            this.treasureBtn.addEventListener(egret.TouchEvent.TOUCH_TAP, this.onTap_treasureBtn, this);
    }

    treasureBtn: eui.Button;
    progressfront: egret.DisplayObject;
    private scoreTxt: eui.Label;
}