using System.Collections.Generic;
using System.Text.Json;
using BattleIce;
using JsonSerializer = System.Text.Json.JsonSerializer;

namespace ET.Server
{
    [FriendOf(typeof (WNPlayer))]
    [FriendOf(typeof (BattleIceAgentComponent))]
    public static class PlayerSystem
    {
        public class PlayerAwakeSystem: AwakeSystem<WNPlayer, Session>
        {
            protected override void Awake(WNPlayer self, Session session)
            {
                Log.Info($"创建玩家实体...");
                PlayerInfo playerInfo = session.GetComponent<SessionPlayerComponent>().PlayerInfo;

                // 绑定sessionId
                self.GameSessionActorId = session.InstanceId;
                self.Session = session;
                self.BasicProp = CharacterConfigCategory.Instance.Get(playerInfo.Pro);
                self.BornType = (int)BORN_TYPE.NORMAL;
                self.EnterState = (int)ENTER_STATE.online;

                // 玩家基础数据组件
                self.AddComponent<PlayerDataComponent, PlayerInfo>(playerInfo);
                // 玩家临时数据组件
                self.AddComponent<PlayerTempDataComponent>();
                // 玩家技能组件
                self.AddComponent<PlayerSkillComponent>();
                // 玩家货币组件
                self.AddComponent<PlayerMoneyComponent>();
                // 玩家属性组件
                self.AddComponent<PlayerBtlComponent>();
            }
        }

        public class PlayerDestroySystem: DestroySystem<WNPlayer>
        {
            protected override void Destroy(WNPlayer self)
            {
                Log.Info($"销毁玩家实体...");
            }
        }

        /// <summary>
        /// 获取角色id
        /// </summary>
        /// <param name="self"></param>
        /// <returns></returns>
        public static long GetId(this WNPlayer self)
        {
            return self.GetComponent<PlayerDataComponent>().Data.Id;
        }

        /// <summary>
        /// 获取玩家类型
        /// </summary>
        /// <param name="self"></param>
        /// <returns></returns>
        public static int GetPlayerType(this WNPlayer self)
        {
            return self.GetComponent<PlayerDataComponent>().Data.PlayerType;
        }

        /// <summary>
        /// 获取直播间id
        /// </summary>
        /// <param name="self"></param>
        /// <returns></returns>
        public static long GetRoomId(this WNPlayer self)
        {
            return self.GetComponent<PlayerDataComponent>().Data.RoomId;
        }

        /// <summary>
        /// 获取名称
        /// </summary>
        /// <param name="self"></param>
        /// <returns></returns>
        public static string GetName(this WNPlayer self)
        {
            return self.GetComponent<PlayerDataComponent>().Data.Name;
        }

        /// <summary>
        /// 获取性别
        /// </summary>
        /// <param name="self"></param>
        /// <returns></returns>
        public static int GetSex(this WNPlayer self)
        {
            return self.GetComponent<PlayerDataComponent>().Data.Sex;
        }

        /// <summary>
        /// 获取职业
        /// </summary>
        /// <param name="self"></param>
        /// <returns></returns>
        public static int GetPro(this WNPlayer self)
        {
            return self.GetComponent<PlayerDataComponent>().Data.Pro;
        }

        /// <summary>
        /// 获取经验
        /// </summary>
        /// <param name="self"></param>
        /// <returns></returns>
        public static long GetExp(this WNPlayer self)
        {
            return self.GetComponent<PlayerDataComponent>().Data.Exp;
        }

        /// <summary>
        /// 获取等级
        /// </summary>
        /// <param name="self"></param>
        /// <returns></returns>
        public static int GetLevel(this WNPlayer self)
        {
            return self.GetComponent<PlayerDataComponent>().Data.Level;
        }

        /// <summary>
        /// 获取金币
        /// </summary>
        /// <param name="self"></param>
        /// <returns></returns>
        public static long GetGold(this WNPlayer self)
        {
            return self.GetComponent<PlayerDataComponent>().Data.Gold;
        }

        /// <summary>
        /// 获取场景实例id
        /// </summary>
        /// <param name="self"></param>
        /// <returns></returns>
        public static long GetMapInstanceId(this WNPlayer self)
        {
            return self.Map.InstanceId;
        }

        /** 获取服务器id **/
        public static int GetLogicServerId(this WNPlayer self)
        {
            return self.GetComponent<PlayerDataComponent>().Data.LogicServerId;
        }

        public static ZoneManagerPrx GetZoneManager(this WNPlayer self)
        {
            return self.DomainScene().GetComponent<BattleIceAgentComponent>().IceZoneManager;
        }

        public static XmdsManagerPrx GetXmdsManager(this WNPlayer self)
        {
            return self.DomainScene().GetComponent<BattleIceAgentComponent>().IceXmdsManager;
        }

        /** bornData相关初始化 **/
        public static void InitBornData(this WNPlayer self)
        {
            switch (self.BornType)
            {
                case (int)BORN_TYPE.HISTORY:
                    self.GetComponent<PlayerTempDataComponent>().MapData.mapId = self.GetComponent<PlayerTempDataComponent>().MapData.historyMapId;
                    self.GetComponent<PlayerTempDataComponent>().MapData.mapInstanceId =
                            self.GetComponent<PlayerTempDataComponent>().MapData.historyMapInstanceId;
                    self.GetComponent<PlayerTempDataComponent>().MapData.x = self.GetComponent<PlayerTempDataComponent>().MapData.historyX;
                    self.GetComponent<PlayerTempDataComponent>().MapData.y = self.GetComponent<PlayerTempDataComponent>().MapData.historyY;
                    break;
                case (int)BORN_TYPE.BORN:
                    self.GetComponent<PlayerTempDataComponent>().MapData.mapId = self.GetComponent<PlayerTempDataComponent>().MapData.bornMapId;
                    self.GetComponent<PlayerTempDataComponent>().MapData.mapInstanceId =
                            self.GetComponent<PlayerTempDataComponent>().MapData.bornMapInstanceId;
                    self.GetComponent<PlayerTempDataComponent>().MapData.x = self.GetComponent<PlayerTempDataComponent>().MapData.bornX;
                    self.GetComponent<PlayerTempDataComponent>().MapData.y = self.GetComponent<PlayerTempDataComponent>().MapData.bornY;
                    break;
            }
        }

        /** 客户端资源加载完成通知 给客户端推送的数据要在这里 **/
        public static void OnReady(this WNPlayer self)
        {
            self.OnEndEnterScene();

            // 登录第一次进场景处理,此次登陆登出期间只处理一次
            if (self.ReadyFirst)
            {
                self.ReadyFirst = false;
            }
        }

        /** 玩家登录事件 **/
        public static void OnLogin(this WNPlayer self)
        {
            self.ReadyFirst = true;
            self.DomainScene().GetComponent<GamePlayerComponent>().Add(self.GetId(), self);
        }

        /** 向客户端推送角色相关数据 **/
        public static void OnEndEnterScene(this WNPlayer self)
        {
            bool ready = self.GetComponent<PlayerTempDataComponent>().MapData.ready;
            if (ready)
            {
                Log.Warning($"$OnEndEnterScene跳过 : playerId={self.GetId()}, 玩家场景:{self.Map.MapId}, 进入场景:" + (self.Map?.MapId ?? -1));
                return;
            }

            self.GetComponent<PlayerTempDataComponent>().MapData.ready = true;

            self.GetXmdsManager().playerReady(self.GetId().ToString().Trim());
            //PKMode设置为All
            self.GetXmdsManager().refreshPlayerPKMode(self.GetId().ToString().Trim(), false, (int)PkModel.All);
            //设置为自动战斗
            self.GetXmdsManager().autoBattle(self.Map.Id.ToString().Trim(), self.GetId().ToString().Trim(), true);
        }

        /// <summary>
        /// 战斗服角色数据
        /// </summary>
        /// <param name="self"></param>
        /// <returns></returns>
        private static Dictionary<string, object> GetBattlerServerBasic(this WNPlayer self)
        {
            Dictionary<string, object> data = new Dictionary<string, object>();
            data.Add("name", self.GetName());
            data.Add("alliesForce", 0);
            data.Add("force", 1);
            data.Add("pro", self.GetPro());
            data.Add("serverId", ConstGame.GameServerId);
            data.Add("titleId", 0);
            data.Add("level", self.GetLevel());
            data.Add("vip", 0);
            data.Add("upLevel", 1);
            // 无悬赏
            data.Add("beReward", 0);
            data.Add("logicServerId", ConstGame.GameServerId);
            data.Add("sex", self.GetSex());
            data.Add("uuid", self.GetId().ToString());
            data.Add("potionAddition", 0);
            return data;
        }

        /// <summary>
        /// 场景中角色需求数据
        /// </summary>
        /// <param name="self"></param>
        /// <param name="map"></param>
        /// <returns></returns>
        public static string ToJSON4EnterScene(this WNPlayer self, Map map)
        {
            var json = new
            {
                effects = self.GetComponent<PlayerBtlComponent>().GetBattleServerEffects(),
                effectsExt = new { },
                skills = self.GetComponent<PlayerSkillComponent>().ToJson4BattleServerSkills,
                tasks = new { },
                flags = new { },
                playerEntered = false,
                avatars = new { },
                basic = self.GetBattlerServerBasic(),
                connectServerId = "bs-" + ConstGame.GameServerId,
                uid = self.GetId().ToString(),
                unitTemplateID = self.BasicProp.TemplateId,
                robot = false,
                tempData = self.GetComponent<PlayerTempDataComponent>().ToJson4BattleServerTempData,
                pkInfo = new { mode = 0, value = 0, level = 1, },
                //petBase,
                addTestPetData = 0,
                sceneData = new { allowAutoGuard = 3, },
            };

            return JsonSerializer.Serialize(json, new JsonSerializerOptions { IncludeFields = true });
        }
    }
}