import { _decorator,  Node, Vec3, tween, director} from 'cc';
import { PoolManager } from '../../core/manager/PoolManager';
import { Game } from '../../game/Game';
import { uiMgr } from '../../core/manager/UIManager';
import { Constants } from '../../data/Constants';
import { PlayerCamera } from '../../game/PlayerCamera';
import { GunfightShootUI } from '../../ui/GunfightShootUI';
import { Bullet3 } from './Bullet3';
import { GunBase } from '../base/GunBase';
import { Enemy } from '../../game/Enemy';
import { Player } from '../../game/Player';
import { audioMgr } from '../../core/manager/AudioManager';
const { ccclass, property } = _decorator;

//玩家所使用的枪 SKS连狙 开3枪然后回缩镜头(VSS	SKS)
@ccclass('Gun3')
export class Gun3 extends GunBase {
    @property({type: Node,tooltip:"子弹节点"})
    public bulletNode: Node = null!;
    @property({type: Node,tooltip:"开火特效节点"})
    fireEffect: Node = null;

    //枪的拥有者
    public holder: Player|Enemy = null;
    //开枪结束回调
    public endCb: Function = null!;
    //换弹匣的回调
    public ammoCb: Function = null;
    //触发间隔时间统计
    private curTime: number = 0;
    //是否是第一次开火
    private isFristShot: boolean = false;
    //所有的烟雾
    public smokes: Array<Node> = []!
    
    onLoad() {
        this.bulletNode.active = false;
        this.muzzleNode.active = false;
    }
    /**
     * 设置枪的数据
     * @param data 枪的数据
     * @param endCB 结束回调
     * @param ammoCb 换弹匣回调
     */
    public init(data: any,holder: any,endCb?: Function,ammoCb?: Function){
        this.data = data;
        this.shotBullets = 0;
        this.isFire = false;
        this.isFristShot = true;
        this.holder = holder;
        this.endCb = endCb;
        this.ammoCb = ammoCb;
    }

    //开火
    public fire() {
        this.isFire = true;
        this.createBullet();
        this.playParticle(this.fireEffect);
    }

    //结束开火
    public endFire(){
        this.isFire = false;
        this.endCb?.(this.data);
        this.recycle();
    }

    /**
     * 直接开抢射杀敌人
     */
    public killEnemy(e: Enemy){
        if(e.isDead
           ||Game.I.isPause){
           return;
        }
        const destPos: Vec3 = e.node.worldPosition.clone();
        const bullet: Bullet3 = this.getBulleNode();
        bullet.init(this,true);
        tween(bullet.node)
            .to(0.3, {worldPosition:destPos})
            .call(() => {
                bullet.isDead = true;
                PoolManager.putNode(bullet.node);
                //直接打死 最大血量乘以2倍
                e.subHP(e.data.hp * 2,this.data);
            })
            .start();
    }

    /**
     * 展示子弹
     */
    public createBullet() {
        if(!this.holder
            ||this.holder.isDead
            ||!this.isFire
            ||Game.I.isPause
            ||Game.I.isGameOver){
           return;
        }
        audioMgr.playOneShot(this.data.gun_sound);
        this.getBulleNode();
        this.shotBullets ++;
        //换弹夹的操作
        if(this.shotBullets >= this.data.magazine){
            this.shotBullets = 0;
            this.ammoCb?.(this.data);
        }
        this.endFire();
    }

    /**
     * 初始化一个子弹
     * @param isGuaranteedHit 子弹是否必中(必中的时候targetNode不能为空)
     * @param targetNode 射击的目标对象
     * @returns 返回一颗子弹
     */
    public getBulleNode(isGuaranteedHit: boolean = true, targetNode: Node = null): Bullet3{
        //从对象池获取子弹节点
        const bulletNode: Node = PoolManager.getNode(this.bulletNode, director.getScene());
        const bullet: Bullet3 = bulletNode.getComponent(Bullet3);
        bullet.init(this);
        bulletNode.worldPosition = this.muzzleNode.worldPosition.clone();
        //计算基准方向（瞄准目标或准星位置）
        const shootUI:GunfightShootUI = uiMgr.getPageComponent(Constants.popUIs.gunfightShootUI);
        const targetPos = targetNode ? targetNode.worldPosition : shootUI.getCrossHairPos();
        const baseDirection = Vec3.subtract(new Vec3(), targetPos, this.muzzleNode.worldPosition).normalize();
        //最终弹道方向
        let finalDirection: Vec3;
        if(isGuaranteedHit) {//100%必中（无偏移）
            finalDirection = baseDirection;
        }else{//非必中：在基准方向上添加小范围随机偏移
            const maxOffsetAngle = 5;
            const offsetX = (Math.random() - 0.5) * maxOffsetAngle * Math.PI / 180;
            const offsetY = (Math.random() - 0.5) * maxOffsetAngle * Math.PI / 180;
            //应用偏移（保持Z轴主要方向）
            finalDirection = new Vec3(
                baseDirection.x + offsetX,
                baseDirection.y + offsetY,
                baseDirection.z // 保持主要前进方向
            ).normalize();
        }
        //设置子弹方向
        bulletNode.forward = finalDirection;
        bullet.setBulletVector(finalDirection);
        return bullet;
    }

    /**
     * 回收烟雾
    */
    public recycle(){
        this.smokes.forEach(e => {
            if(e && e.parent){
               PoolManager.putNode(e);
            }
        });
        this.smokes = [];
    }
}

