import { Animation, director } from "cc";
import { GameMgr } from "../../module_basic/scripts/GameMgr";
import { NetGameServer } from "../../module_basic/scripts/NetGameServer";
import { SubGameMgr } from "../../module_basic/scripts/SubGameMgr";
import { UserMgr } from "../../module_basic/scripts/UserMgr";
import { MsgAreanBattleReportPush } from "../../module_basic/shared/protocols/public/arean/MsgAreanBattleReportPush";
import { MsgAreanPlayerComesPush } from "../../module_basic/shared/protocols/public/arean/MsgAreanPlayerComesPush";
import { MsgAreanGameStatusPush } from "../../module_basic/shared/protocols/public/arean/MsgAreanGameStatusPush";
import { MsgAreanBloodVolumePush } from "../../module_basic/shared/protocols/public/arean/MsgAreanBloodVolumePush";
import { MsgAreanCareerPush } from "../../module_basic/shared/protocols/public/arean/MsgAreanCareerPush";
import { MsgAreanPlayerStatusPush } from "../../module_basic/shared/protocols/public/arean/MsgAreanPlayerStatusPush";
import { MsgAreanSelectCardListPush } from "../../module_basic/shared/protocols/public/arean/MsgAreanSelectCardListPush";
import {
    EPlayerPushType,
    GameStage,
    IAreanGameData,
    IAreanPlayer,
    IAreanUserData
} from "../../module_basic/shared/protocols/public/arean/AreanTypeDef";
import { areanMgr } from "./AreanManager";
import { MsgNoticePush } from "../../module_basic/shared/protocols/public/lobby/MsgNoticePush";
import { MsgAreanGameDataPush } from "../../module_basic/shared/protocols/public/arean/MsgAreanGameDataPush";
import { MsgAreanSelectEquipListPush } from "../../module_basic/shared/protocols/public/arean/MsgAreanSelectEquipListPush";
import { MsgAreanSelectTreasureListPush } from "../../module_basic/shared/protocols/public/arean/MsgAreanSelectTreasureListPush";
import { tgxSceneUtil, tgxUIAlert } from "../../core_tgx/tgx";
import { SceneDef } from "../../scripts/SceneDef";
import { MsgAreanStageReadyPush } from "db://assets/module_basic/shared/protocols/public/arean/MsgAreanStageReadyPush";
import { MsgAreanAttrUpdatePush } from "../../module_basic/shared/protocols/public/arean/MsgAreanAttrUpdatePush";
import { MsgAreanGameBeginPush } from "../../module_basic/shared/protocols/public/arean/MsgAreanGameBeginPush";
import { MsgAreanInBattleViewPush } from "../../module_basic/shared/protocols/public/arean/MsgAreanInBattleViewPush";
import { MsgAreanDanUpdatePush } from "db://assets/module_basic/shared/protocols/public/arean/MsgAreanDanUpdatePush";
import { MsgPlayerInfoPush } from "db://assets/module_basic/shared/protocols/public/lobby/MsgPlayerInfoPush";
import { UserInfo } from "../../module_basic/shared/types/UserInfo";
import { MsgAreanGetBattleRewards } from "../../module_basic/shared/protocols/public/arean/MsgAreanGetBattleRewards";
import { MsgAreanBattleRewardsPush } from "../../module_basic/shared/protocols/public/arean/MsgAreanBattleRewardsPush";

export class AreanEvent {
    /**
     * 玩家同步
     */
    public static PlayerComes = 'KingTDEvent.PLAYER_COMES';
    /**
     * 玩家数据更新
     */
    public static PlayerDataChanged = 'KingTDEvent.PLAYER_DATA_CHANGED';
    /**
     * 游戏开始
     */
    public static GameBegin = 'KingTDEvent.GAME_BEGIN';
    /**
     * 游戏结束
     */
    public static GameOver = 'KingTDEvent.GAME_OVER';
    /**
     * 游戏数据更新
     */
    public static GameDataChanged = 'KingTDEvent.TANK_DATA_CHANGED';
    /**
     * 
     */
    public static KingTDShoot = 'KingTDEvent.TANK_SHOOT';
    /**
     * 玩家攻击
     */
    public static KingTDAttack = 'KingTDEvent.TANK_ATTACK';

    /**
     * 玩家死亡
     */
    public static PlayerDie = 'KingTDEvent.PLAYER_DIE';

    /**
     * 游戏数据同步
     */
    public static GameDataSync = 'KingTDEvent.GAME_DATA_SYNC';

    /**
     * 获取卡牌
     */
    public static GetCards = "KingTDEvent.GET_CARDS";

    /**
     * 士气升级
     */
    public static MoraleLevelUp = "KingTDEvent.MORALE_LEVEL_UP";
    /**
     * 修改角色学血量
     */
    public static ChangeHp = "KingTDEvent.CHANGE_HP";

    /**
     * 修改卡片数据
     */
    public static CardChanged = "KingTDEvent.CARD_CHANGED";

    /**
     * 删除卡片
     */
    public static CardDelete = "KingTDEvent.CARD_DELETE";

    /**
     * 卡片移动
     */
    public static CardMoving = "KingTDEvent.CARD_MOVING";

    /**
     * buff修改
     */
    public static CardChangeBuff = "KingTDEvent.CARD_CHANGE_BUFF";

    /**
     * 子弹修改
     */
    public static CardChangeBullet = "KingTDEvent.CARD_CHANGE_BULLET";

    /**
     * 技能修改
     */
    public static CardChangeSkill = "KingTDEvent.CARD_CHANGE_SKILL";

    /**
     * 修改角色信息
     */
    public static UpdateUserData = "KingTDEvent.UPDATE_USER_DATA";

    /**
     * 推送道具数量
     */
    public static PropsPush = "KingTDEvent.PROPS_PUSH";

    /**
     * 获取指定道具列表的道具列表
     */
    public static GetProp = "KingTDEvent.GET_PROPS";

    /**
     * 用户使用道具
     */
    public static UseProp = "KingTDEvent.USE_PROP";

    /**
     * 进入关卡检测
     */
    public static CheckMapLevel = 'KingTDEvent.CHECK_MAP_LEVEL';

    /**
     * 通用资源推送
     */
    public static CommonPush = 'KingTDEvent.COMMON_PUSH';

    /**
     * 指挥官数据更新
     */
    public static CommanderPush = 'KingTDEvent.COMMANDER_PUSH';

    /**
     * 军需官数据更新
     */
    public static MasterPush = 'KingTDEvent.MASTER_PUSH';

    /**
     * 指挥官升级
     */
    public static CommanderLevelUp = 'KingTDEvent.COMMANDER_LEVEL_UP';

    /**
     * 设置卡牌出战
     */
    public static SetCardInBattled = 'KingTDEvent.SET_CARD_IN_BATTLE';

    /**
     * 传信官合并
     */
    public static MsgerMarge = 'KingTDEvent.MSGER_MARGE';

    /**
     * 设置指挥官出战
     */
    public static CommanderInBattled = 'KingTDEvent.COMMANDER_IN_BATTLE';

    /**
     * 设置传信官出战
     */
    public static MsgerInBattled = 'KingTDEvent.MSGER_IN_BATTLE';

    /**
     * 卡片升级
     */
    public static CardLevelUp = 'KingTDEvent.CARD_LEVEL_UP';

    /**
     * 卡片推送
     */
    public static UserCardPush = 'KingTDEvent.USER_CARD_PUSH';

    /**
     * 战报
     */
    public static BattleReportPush = 'AreanEvent.BATTLE_REPORT_PUSH';

    /**
   * 游戏阶段
   */
    public static BattleStagePush = 'AreanEvent.BATTLE_STAGE_PUSH';

    /**
    * 挑选卡牌
    */
    public static SelectCardList = 'AreanEvent.SELECT_CARD_LIST';

    /**
    * 选卡返回
    */
    public static SelectCardBack = 'AreanEvent.SELECT_CARD_BACK';

    /**
    * 玩家数据
    */
    public static PlayerStatus = 'AreanEvent.PLAYER_STATUS';

    /**
     * 装备
     */
    public static SelectEquipList = 'AreanEvent.SELECT_EUIPLIST_PUSH';


    /**
     * 圣物
     */
    public static SelectTreasureList = 'AreanEvent.SELECT_TREASURELIST_PUSH';

    /**
    * 切换英雄
    */
    public static ChangeHero = 'AreanEvent.ChangeHero';

    // 玩家准备
    public static PlayerReady = 'AreanEvent.PlayerReady';

    // 属性变化
    public static AttrUpdate = 'AreanEvent.AttrUpdate';



    /**
     * 玩家进入战斗
     */
    public static InBattleView = 'AreanEvent.InBattleView';
    /**
     * 玩家段位更新
     */
    public static UpdateDan = 'AreanEvent.UpdateDan';

    /**
     * 头像头像框更新
     */
    public static UpdateHeadOrFrame = 'AreanEvent.UpdateHeadOrFrame';
    /**
     * 玩家战斗奖励结算
     */
    public static UpdateBattleResult = 'AreanEvent.UpdateBattleResult';

    
    /**
     * 获得新卡牌
     */
    public static GetBattleRewards = 'AreanEvent.GetBattleRewards';



}


export class AreanNetMgr extends GameMgr {

    private static _inst: AreanNetMgr;
    public static get inst(): AreanNetMgr {
        if (!this._inst) {
            this._inst = new AreanNetMgr();
            if (!this._inst.userData) {
                this._inst.userData = {
                    uid: '',
                    nickname: '',
                    gameLevel: 1,
                };
            }
        }
        return this._inst;
    }


    /**
     * 用户数据
     */
    private userData: IAreanUserData;

    /**
     * 游戏数据
     */
    private _gameData: IAreanGameData;

    /**
     * 游戏数据
     */
    public get gameData(): IAreanGameData {
        return this._gameData;
    }

    public set gameData(data: IAreanGameData) {
        this._gameData = data;
    }
    /**
     * 游戏玩家
     */
    playerMap: { [key: number]: IAreanPlayer } = {};

  
    /**
     * 自己
     */
    public get selfPlayer(): IAreanPlayer {
        let gameUserData = this._gameData.players.find((p) => p.uid == UserMgr.inst.uid);
        if (!gameUserData) {
            console.log("没有找到自己", this._gameData.players);
            return null;
        }
        let self = this.playerMap[gameUserData.playerId];
        if (!self) {
            console.log("没有找到自己", this.playerMap);
        }
        return self;
    }

    /**
     * 直接进入战斗
     */
    // public isInBattleView: boolean = false;k


    public reset() {
        super.reset();
        SubGameMgr.gameMgr = this;
    }

    protected async beforeLoadScene(): Promise<void> {
        await AreanNetMgr.inst.rpc_JoinGame();
    }


    /**
     * 
     * @returns 是否在游戏内
     */
    public isInGame(): boolean {
        console.log("是否在游戏中", this.gameData);
        return this.gameData && this.gameData.gameStage> GameStage.GameAwait && this.gameData.gameStage < GameStage.GameEnd;
    }


    /**
     * 游戏内广播推送
     */
    initNetMsgHandlers() {
        super.initNetMsgHandlers();
        //监听战报
        this.listenMsg("arean/AreanBattleReportPush", this.onNet_BattleReportPush, this);
        this.listenMsg("arean/AreanGameStatusPush", this.onNet_GameStatusPush, this);
        this.listenMsg("arean/AreanBloodVolumePush", this.onNet_BloodVolumePush, this);
        this.listenMsg("arean/AreanCareerPush", this.onNet_CareerPush, this);
        this.listenMsg("arean/AreanPlayerStatusPush", this.onNet_PlayerStatusPush, this);
        this.listenMsg("arean/AreanSelectCardListPush", this.onNet_SelectCardList, this);
        this.listenMsg("arean/AreanSelectEquipListPush", this.onNet_SelectEquipList, this);
        this.listenMsg("arean/AreanSelectTreasureListPush", this.onNet_SelectTreasureList, this);
        this.listenMsg("arean/AreanPlayerComesPush", this.onNet_PlayerComesPush, this);
        this.listenMsg('arean/AreanGameDataPush', this.onNet_AreanGameDataPush, this);
        this.listenMsg('arean/AreanStageReadyPush', this.onNet_AreanPlayerReadyDataPush, this);
        this.listenMsg('arean/AreanAttrUpdatePush', this.onNet_AttrUpdatePush, this);
        this.listenMsg('arean/AreanGameBeginPush', this.onNet_AreanGameBeginPush, this);
        this.listenMsg('arean/AreanDanUpdatePush', this.onNet_AreanDanUpdatePush, this);
        this.listenMsg('arean/AreanGetBattleRewards', this.onNet_AreanGetBattleRewards, this);
        this.listenMsg('arean/AreanBattleRewardsPush', this.onNet_AreaBattleResult, this);
        this.listenMsg("lobby/PlayerInfoPush", this.onNet_PlayerInfoPush, this);
        this.initUINetMsgHandlers();
    }


    /**
     *游戏外广播监听
     */
    initUINetMsgHandlers() {
        try {
            NetGameServer.inst.listenMsg('lobby/NoticePush', this.onNet_NoticePush, this);
            NetGameServer.inst.listenMsg("arean/AreanInBattleViewPush", this.onNet_InBattleViewPush, this);
        } catch (error) {
            console.log(error);
        }
    }


    /**
     * 
     * @param msg 游信息推送
     */
    public onNet_AreanGameDataPush(msg: MsgAreanGameDataPush) {
        try {
            this.gameData = msg.gameData;
            console.log("游戏数据推送 ====== ", this.gameData)
            switch (this.gameData.gameStage) {
                case GameStage.GameAwait:
                    break;
                case GameStage.GameStart:
                    // director.emit(AreanEvent.GameBegin);
                    break;
            }
        } catch (error) {
            console.log(error);
        }
    }

    /**
     *
     * @param msg 游信息推送
     */
    public onNet_AreanPlayerReadyDataPush(msg: MsgAreanStageReadyPush) {
        // console.log("AreanNetMgr onNet_AreanPlayerReadyDataPush", msg);
        director.emit(AreanEvent.PlayerReady, msg);
    }

    public onNet_AttrUpdatePush(msg: MsgAreanAttrUpdatePush) {
        console.log("AreanNetMgr onNet_AttrUpdatePush", msg);
        let playerId = this.selfPlayer.playerId;
        this.playerMap[playerId].attr = msg[playerId][0];
        this.playerMap[playerId].curAttrAdd = msg[playerId][1];
        director.emit(AreanEvent.AttrUpdate, msg[playerId][2]);
    }

    public onNet_InBattleViewPush(msg: MsgAreanInBattleViewPush) {
        console.log('进入战斗推送', msg);
        try {
            director.emit(AreanEvent.InBattleView);
            director.emit(AreanEvent.GameBegin);
        } catch (error) {
            console.log(error);
        }

    }

    public onNet_AreanGameBeginPush(msg: MsgAreanGameBeginPush) {
        console.log('游戏开始', msg);
        director.emit(AreanEvent.GameBegin);
    }

    public onNet_NoticePush(msg: MsgNoticePush) {
        console.log('广播推送', msg);
    }

    //每个阶段的剩余时间 那个阶段 剩余时间  阶段id  1等人 2选职业 3选卡 4战斗 5装备
    onNet_GameStatusPush(msg: MsgAreanGameStatusPush) {
        //console.log("MsgAreanGameStatusPush", msg);
        director.emit(AreanEvent.BattleStagePush, msg);
    }

    //玩家血量
    onNet_BloodVolumePush(msg: MsgAreanBloodVolumePush) {
        console.log("MsgAreanBloodVolumePush", msg);
    }

    //玩家职业
    onNet_CareerPush(msg: MsgAreanCareerPush) {
        console.log("MsgAreanCareerPush", msg);
    }

    // 玩家信息列表
    onNet_PlayerStatusPush(msg: MsgAreanPlayerStatusPush) {
        console.log("游戏玩家列表", msg);
        this.playerMap = msg;
        //director.emit(AreanEvent.PlayerStatus, {});
    }


    //单独选卡接口
    onNet_SelectCardList(msg: MsgAreanSelectCardListPush) {
        this.playerMap[this.selfPlayer.playerId].selectCardList = msg.list;
        console.log("MsgAreanSelectCardListPush", msg);
        //director.emit(AreanEvent.SelectCardList, msg.list);
    }

    //选择装备
    onNet_SelectEquipList(msg: MsgAreanSelectEquipListPush) {
        this.playerMap[this.selfPlayer.playerId].selectEquipList = msg.list;
        console.log("MsgAreanSelectEquipListPush", msg);
        //director.emit(AreanEvent.SelectEquipList, msg.list);
    }

    //选择圣物
    onNet_SelectTreasureList(msg: MsgAreanSelectTreasureListPush) {
        this.playerMap[this.selfPlayer.playerId].selectTreasureList = msg.list;
        console.log("MsgAreanSelectTreasureListPush", msg);
        //director.emit(AreanEvent.SelectTreasureList, msg.list);
    }

    // 段位发生变化
    onNet_AreanDanUpdatePush(msg: MsgAreanDanUpdatePush): void {
        director.emit(AreanEvent.UpdateDan, msg);
    }

    // 获得战中奖励
    onNet_AreanGetBattleRewards(msg: MsgAreanGetBattleRewards): void {
        director.emit(AreanEvent.GetBattleRewards, msg);
        console.log("MsgAreanGetBattleRewards", msg);
    }
    // 战斗结算
    onNet_AreaBattleResult(msg: MsgAreanBattleRewardsPush): void {
        director.emit(AreanEvent.UpdateBattleResult, msg);
    }

    //接收战报
    onNet_BattleReportPush(msg: MsgAreanBattleReportPush) {
        console.log("MsgAreanBattleReportPush", msg);
        this.gameData.curBattleReport = msg;
        //director.emit(AreanEvent.BattleReportPush, msg);
    }
    /**
     * 购买道具
     * @param itemId 购买物品id
     * @param itemNum 购买数量
     */
    async sendMsg_BuyItem(itemId: number,itemNum:number=1,moneyType:number=11) {
        let res = await NetGameServer.inst.conn.callApi('arean/shop/AreanShopBuyItem', { itemId: itemId,count:itemNum,moneyType:moneyType});
        if(res.isSucc){

            tgxUIAlert.show('购买成功');
        }
        else{
            tgxUIAlert.show('购买失败');
        }
        return res;
    }
    /**
     * 
     * 开始游戏
     * @returns 
     */
    async sendMsg_StartGame() {
        console.log("sendMsg_StartGame ===== 1111")
        return await NetGameServer.inst.conn.callApi('arean/AreanStartGame', {});
    }

    async sendMsg_Ready() {
        return await NetGameServer.inst.conn.callApi('arean/AreanReady', { readyStatus: true })
    }

    async sendMsg_GetUserData() {
        return await NetGameServer.inst.conn.callApi('arean/logic/AreanGetUserData', {});
    }
    async sendMsg_surrender() {
        let res = await NetGameServer.inst.conn.callApi('arean/AreanPlayerSurrender', {});
        console.log("投降的结果 === ", res);
        // if (res.isSucc) areanMgr.BattleView.showSettlementView(areanMgr.BattleView.getLocalPlayerData().rank);
    }

    async sendMsg_exit() {
        let res = await this.rpc_LeaveRoom();
        if (res.isSucc) {
            tgxSceneUtil.loadScene(SceneDef.LOBBY_AREAN);

        }
        else {
            tgxUIAlert.show('退出房间失败');
        }
    }

    async sendMsg_InBattleView() {
       await  NetGameServer.inst.conn.callApi('arean/AreanInBattled', { });
    }


    /**
     * 选择英雄
     * @param heroId 英雄id
     */
    async sendMsg_ChooseHero(heroId: number) {
        await NetGameServer.inst.conn.callApi('arean/AreanChooseHero', { id: heroId });
    }

    /**
     * 选择职业
     * @param careerId 职业id
     */
    async sendMsg_SelectCareer(careerId: number) {
        await NetGameServer.inst.conn.callApi('arean/AreanSelectCareer', { careerId })
    }

    /**
     * 购买刷新选择卡牌列表
     */
    async sendMsg_BuySelectCardListRefresh() {
        let msg = await NetGameServer.inst.conn.callApi('arean/AreanBuyCardRefresh', {});
        if (msg.isSucc) {
            // let playerId = areanMgr.BattleView.getLocalPlayerData().playerId;
            // this.playerMap[playerId] = msg.res.playerData;
            // director.emit(AreanEvent.SelectCardList, msg.res);
        }
    }

    /**
     * 购买经验
     */
    async sendMsg_BuyExp() {
        let msg = await NetGameServer.inst.conn.callApi('arean/AreanBuyExp', {});
        if (msg.isSucc) {
            // let data = areanMgr.BattleView.getLocalPlayerData();
            // areanMgr.BattleView.moneyChange();
            // data.lv = msg.res.playerStatus.lv;
            // data.exp = msg.res.playerStatus.exp;
            // data.money = msg.res.playerStatus.money;
            // areanMgr.BattleView.refreshExpLevel();
        }
    }

    /**
     * 修改选择卡牌列表锁定状态
     * @param lockStatus 锁定状态
     */
    async sendMsg_SelectCardListLock(lockStatus: boolean) {
        let msg = await NetGameServer.inst.conn.callApi('arean/AreanSelectCardListLock', { lockStatus })
        if (msg.isSucc) {
            // areanMgr.BattleView.lockBool = msg.res.lockStatus;
            // areanMgr.BattleView.lockNode.active = msg.res.lockStatus;
        }
    }

    /**
     * 选择卡牌
     * @param index 卡牌索引
     */
    async sendMsg_SelectCard(index: number) {
        let msg = await NetGameServer.inst.conn.callApi('arean/AreanSelcetCard', { index })
        if (msg.isSucc) {
            // let playerId = areanMgr.BattleView.getLocalPlayerId();
            // this.playerMap[playerId] = msg.res.playerData;
            // director.emit(AreanEvent.SelectCardBack, msg.res);

        }
    }

    async sendMsg_SelectEquip(index: number) {
        let msg = await NetGameServer.inst.conn.callApi('arean/AreanSelcetEquip', { index });
        if (msg.isSucc) {
            // areanMgr.BattleView.playwarning("获得新装备");

        }
    }

    async sendMsg_SelectTreasure(index: number) {
        let msg = await NetGameServer.inst.conn.callApi('arean/AreanSelectTreasure', { index });
        if (msg.isSucc) {
            // areanMgr.BattleView.playwarning("获得新圣物");
        }
    }

  
    // 刷新装备
    async sendMsg_refresh_equip() {
        return await NetGameServer.inst.conn.callApi("arean/AreanEquipRefresh", {});
    }

    // 刷新圣物
    async sendMsg_refresh_treasure() {
        return await NetGameServer.inst.conn.callApi("arean/AreanTreasureRefresh", {});
    }

    onNet_PlayerComesPush(msg: MsgAreanPlayerComesPush) {
        director.emit(AreanEvent.PlayerComes, msg.player);
        this.playerMap[msg.player.playerId] = msg.player;
        console.log("--------玩家数据同步--------", msg);
    }

    onNet_PlayerInfoPush(msg: MsgPlayerInfoPush): void {
        console.log("收到服务端推送的个人信息 === ", msg)
        let data = msg.data;
        switch (data.pushType) {
            case EPlayerPushType.HeroListType: {
                let info: UserInfo = UserMgr.inst.userInfo;
                if (info) {
                    info.hero = data.info;
                }
            }
                break;
            case EPlayerPushType.DanType: {
                let info: UserInfo = UserMgr.inst.userInfo;
                if (info) {
                    info.danInfo = data.info;
                }
            }
                break;
            case EPlayerPushType.ItemListType: {
                let info: UserInfo = UserMgr.inst.userInfo;
                if (info) {
                    info.itemList = data.info;
                }
            }
                break;
            case EPlayerPushType.MainDanType:{
                let info : UserInfo = UserMgr.inst.userInfo;
                if(info){
                    info.mainDanInfo = data.info;
                }
            }
                break;
            case EPlayerPushType.SeasonDataType:{
                let info : UserInfo = UserMgr.inst.userInfo;
                if(info){
                    info.seasonInfo = data.info;
                }
            }
                break;
            default:
                break
        }
    }
}
SubGameMgr.inst.registerGameMgr('arean', AreanNetMgr.inst);