import { _decorator, Component, Node, log, AnimationComponent, RigidBodyComponent, Vec3, find, ParticleSystemComponent, instantiate } from 'cc';
import { SoundManager } from '../../../../engines/sounds/SoundManager';
import CCSAnimationUtils from '../../../../engines/utils/CCSAnimationUtils';
import { MathUtils } from '../../../../engines/utils/MathUtils';
import GameConfigManager from '../../../models/GameConfigManager';
import { GameController } from '../GameController';
import { MonsterHP } from './MonsterHP';
import { MonsterHPUIPool } from './MonsterHPUIPool';
const { ccclass, property } = _decorator;

@ccclass('MonsterBase')
export class MonsterBase extends Component {
    config:any;
    monsterConfig:any;
    
    hpView:MonsterHP;
    /**
     * 血量
     */
    hp:number=0;
    /**
     * 最大血量
     */
    maxHP:number=0;
    /**
     * 伤害
     */
    damage:number;

    private speedVec3:Vec3=new Vec3();
    private speedVec3N:Vec3=new Vec3();
    private endNode:Node;
    
    private animation:AnimationComponent;
    /**
     * 0 移动 1攻击 2 被攻击 3死亡
     */
    private state:number=0;
    /**
     * 攻击类型 0攻击栅栏 1攻击玩家
     */
    private attackType:number=0;

    /**
     * 弹痕粒子
     */
    private danHen:AnimationComponent;
    

    start () {
        this.monsterConfig=GameConfigManager.GetMonsterConfig(this.config.monsterId);
        this.hp=this.maxHP=this.config.hp;
        this.damage=this.config.damage;

        this.animation=this.getComponent(AnimationComponent);
        if(this.animation==null){
            throw new Error("动画组件为空！");
        }

        this.InitAnimations();
        this.InitPostitionAndEndPos();
        this.InitScale();
    }


    /**
     * 子节点收集
     * @param root 
     * @param list 
     */
    private getChildren(root:Node,list:Node[]):void{
        root.children.forEach(element => {
            list.push(element);
            if(element.children.length>0){
                this.getChildren(element,list);
            }
        });
    }

    /**
     * 动画数据初始化
     */
    private InitAnimations():void{
        CCSAnimationUtils.SetAnimationSpeed(this.animation,this.monsterConfig.moveAnimation,this.monsterConfig.moveAnimationSpeed);
        CCSAnimationUtils.SetAnimationSpeed(this.animation,this.monsterConfig.attackAnimation,this.monsterConfig.attackAnimationSpeed);
        // CCSAnimationUtils.SetAnimationEvent(this.animation,this.monsterConfig.attackAnimation,this.monsterConfig.attackAnimationEvents);
        CCSAnimationUtils.SetAnimationSpeed(this.animation,this.monsterConfig.dieAnimation,this.monsterConfig.dieAnimationSpeed);
    }

    /**
     * 初始化开始位置及结束位置
     */
    private InitPostitionAndEndPos():void{
        //左
        if(this.config.startPos==0){
            this.endNode=GameController.single.leftEndNode;
        }else if(this.config.startPos==1){//中
            this.endNode=GameController.single.middleEndNode;
        }else{//右
            this.endNode=GameController.single.rightEndNode;
        }
        Vec3.subtract(this.speedVec3N,this.endNode.worldPosition,this.node.worldPosition);
        this.speedVec3N.normalize();
        this.Move();
    }

    /**
     * 初始化Scale
     */
    private InitScale():void{
        let scale:Vec3=this.node.scale;
        scale.x*=this.monsterConfig.scale.x;
        scale.y*=this.monsterConfig.scale.y;
        scale.z*=this.monsterConfig.scale.z;
        this.node.setScale(scale);
    }
    
    update (deltaTime: number) {
        if(GameController.single.GameOver){
            return;
        }
        if(GameController.single.paused){
            this.animation.pause();
            return;
        }else{
            this.animation.resume();
        }
        if(this.isDie){
            return;
        }
        let dis:number;
        if(GameController.single.fence.IsDie==false){
            dis=Vec3.distance(GameController.single.fence.node.worldPosition,this.node.worldPosition);
            if(dis<2){
                this.Attack(0);
            }else{
                this.Move();
            }
        }else{
            dis=Vec3.distance(this.endNode.worldPosition,this.node.worldPosition);
            //到达终点
            if(dis<0.5){
                //攻击
                this.Attack(1);
                return;
            }else{
                this.Move();
            }
        }
        if(this.state==0){
            this.MoveUpdate(deltaTime);
        }
    }

    /**
     * 开始移动
     */
    Move():void{
        if(this.state>0){
            return;
        }
        this.removeAllAnimationEvent();
        this.state=0;
    }

    private MoveUpdate(deltaTime:number):void{
        this.animation.crossFade(this.monsterConfig.moveAnimation);
        let currentPos:Vec3=this.node.position;
        Vec3.multiplyScalar(this.speedVec3,this.speedVec3N,this.monsterConfig.moveSpeed*deltaTime);
        Vec3.add(currentPos,currentPos,this.speedVec3);
        this.node.setPosition(currentPos);
    }

    /**
     * 攻击
     */
    private Attack(attackType:number):void{
        this.attackType=attackType;
        if(this.state==1||this.state==2){
            return;
        }
        this.state=1;
        this.removeAllAnimationEvent();
        this.animation.on(AnimationComponent.EventType.FINISHED,this.AttackComplete,this,true);
        this.animation.play(this.monsterConfig.attackAnimation);
    }

    // /**
    //  * 攻击生效帧回调
    //  */
    // AttackDamageFrame():void{
    //     console.log(this.config.mId+"攻击"+this.attackType);
    //     GameController.single.MonsterAttack(this.attackType,this.config.damage);
    // }

    private AttackComplete():void{
        console.log(this.config.mId+"攻击"+this.attackType);
        GameController.single.MonsterAttack(this.attackType,this.config.damage);
        this.state=0;
        this.Move();
    }

    /**
     * 受伤
     * @param value 
     */
    Damage(value:number):void{
        if(this.hp==0){
            return;
        }
        this.hp-=value;
        if(this.hp<=0){
            this.hp=0;
            this.Die();
        }else{
            if(this.state==3){
                return;
            }
            this.state=2;
            this.removeAllAnimationEvent();
            if(this.animation==null){
                return;
            }
            this.animation.on(AnimationComponent.EventType.FINISHED,this.DamageComplete,this,true);
            this.animation.play(this.monsterConfig.damageAnimation);
        }
        //音效
        let v:number=Math.random()*10;
        let url:string;
        if(v<5){
            url="sounds/zombieDamage";
        }else{
            url="sounds/zombieDamage1";
        }
        if(SoundManager.single.ChannelIsPlaying(this.config.id)){
            SoundManager.single.PlaySound(this.config.id,url);
        }
        //弹痕
        if(this.danHen==null){
            let danhenNode:Node=instantiate(GameController.single.monsterZhouDanPrefab);
            this.danHen=danhenNode.getComponent(AnimationComponent);
            this.node.addChild(danhenNode);
        }

        if(this.playingDanHen==false){
            this.danHen.node.active=true;
            let pos:Vec3=this.danHen.node.position;
            pos.x=MathUtils.RandomRange(-0.08,0.08);
            pos.y=MathUtils.RandomRange(0.5,0.8);
            this.danHen.node.position=pos;
            this.danHen.on(AnimationComponent.EventType.FINISHED,this.DanHenComplete,this,true);
            this.danHen.play("Damage");
        }
    }

    private playingDanHen:boolean=false;
    private DanHenComplete():void{
        this.danHen.off(AnimationComponent.EventType.FINISHED,this.DanHenComplete,this);
        this.danHen.node.active=false;
        this.playingDanHen=false;
    }

    private DamageComplete():void{
        this.state=0;
        this.Move();
    }

    Die():void{
        if(this.state==3){
            return;
        }
        this.state=3;
        SoundManager.single.PlaySound(this.config.id,"sounds/zombieDie");
        this.removeAllAnimationEvent();
        this.animation.on(AnimationComponent.EventType.FINISHED,this.DieComplete,this,true);
        this.animation.play(this.monsterConfig.dieAnimation);
    }

    private DieComplete():void{
        this.node.active=false;
        this.node.destroy();

    }

    onDestroy():void{
        SoundManager.single.ClearSound(this.config.id);
        this.danHen=null;
        MonsterHPUIPool.Recycle(this.hpView);
        this.hpView=null;
    }

    private removeAllAnimationEvent():void{
        if(this.animation==null){
            return;
        }
        if(this.animation.hasEventListener(AnimationComponent.EventType.FINISHED,this.DamageComplete,this)){
            this.animation.off(AnimationComponent.EventType.FINISHED,this.DamageComplete,this);
        }
        if(this.animation.hasEventListener(AnimationComponent.EventType.FINISHED,this.AttackComplete,this)){
            this.animation.off(AnimationComponent.EventType.FINISHED,this.AttackComplete,this);
        }
        if(this.animation.hasEventListener(AnimationComponent.EventType.FINISHED,this.DieComplete,this)){
            this.animation.off(AnimationComponent.EventType.FINISHED,this.DieComplete,this);
        }
    }

    get isDie():boolean{
        if(this.hp<=0){
            return true;
        }
        return false;
    }

    /**
     * 血条显示位置
     */
    get hpSocket():Node{
        let socket:Node=find("RootNode/Root/HpSocket",this.node);
        return socket?socket:this.node;
    }
}
