import { _decorator, Animation, AnimationClip, AnimationState, BoxCollider2D, Component, find, instantiate, ITriggerEvent, Node, ObjectCurve, PhysicsSystem2D, SpriteFrame, Vec2, Vec3 } from 'cc';
import { Tools } from '../Tools/Tools';
import { RoleData } from '../../DataItem/ItemData';
import { resMgr } from '../../Frames/ResourcesMgr';
import { Bullet } from './GameScene/Bullet';
import { LifeBar } from './GameScene/LifeBar';
const { ccclass, property } = _decorator;
export enum RoleState {
    Attack,
    Move,
    Idle,
    Die
}
@ccclass('Role')
export class Role extends Component {
    //基础数据
    hp: number = null; //血量
    atk: number = null; //攻击力
    atkLength: number = null; //攻击距离
    moveSpeed: number = null; //移速

    //向左-1 向右1
    direction: number = 1;
    //是否停下
    //isStop: boolean = true;
    //攻击目标
    targetNode: Node = null;

    //战斗系统
    private _attackTimer: number = 0;
    private _attackInterval: number = 3;//攻击间隔
    private currentTarget: Role | null = null;//当前目标

    //子弹
    private _bullet: Node | null = null;
    private _bulletLayer: Node | null = null;

    //动画管理
    private _animations: Map<RoleState, string> = new Map();
    private _moveFrames: SpriteFrame[] = [];
    private _atkFrames: SpriteFrame[] = [];
    private _idleFrames: SpriteFrame[] = [];
    private _dieFrames: SpriteFrame[] = [];
    private _explodeframes: SpriteFrame[] = [];
    private _bulletFrames: SpriteFrame[] = [];

    private _animation: Animation = null;
    //角色数据
    private _roleData: RoleData = null;

    //状态管理
    _state: RoleState = null;

    protected init(name: string, pos: Vec3, roleDatas: RoleData[], dir?: number) {
        this._animation = this.node.getComponent(Animation) || this.node.addComponent(Animation);
        this.direction = dir;
        let whichData: number = -1;
        for (let i = 0; i < roleDatas.length; i++) {
            if (!roleDatas[i]) {
                console.log(null)
            }
            if (roleDatas[i].imgName === name) {
                this._roleData = roleDatas[i];
                whichData = i;
                break;
            }
        }
        if (whichData != -1) {
            //获取move精灵帧
            this._getFrames(this._roleData.moveCount, this._moveFrames, this._roleData.moveImg, 1);
            //attack
            this._getFrames(this._roleData.atkCount, this._atkFrames, this._roleData.atkImg, 1);
            //idle
            this._getFrames(this._roleData.idleCount, this._idleFrames, this._roleData.idleImg, 1)
            //die
            this._getFrames(this._roleData.dieCount, this._dieFrames, this._roleData.dieImg, 1)

            //动画
            this._collectAni();

            //子弹精灵帧
            this._getFrames(this._roleData.bulletCount, this._bulletFrames, this._roleData.bulletImg, 1)
            //子弹爆炸精灵帧
            this._getFrames(this._roleData.bulletCount, this._explodeframes, this._roleData.bulletExplodeImg, 1)

            //设置基础数据
            this._setRoleData(this._roleData);

            this.playAnimation(RoleState.Move);
        }

        //位置
        this.node.setWorldPosition(pos);
        this._bulletLayer = find("Canvas/GameRoot/BulletLayer");

        this._setupPhysics();
    }

    private _setRoleData(roleData: RoleData) {
        this.hp = roleData.hp;
        this.atk = roleData.atk;
        this.atkLength = roleData.atkLength + 100;
        this.moveSpeed = roleData.moveSpeed;
    }

    private _setupPhysics() {
        //确保有碰撞组件
        const collider2D = this.getComponent(BoxCollider2D) || this.addComponent(BoxCollider2D);
        collider2D.group = this._getCollisionGroup();
        collider2D.apply();
    }

    //获取精灵帧组 
    /*
    count -> 精灵帧的数量 
    imgType -> 图片类型（atk、walk、idle、die）
    startIdx -> 索引起始数
    */
    private _getFrames(count: number, frames: SpriteFrame[], imgType: string, startIdx: number) {
        for (let i = startIdx; i <= count; i++) {
            if (count > 1) {
                frames.push(resMgr.getSpriteFrame(imgType + ' (' + i + ')'));
            }
            else {
                frames.push(resMgr.getSpriteFrame(imgType + ' (1)'));
            }
        }
    }

    update(deltaTime: number) {
        if (this._state === RoleState.Die) return;

        if (!this.currentTarget) {
            this._handleMovement(deltaTime);
            this._detectEnemies();
        } else {
            this._handleAttack(deltaTime);
        }
    }

    //移动
    private _handleMovement(dt: number) {
        if (this._state !== RoleState.Move) return;

        let x = this.node.position.x;
        let y = this.node.position.y;
        let z = this.node.position.z;

        x = x + this.moveSpeed * this.direction * dt
        this.node.setPosition(x, y, z);
        this.stop();
    }

    //寻敌
    private _detectEnemies() {
        if (!this.node.isValid) return;
        //const startPos = new Vec2(this.node.position.x, this.node.position.y);
        const startPos = this.node.position.clone();
        const endPos = new Vec2((this.direction * this.atkLength) + this.node.position.x, this.node.position.y);
        const results = PhysicsSystem2D.instance.raycast(startPos, endPos);

        if (results?.length) {
            for (const result of results) {
                const target = result.collider.node.getComponent(Role);
                if (target && this._isValidTarget(target)) {
                    this._setTarget(target);
                    break;
                }
            }
        }
    }

    //设置攻击目标
    private _setTarget(target: Role) {
        this.currentTarget = target;
        this.playAnimation(RoleState.Attack);

        // 使得第一次update就会触发attackTimer >= attackInterval条件
        this._attackTimer = this._attackInterval - 0.001;
        //监听目标销毁事件
        target.node.once(Node.EventType.NODE_DESTROYED, this._onTargetDestroyed, this);
    }

    //攻击
    private _handleAttack(deltaTime: number) {
        //目标是否可以攻击
        if (!this._validateTarget()) {
            this._clearTarget();
            return;
        }
        /*
        //立即攻击判断
        if (this._attackTimer === 0) {
            this._createBullet();
            this._attackTimer += deltaTime;
            return;
        }

        //后续间隔攻击
        this._attackTimer += deltaTime;
        if (this._attackTimer >= this._attackInterval) {
            this._createBullet();
            this._attackTimer = 0; //重置计时器
        }
            */
        // this._createBullet();
        // this.schedule(() => {
        //     this._createBullet();
        // }, this.attackInterval);
    }

    //目标是否可以攻击 hp大于0 并且 在攻击范围内 -> 可以攻击
    private _validateTarget(): boolean {
        return !!this.currentTarget?.node?.isValid &&
            this.currentTarget.hp > 0 &&
            this._getDistanceToTarget() <= this.atkLength;
    }

    //攻击目标与自身的距离
    private _getDistanceToTarget(): number {
        return Math.abs(this.node.getWorldPosition().x - this.currentTarget.node.getWorldPosition().x);
    }

    //销毁目标
    private _onTargetDestroyed() {
        this._clearTarget();
        if (this.node === null) return;
        this._detectEnemies();//立即检测新目标
    }

    //清除目标 关闭触发事件 当前目标置空 设置移动状态 播放移动动画
    private _clearTarget() {
        this.currentTarget?.node.off(Node.EventType.NODE_DESTROYED, this._onTargetDestroyed, this);
        this.currentTarget = null;
        this.playAnimation(RoleState.Move);
    }

    stop() {

    }

    //将各个动画存储起来
    private _collectAni() {
        // const moveAni: Animation = Tools.createAnimation(this._moveFrames, 8, this.node, AnimationClip.WrapMode.Loop)
        // this._animations.set(RoleState.Move, moveAni);

        // const atkAni: Animation = Tools.createAnimation(this._atkFrames, 8, this.node, AnimationClip.WrapMode.Loop)
        // this._animations.set(RoleState.Attack, atkAni);

        // const idleAni: Animation = Tools.createAnimation(this._idleFrames, 8, this.node, AnimationClip.WrapMode.Loop)
        // this._animations.set(RoleState.Idle, idleAni);

        // const dieAni: Animation = Tools.createAnimation(this._dieFrames, 8, this.node, AnimationClip.WrapMode.Normal)
        // this._animations.set(RoleState.Die, dieAni);

        this._createClip(RoleState.Move, this._moveFrames, 8);
        this._createClip(RoleState.Attack, this._atkFrames, 8);
        this._createClip(RoleState.Idle, this._idleFrames, 8);
        this._createClip(RoleState.Die, this._dieFrames, 9);
    }

    //创建动画剪辑 fps越大 速度越快
    private _createClip(state: RoleState, frames: SpriteFrame[], fps: number) {
        const clip: AnimationClip = AnimationClip.createWithSpriteFrames(frames, fps);
        clip.name = RoleState[state];
        clip.wrapMode = state === RoleState.Die ?
            AnimationClip.WrapMode.Normal :
            AnimationClip.WrapMode.Loop;
        if(clip.name === 'Attack'){
            clip.events = [{
                frame: 0.5,
                func: "onTriggered",
                params: ["a"] //向func传递的参数
            }]
        }
        this._animation.addClip(clip, clip.name);
        this._animations.set(state, clip.name);
    }
    onTriggered(){
        this._createBullet();
    }
    //设置动画
    public playAnimation(state: RoleState) {
        if (!this._animation || this._state === state) return;

        const clipName = this._animations.get(state);
        if (!clipName) return;

        this._state = state;
        this._animation.stop();
        this._animation.play(clipName);

        if (state === RoleState.Die) {
            this.node.removeAllChildren();
            this._animation.once(Animation.EventType.FINISHED, () => {
                this.node.destroy();
            });
        }

        // if (this._animations === null) {
        //     Error("No found" + state);
        //     return;
        // }
        // if (this._state === state) return;
        // this._state = state;
        // this._animations.get(state).play();
        // if (state === RoleState.Die) {
        //     this._animations.get(state).once(Animation.EventType.FINISHED, () => {
        //         this.node.destroy();
        //     })
        // }

        // this._animations.forEach((anim, key) => {
        //     if(key === state){
        //         anim.play();
        //         if(key === RoleState.Die){
        //             anim.once(Animation.EventType.FINISHED,()=>{
        //                 this.node.destroy();
        //             })
        //         }
        //     }
        //     //key === state ? anim.play() : anim.stop();
        // })
    }

    //判断是否攻击
    // getEnemiesAhead(parent: Node) {
    //     for (const node of parent.children) {
    //         const enemyY = node.getWorldPosition().y;
    //         const enemyX = node.getWorldPosition().x;
    //         const y = this.node.getWorldPosition().y;
    //         const x = this.node.getWorldPosition().x;
    //         if (enemyY === y) {
    //             const distance = Math.abs(enemyX - x);
    //             if (distance <= this.atkLength) {
    //                 //开始攻击
    //                 this.isAttacking = true;
    //                 //设置攻击目标
    //                 this.targetNode = node;
    //                 //停止移动
    //                 this.isStop = true;
    //                 //开始开火
    //                 this.isFire = true;
    //                 this.attack(this.targetNode, this.isFire);
    //                 break;
    //             }
    //         }
    //     }
    // }

    // attack(targetNode: Node, isFire: boolean) {
    //     if (!targetNode) return;
    //     const targetNodeTS = targetNode.getComponent(Role);
    //     if (isFire && targetNodeTS.hp > 0) {
    //         this._createBullet();
    //         this.schedule(() => {
    //             this._createBullet();
    //         }, 3)
    //     }
    // }
    //创建子弹

    private _createBullet() {
        if (this.direction === -1) {
            this._bullet = instantiate(resMgr.getPrefab("BulletEnemy"));
        } else if (this.direction === 1) {
            this._bullet = instantiate(resMgr.getPrefab("Bullet"));
        }
        this._bullet.setWorldPosition(this.node.getWorldPosition());
        this._bullet.parent = this._bulletLayer;
        const bulletTS = this._bullet.getComponent(Bullet);
        bulletTS.direction = this.direction;
        bulletTS.bulletFrames = this._bulletFrames;
        bulletTS.explodeframes = this._explodeframes;
        bulletTS.targetNode = this.currentTarget.node;
        bulletTS.atk = this.atk;
    }

    //要求子类实现的碰撞分组和阵营判断方法，确保不同阵营角色可以正确交互
    protected _getCollisionGroup(): number {
        throw new Error("Method not implemented");
    }
    protected _isValidTarget(target: Role): boolean {
        throw new Error("Method not implemented");
    }
}