import CMath from "../../../../util/CMath";
import FSprite, { SpriteActionType } from "../FSprite";
import SkillBase from "../skill/SkillBase";

/**
 * 基础AI
 */
const {ccclass, property} = cc._decorator;

/**
 * 基础AI设定
 * 1.范围巡逻
 * 2.攻击进入范围内的敌人
 * 3.距离超出后脱离战斗
 */

@ccclass
export default class AIBase extends cc.Component {
    /**
     * AI灵敏度
     * 发现敌人后多久开始行动
     */
    @property({
        displayName: '灵敏度(毫秒)'
    })
    public AI_CD:number = 1000;
    /**
     * 移动速度
     */
    @property({
        displayName: '角色移动速度'
    })
    public speed = 50;
    /**
     * 当前AI拥有的全部技能
     */
    public skills:Array<SkillBase> = null;

    /**
     * 当前AI控制的精灵
     */
    public sprite:FSprite;
    /**
     * 攻击目标
     */
    public target:FSprite;
    
    /**
     * 最后一次执行AI事件
     */
    public AI_Time = 0;
    /**
     * 最后一次执行攻击事件
     */
    public atk_Time = 0;
    /**
     * 是否可以释放技能
     */
    public canSkill = true;

    onLoad () {
        this.sprite = this.node.getComponent(FSprite);
        this.sprite.SPEED_WALK = this.speed;

        this.skills = this.node.getComponents(SkillBase);
    }
    public setTarget(target:FSprite){
        if(target != this.target){
            this.target = target;
        }
    }
    /**
     * 查询目标
     */
    public checkTarget():FSprite{
        if(this.target){
            if(this.target.isValid && this.target.hp > 0){
            }else{
                //死亡或者销毁后查询新的目标
                this.target = this.sprite.findEnemy(500).sprite;
            }
        }else{
            this.target = this.sprite.findEnemy(500).sprite;
        }
        return this.target;
    }
    update (dt) {
        if(this.sprite && this.sprite.isActive){
            if(this.sprite.gamePause){
                return;
            }
            this.AI();
        }
    }
    
    public AI(){
        //查询是否有可攻击目标
        //查询是否有可用技能
        //查询可用技能是否在当前技能攻击范围以内
        //超出范围,执行AI移动
        //执行巡逻任务
        if(!this.canSkill){
            return;
        }
        let target = this.checkTarget();
        if(target){
            if(this.skills.length > 0){
                let skill:SkillBase = this.checkSkill(target);
                if(skill){
                    if(this.speed <= 0){
                        this.canSkill = false;
                        skill.exe(target,()=>{
                            this.canSkill = true;
                            // cc.log('技能使用结束 :',skill)
                        });
                    }else{
                        let p1 = this.sprite.node.getPosition()
                        let p2 = target.node.getPosition()
                        let dis = CMath.getDistance(p1,p2);
                        if(dis < skill.range){
                            this.canSkill = false;
                            skill.exe(target,()=>{
                                this.canSkill = true;
                                // cc.log('技能使用结束 :',skill)
                            });
                        }else{
                            this.walk(skill.range);
                            // this.moveToTarget(target)
                        }
                    }
                }
            }
        }
        // else{
        //     if(this.AI_Time == 0){
        //         this.AI_Time = time;
        //     }else if(time - this.AI_Time > this.AI_CD){
        //         this.AI_Time = time;
        //         this.walk(0);
        //     }
        // }
    }
    /**
     * 查询可用技能
     */
    public checkSkill(target:FSprite):SkillBase{
        let lists:Array<SkillBase> = [];
        for (let i = 0; i < this.skills.length; i++) {
            const element = this.skills[i];
            if(element.ready()){
                lists.push(element);
            }
        }
        if(lists.length <= 0){
            return null;
        }else{
            let index = CMath.getRandom(0,lists.length-1);
            return lists[index];

            // let p1 = this.node.getPosition();
            // let p2 = target.node.getPosition();
            // let dis = cc.Vec2.distance(p1,p2);
            // let fList = [];
            // for (let i = 0; i < lists.length; i++) {
            //     const element = lists[i];
            //     if(dis < element.range){
            //         fList.push(element);
            //     }
            // }
            // if(fList.length <= 0){
            //     this.moveToTarget(target);
            //     return null;
            // }else{
            //     this.sprite.playAction(SpriteActionType.stand,true)
            //     let index = CMath.getRandom(0,fList.length-1);
            //     return fList[index];
            // }
        }
    }
    /**
     * 向目标移动
     * @param target 
     */
    private moveToTarget(target:FSprite){
        this.sprite.playAction(SpriteActionType.move,true)
        let p1 = target.node.getPosition();
        let p2 = this.sprite.node.getPosition();
        this.atk_Time = 0;
        let tmp = {
            x:0,
            y:0
        }
        let px1 = p1.x - p2.x;
        if(Math.abs(px1) < 50){
            tmp.x = 0;
        }else if(px1 > 0){
            tmp.x = 1;
        }else{
            tmp.x = -1;
        }
        let py1 = p1.y - p2.y;
        if(Math.abs(py1) < 50){
            tmp.y = 0;
        }else if(py1 > 0){
            tmp.y = 1;
        }else{
            tmp.y = -1;
        }
        this.sprite.setDir(tmp);
    }

    /**
     * 远程怪物的闲逛
     */
    public walk(distance){
        if(this.speed > 0){
            this.canSkill = false;
            this.sprite.setDir(this.getRandState(distance));
            this.sprite.playAction(SpriteActionType.move,true)
            cc.tween(this).delay(0.5).call(()=>{
                this.sprite.setDir({x:0,y:0});
                this.sprite.playAction(SpriteActionType.stand,true)
            }).delay(1).call(()=>{
                this.canSkill = true;
            }).start()
        }else{
            this.canSkill = true;
            this.sprite.setDir({x:0,y:0});
            this.sprite.playAction(SpriteActionType.stand,true)
        }
    }

    public getRandState(distance){
        if(this.target && this.target.isValid && this.target.hp > 0){//如果有目标
            let p1 = this.target.node.getPosition();
            let p2 = this.sprite.node.getPosition();

            let dis = CMath.getDistance(p1,p2);
            if(dis > distance){
                let tmp = {
                    x:0,
                    y:0
                }
                let px1 = p1.x - p2.x;
                if(Math.abs(px1) < 50){
                    tmp.x = 0;
                }else if(px1 > 0){
                    tmp.x = 1;
                }else{
                    tmp.x = -1;
                }
                let py1 = p1.y - p2.y;
                if(Math.abs(py1) < 50){
                    tmp.y = 0;
                }else if(py1 > 0){
                    tmp.y = 1;
                }else{
                    tmp.y = -1;
                }
                return tmp;
            }
            // else if(dis < 100){
            //     let tmp = {
            //         x:0,
            //         y:0
            //     }
            //     let px1 = p1.x - p2.x;
            //     if(Math.abs(px1) < 50){
            //         tmp.x = 0;
            //     }else if(px1 > 0){
            //         tmp.x = -1;
            //     }else{
            //         tmp.x = 1;
            //     }

            //     let py1 = p1.y - p2.y;
            //     if(Math.abs(py1) < 50){
            //         tmp.y = 0;
            //     }else if(py1 > 0){
            //         tmp.y = -1;
            //     }else{
            //         tmp.y = 1;
            //     }
            //     return tmp;
            // }
        }
        let rand = CMath.getRandom(1,80);
        if(rand < 10){
            return {x:1,y:0};
        }else if(rand < 20){
            return {x:1,y:1};
        }else if(rand < 30){
            return {x:1,y:-1};
        }else if(rand < 40){
            return {x:0,y:1};
        }else if(rand < 50){
            return {x:0,y:-1};
        }else if(rand < 60){
            return {x:-1,y:0};
        }else if(rand < 70){
            return {x:-1,y:1};
        }else{
            return {x:-1,y:1};
        }
    }

}
