import { _decorator,Node } from "cc";
import GBaseMode from "../GBaseMode";
import { GTactical } from "../entity/GTactical";
import { Prefab } from "cc";
import { instantiate } from "cc";
import { Vec2 } from "cc";
import { GRoleUtil } from "../entity/GRole";
import GRoleDefault from "../base/role/GRoleDefault";
import { v3 } from "cc";
import { TB } from "../../config/data/schema";
import JNFrameTime from "../../../../extensions/ngame/assets/ngame/sync/frame/game/time/JNFrameTime";
import GBattleModeManager from "../GBattleModeManager";
import { app, TD } from "../../App";
import { GPVPStart } from "../../action/PVPAction";
import { PlayerPetOV } from "../../consts/API";
import GPetAttribute from "../base/values/attribute/role/GPetAttribute";
import { GModeEvent } from "./GMode";
const { ccclass, property } = _decorator;

//PVP 角色
export enum GPVPModePlayerEnum{
    PLAYER, //玩家
    ENEMY, //敌人
}

//PVP 玩家信息
export interface GPVPModePlayerInfo{
    //阵法
    tactical: GTactical;
    //宠物列表
    roles: PlayerPetOV[];
}

/**
 * PVP 模式
 */
@ccclass('GPVPMode')
export default class GPVPMode extends GBaseMode<{},GPVPStart>{

    @property(Prefab)
    rolePrefab: Prefab = null;

    @property(Node)
    objects: Node = null;
    
    //玩家信息
    playerInfo: GPVPModePlayerInfo;
    //敌方信息
    enemyInfo: GPVPModePlayerInfo;

    //玩家宠物
    playerRoles: GRoleDefault[] = [];
    //敌方宠物
    enemyRoles: GRoleDefault[] = [];

    //玩家位置
    playerPos: Vec2 = new Vec2(-400,0);
    //敌方位置
    enemyPos: Vec2 = new Vec2(400,0);

    //是否结束游戏
    isEndGame:boolean = false;

    get scene():Node{
        return this.objects;
    }

    onLoad(){

        //整理GPVPStart数据
        //宠物Id列表
        let leftTactical:number[] = JSON.parse(this.data.leftTactical);     
        let rightTactical:number[] = JSON.parse(this.data.rightTactical);

        //宠物列表
        let leftTbs:PlayerPetOV[] = [];
        let rightTbs:PlayerPetOV[] = [];

        //整理宠物信息
        for (let index = 0; index < leftTactical.length; index++) {
            const petId = leftTactical[index];
            leftTbs[index] = null;

            if(petId != 0){
                let pet:PlayerPetOV = JSON.parse(this.data.leftPets[petId]);
                if(pet && pet.petId)
                    leftTbs[index] = pet;
            }
        }

        for (let index = 0; index < rightTactical.length; index++) {
            const petId = rightTactical[index];
            rightTbs[index] = null;

            if(petId != 0){
                let pet:PlayerPetOV = JSON.parse(this.data.rightPets[petId]);
                if(pet && pet.petId)
                    rightTbs[index] = pet;
            }
        }


        this.playerInfo = { tactical: GTactical.getTactical().setOffset(this.playerPos), roles: leftTbs };
        this.enemyInfo = { tactical: GTactical.getTactical(true).setOffset(this.enemyPos), roles: rightTbs };

        super.onLoad();
    }


    onSyncInitSuccess(): void {
                    
        //调整相机
        this.camera.enabled = true;
        let camreaPos = this.camera.node.worldPosition;
        this.camera.node.worldPosition = v3(0,360,camreaPos.z)

        //初始化战斗
        console.log("GPVPMode 模式初始化");
        
        //生成宠物
        this.playerInfo.roles.forEach((info,index) => info && this.onGenRole(GPVPModePlayerEnum.PLAYER,index+1,info))
        this.enemyInfo.roles.forEach((info,index) => info && this.onGenRole(GPVPModePlayerEnum.ENEMY,index+1,info))

    }

    //生成角色
    onGenRole(type: GPVPModePlayerEnum,index:number,info:PlayerPetOV) {

        let tactical = this.getInfo(type).tactical;
        let pos:Vec2 = this.getInfo(type).tactical.getPosition(index);
        if(!pos) return;
        let role = instantiate(this.rolePrefab);
        let entity = role.getComponent(GRoleDefault);
        //初始化
        entity.onInit(type,TD.TbGRole.get(info.petTbId),tactical,index);

        //绑定寻敌
        entity.onQueryEunmy = () => {
            return this.getEnumy(entity,type);
        }

        //绑定受击回调
        entity.addHitCallback(this.onHitBack.bind(this));
        //绑定死亡回调
        entity.addKillBackEvent(this.onRoleKillBack.bind(this))

        //添加宠物属性
        entity.onEffectiveValues(new GPetAttribute(info));

        this.addGObject(entity,tactical.getPosition(index));
        this.getOnesRole(type).push(entity);

    }

    //获取配置
    getInfo(type: GPVPModePlayerEnum): GPVPModePlayerInfo {
        if(type == GPVPModePlayerEnum.PLAYER) return this.playerInfo;
        if(type == GPVPModePlayerEnum.ENEMY) return this.enemyInfo;
    }

    //获取阵营角色
    getOnesRole(type: GPVPModePlayerEnum):GRoleDefault[]{
        if(type == GPVPModePlayerEnum.PLAYER) return this.playerRoles;
        if(type == GPVPModePlayerEnum.ENEMY) return this.enemyRoles;
    }

    //获取存活的宠物
    getOnesRoleAlive(type: GPVPModePlayerEnum):GRoleDefault[]{
        if(type == GPVPModePlayerEnum.PLAYER) return this.playerRoles.filter(role => !!role.get());
        if(type == GPVPModePlayerEnum.ENEMY) return this.enemyRoles.filter(role => !!role.get());
    }

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

        let enumyOnes = GPVPModePlayerEnum.ENEMY
        //如果是ENEMY 则 它的敌人是 PLAYER
        if(type == GPVPModePlayerEnum.ENEMY) enumyOnes = GPVPModePlayerEnum.PLAYER

        //获取敌人
        let roles = this.getOnesRoleAlive(enumyOnes);

        //通过距离获取最近的敌人
        if(roles[0]){
            let len = Math.abs(Vec2.distance(player.v2World,roles[0].v2World));
            let enumy = roles[0];
            for (let index = 0; index < roles.length; index++) {
                const role = roles[index];
                let tLen;
                if(tLen = Math.abs(Vec2.distance(player.v2World,role.v2World)) < len){
                    enumy = role;
                    len = tLen;
                }
                
            }
            return enumy;
        }else{
            return null;
        }

    }

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

        //死亡销毁
        JNFrameTime.getInstance().setTimeout(() => {
            if(role.isValid)
                role.node.destroy()
        },3000)

        this.onUpdateEndState();

    }

    //刷新结束状态
    onUpdateEndState(){

        //如果已经结束则返回
        if(this.isEndGame) return;

        //判断是否有队伍都死亡
        if(this.getOnesRoleAlive(GPVPModePlayerEnum.PLAYER).length == 0 || this.getOnesRoleAlive(GPVPModePlayerEnum.ENEMY).length == 0){
            this.isEndGame = true;
            let winner = this.data.leftPlayerId;
            if(this.getOnesRoleAlive(GPVPModePlayerEnum.ENEMY).length){
                winner = this.data.rightPlayerId;
            }
            //结束游戏
            JNFrameTime.getInstance().setTimeout(() => {
                console.log(this.getOnesRoleAlive(GPVPModePlayerEnum.PLAYER).length,this.getOnesRoleAlive(GPVPModePlayerEnum.ENEMY).length)
                this.Close(winner);
            },3000)
        }

    }
    
    //角色受击回调
    onHitBack(role:GRoleDefault,hit:number){

        if(!role.get()) return;

        //添加受击显示
        app.event.emit(GModeEvent.HIT,{
            mode:this,
            role:role,
            hit:hit,
            world:role.v2World,
            camera:this.camera,
        });

    }
    
}


