import { _decorator, Node, SkeletalAnimation, Tween, Vec3 } from 'cc';
import { BaseExp } from '../core/base/BaseExp';
import { PoolManager } from '../core/manager/PoolManager';
import { uiMgr } from '../core/manager/UIManager';
import { Constants } from '../data/Constants';
import { userIns } from '../data/UserData';
import { autoBind } from '../extend/AutoBind';
import { GunBase } from '../items/base/GunBase';
import { GunfightShootUI } from '../ui/GunfightShootUI';
import { ResUtil } from '../utils/ResUtil';
import { Game } from './Game';
import MsgHints from '../utils/MsgHints';
import { PlayerCamera } from './PlayerCamera';
import { audioMgr } from '../core/manager/AudioManager';
import { Utils } from '../utils/Utils';
const { ccclass, property } = _decorator;

//玩家动作类型
export enum PAnimType {
    idle = "idle",//idle 待机状态
    die = "die",//die 死亡状态
    reload = "reload",//reload 换弹夹状态
}

@ccclass('Player')
export class Player extends BaseExp {
    @autoBind({type: Node,tooltip: "创建枪的位置"})
    public gun_pos: Node  = null!;
    @autoBind({type: Node,tooltip: "玩家头的位置"})
    public head: Node  = null!;
    @autoBind({type: Node,tooltip: "敌人埋伏点"})
    public ambush: Node  = null!;
    @autoBind({type: Node,tooltip: "玩家身子的位置"})
    public body: Node  = null!;
    @autoBind({type: SkeletalAnimation,tooltip: "玩家人物动画节点"})
    public player_skeletal: SkeletalAnimation  = null!;
    @autoBind({type: PlayerCamera,tooltip: "玩家摄像机抖动控制"})
    public mainCamera: PlayerCamera = null!;
    @autoBind({type: Node,tooltip: "玩家摄像机抖动控制"})
    public GGGGGGG: Node = null!;

    /**玩家的位置节点*/
    public playPosNodes: Node[] = []!;
    /**玩家当前血量*/
    public curHP: number = 0;
    /**玩家是否死亡*/
    public isDead: boolean = false;
    /**玩家拥有的枪*/
    public gun: GunBase = null;
    //玩家数据
    public pData:any = null
    //是否去设置gunfightShootUI的基础信息
    public isCutShoot:boolean = false;
    //射击ui类
    private _shootUI: GunfightShootUI | null = null;
    //懒获取射击界面
    public get shootUI(): GunfightShootUI {
        if (!this._shootUI) {
            this._shootUI = uiMgr.getPageComponent(Constants.popUIs.gunfightShootUI);
        }
        return this._shootUI!;
    }
    //是否是换弹夹状态
    public isReloadMagazine: boolean = false;
    //玩家打敌人爆头的个数
    public headShotNum:number = 0;

    start() {
        //隐藏玩家设置的位置坐标节点
        (this.playPosNodes = this.node.parent.getChildByName('player_points').children)
            .forEach(e => e.active = false);
        //隐藏的枪的位置节点
        this.gun_pos.children.forEach(e => e.active = false);
        this.pData = userIns.getCurUseGun();
        //创建玩家拥有的枪
        this.loadGunName(this.pData.prb_name);
    }

    /**
     * 加载枪
     * @param name 枪的名字
     * @param isCut 是否是切换枪
     */
    public loadGunName(name: string = this.pData.prb_name,isCut: boolean = false){
        if(Utils.isNull(name))return;
        //玩家待机状态
        this.player_skeletal.play(PAnimType.idle);
        this.pData = userIns.getCurUseGun();
        this.curHP = this.pData.hp;
        if(!isCut && this.gun)return;
        if(isCut && this.gun){
           PoolManager.putNode(this.gun.node);
        }
        ResUtil.loadRes(`player/${name}`).then((gunNode: Node) => {
            if(!gunNode)return;
            this.isCutShoot = true;
            gunNode.parent = this.node;
            this.gun = gunNode.getComponent(GunBase);
            let pos_ui: Node = this.gun_pos.children.find(e=>e.name == this.pData.prb_name);
            if(!pos_ui){
                MsgHints.show("未找到武器没有对应的位置节点");
            }
            pos_ui = pos_ui || this.gun_pos;
            if(pos_ui){
               gunNode.worldPosition = pos_ui.worldPosition.clone();
               gunNode.eulerAngles = pos_ui.parent.eulerAngles.clone();
               gunNode.scale = pos_ui.scale.clone();
            }
            this.gun.init(this.pData,this,()=>{},this.reloadMagazine.bind(this));
        });
    }

    /**
     * 更换弹匣
     */
    public reloadMagazine(data:any){
        if(!data || this.isReloadMagazine)return;
        this.isReloadMagazine = true; 
        const factor: number = 130;
        let time: number = data.reloadingSpeed / factor;
        //换弹匣动画
        ResUtil.playSkeletalAnim(this.player_skeletal,PAnimType.reload,time);
        this.shootUI.reloadMagazineing(time,()=>{
            this.isReloadMagazine = false;
            this.shootUI.gunDataUI();
            this.player_skeletal?.play(PAnimType.idle);
        });
    }

    /**
     * 重置
     */
    public restart(){
        Game.I.isGameOver = Game.I.isPause = false;
        this.isDead = false;
        this.isReloadMagazine = false;
        if(this.shootUI){
           this.shootUI.hpProgressBar.progress = 1;
           Tween.stopAllByTarget(this.shootUI.injury_blood);
           this.shootUI.injury_blood.active = false;
        }
        this.loadGunName();
        this.player_skeletal.unscheduleAllCallbacks();
        this.player_skeletal.stop();
        this.player_skeletal.node.active = true;
        this.player_skeletal.play(PAnimType.idle);
    }

    /**
     * 玩家发射子弹
     */
    public shoot() {
        if(!this.gun 
            || this.isReloadMagazine)return;
        this.gun.fire();
        this.shootUI.crossHairStability();
        Game.I.player.mainCamera.shake(0.2,0,0.1);
    }

    /**
     * 随机切枪
     */
    public randomCutGun(){
        let guns = userIns.data.guns;
        if(guns.length > 1){
            let idx : number = guns.findIndex(e=>e.id == this.pData.id);
            let next:number = (idx + 1) % guns.length;
            const cutGun:any = guns[next];
            userIns.changeGun(cutGun.id);
            this.loadGunName(cutGun.prb_name,true);
        }
    }

    /**
     * 移除枪回收武器
     */
    public removeGun(){
        if(!this.gun)return;
        this.gun.endFire();
        PoolManager.putNode(this.gun.node);
        this.gun = null;
    }

    /**
     * 玩家扣掉血
     * @param hp 血
     * @param eData 敌人数据
    */
    public subHP(hp: number,eData:any){
        if(Game.I.isPause
            ||Game.I.isGameOver
            ||this.isDead
            ||hp <= 0){
            return;
        }
        this.curHP -= hp;
        this.curHP = this.curHP < 0 ? 0 : this.curHP;
        //设置血条
        const progress:number = this.curHP / this.pData.hp;
        this.shootUI.playerHurtTwinkle(progress);
        //敌人死亡
        if(this.curHP <= 0 && !this.isDead){
            Game.I.isGameOver = true;
            audioMgr.playOneShot(Constants.audios.loss);
            uiMgr.show(Constants.popUIs.settleUI,[{
                isWin: false,
                headShotNum: this.headShotNum,
                cb: ()=>{}
            }]);
            this.isDead = true;
            this.recycle();
            ResUtil.playSkeletalAnim(this.player_skeletal,PAnimType.die,1.5,()=>{
                this.player_skeletal.stop();
                this.player_skeletal.node.active = false;
            });
        }
    }

   
    /**
     * 根据关卡设置玩家的位置
     */
    public setPlayerPos(){
        if(!this.pData)return;
        let length:number = this.playPosNodes.length;
        const data = userIns.getCurLevelData();
        const safeIndex = Math.min(data.point -1, length - 1);
        const n: Node = this.playPosNodes[safeIndex];
        this.node.worldPosition = n.worldPosition.clone();
    }

    /**
     * 回收
     */
    public recycle(){
        this.removeGun();
        this.isReloadMagazine = false;
        this.headShotNum = 0;
    }


    /**
     * 设置枪的数据
     */
    protected update(dt: number): void {
        if(this.isCutShoot){
            //设置玩家枪的信息
            if(this.shootUI && this.pData){
                this.shootUI.gunDataUI();
                this.isCutShoot = false;
            }   
        }
    }
}

