import { _decorator, Animation, AnimationClip, Component, find, Node, Sprite, SpriteFrame, UITransform, Vec3 } from 'cc';
import { LifeBar } from './LifeBar';
import { BulletPool } from './BulletPool';
import { Role } from '../Role';
import { GameMgr } from '../../GameFrameWork/GameMgr';
import { Top } from './Top';
const { ccclass, property } = _decorator;
export enum BulletState {
    Normal,
    Explode,
}
@ccclass('Bullet')
export class Bullet extends Component {

    //对象池
    private _pool: BulletPool = null!;
    private _isEnemyBullet: boolean = false;

    private _animation: Animation = null;
    private _animations: Map<BulletState, string> = new Map();

    private _explodeframes: SpriteFrame[] = [];
    private _bulletFrames: SpriteFrame[] = [];

    //是否爆炸 true -> 爆炸
    isExplode: boolean = false;
    //子弹速度
    bulletSpeed: number = 100;
    //子弹方向
    direction: number = 1;
    //攻击力
    atk: number = null;
    //被攻击的节点
    targetNode: Node = null;

    //是否碰撞
    private _hasCollided: boolean = false;

    private _initPos: Vec3 = null;

    protected onLoad(): void {
        this._animation = this.node.addComponent(Animation);
        this._createClip(BulletState.Normal, [], 10);
        this._createClip(BulletState.Explode, [], 10);
    }
    start() {
        this._initPos = this.node.position.clone();
        this._collectAni();
        this._playAnimation(BulletState.Normal);
    }
    public reset(config: {
        pool: BulletPool,
        isEnemy: boolean,
        direction: number,
        bulletFrames: SpriteFrame[],
        explodeFrames: SpriteFrame[],
        targetNode: Node,
        atk: number,
    }) {
        //重置状态
        this._pool = config.pool;
        this._isEnemyBullet = config.isEnemy;
        this.direction = config.direction;
        this._bulletFrames = config.bulletFrames;
        this._explodeframes = config.explodeFrames;
        this.targetNode = config.targetNode;
        this.atk = config.atk;
        this._hasCollided = false;
        this.isExplode = false;
        this.bulletSpeed = this._isEnemyBullet ? 100 : 90;
        this._initPos = this.node.position.clone();
        this._collectAni();
        this._playAnimation(BulletState.Normal);
        //重置位置和动画
        this.node.active = true;
    }

    private _recycle() {
        if (this._pool) {
            //停止所有动画和事件
            this._animation.stop();
            this._animation.off(Animation.EventType.FINISHED);
            this.unscheduleAllCallbacks();
            this.node.active = false;
            //回收到对象池
            this._pool.recycle(this.node, this._isEnemyBullet);
        } else {
            console.log("destroy");
            this.node.destroy();
        }
    }

    update(deltaTime: number) {
        this.move(deltaTime);
        this.onBulletCollision(this.targetNode);
        this._checkDistance();
    }

    // 处理子弹碰撞
    private onBulletCollision(targetNode: Node) {
        if (this._hasCollided || !targetNode.isValid) return;
        const boxBullet = this.node.getComponent(UITransform).getBoundingBoxToWorld();
        const boxTarget = targetNode.getComponent(UITransform).getBoundingBoxToWorld();
        if (boxTarget.intersects(boxBullet)) {
            const targetLifeBar = targetNode.getComponent(LifeBar);
            const curHp: number = targetLifeBar._curHp - this.atk;
            targetLifeBar.updateProgressBar(curHp);
            if (curHp <= 0) {
                this._recycle();
            }
            this._hasCollided = true;
            this._playAnimation(BulletState.Explode);
        }
    }

    move(dt: number) {
        let x = this.node.getWorldPosition().x;
        let y = this.node.getWorldPosition().y;
        let z = this.node.getWorldPosition().z;

        x = x + this.bulletSpeed * this.direction * dt;
        this.node.setWorldPosition(x, y, z)
    }

    private _checkDistance() {
        const currentPos: Vec3 = this.node.position;
        const distance: number = Vec3.distance(currentPos, this._initPos);
        if (distance >= 250) {
            this._recycle();
        }
    }

    private _collectAni() {
        this._createClip(BulletState.Explode, this._explodeframes, 10);
        this._createClip(BulletState.Normal, this._bulletFrames, 10);
    }

    private _createClip(state: BulletState, frames: SpriteFrame[], fps: number) {
        const clip: AnimationClip = AnimationClip.createWithSpriteFrames(frames, fps);
        clip.name = BulletState[state];
        clip.wrapMode = state === BulletState.Explode ?
            AnimationClip.WrapMode.Normal :
            AnimationClip.WrapMode.Loop;
        this._animation.addClip(clip, clip.name);
        this._animations.set(state, clip.name);
    }

    private _playAnimation(state: BulletState) {
        if (!this._animation) return;
        const clipName = this._animations.get(state);
        if (!clipName) return;
        this._animation.stop();
        this._animation.play(clipName);

        if (state === BulletState.Explode) {
            this.bulletSpeed = 0;
            this._animation.once(Animation.EventType.FINISHED, () => {
                this._recycle();
            })
        }
    }
}