import { ResMgr } from "../res/resMgr";
import { ConfigConst, EConfigConst } from "../cfg/ConfigDef";
import { ConfigMgr } from "../cfg/configMgr";
import { NestItem } from "../cfg/nestItem";
import { Utils } from "../common/utils";
import { MonsterModel } from "../monster/monsterModel";

const patternArr = [
    'monster',
    'pattern',
    'pattern2',
    'monsterboss',
];

const Shape = {
    101: 'monster',
    701: 'pattern',
    501: 'pattern2',
    103: 'monsterboss',
    102: 'monsterboss2',
    201: 'pattern201',
    202: 'pattern202',

}

const aniArr = [
    ['line-1700'], // 直线, 顶部到底部 1
    ['yingji', 'yingji1'], // 从上飞入，左右循环摆动
    ['jiejizhiyuan_L'], // 从左弧线飞入，飞出屏幕
    ['jiejizhiyuan_R'], // 从右弧线飞入，飞出屏幕
    ['zhuiji_L'], // 从左下往右上飞入，折线从右侧飞出 5
    ['zhuiji_R'], //
    ['yingji', 'loopCricle'], // 从上飞入，圆弧运动
    ['ani8'],// 从坐上往右下飞入，从右下飞出
    ['ani9'], // 8 的反向
    ['yingji'], // 从上飞入 10
    ['ani11'],
    ['ani12'],
    ['ani13'], // 直线向下，横向交替--左
    ['ani14'],
    ['ani15'], // 向下飞入，弧线转弯，向上飞出
    ['yingji'], // 16
    ['ani17', 'ani17_1'],
    ['ani18', 'ani18_1'],
]

const {ccclass, property, executeInEditMode, playOnFocus} = cc._decorator;
@ccclass
export class NestPlay extends cc.Component {
    monsterNode: cc.Node;
    timeArr = [];
    monsterCnt: number;
    num: number;
    monster: cc.Prefab;
    aniClip: cc.AnimationClip[];
    time: number;
    pattern: any;
    private _id: string;
    private _level: number;
    bullet: string;
    
    async init(id: string, level: number){
        this._id = id;
        this._level = level;

        let nestItem = ConfigMgr.inst.getCfgClassById<NestItem>(EConfigConst.nest, id, NestItem);
        let shapeId = Utils.intDefault(nestItem.data.shape);
        let monsterName = 'monster/' + Shape[shapeId];
        this.num = Utils.intDefault(nestItem.data.num, 1);
        let delay = Utils.intDefault(nestItem.data.delay);
        this.time = Utils.intDefault(nestItem.data.time) / 100;
        let type = Utils.intDefault(nestItem.data.type, 1);
        this.pattern = Utils.strToJson(nestItem.data.pattern);
        this.bullet = nestItem.data.bullet;

        let aniName = aniArr[type-1].map(v=>{return 'level/'+v});
        let posJson = Utils.pos2vec2(nestItem.data.pos);
        this.node.setPosition(posJson);
        this.aniClip = await ResMgr.inst.loadAniArr(aniName, this.node);
        this.monster = await ResMgr.inst.getPrefab(monsterName);
        this.monster.addRef();

        let monsterNode = new cc.Node('monsterGroup');
        this.monsterNode = monsterNode;
        this.node.addChild(monsterNode);

        cc.log('[nestPlay] [init]',`[num:${this.num}] [time:${this.time}]`);

        if(delay > 0) {
            let tId = setTimeout(() => {
                this.createMonster();
            }, delay * 1000);

            this.timeArr.push(tId);
        }
        else{
            this.createMonster();
        }
    }

    protected onDestroy(): void {
        this.monster.decRef();
    }

    createMonster(){
        this.createMonster2();
    }

    setPattern(monsterNode: cc.Node){
        let arr = [];
        this.pattern.forEach(v => {
            for (let index = 0; index < v[0]; index++) {
                arr.push(v[1]);
            }
        });
        if(arr.length == 0){
            cc.error('[nestPlay] [pattern] 配置空',`[nestId:${this._id}]`);
            arr.push('1001');
        }

        let bulletArr = [];
        let json = Utils.strToJson(this.bullet);
        json.forEach(v=>{
            if(v.length <= 0) return;
            
            for (let index = 0; index < v[0]; index++) {
                bulletArr.push(v);
            }
        });


        let models = monsterNode.getComponentsInChildren(MonsterModel);
        models.forEach((v, k)=>{
            let id = '1001';
            if(k < arr.length){
                id = arr[k];
            }
            else{
                id = arr[arr.length-1];
            }

            v.init(id, this._level);
            
            if(k< bulletArr.length){
                v.setBullet(bulletArr[k])
            }
            else{
                v.setBullet(null);
            }
        });
    }

    createMonster2(){
        this.monsterCnt = 0;
        for (let index = 0; index < this.num; index++) {
            let tId = setTimeout(() => {
                this.monsterCnt++;

                cc.log('[nestPlay] [create]',`[num:${this.monsterCnt} / ${this.num}]`);
                let monsterNode = ResMgr.inst.createNode(this.monster, this.monsterNode);

                this.setPattern(monsterNode);

                let cnt = 0;
                let callAni = ()=>{

                    if(!cc.isValid(monsterNode, true)){
                        return;
                    }

                    let aniNode = new cc.Node('AniItem');
                    let parent = monsterNode.parent ? monsterNode.parent : this.monsterNode;
                    monsterNode.removeFromParent(false);
                    aniNode.addChild(monsterNode);
                    parent.addChild(aniNode);

                    let ani = aniNode.addComponent(cc.Animation);
                    ani.addClip(this.aniClip[cnt], 'path')
                    ani.play('path');
                    ani.once(cc.Animation.EventType.FINISHED, ()=>{
                        cnt++;
                        if(cnt < this.aniClip.length){
                            aniNode.angle = 0;
                            callAni();
                        }
                        else{
                            let nodeBox = aniNode.getBoundingBoxToWorld();
                            let viewsize = cc.view.getVisibleSize();
                            let viewBox = cc.rect(0,0,viewsize.width,viewsize.height);
                            // cc.log('@@', nodeBox.toString(), viewBox.toString());
                            if(!viewBox.containsRect(nodeBox)) {
                                aniNode.destroy();
                            }
                        }
                    });
                }

                callAni();


            }, 1000 * this.time * index);
            this.timeArr.push(tId);
        }
    }


    createMonster1(){
        this.monsterCnt = 0;
        for (let index = 0; index < this.num; index++) {
            let tId = setTimeout(() => {

                let aniNode = new cc.Node('AniItem');
                ResMgr.inst.createNode(this.monster, aniNode);
                let ani = aniNode.addComponent(cc.Animation);
                ani.addClip(this.aniClip[0], "path");

                this.monsterNode.addChild(aniNode);
                ani.play('path');
                this.monsterCnt++;
                ani.once(cc.Animation.EventType.FINISHED, ()=>{
                    let nodeBox = aniNode.getBoundingBoxToWorld();
                    let viewBox = cc.view.getViewportRect();

                    if(!viewBox.containsRect(nodeBox)) {
                        aniNode.destroy();
                    }
                });
            }, 1000 * this.time * index);

            this.timeArr.push(tId);
        }
    }

    isDone(){
        return this.monsterCnt == this.num;
    }

    waitDone(): Promise<void> {
        return new Promise(resolve=>{
            let id = setInterval(()=>{
                if(this.isDone()){
                    clearInterval(id);
                    resolve();
                }
            },100);
        });
    }
}