import { EConfigConst } from "../cfg/ConfigDef";
import { BulletItem } from "../cfg/bulletItem";
import { ConfigMgr } from "../cfg/configMgr";
import { Utils } from "../common/utils";
import { MonsterModel } from "../monster/monsterModel";
import monsterbullet from "../monster/monsterbullet";
import bullet from "../player/bullet";
import { ResMgr } from "../res/resMgr";
import { ResRelease } from "../res/resRelease";
import DelayStop from "../update/delayStop";
import { GameSysLogic } from "../update/gameSysLogic";
import Move from "../update/move";
import MoveTime from "../update/moveTime";
import { ZooMgr } from "../zoo/zooMgr";

/**
 * 1 扇形弹幕: 开始角度(相对于向上), 角度，数量
 * 2 旋转飞行:  半径
 * 3 直线:  开始角度
 * 4 直线后炸开: 时间,开始角度,数量
 */

enum EBulletZ {
    monster,
    player,
}

interface IMonsterBullet{
    worldPos: cc.Vec2;
    dirction: cc.Vec2;
    atk: number;
}

export class Barrage extends GameSysLogic{
    layer: cc.Node;

    static skillNum = 1;

    private static _inst: Barrage;
    public static get inst(): Barrage {
        if (this._inst == null) {
            this._inst = new Barrage();
        }
        return this._inst;
    }

    async createPlayerBullet(worldPos: cc.Vec2){
        switch(Barrage.skillNum){
            case 1:
                this.createPlayerBullet1(worldPos);
                break;
            case 2:
                this.createPlayerBullet2(worldPos);
                break;
            case 3:
                this.createPlayerBullet3(worldPos);
                break;
            case 4:
                this.createPlayerBullet4(worldPos);
                break;
        }
    }

    createMonsterBulletByZooid(monsterZooid: number, id: string){
        let bulletItem = ConfigMgr.inst.getCfgClassById(EConfigConst.bullet, id, BulletItem);
        let monsterNode = ZooMgr.inst.get(monsterZooid).node;
        let model = monsterNode.getComponent(MonsterModel);
        let worldPos = monsterNode.convertToWorldSpaceAR(cc.Vec2.ZERO);
        let dirction = monsterNode.convertToWorldSpaceAR(cc.v2(0,-1));
        dirction = dirction.sub(worldPos).normalize();

        let data: IMonsterBullet = {
            worldPos,
            dirction,
            atk: model.atk,
        };

        this.createMonsterBullet(data, bulletItem);
    }

    
    createMonsterBullet(data: IMonsterBullet, bulletItem: BulletItem) {
        switch (Utils.intDefault(bulletItem.data.travel, 1)) {
            case 1:
                this.createBulletById1(data, bulletItem);
                break;
            case 2:
                this.createBulletById2(data, bulletItem);
                break;
            case 3:
                this.createBulletById3(data, bulletItem);
                break;
            case 4:
                this.createBulletById4(data, bulletItem);
                break;
        }
    }

    // 直线
    async createBulletById1(data: IMonsterBullet, bulletData: BulletItem){
        let bulletNode = await ResMgr.inst.loadPrefab('monster/monsterBullet', this.layer);

        let worldPos = data.worldPos;
        let dirction = data.dirction;
        let bulletCpt = bulletNode.getComponent(monsterbullet);
        bulletCpt.atk = Utils.intDefault(bulletData.data.effect1) * data.atk;

        bulletNode.zIndex = EBulletZ.monster;
        let moveCpt = Utils.getCpt(Move, bulletNode);
        moveCpt.dirction = dirction;
        moveCpt.speed = Utils.intDefault(bulletData.data.speed, 500);
        let localPos = this.layer.convertToNodeSpaceAR(worldPos);
        bulletNode.setPosition(localPos);

        let endJson = Utils.strToJson(bulletData.data.end);
        if(endJson[0]== 2) {
            let delayCpt = bulletNode.addComponent(DelayStop)
            delayCpt.time = endJson[1] / 100;
            delayCpt.call = ()=>{
                bulletNode.destroy();
            }
        }
    }

    // 直线
    async createPlayerBullet1(worldPos: cc.Vec2){
        let bulletNode = await ResMgr.inst.loadPrefab('monster/bullet', this.layer);
        bulletNode.zIndex = EBulletZ.player;
        let moveCpt = Utils.getCpt(Move, bulletNode);
        moveCpt.dirction = cc.v2(0,1);
        moveCpt.speed = 500;
        let localPos = this.layer.convertToNodeSpaceAR(worldPos);
        bulletNode.setPosition(localPos);
    }

    // 扇形弹幕
    async createBulletById2(data: IMonsterBullet, bulletData: BulletItem){
        let worldPos = data.worldPos;
        let dirction = data.dirction;


        dirction = dirction.sub(worldPos).normalize();
        let paramJson = Utils.strToJson(bulletData.data.param);
        let num = paramJson[2];
        let angle = paramJson[1];
        let leftVec2 = dirction.rotateSelf(Utils.radian(angle/2));
        let prefab = await ResMgr.inst.getPrefab('monster/monsterBullet');

        for (let index = 0; index < num; index++) {
            let bulletNode = ResMgr.inst.createNode(prefab, this.layer)

            let bulletCpt = bulletNode.getComponent(monsterbullet);
            bulletCpt.atk = Utils.intDefault(bulletData.data.effect1) * data.atk;

            bulletNode.zIndex = EBulletZ.monster;
            let moveCpt = Utils.getCpt(Move, bulletNode);
            if(angle == 360){
                moveCpt.dirction = leftVec2.rotate(Utils.radian(-angle / (num) * index));
            }
            else{
                moveCpt.dirction = leftVec2.rotate(Utils.radian(-angle / (num-1) * index));
            }
            moveCpt.speed = Utils.intDefault(bulletData.data.speed, 500);
            let localPos = this.layer.convertToNodeSpaceAR(worldPos);
            bulletNode.setPosition(localPos);

            let endJson = Utils.strToJson(bulletData.data.end);
            if(endJson[0]== 2) {
                let delayCpt = bulletNode.addComponent(DelayStop)
                delayCpt.time = endJson[1] / 100;
                delayCpt.call = ()=>{
                    bulletNode.destroy();
                }
            }
        }
    }

    // 扇形弹幕
    async createPlayerBullet2(worldPos: cc.Vec2){
        let num = 9;
        let angle = 60;
        let leftVec2 = cc.v2(0,1).rotateSelf(Utils.radian(angle/2));
        let prefab = await ResMgr.inst.getPrefab('monster/bullet');

        for (let index = 0; index < num; index++) {
            let bulletNode = ResMgr.inst.createNode(prefab, this.layer)
            bulletNode.zIndex = EBulletZ.player;
            
            let bulletCpt = bulletNode.getComponent(bullet);
            let moveCpt = Utils.getCpt(Move, bulletNode);
            moveCpt.dirction = leftVec2.rotate(Utils.radian(-angle / (num-1) * index));
            moveCpt.speed = 500;
            bulletCpt.setDirction(moveCpt.dirction);
            let localPos = this.layer.convertToNodeSpaceAR(worldPos);
            bulletNode.setPosition(localPos);
        }
    }

    // 直线炸开
    async createBulletById4(data: IMonsterBullet, bulletData: BulletItem){
        // monsterZooid: number,
        let worldPos = data.worldPos;
        let dirction = data.dirction;

        let prefab = await ResMgr.inst.getPrefab('monster/monsterBullet');
        let bulletNode = ResMgr.inst.createNode(prefab, this.layer)
        bulletNode.zIndex = EBulletZ.monster;

        let bulletCpt = bulletNode.getComponent(monsterbullet);
        bulletCpt.atk = Utils.intDefault(bulletData.data.effect1) * data.atk;
        
        let paramJson = Utils.strToJson(bulletData.data.param);
        let speed = Utils.intDefault(bulletData.data.speed, 500);

        let time = Utils.intDefault(paramJson[1], 100) / 100;
        let moveCpt = Utils.getCpt(MoveTime, bulletNode);
        moveCpt.dirction = dirction;
        moveCpt.speed = speed;
        moveCpt.overTime =  time;

        moveCpt.call = ()=>{
            let subWorldPos = bulletNode.convertToWorldSpaceAR(cc.Vec2.ZERO);
            let subBulletItem = ConfigMgr.inst.getCfgClassById(EConfigConst.bullet, paramJson[2], BulletItem);
            this.createMonsterBullet({
                worldPos: subWorldPos,
                dirction,
                atk: data.atk,
            }, subBulletItem);

            bulletNode.destroy();
            console.log('@@=',bulletNode.getPosition().toString());
        }
        let localPos = this.layer.convertToNodeSpaceAR(worldPos);
        bulletNode.setPosition(localPos);

        let endJson = Utils.strToJson(bulletData.data.end);
        if(endJson[0]== 2) {
            let delayCpt = bulletNode.addComponent(DelayStop)
            delayCpt.time = endJson[1] / 100;
            delayCpt.call = ()=>{
                bulletNode.destroy();
            }
        }
    }

    // 直线炸开
    async createPlayerBullet4(worldPos: cc.Vec2){
        let time = 1;

        let prefab = await ResMgr.inst.getPrefab('monster/bullet');
        let bulletNode = ResMgr.inst.createNode(prefab, this.layer)
        bulletNode.zIndex = EBulletZ.player;

        let moveCpt = Utils.getCpt(MoveTime, bulletNode);
        moveCpt.dirction = cc.v2(0,1);
        moveCpt.speed = 500;
        moveCpt.overTime =  time;

        moveCpt.call = ()=>{
            let num = 10;
            let angle = 360;
            let leftVec2 = cc.v2(1,1).normalize();
    
            for (let index = 0; index < num; index++) {
                let bulletNode1 = ResMgr.inst.createNode(prefab, this.layer)
                bulletNode1.zIndex = EBulletZ.player;
                let bulletCpt = bulletNode1.getComponent(bullet);
                let moveCpt = Utils.getCpt(Move, bulletNode1);
    
                moveCpt.dirction = leftVec2.rotate(Utils.radian(-angle / (num) * index));
                moveCpt.speed = 500;
                bulletCpt.setDirction(moveCpt.dirction);
                bulletNode1.setPosition(bulletNode.getPosition());

                // console.log( "@@-", bulletNode1.getPosition().toString());
            }
            bulletNode.destroy();
            console.log('@@=',bulletNode.getPosition().toString());
        }
        let localPos = this.layer.convertToNodeSpaceAR(worldPos);
        bulletNode.setPosition(localPos);
    }

    // 旋转弹幕 --
    async createBulletById3(data: IMonsterBullet, bulletData: BulletItem){ 
        let worldPos = data.worldPos;
        let dirction = data.dirction;
        
        let paramJson = Utils.strToJson(bulletData.data.param);
        let r = paramJson[1];
        let num = paramJson[2];
        let leftVec2 = dirction;
        let angle = 360;
        let prefab = await ResMgr.inst.getPrefab('monster/monsterBullet');

        let cricleNode = new cc.Node('cricleBullet');
        this.layer.addChild(cricleNode);

        let moveCpt = Utils.getCpt(Move, cricleNode);
        moveCpt.dirction = dirction;
        moveCpt.speed = Utils.intDefault(bulletData.data.speed, 500);

        let localPos = this.layer.convertToNodeSpaceAR(worldPos);
        cricleNode.setPosition(localPos);

        let t = cc.tween(cricleNode).by(1, {angle: 360}).repeatForever().start();

        let isOver = ()=>{ 
            if(cc.isValid(cricleNode, true)){
                if(cricleNode.childrenCount <= 0){
                    t.stop();
                    cricleNode.destroy();
                }
            }
        }

        for (let index = 0; index < num; index++) {
            let bulletNode = ResMgr.inst.createNode(prefab, cricleNode)
            let bulletCpt = bulletNode.getComponent(monsterbullet);

            bulletCpt.atk = Utils.intDefault(bulletData.data.effect1) * data.atk;
            bulletNode.zIndex = EBulletZ.monster;

            let dirction = leftVec2.rotate(Utils.radian(-angle / (num) * index));
            bulletNode.setPosition(dirction.mul(r));
            bulletCpt.setDirction(dirction.rotate(Utils.radian(90)));

            bulletNode.addComponent(ResRelease).call = function(){
                isOver();
            }

            let endJson = Utils.strToJson(bulletData.data.end);
            if(endJson[0]== 2) {
                let delayCpt = bulletNode.addComponent(DelayStop)
                delayCpt.time = endJson[1] / 100;
                delayCpt.call = ()=>{
                    bulletNode.destroy();
                }
            }
        }
    }

    // 旋转弹幕
    async createPlayerBullet3(worldPos: cc.Vec2){
        let num = 8;
        let r = 40;
        let leftVec2 = cc.v2(0,1)
        let angle = 360;
        let prefab = await ResMgr.inst.getPrefab('monster/bullet');

        let node = new cc.Node('cricleBullet');
        this.layer.addChild(node);

        let moveCpt = Utils.getCpt(Move, node);
        moveCpt.dirction = cc.v2(0,1);
        moveCpt.speed = 500;
        let localPos = this.layer.convertToNodeSpaceAR(worldPos);
        node.setPosition(localPos);

        let t = cc.tween(node).by(1, {angle: 360}).repeatForever().start();

        let isOver = ()=>{ 
            if(cc.isValid(node, true)){
                if(node.childrenCount <= 0){
                    t.stop();
                    node.destroy();
                }
            }
        }

        for (let index = 0; index < num; index++) {
            let bulletNode = ResMgr.inst.createNode(prefab, node)
            let bulletCpt = bulletNode.getComponent(bullet);
            bulletNode.zIndex = EBulletZ.player;

            let dirction = leftVec2.rotate(Utils.radian(-angle / (num) * index));
            bulletNode.setPosition(dirction.mul(r));
            bulletCpt.setDirction(dirction.rotate(Utils.radian(90)));


            bulletNode.addComponent(ResRelease).call = function(){
                setTimeout(() => {
                    isOver();
                }, 100);
            }
        }
    }
}