import { Vec2 } from "cc";
import GBaseMode from "../GBaseMode";
import { GRoleUtil } from "../entity/GRole";
import { GTactical } from "../entity/GTactical";
import GRoleDefault from "../base/role/GRoleDefault";
import { Prefab } from "cc";
import { _decorator } from "cc";
import { instantiate } from "cc";
import { GPVPModePlayerEnum } from "./GPVPMode";
import { JNFrameInfo } from "../../../../extensions/ngame/assets/ngame/sync/frame/JNSyncFrame";
import { GMapLoop } from "../base/common/map/GMapLoop";
import { Node } from "cc";
import JNFrameTime from "../../../../extensions/ngame/assets/ngame/sync/frame/game/time/JNFrameTime";
import { TD, app } from "../../App";
import { v3 } from "cc";
import { v2 } from "cc";
import GFSMOnHookMode from "./OnHook/GFSMOnHookMode";
import { TB, TbGEntity } from "../../config/data/schema";
import PlayerTacticalData, { PlayerTacticalEvent } from "../../data/PlayerTacticalData";
import GRoleOnHookPlayerExpand from "../base/role/expand/OnHook/GRoleOnHookPlayerExpand";
import PlayerPetData from "../../data/PlayerPetData";
import { GUI } from "../../ui/UIConfig";
import { GOnHookPet, GOnHookPets } from "../../../../extensions/ngame/assets/ngame/message/proto";
import GOnHookManager, { GOnHookManagerEvent } from "../../manager/battle/mode/GOnHookManager";
import GRoleOnHookCreepsExpand from "../base/role/expand/OnHook/GRoleOnHookCreepsExpand";
import GPetAttribute from "../base/values/attribute/role/GPetAttribute";
import GOnHookData from "../../data/GOnHookData";
import { GModeEvent, GModeHitInfo } from "./GMode";
import GBattleData, { GBattleDataEnum } from "../../data/GBattleData";
import GNormalModeBase, { GNormalModePlayerEnum } from "./default/GNormalModeBase";
const { ccclass, property } = _decorator;

//挂机模式状态
export enum GOnHookModeState{
    GoTarget,//前往目标
    Attack, //攻击
    AttackEnd, //攻击结束
}

/**
 * 挂机模式 无限出现小怪 (不是联机模式 该模式支持使用本地数据 和 API)
 */
@ccclass('GOnHookMode')
export default class GOnHookMode extends GNormalModeBase<{},{}>{
    
    //玩家宠物
    playerRoles: GRoleDefault[] = [];
    //敌方宠物
    enemyRoles: GRoleDefault[] = [];

    //每一波怪的距离
    everyX:number = 600;

    //下一波怪的对战位置X
    _nextFightX:number = 0;
    get nextFightX(){return this._nextFightX}
    set nextFightX(value:number){
        //修改玩家阵法位置
        this.playerInfo.tactical.setOffset(this.playerPos.clone().add(v2(value,0)))
        this.enemyInfo.tactical.setOffset(this.enemyPos.clone().add(v2(value,0)))
        this._nextFightX = value;
    }

    fsm:GFSMOnHookMode;

    //是否允许攻击
    isAllowAttack:boolean = false;

    //是否战斗失败
    isFail:boolean = false;

    //让胜负失效
    get isEndGame(){return true;}

    //添加监听事件
    addEvent(){
        app.event.on(PlayerTacticalEvent.UPDATE_TACTICAL,this.onUpdatePlayerPet,this);
        app.event.on(GBattleDataEnum.UPDARE_ATTRIBUTE_SUCCESS,this.onUpdateAttribute,this);
        // app.event.on(GOnHookManagerEvent.UPDATE_MAP,this.onUpdateWorld,this);
    }
    //移除监听事件
    onDestroy(){
        super.onDestroy();
        app.event.off(PlayerTacticalEvent.UPDATE_TACTICAL,this.onUpdatePlayerPet,this);
        app.event.off(GBattleDataEnum.UPDARE_ATTRIBUTE_SUCCESS,this.onUpdateAttribute,this);
        // app.event.off(GOnHookManagerEvent.UPDATE_MAP,this.onUpdateWorld,this);
    }

    onSyncInitSuccess():void{

        //初始化战斗
        console.log("GOnHookMode 模式初始化");

        super.onSyncInitSuccess();

        //初始化状态机
        this.fsm = new GFSMOnHookMode(this);

        //更新场景
        this.onUpdateWorld();
        this.onUpdatePlayerPet();

        //添加监听
        this.addEvent();

        // //模拟请求生成宠物
        // app.socket.SendBack(GAction.MODE_ON_HOOK_SPAWN_PET,{
        //     type:GActionType.GOnHookPets,
        //     fun:(info:GOnHookPets) => {
        //         console.log("接受到野怪列表",info)
        //     }
        // })

        //生成玩家
        // this.playerInfo.roles.forEach((info,index) => this.onGenRole(GNormalModePlayerEnum.PLAYER,index + 1,info))

        // //生成敌人
        // this.onResetGenerateEnemy();

    }

    //更新地图
    onUpdateWorld(){
        let info = TD.TbGOnHookMaps.get(GOnHookData.getIns().info.onHookMap);
        this.setWorldMap(info.mapId);
    }

    //更新页面
    onUpdateView(){

    }
    
    //更新玩家宠物
    onUpdatePlayerPet(){
        //获取玩家阵容
        let infos = PlayerTacticalData.getIns().getTacticalInfo();
        
        //移除不再阵容中的宠物
        let roles = [...this.getOnesRoleAlive(GNormalModePlayerEnum.PLAYER)]
        roles.forEach(role => {
            let expand = role.getComponent(GRoleOnHookPlayerExpand);
            //如果宠物不再阵容中 则 移除宠物
            if(infos.indexOf(expand.petId) < 0){
                //移除宠物
                this.playerRoles.splice(this.playerRoles.indexOf(role),1);
                role.isDie = true;
            }
        })

        infos.forEach((petId,index) => {
            if(petId){
                this.onGenPlayerPet(index+1,petId);
            }
        })

    }

    //更新属性
    onUpdateAttribute(){
        
        this.getOnesRole(GNormalModePlayerEnum.PLAYER).forEach(pet => {
            pet.onEffectiveValue(GBattleData.getIns().data.getPetAttribute(pet.getComponent(GRoleOnHookPlayerExpand).petId));
        });

    }

    //更新帧
    onSyncUpdate(dt: number,frame:JNFrameInfo, input?: {}){
        super.onSyncUpdate(dt,frame,input);
        this.onUpdateMap(dt);
        this.onUpdateCamera(dt);
        this.fsm.onUpdate(dt,frame);
    }

    //更新相机逻辑
    onUpdateCamera(dt:number){

        //如果没有敌人相机永远锁定最前面的宠物
        if(this.isAllowAttack && this.isHaveEnemy()){

            //如果有敌人则移动到战斗位置
            let cameraWorld = this.camera.node.worldPosition.clone();
            this.camera.node.worldPosition = cameraWorld.lerp(v3(this.nextFightX,cameraWorld.y,cameraWorld.z),(dt / 1000));

        }else{
            //获取冲到最前面的宠物
            let roles = this.getOnesRoleAlive(GNormalModePlayerEnum.PLAYER);
            let frontRole = roles.sort((role1,role2) => role2.v2World.x - role1.v2World.x)[0];
            if(!frontRole) return;

            //设置相机 位置
            let cameraWorld = this.camera.node.worldPosition.clone();
            this.camera.node.worldPosition = cameraWorld.lerp(v3(frontRole.v2World.x,cameraWorld.y,cameraWorld.z),(dt / 1000));
        }

    }

    //生成玩家宠物
    onGenPlayerPet(index:number,petId:number){

        //如果场上有这个宠物则更新阵法位置
        let passRole:GRoleDefault;
        this.playerRoles.forEach(role => {
            if(role.getComponent(GRoleOnHookPlayerExpand).petId == petId)
                passRole = role;
        })
        if(passRole){
            //更新宠物阵法位置
            passRole.tacticalIndex = index;
            return;
        }


        //获取要生成的宠物
        let info = PlayerPetData.getIns().petIdQueryPetInfo(petId);
        if(!info){
            app.layer.Open(GUI.Tips,{text:"未拥有当前上阵的宠物"});
            return;
        }
        let role = this.onGenRole(GNormalModePlayerEnum.PLAYER,index,TD.TbGRole.get(info.petTbId));
        //向宠物添加 OnHook 扩展
        let expand = role.node.addComponent(GRoleOnHookPlayerExpand);
        expand.petId = petId;

        //添加宠物属性
        role.onEffectiveValue(GBattleData.getIns().data.getPetAttribute(petId));

    }

    //生成野怪
    onGenCreeps(index:number,creeps:GOnHookPet){

        let role = this.onGenRole(GNormalModePlayerEnum.ENEMY,index,TD.TbGRole.get(creeps.petTbId));

        //向野怪添加扩展
        let expand = role.node.addComponent(GRoleOnHookCreepsExpand);
        expand.creeps = creeps;

        //添加野怪属性
        role.onEffectiveValues(new GPetAttribute({
            petId:0,               
            petPlayerId:0,         
            petTbId:creeps.petTbId,        
            petLevel:creeps.petLevel,            
            petStar:0,             
            petStarExp:0,          
        }));

    }

    //获取敌人
    getEnumy(player:GRoleDefault,type:GNormalModePlayerEnum):GRoleDefault{

        if(!this.isAllowAttack) return null;

        return super.getEnumy(player,type);

    }

    //生成敌人
    onResetFight(){

        //初始化战斗失败
        this.isFail = false;

        this.enemyRoles = [];
        let sign = TD.TbGOnHookMaps.get(GOnHookData.getIns().info.onHookMap).sign;
        let table:{data:TbGEntity.TOnHookLevel} = TD[sign].get(GOnHookData.getIns().info.levelId);

        for (let index = 0; index < table.data.petSize; index++) {
            //获取敌人
            let creeps = GOnHookManager.getIns().getNextCreeps();
            if(!creeps) return; //没有获取到野怪则返回
            this.onGenCreeps(index + 1,creeps);
        }

        this.onUpdatePlayerPet();
        // this.enemyInfo.roles.forEach((info,index) => this.onGenRole(GNormalModePlayerEnum.ENEMY,index + 1,info));
    }

    //角色死亡回调
    onRoleKillBack(role:GRoleDefault){
        
        super.onRoleKillBack(role);

        //如果死亡的是野怪则通知野怪死亡
        if(role.getComponent(GRoleOnHookCreepsExpand)){
            GOnHookManager.getIns().onKillSreeps(role.getComponent(GRoleOnHookCreepsExpand).creeps);
            //如果野怪都死了 并且 战斗成功 则向服务器发送战斗成功
            if(this.enemyRoles.length <= 0 && !this.isFail){
                GOnHookManager.getIns().onWinLevel();
            }
        }

        //如果死亡的是玩家宠物 并且 场上没有玩家宠物则重新战斗
        if(role.getComponent(GRoleOnHookPlayerExpand)){
            if(this.playerRoles.length <= 0){
                //玩家战斗失败
                this.isFail = true;
                this.onUpdatePlayerPet();
            }
        }

    }

    //清理缓存
    onClearCache(){

        //清理宠物
        let roles = [...this.playerRoles];
        roles.forEach(role => {
            if(!role.get()){
                this.playerRoles.splice(this.playerRoles.indexOf(role),1);
            }
        })
        roles = [...this.enemyRoles];
        roles.forEach(role => {
            if(!role.get()){
                this.enemyRoles.splice(this.enemyRoles.indexOf(role),1);
            }
        })

    }

    //是否有怪物
    isHaveEnemy(){
        if(!this.isAllowAttack) return [];
        return this.getOnesRoleAlive(GNormalModePlayerEnum.ENEMY).filter(role => !!role.get()).length > 0;
    }

    //前往下一个目标
    onNextTarget(){

        //下一个目标点
        this.nextFightX = this.nextFightX + this.everyX;

    }

}

