import { _decorator, sp } from "cc";
import GObject, { GTowards } from "../GObject";
import { JNFrameInfo } from "../../../../../extensions/ngame/assets/ngame/sync/frame/JNSyncFrame";
import { Vec2 } from "cc";
import { v3 } from "cc";
import JNSkeleton from "../../../../../extensions/ngame/assets/ngame/sync/frame/game/spine/JNFrameSkeleton";
import { GFSMAnimBase } from "../fsm/GFSMAnimBase";
import GFSMBase from "../fsm/GFSMBase";
import { app } from "../../../App";
import { TB } from "../../../config/data/schema";
import GRoleValues, { GRoleAttackType } from "../values/GRoleValues";
import GAttributeBase from "../values/attribute/GAttributeBase";
import { GPetAminEnum } from "../anim/GPetAnim";
import NOV2DSimple from "../../../../../extensions/ngame/assets/ngame/util/collide/OV/NOV2DSimple";
import NOVBase from "../../../../../extensions/ngame/assets/ngame/util/collide/OV/NOVBase";
import { BoxCollider2D } from "cc";
import { Vec3 } from "cc";
import GAttribute from "../values/attribute/GAttribute";
const { ccclass, property } = _decorator;

export enum GRoleAnimEvent{
    Attack = "attack", //普通攻击
}

//角色基类
export default abstract class GRoleBase<T> extends GObject<T>{

    @property(JNSkeleton)
    spine:JNSkeleton;

    //角色
    role:TB.TbGRole;

    //状态机
    fsm:GFSMBase;

    //动画状态机
    fsmAnim:GFSMAnimBase;

    //玩家攻击范围
    range:number = 100;

    //移动速度
    moveSpeed:number = 80;

    //血量
    blood:number = 100;
    fullBlood:number = 100;

    //是否死亡
    _isDie:boolean = false;
    get isDie(){ return this._isDie}
    set isDie(value:boolean){ 
        this._isDie = value;
        if(this.isDie){
            //如果死亡则关闭状态机
            //关闭状态机
            this.fsm.close();
        }
    }

    //受击回调
    hitCallbacks:Function[] = [];
    //添加受击回调
    addHitCallback(fun:Function){this.hitCallbacks.push(fun)};

    //攻击回调
    attackCallbacks:Function[] = [];
    //添加攻击回调
    addAttackCallback(fun:Function){this.attackCallbacks.push(fun)};

    //角色数值类
    _values:GRoleValues;
    get values(){
        if(!this._values) this._values = new GRoleValues();
        return this._values;
    }
    set values(value){
        this._values = value;
    }

    //添加避障
    ov:NOVBase;

    get():this{
        if(this.isDie) return null;
        return this;
    }

    onSyncLoad(){

        //避障
        this.ov = new NOV2DSimple(this.node.getComponent(BoxCollider2D));
        
        if(!this.spine) this.spine = this.node.getComponent(JNSkeleton);
        //如果没有生成则直接销毁
        if(!this.spine) {
            this.node.destroy();
            return;
        }

        //创建角色状态机
        this.fsm = this.fsmCreate();
        //创建角色动画状态机
        this.fsmAnim = this.fsmAnimCreate();

        // //创建数值类
        // this.values = new GRoleValues();

    }

    //初始化
    public init(role:TB.TbGRole){
        console.log("初始化宠物",!!this.spine,!!(app.battleRes.getRoleSpine(role.id)));
        this.spine.skeletonData = app.battleRes.getRoleSpine(role.id);
        this.node.scale = v3(role.roleScale,role.roleScale,role.roleScale);
    }

    //创建一个状态机
    protected abstract fsmCreate():GFSMBase;
    //创建一个动画状态机
    protected abstract fsmAnimCreate():GFSMAnimBase;

    onSyncUpdate(dt: number,frame:JNFrameInfo, input?: T){

        //更新状态机
        this.fsm && this.fsm.onUpdate(dt / 1000,frame);
        this.fsmAnim && this.fsmAnim.onUpdate(dt / 1000,frame);

    }

    //向目标点移动
    onMoveTarget(target:Vec2,dt:number){
        
        //获取两个坐标差值向量
        let mins = this.v2World.subtract(target);
        let normal = this.v2World.subtract(target).normalize();
        
        //设置朝向
        if(normal.x != 0){
            if(normal.x < 0){
                this.setTowards(GTowards.RIGHT)
            }else{
                this.setTowards(GTowards.LEFT)
            }
        }
        
        
        if(Vec2.len(normal) >= Vec2.len(mins)){
            this.setWorldPosition(Object.assign(v3(),target.clone()));
            return true;
        }else{
            //移动
            this.setWorldPosition(this.node.worldPosition.clone().subtract(v3(normal.x*dt*this.moveSpeed,normal.y*dt*this.moveSpeed,0)));
            return false;
        }
        
    }

    //设置世界坐标
    setWorldPosition(worldPos:Vec3){
        // if(worldPos = this.ov.moveTo(worldPos)){
            this.node.setWorldPosition(worldPos);
        // }
        // return worldPos;
    }

    //朝向目标
    onTowardsTarget(role:GRoleBase<{}>){
        //获取两个坐标差值向量
        let normal = this.v2World.subtract(role.v2World).normalize();
        //设置朝向
        if(normal.x != 0){
            if(normal.x < 0){
                this.setTowards(GTowards.RIGHT)
            }else{
                this.setTowards(GTowards.LEFT)
            }
        }
    }

    //受击 伤害类型 伤害
    onHit(type:GRoleAttackType,harm:number,enemy:GRoleBase<{}>){
        // return;
        harm = this.values.onUnderAttack(type,harm)
        this.blood -= harm;
        this.hitCallbacks.forEach(fun => fun(this,harm));
        //检测是否死亡
        if(this.blood <= 0){
            //关闭状态机
            this.fsm.close();
            //设置死亡
            this.isDie = true;
        }
    }

    onDebugHit(){
        this.blood -= 10;
        //检测是否死亡
        if(this.blood <= 0){
            //关闭状态机
            this.fsm.close();
            //设置死亡
            this.isDie = true;
        }
    }

    //生效数值
    onEffectiveValues(...values:GAttributeBase[]){

        this.values.reset();
        values.forEach(value => {
            this.values.add(value);
        })
        this.values.update();

        //赋值血量
        this.blood = this.fullBlood = this.values.onBlood();

    }

    //生效属性
    onEffectiveValue(data:GAttribute){

        this.values.reset(data);
        this.values.update();

        //赋值血量
        this.blood = this.fullBlood = this.values.onBlood();

    }


}

