import { _decorator,  Node, Vec3, director} from 'cc';
import { PoolManager } from '../../core/manager/PoolManager';
import { Game } from '../../game/Game';
import { GunBase } from '../base/GunBase';
import { Bullet14 } from './Bullet14';
import { Utils } from '../../utils/Utils';
import { Enemy } from '../../game/Enemy';
import { Player } from '../../game/Player';
import { audioMgr } from '../../core/manager/AudioManager';
import { Constants } from '../../data/Constants';
const { ccclass, property } = _decorator;

//1006 坦克
@ccclass('Gun14')
export class Gun14 extends GunBase {
    @property({type: Node,tooltip:"子弹节点"})
    public bulletNode: Node = null!;
    @property({type: Node,tooltip:"开火特效节点"})
    fireEffect: Node = null;

    private isCb: boolean = false;
    //枪的拥有者
    public enemy: Enemy = null;
    //开枪结束回调
    public endCb: Function = null!;
    //换弹匣的回调
    public ammoCb: Function = null;
    //触发间隔时间统计
    private curTime: number = 0;
    //是否是第一次开火
    private isFristShot: boolean = false;
    //所有的烟雾
    public smokes: Array<Node> = []!
    //是否是第一次激活开枪
    public isFristShoot: boolean = false;
    //为了戳开子弹产生的时间间隔统计
    public diff: number = 0;
    //随机延迟的时间
    public r_delay: number = 0;
    //继续正常统计时间
    public isGo: boolean = true;

    onLoad() {
        this.bulletNode.active = false;
        this.muzzleNode.active = false;
    }

    /**
     * 设置枪的数据
     * @param data 枪的数据
     * @param endCB 结束回调
     * @param ammoCb 换弹匣回调
     */
    public init(data: any,enemy: any,endCb?: Function,ammoCb?: Function){
        this.data = data;
        this.curTime = 0;
        this.isFire = false;
        this.isFristShot = true;
        this.enemy = enemy;
        this.endCb = endCb;
        this.ammoCb = ammoCb;
        this.node.eulerAngles = new Vec3(0, 180, 0);
    }

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

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

    /**
     * 展示子弹
     */
    public createBullet() {
        if(!this.getNextAllow())return;
        let delay: number = 0.1;
        for(let i = 0; i < this.data.bullet_number; i++){
            this.scheduleOnce((k: number)=>{
                delay += Utils.getRandomFloat(0,0.2);
                if(!this.getNextAllow())return;
                //获取射击的精准度
                const isHit: boolean = this.enemy.calculateIsHit();
                //创建子弹
                this.getBulleNode(isHit);
            },delay * i);
        }
    }

    /**
     * 初始化一个子弹
     * @param isGuaranteedHit 子弹是否必中
     * @returns 返回一颗子弹
     */
    public getBulleNode(isHit: boolean = true): Bullet14{
        //从对象池获取子弹节点
        const bulletNode: Node = PoolManager.getNode(this.bulletNode, director.getScene());
        const bullet: Bullet14 = bulletNode.getComponent(Bullet14);
        bullet.init(this);
        bulletNode.setWorldPosition(this.muzzleNode.worldPosition);
        let playPos: Vec3 = Game.I.player.head.worldPosition.clone();
        const baseDirection = Vec3.subtract(new Vec3(), playPos,this.muzzleNode.worldPosition).normalize();
        //最终弹道方向
        let finalDirection: Vec3;
        if(isHit) {//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,isHit);
        return bullet;
    }

    //激活调用 持续开火
    protected update(dt: number): void {
        if(!this.getNextAllow())return;
        //每几秒攻击一次
        let m: number = this.data.atk_speed;
        //不是第一次激活 有延迟间隔
        if(!this.isFristShoot){
            m = this.isFristShoot ? 0 : m;
            if(this.diff >= this.r_delay && !this.isGo){
                this.diff += dt;
                this.isGo = true;
                return;
            }else{
                this.curTime += dt;  
            }
        }else{//第一次激活 就直接开枪不延迟
            m = this.isFristShoot ? 0 : m;
        }
        //在随机延迟的时间间隔里 发射一颗子弹
        if(this.curTime >= m - this.r_delay) {
            if(this.isFire){
                this.isFristShoot = false;
                this.r_delay = Utils.getRandomFloat(0.4,0.8); 
                this.diff = 0;
                this.isGo = false;
                audioMgr.playOneShot(Constants.audios.Tank_Attack,false);
                this.createBullet();
                this.curTime = 0;
                this.isCb = false;
            }else{
                if(!this.isFire && !this.isCb){
                    this.isFire = false;
                    this.endCb?.(this.data.type);
                    this.isCb = true;
                }
            } 
        }
    }

    /**
     * 是否可以允许操作
     */
    private getNextAllow(){
        let player: Player = Game.I.player;
        if(!player
            ||player.isDead
            ||!this.isFire
            ||Game.I.isPause
            ||Game.I.isGameOver){
            return false;
        }
        return true;
    }

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