import { LoopComponent } from './LoopComponent';
import { GCache } from './../../libs/tc/util/GCache';
import { WinnersData } from './../../libs/tw/data/common/winners/WinnersData';
import { NetManager } from './../../libs/tw/manager/NetManager';
import { DataManager } from './../../libs/tw/manager/DataManager';
import Scene from "../views/Scene";
import showAlertPanel from "../ctrls/showAlertPanel";
import MovieClipManager from "../ctrls/MovieClipManager";
import Panel from "../views/Panel";
import PanelCtrl from "../ctrls/panelCtrl";
import { ModuleTypes } from "../types/sceneTypes";
import SceneCtrl from '../ctrls/sceneCtrl';
import GameConst from '../GameConst';
import fishesConfig from './fishesConfig';
export default class PlayScene extends Scene {
    protected get skinKey() { return 'Play' }

    public bg1: eui.Image;
    public bg2: eui.Image;
    public mainFish: eui.Image;
    public gameTips: eui.Image;
    public levelUpPanel: eui.Component;
    public guide: eui.Component;

    private bgSpeed: number = 3; // 背景移动速度
    private currLevel: number = 1; // 当前等级
    private gameCount: number = 0; // 游戏计数
    private eFishLv1Count: number = 0;
    private eFishLv2Count: number = 0;
    private eFishLv3Count: number = 0;
    private eFishLv4Count: number = 0;
    private eFishLv5Count: number = 0;
    private eFishLv6Count: number = 0;
    private eFishLv7Count: number = 0;
    private eFishLv8Count: number = 0;
    private eFishLv9Count: number = 0;
    private eFishLv10Count: number = 0;
    private bubbleMoveCount: number = 0; // 泡泡计数
    private bubblePool: any[] = []; // 泡泡池
    private eatableFishesTempPool: any[] = []; // 样品池
    private eatableFishesPool: any[] = []; // 鱼池
    private diveSpeed: number = 1; // 用户下潜速度
    private diveAddSpeed: number = 0.45; // 用户下潜加速度
    private effect: any; // 吃鱼效果
    private addScorePool: any[] = [];
    private addScoreCount: number = 0;
    private eatTimes: number; // 吃鱼次数
    private levelUpSpritePool: any[] = []; // 升级粒子效果
    private bg: LoopComponent = new LoopComponent();

    async start(data?) {
        this.initUI();
        this.restart();
    }

    initUI() {
        // 移除所有Tween
        egret.Tween.removeAllTweens();

        this.percentWidth = 100;
        this.percentHeight = 100;

        this.initEatEffect();

        for (let i = 0; i < 5; i++) {
            let addScore = new eui.Image();
            addScore.source = `addScore_png`;
            addScore.anchorOffsetX = addScore.width / 2;
            addScore.anchorOffsetY = addScore.height / 2;
            addScore.alpha = 0;
            this.addChild(addScore);
            this.addScorePool.push(addScore)
        }

        for (let s = 0; s < 30; s++) {
            let sprite = new eui.Image();
            sprite.source = `sprite_png`;
            sprite.anchorOffsetX = sprite.width / 2;
            sprite.anchorOffsetY = sprite.height / 2;
            sprite.x = this.levelUpPanel['fish'].x;
            sprite.y = this.levelUpPanel['fish'].y;
            this.levelUpPanel.addChild(sprite);
            this.levelUpSpritePool.push(sprite);
        }
        this.levelUpPanel.addChild(this.levelUpPanel['fish']);

        this.addChildAt(this.bg, 0);
        this.bg.setupLoop(['playBg_jpg', 'playBg_jpg']);

        this.once(egret.Event.ADDED_TO_STAGE, function () {
            this.bg.y = this.stage.stageHeight - 1624;
        }, this);
    }

    restart() {
        // 移除所有Tween
        egret.Tween.removeAllTweens();

        this.bubbleMoveCount = 0;
        this.gameCount = 0;
        this.eatTimes = 0;
        this.eFishLv1Count = 0;
        this.eFishLv2Count = 0;
        this.eFishLv3Count = 0;
        this.eFishLv4Count = 0;
        this.eFishLv5Count = 0;
        this.eFishLv6Count = 0;
        this.eFishLv7Count = 0;
        this.eFishLv8Count = 0;
        this.eFishLv9Count = 0;
        this.eFishLv10Count = 0;
        this.addScoreCount = 0;

        this.bg.setViewport(0);

        this.mainFish.y = GameConst.stage.stageHeight / 2;
        // 初始化引导
        this.initGuide();
        // this.initEatableFishes();
        // 监听动画帧
        // this.addEventListener(egret.Event.ENTER_FRAME, this.onEnterFrame, this);
    }

    initGuide() {
        // this.addChild(this.gameTips);
        // this.gameTips.scaleX = 0;
        // this.gameTips.scaleY = 0;
        // let gameTipsTW = egret.Tween.get(this.gameTips);
        // gameTipsTW.to({scaleX:1,scaleY:1},500).wait(2000).to({scaleX:0, scaleY:0},200);
        this.guide['circle'].scaleX = 0.6;
        this.guide['circle'].scaleY = 0.6;
        let circleTW = egret.Tween.get(this.guide['circle'], { loop: true });
        circleTW.to({ scaleX: 1.5, scaleY: 1.5 }, 500);
        let fingerTW = egret.Tween.get(this.guide['finger'], { loop: true });
        this.guide['finger'].x = this.guide['circle'].x + 10;
        this.guide['finger'].y = this.guide['circle'].y + 10;
        fingerTW.to({ x: this.guide['circle'].x - 10, y: this.guide['circle'].y - 10 }, 250).to({ x: this.guide['circle'].x + 10, y: this.guide['circle'].y + 10 }, 250);
        this.addChild(this.guide);
        this.guide.addEventListener(egret.TouchEvent.TOUCH_TAP, this.onTap_guide, this);
    }

    onTap_guide() {
        this.guide.visible = false;
        // 初始化泡泡
        this.initBubbles();
        this.addEventListener(egret.Event.ENTER_FRAME, this.onEnterFrame, this);
    }

    viewport = 0;
    onEnterFrame() {
        /**if (this.bg1.x < -this.bg1.width) {
            this.bg1.x += 2250 * 2;
        } else {
            this.bg1.x -= this.bgSpeed;
        }

        if (this.bg2.x < -this.bg2.width) {
            this.bg2.x += 2250 * 2;
        } else {
            this.bg2.x -= this.bgSpeed;
        }**/

        this.bg.setViewport(this.viewport += this.bgSpeed);

        this.gameCount++;
        if (Math.floor(this.gameCount / 15) % 2 == 0) {
            this.mainFish.source = `fishCLv${this.currLevel}_png`;
        } else {
            this.mainFish.source = `fishOLv${this.currLevel}_png`;
        }

        this.dive(this.mainFish);

        // 动态生成吃的鱼
        if (this.gameCount > 200) {
            if (this.gameCount % 20 == 0) {
                let level: number = 1;
                if (this.currLevel == 1) {
                    level = 1;
                } else {
                    level = Math.max(Math.round(Math.random() * (Math.min(this.currLevel + 3, 10))), 1);
                }
                // let fish = new eui.Image();
                let fish = MovieClipManager.instance.getMovieClipByName(`eFishLv${level}_${this[`eFishLv${level}Count`]}`);
                if (this[`eFishLv${level}Count`] < 29) {
                    this[`eFishLv${level}Count`]++;
                } else {
                    this[`eFishLv${level}Count`] = 0;
                }
                fish.play(-1);
                // fish.source = `eatableFishLv${level}_png`;
                // fish.play();
                fish['level'] = level;
                fish.scaleX = (1 + (level - 1) * 0.1);
                fish.scaleY = (1 + (level - 1) * 0.1);
                fish.width = fishesConfig.config[`lv${level}`].eW;
                fish.height = fishesConfig.config[`lv${level}`].eH;
                fish.anchorOffsetX = fish.width / 2;
                fish.anchorOffsetY = fish.height / 2;
                fish.y = Math.min(Math.max(Math.random() * GameConst.stage.stageHeight, 200), GameConst.stage.stageHeight - 200);
                fish.x = 750 + fish.width + 50;
                this.eatableFishesPool.push(fish);
                this.addChild(fish);
                this.addChild(this.mainFish)
            }
        }

        // 吃的鱼移动
        if (this.eatableFishesPool.length > 0) {
            this.eatableFishesPool.forEach(fish => {
                fish.x -= fishesConfig.config[`lv${fish['level']}`].eSpeed;
            })
        }

        // 回收吃的鱼
        for (let i = this.eatableFishesPool.length - 1; i >= 0; i--) {
            let fish = this.eatableFishesPool[i];
            if (fish.x < -400) {
                this.removeChild(fish);
                this.eatableFishesPool.splice(i, 1);
            } else {
                // 碰撞检测
                let eatD = this.mainFish.height / 2 + fish.height / 2;
                let currD = GameConst.distance(this.mainFish, fish);
                if (eatD > currD) {
                    // 发生了碰撞
                    this.effect.alpha = 1;
                    this.effect.x = this.mainFish.x + this.mainFish.width / 4;
                    this.effect.y = this.mainFish.y - this.mainFish.height / 4;
                    this.effect.gotoAndPlay(0);

                    if (this.currLevel >= fish['level']) {
                        // 吃掉对方
                        let addScore = this.addScorePool[this.addScoreCount];
                        if (this.addScoreCount < 4) {
                            this.addScoreCount++;
                        } else {
                            this.addScoreCount = 0;
                        }
                        this.addChild(addScore);
                        addScore.alpha = 1;
                        addScore.scaleX = 1 + this.currLevel * 0.1;
                        addScore.scaleY = 1 + this.currLevel * 0.1
                        addScore.x = this.mainFish.x + this.mainFish.width / 4;
                        addScore.y = this.mainFish.y - this.mainFish.height / 4;
                        addScore.rotation = -15;
                        let addScoreTW = egret.Tween.get(addScore);
                        addScoreTW.to({ y: this.mainFish.y - this.mainFish.height * 3, rotation: 0 }, 400).call(() => {
                            addScore.alpha = 0;
                        });

                        if (this.currLevel < 4) {
                            let mainFishTW = egret.Tween.get(this.mainFish);
                            mainFishTW.to({ scaleX: 2, scaleY: 2 }, 150).to({ scaleX: 1, scaleY: 1 }, 150)
                        } else {
                            let mainFishTW = egret.Tween.get(this.mainFish);
                            mainFishTW.to({ scaleX: 1.5, scaleY: 1.5 }, 150).to({ scaleX: 1, scaleY: 1 }, 150)
                        }

                        this.removeChild(fish);
                        this.eatableFishesPool.splice(i, 1);

                        this.eatTimes++;
                        switch (this.eatTimes) {
                            case 10:
                                this.currLevel = 2;
                                this.levelUpAni();
                                this.mainFish.width = fishesConfig.config[`lv${this.currLevel}`].uW;
                                this.mainFish.height = fishesConfig.config[`lv${this.currLevel}`].uH;
                                this.mainFish.anchorOffsetX = this.mainFish.width / 2;
                                this.mainFish.anchorOffsetY = this.mainFish.height / 2;
                                this.removeEventListener(egret.Event.ENTER_FRAME, this.onEnterFrame, this);
                                break;
                            case 20:
                                this.currLevel = 3;
                                this.levelUpAni();
                                this.mainFish.width = fishesConfig.config[`lv${this.currLevel}`].uW;
                                this.mainFish.height = fishesConfig.config[`lv${this.currLevel}`].uH;
                                this.mainFish.anchorOffsetX = this.mainFish.width / 2;
                                this.mainFish.anchorOffsetY = this.mainFish.height / 2;
                                this.removeEventListener(egret.Event.ENTER_FRAME, this.onEnterFrame, this);
                                break;
                            case 35:
                                this.currLevel = 4;
                                this.levelUpAni();
                                this.mainFish.width = fishesConfig.config[`lv${this.currLevel}`].uW;
                                this.mainFish.height = fishesConfig.config[`lv${this.currLevel}`].uH;
                                this.mainFish.anchorOffsetX = this.mainFish.width / 2;
                                this.mainFish.anchorOffsetY = this.mainFish.height / 2;
                                this.removeEventListener(egret.Event.ENTER_FRAME, this.onEnterFrame, this);
                                break;
                            case 50:
                                this.currLevel = 5;
                                this.levelUpAni();
                                this.mainFish.width = fishesConfig.config[`lv${this.currLevel}`].uW;
                                this.mainFish.height = fishesConfig.config[`lv${this.currLevel}`].uH;
                                this.mainFish.anchorOffsetX = this.mainFish.width / 2;
                                this.mainFish.anchorOffsetY = this.mainFish.height / 2;
                                this.removeEventListener(egret.Event.ENTER_FRAME, this.onEnterFrame, this);
                                break;
                            case 70:
                                this.currLevel = 6;
                                this.levelUpAni();
                                this.mainFish.width = fishesConfig.config[`lv${this.currLevel}`].uW;
                                this.mainFish.height = fishesConfig.config[`lv${this.currLevel}`].uH;
                                this.mainFish.anchorOffsetX = this.mainFish.width / 2;
                                this.mainFish.anchorOffsetY = this.mainFish.height / 2;
                                this.removeEventListener(egret.Event.ENTER_FRAME, this.onEnterFrame, this);
                                break;
                            case 90:
                                this.currLevel = 7;
                                this.levelUpAni();
                                this.mainFish.width = fishesConfig.config[`lv${this.currLevel}`].uW;
                                this.mainFish.height = fishesConfig.config[`lv${this.currLevel}`].uH;
                                this.mainFish.anchorOffsetX = this.mainFish.width / 2;
                                this.mainFish.anchorOffsetY = this.mainFish.height / 2;
                                this.removeEventListener(egret.Event.ENTER_FRAME, this.onEnterFrame, this);
                                break;
                            case 110:
                                this.currLevel = 8;
                                this.levelUpAni();
                                this.mainFish.width = fishesConfig.config[`lv${this.currLevel}`].uW;
                                this.mainFish.height = fishesConfig.config[`lv${this.currLevel}`].uH;
                                this.mainFish.anchorOffsetX = this.mainFish.width / 2;
                                this.mainFish.anchorOffsetY = this.mainFish.height / 2;
                                this.removeEventListener(egret.Event.ENTER_FRAME, this.onEnterFrame, this);
                                break;
                            case 140:
                                this.currLevel = 9;
                                this.levelUpAni();
                                this.mainFish.width = fishesConfig.config[`lv${this.currLevel}`].uW;
                                this.mainFish.height = fishesConfig.config[`lv${this.currLevel}`].uH;
                                this.mainFish.anchorOffsetX = this.mainFish.width / 2;
                                this.mainFish.anchorOffsetY = this.mainFish.height / 2;
                                this.removeEventListener(egret.Event.ENTER_FRAME, this.onEnterFrame, this);
                                break;
                            // case 170:
                            //     this.currLevel = 10;
                            //     this.levelUpAni();
                            //     this.mainFish.width = fishesConfig.config[`lv${this.currLevel}`].uW;
                            //     this.mainFish.height = fishesConfig.config[`lv${this.currLevel}`].uH;
                            //     this.mainFish.anchorOffsetX = this.mainFish.width / 2;
                            //     this.mainFish.anchorOffsetY = this.mainFish.height / 2;
                            //     this.removeEventListener(egret.Event.ENTER_FRAME, this.onEnterFrame, this);
                            //     break;
                        }
                    } else {
                        // 被吃，游戏结束
                        this.gameOver();
                    }
                }
            }
        }
        // console.log(this.eatableFishesPool.length);

    }

    levelUpAni() {
        this.addChild(this.levelUpPanel);
        this.levelUpPanel.visible = true;
        this.levelUpPanel.touchEnabled = false;
        let children = this.levelUpPanel.$children;
        children['forEach'](element => {
            element.touchEnabled = false;
        });
        this.levelUpPanel['dark'].touchEnabled = false;
        this.levelUpPanel['newFish'].source = `eatableFishLv${this.currLevel}_png`;
        this.levelUpPanel['currLevel'].text = `等级：${this.currLevel}`;
        this.levelUpPanel['eatTxt'].x = (750 - (200 + this.levelUpPanel['newFish'].width)) / 2 + 100;
        this.levelUpPanel['eatTxt'].y = 810 + this.levelUpPanel['newFish'].height / 2;
        this.levelUpPanel['newFish'].anchorOffsetX = this.levelUpPanel['newFish'].width / 2;
        this.levelUpPanel['newFish'].anchorOffsetY = this.levelUpPanel['newFish'].height / 2;
        this.levelUpPanel['newFish'].x = (750 - (200 + this.levelUpPanel['newFish'].width)) / 2 + 200 + this.levelUpPanel['newFish'].width / 2 + 10;
        this.levelUpPanel['newFish'].y = 810 + this.levelUpPanel['newFish'].height / 2;
        let star1 = this.levelUpPanel['star1'];
        star1.scaleX = 0;
        star1.scaleY = 0;
        let star2 = this.levelUpPanel['star2'];
        star2.scaleX = 0;
        star2.scaleY = 0;
        let star3 = this.levelUpPanel['star3'];
        star3.scaleX = 0;
        star3.scaleY = 0;
        let ro = this.levelUpPanel['ro'];
        let newFish = this.levelUpPanel['newFish'];
        newFish.scaleX = 2;
        newFish.scaleY = 2;
        let star1TW = egret.Tween.get(star1);
        star1TW.to({ scaleX: 0.9, scaleY: 0.9 }, 300).call(() => {
            let star2TW = egret.Tween.get(star2);
            star2TW.to({ scaleX: 1, scaleY: 1 }, 300).call(() => {
                let star3TW = egret.Tween.get(star3);
                star3TW.to({ scaleX: 0.9, scaleY: 0.9 }, 300).call(() => {
                    this.levelUpPanel.touchEnabled = true;
                    let children = this.levelUpPanel.$children;
                    children['forEach'](element => {
                        element.touchEnabled = false;
                    });
                })
            })
        })

        this.levelUpSpritePool.forEach((sprite) => {
            let spriteTW = egret.Tween.get(sprite, { loop: true });
            sprite.x = GameConst.stage.stageWidth / 2 - 20;
            sprite.y = this.levelUpPanel['fish'].y - 20;
            let targetAngle = Math.random() * 2 * Math.PI;
            let targetX = this.levelUpPanel['fish'].x + 120 * Math.cos(targetAngle);
            let targetY = this.levelUpPanel['fish'].y + 120 * Math.sin(targetAngle);
            spriteTW.wait(Math.random() * 600).to({ x: targetX, y: targetY }, Math.max(Math.random() * 400, 200));
        })

        let roTW = egret.Tween.get(ro, { loop: true });
        roTW.to({ rotation: 360 }, 3000);

        let newFishTW = egret.Tween.get(newFish);
        newFishTW.to({ scaleX: 0.8, scaleY: 0.8 }, 500).to({ scaleX: 1, scaleY: 1 }, 200);
        // let 
    }

    onEffectComplete() {
        this.effect.alpha = 0;
    }

    // 用户鱼下潜
    dive(fish: any) {
        if (this.diveSpeed < 0) {
            this.diveSpeed += this.diveAddSpeed;
            fish.y += this.diveSpeed;
            if (fish.y <= 100) {
                this.diveSpeed = 0;
                fish.y = 100;
            }
        } else {
            if (fish.y < GameConst.stage.stageHeight - 200) {
                this.diveSpeed += this.diveAddSpeed;
                fish.y += this.diveSpeed;
            }
        }
    }

    initEatEffect() {
        this.effect = MovieClipManager.instance.getMovieClipByName('effect_0');
        this.effect.alpha = 0;
        this.effect.anchorOffsetX = this.effect.width / 2;
        this.effect.anchorOffsetY = this.effect.height / 2;
        this.addChild(this.effect);
        this.effect.addEventListener(egret.Event.COMPLETE, this.onEffectComplete, this);
    }

    initBubbles() {
        this.bubbleMoveCount = 0;
        this.bubblePool = [];
        for (let i = 0; i < 6; i++) {
            let bubble = new eui.Image;
            bubble.source = 'bubble_png';
            bubble.x = Math.max(Math.random() * 1, 0.5) * 750 / 6 + 750 / 6 * (i - 1);
            bubble['dir'] = [-1, 1][Math.round(Math.random() * (2 - 1))];
            bubble.y = GameConst.stage.stageHeight;
            bubble.scaleX = 0;
            bubble.scaleY = 0;
            this.addChild(bubble);
            this.addChild(this.mainFish);
            this.bubblePool.push(bubble);

            setTimeout(() => {
                let bubbleTW = egret.Tween.get(bubble, { loop: true, onChange: this.updatebubble.bind(this) });
                let nScaleX = Math.max(Math.random() * 1.6, 0.8);
                let nY = GameConst.stage.stageHeight - 300;
                bubbleTW.to({ scaleX: nScaleX, scaleY: nScaleX, y: nY }, 1000).to({ y: 300 }, 2500);
            }, Math.random() * 3000)
        }
    }

    updatebubble(e) {
        this.bubbleMoveCount++;
        for (let i = 0; i < this.bubblePool.length; i++) {
            let speed = 0.3;
            let bubble = this.bubblePool[i];
            setTimeout(() => {
                bubble.x += Math.cos(this.bubbleMoveCount / 400) * bubble.dir * speed;
            }, (i + 1) * 300);
        }
    }

    // 初始化所有事件
    initEvents() {
        this.levelUpPanel.addEventListener(egret.TouchEvent.TOUCH_TAP, this.onTap_levelUpPanel, this);
        this.addEventListener(egret.TouchEvent.TOUCH_BEGIN, this.onTap_stage, this);
    }

    // 移除所有事件
    removeEvents() {
        this.levelUpPanel.removeEventListener(egret.TouchEvent.TOUCH_TAP, this.onTap_levelUpPanel, this);
        this.removeEventListener(egret.TouchEvent.TOUCH_BEGIN, this.onTap_stage, this);
    }


    onTap_levelUpPanel(e) {
        this.levelUpPanel.visible = false;
        this.bgSpeed += 0.2;
        // 监听动画帧
        this.addEventListener(egret.Event.ENTER_FRAME, this.onEnterFrame, this);
    }

    onTap_stage() {
        this.diveSpeed = -12;
    }


    // 游戏结束
    private gameOver() {
        this.removeEventListener(egret.Event.ENTER_FRAME, this.onEnterFrame, this);
        egret.Tween.removeAllTweens();
        let maxLevel = GCache.readCache(`maxLevel`);
        if (maxLevel) {
            if (this.currLevel > Number(GCache.readCache(`maxLevel`))) {
                GCache.writeCache(`maxLevel`, this.currLevel);
            }
        } else {
            GCache.writeCache(`maxLevel`, this.currLevel);
        }
        this.gameSubmit(this.gameSubmitResult, this.currLevel);
    }

    // 提交成绩的回调
    private gameSubmitResult(success) {
        if (!success) {
            return;
        }
        let data = { score: this.currLevel }
        if (DataManager.ins.gameGetSubmitResultData && DataManager.ins.gameGetSubmitResultData.lottery) {
            PanelCtrl.instance.show(ModuleTypes.PRIZE_PANEL, data);
        } else {
            PanelCtrl.instance.show(ModuleTypes.NOPRIZE_PANEL, data);
        }
    }

    /**
     * 提交游戏成绩
     * @param callback 
     * @param score 得分
     * @param allDynamics 防作弊数据
     * @param checkScore  是否校验得分
     * @param customizedType 定制类型 1推币机    
     */
    protected gameSubmit(callback: Function, score: number, checkScore?: boolean, customizedType?: number): void {
        NetManager.ins.gameSubmit(
            (success: boolean) => {
                if (success) {
                    this.getSubmitResult(callback, DataManager.ins.gameSubmitData.orderId);
                } else {
                    callback(success);
                }
            },
            DataManager.ins.doStartData.ticketId,
            score,
            '[]',
            DataManager.ins.doStartData.submitToken,
            '',
            checkScore,
            customizedType);
    }

    /**
     * 查询提交结果
     * @param callback 
     * @param orderId 
     */
    private getSubmitResult(callback: Function, orderId: number): void {
        NetManager.ins.getSubmitResult(callback, orderId, () => {
            return DataManager.ins.gameGetSubmitResultData.flag;
        });
    }

}