using System;
using MrWu.Debug;
using Server.Pack;
using Server.Data;
using Server.MQ;
using GameData;
using Server.Module;
using GameData.Club;
using Server.Config;
using Server.Data.Module;
using GameConfig = GameData.GameConfig;
using TingConfig = GameData.TingConfig;

namespace Server
{
    /// <summary>
    /// 游戏通用发包类
    /// </summary>
    public static class GeneralSendPack
    {
        /// <summary>
        /// 发送玩家自身信息
        /// </summary>
        public static void SendPlayerInfo(PlayerDataAsyc pl)
        {
            PackHead head = PackHead.Create(GamePackAgreement.playerInfo);
            head.userid = pl.userid;

            GameNet.SendPack(pl, head, pl);
            head.Dispose();
        }

        public static void SendPackToPlayer(PackHead head, PlayerDataAsyc pl, object data)
        {
            if (pl == null || head == null) return;
            head.gameNode = GameBase.instance.myUtil;
            GameNet.SendPack(pl, head, data == null ? null : JsonPack.GetJson(data));
        }

        private static GameData.GameConfig gameConfig;

        private static void SetOldGameConfig()
        {
            if (gameConfig == null)
            {
                Server.Config.GameConfig config = ServerConfigManager.Instance.GameConfig;
                //新客户端可以改成一个新包,这里是兼容老的客户端
                gameConfig = new GameConfig();
                gameConfig.gameid = config.GameId;
                gameConfig.gameClientId = config.ClientId;
                gameConfig.gameName = config.GameName;
                gameConfig.maxPlayer = 10000;
                gameConfig.OpenFriendRoom = config.OpenFriend;
                gameConfig.OpenGlod = config.OpenGold;
                gameConfig.gameMode = config.GameMode;
                gameConfig.gameGz = config.GameGz;
                gameConfig.style = config.GameStyle;
                gameConfig.plat = 0;
                gameConfig.sortNum = 0;
                gameConfig.imgNum = 0;
                gameConfig.activezt = 1;

                gameConfig.tings = new TingConfig[ServerConfigManager.Instance.TingCnt];
                //厅配置
                for (int i = 0; i < ServerConfigManager.Instance.TingCnt; i++)
                {
                    gameConfig.tings[i] = new TingConfig();
                    var tingConfig = gameConfig.tings[i];
                    var originTingConfig = ServerConfigManager.Instance.Tings[i];
                    tingConfig.id = originTingConfig.TingId;
                    tingConfig.deskCnt = originTingConfig.DeskCnt;
                    tingConfig.warCnt = originTingConfig.MinPlayerCnt;
                    tingConfig.maxCnt = originTingConfig.MaxPlayerCnt;
                    tingConfig.tingGz = originTingConfig.TingGz;
                }

                int castlesCnt = 0;
                if (ServerConfigManager.Instance.OpenFriend > 0) //开启了朋友房
                {
                    castlesCnt = (ServerConfigManager.Instance.CastlesCnt - 1) * 3 + 1;
                }else
                {
                    castlesCnt = ServerConfigManager.Instance.CastlesCnt * 3;
                }
                 
                
                gameConfig.castles = new CastleConfig[castlesCnt];
                int castleIndex = 0;
                for (int i = 0; i < ServerConfigManager.Instance.CastlesCnt; i++) // 一个拓展成3个
                {
                    bool isFriendRoomCastles = ServerConfigManager.Instance.OpenFriend > 0 &&
                                               i == (ServerConfigManager.Instance.CastlesCnt - 1);

                    int virtualCastleCnt = isFriendRoomCastles ? 1 : 3;
                    for (int j = 0; j < virtualCastleCnt; j++)
                    {
                        gameConfig.castles[castleIndex] = new CastleConfig();
                        var castleConfig = gameConfig.castles[castleIndex];
                        var originCastleConfig = ServerConfigManager.Instance.Castles[i];

                        castleConfig.tingids = originCastleConfig.Tings;
                        castleConfig.peilv = originCastleConfig.BeiLv;
                        castleConfig.roomMode = isFriendRoomCastles ? 2 : 0;

                        castleConfig.tax = originCastleConfig.Tax;
                        castleConfig.exp = originCastleConfig.Exp;
                        
                        //就限制进入的数据不一致
                        if (isFriendRoomCastles)
                        {
                            castleConfig.minMoney = originCastleConfig.MinMoney;
                            castleConfig.maxMoney = int.MaxValue;
                        }
                        else
                        {
                            if (j == 0)
                            {
                                castleConfig.minMoney = originCastleConfig.MinMoney;
                                castleConfig.maxMoney = originCastleConfig.MinMoney + 1;
                            }else if (j == 1)
                            {
                                castleConfig.minMoney = originCastleConfig.MinMoney + 1;
                                castleConfig.maxMoney = originCastleConfig.MinMoney + 2;
                            }
                            else
                            {
                                castleConfig.minMoney = originCastleConfig.MinMoney + 2;
                                castleConfig.maxMoney = originCastleConfig.MaxMoney == 0 ? int.MaxValue : originCastleConfig.MaxMoney;
                            }
                        }
                        
                        castleIndex++;
                    }
                }
            }
        }

        /// <summary>
        /// 发送游戏信息 只发送配置
        /// </summary>
        /// <param name="pl">玩家</param>
        public static void SendGameInfo(PlayerDataAsyc pl)
        {
            try
            {
                if (pl.ClientVer >= VersionConfigCategory.Instance.CVersion48)
                {
                    if (ServerConfigManager.Instance.CastleRewardData != null)
                    {
                        PackHead rewardHead = PackHead.Create(GameSeverAgreement.CastleRewardData);
                        GameNet.SendMessagePack(pl,rewardHead,ServerConfigManager.Instance.CastleRewardData);
                        rewardHead.Dispose();
                    }
                    
                    PackHead head = PackHead.Create(GameSeverAgreement.gameConfig);
                    GameNet.SendMessagePack(pl,head,ServerConfigManager.Instance.ServerGameConfig);
                    head.Dispose();
                }
                else
                {
                    //旧版客户端
                    SetOldGameConfig();
                    PackHead head = PackHead.Create(GameSeverAgreement.gameConfig);
                    Debug.Info($"发送游戏信息给老的客户端:{GameSeverAgreement.gameConfig}");
                    head.gameNode = GameBase.instance.myUtil;
                    GameNet.SendPack(pl, head, gameConfig);
                    head.Dispose();
                }
            }
            catch (Exception e)
            {
                Debug.Error($"报错了:{e.Message}{e.StackTrace}");
            }
        }

        #region 场景变化包

        /// <summary>
        /// 发送场景变化包
        /// </summary>
        /// <param name="pl"></param>
        /// <param name="scene"></param>
        /// <param name="isSendPldata">是否发送玩家数据</param>
        public static void SendSceneChange(PlayerDataAsyc pl, SceneType scene, bool isSendPldata = true)
        {
            SendSceneChange(pl, (int)scene, isSendPldata);
        }

        /// <summary>
        /// 发送场景变化包
        /// </summary>
        /// <param name="pl"></param>
        /// <param name="scene"></param>
        /// <param name="isSendPldata">是否发送玩家数据</param>
        public static void SendSceneChange(PlayerDataAsyc pl, int scene, bool isSendPldata = true)
        {
            ChangeScenePack csp = new ChangeScenePack(scene, pl);

            if (pl.ClientVer < VersionConfigCategory.Instance.CVersion48)
            {
                //发虚拟房间id
                csp.data = pl.Clone();
                csp.data.roomid = CastleHelper.GetVirtualCastle(csp.data.roomid);
            }
            
            PackHead head = PackHead.Create(GamePackAgreement.SceneChange);
            GameNet.SendPack(pl, head, csp);

            Debug.Info("发送场景切换包!" + head.transfer + "," + scene);
            head.Dispose();
        }

        // /// <summary>
        // /// 发送场景变化包
        // /// </summary>
        // /// <param name="userid"></param>
        // /// <param name="scene"></param>
        // /// <param name="socket"></param>
        // public static void SendSceneChange(int userid, SceneType scene, ServerNode socket)
        // {
        //     SendSceneChange(userid, (int)scene, socket);
        // }
        //
        // /// <summary>
        // /// 发送场景变化包
        // /// </summary>
        // /// <param name="userid">userid</param>
        // /// <param name="scene">场景变化</param>
        // /// <param name="socket">Socket</param>
        // public static void SendSceneChange(int userid, int scene, ServerNode socket)
        // {
        //     ServerHead head = ServerHeadPool.GetServerHead(ServerPackAgreement.TransFerPack);
        //     head.userid = userid;
        //     head.transfer = GamePackAgreement.SceneChange;
        //     ChangeScenePack csp = new ChangeScenePack(scene, null);
        //     GlobalMQ.instance.DeliveryOne(socket, GlobalMQ.CreateMessage(head, csp, FailTags.net_error_netRe, (int)ModuleType.SocketModule),true);
        //     //Debug.Log("玩家不在线情况发送场景切换包!");
        // }

        /// <summary>
        /// 发送自定义提示信息
        /// </summary>
        /// <param name="userid">userid</param>
        /// <param name="style">提示类型</param>
        /// <param name="tiptext">提示的消息</param>
        /// <param name="node">节点</param>
        public static void SendErrorInfo_Socket(int userid, int style, string tiptext, ServerNode node)
        {
            PackHead head = PackHead.Create(GamePackAgreement.autoTipInfo);

            head.userid = userid;
            head.otherString = new string[] { tiptext };

            GameNet.SendPack_Userid(userid, head, tiptext);
            head.Dispose();
        }

        /// <summary>
        /// 0.不启用
        /// 1.服务器维护中，请稍后再试!
        /// 2.请求超时！请稍后再试!
        /// 3.服务器爆满！请稍后再试!
        /// 4.房间号错误,无此房间!
        /// 5.进入失败!密码错误!
        /// 6.房间已开战,进入失败!
        /// 7.房间已满员,进入失败!
        /// 8.检测到相同ip账号，进入失败!
        /// 9.未获取到您的ip,进入失败!
        /// 10.进入失败,必须微信登录或者微信绑定才能进入此房间!
        /// 11.进入失败,必须是微信绑定的账号才能进入此房间!
        /// 12.房卡不足创建失败!
        /// 13.数据错误,请重新登录!
        /// 14.登录过期,请重新登录!
        /// 15.用户名或密码为空
        /// 16.用户名或密码错误
        /// 17.对方不在线
        /// 18.您在朋友房中，不能重复创建!
        /// 19.您已经在朋友房中了!
        /// 20.朋友房规则错误!
        /// 21.房卡不足创建失败!
        /// 22.竞技比赛名称必须是3-8个字符串组成!
        /// 23.竞技比赛名称非法!
        /// 24.创建失败!请稍后再试!
        /// 25.创建的竞技比赛已达上限!
        /// 26.竞技比赛公告过长!
        /// 27.竞技比赛公告包含特殊字符!
        /// 28.竞技比赛名称已被使用!
        /// 29.数据错误!
        /// 30.您不在此竞技比赛!
        /// 31.您的权限不足!
        /// 32.修改失败,公告过长或有特殊字符!
        /// 33.房卡不足，创建失败!
        /// 34.充值失败!
        /// 35.您被禁止进入!
        /// 36.房卡不足加入失败！
        /// 37.未知错误,服务器报错!!!
        /// 38.竞技比赛房间，无法手动加入!",
        /// 39.操作失败,您在游戏中无法进行仓库操作!,
        /// 40.仓库密码错误
        /// 41.您在游戏中无法进行存取金币操作
        /// 42.金币操作数额过大。
        /// 43.您身上的金币不足，取出失败
        /// 44.您身上的游戏币超过限额，无法取出!
        /// 45.您身上的游戏币不足，存入失败
        /// 46.您的金币不足，赠送失败!
        /// 47.操作失败,请稍后重新发起!
        /// 48.赠送的金币必须大于1！
        /// 49.金币不足，购买失败!
        /// 50.操作失败,请稍后再试!
        /// 51.卖出失败!
        /// 52.不能卖出身上的物品!
        /// 53.保存失败!
        /// 54.玩法已被修改或者删除!
        /// 55.防作弊检查,进入房间失败!
        /// 56.创建失败,未检测到ip地址!
        /// 57.暂时微信用户才可创建房间,绑定后再试!
        /// 58.防作弊房间需开启定位才可创建!
        /// 59.未获取到设备信息,请稍后再试!
        /// 60.超时未准备,您已被踢出房间!
        /// 61.您在别处登录游戏!
        /// 62.等级不满6级不能使用该功能!
        /// 63.密码修改失败!
        /// 64.旧密码错误!
        /// 65.验证码不正确!
        /// 66.参数不正确，必须包含联系方式、登录名、登录密码及预留的联系信息!
        /// 67.新密码格式不对!
        /// 68.房卡不足，充值失败!
        /// 69.没有这个玩家，赠送失败!
        /// 70."没有这个用户，请检查手机号是否输入正确!"
        /// 71."没有这个用户,请检查用户名是否正确！",
        /// 72."该用户未绑定手机，请联系客服修改密码！"
        /// 73."加入失败!"
        /// 74."不存在这个房间!"
        /// 75."解散成功!"
        /// 76."已存在相同名称的战队！"
        /// 77."金币不足，创建战队失败！"
        /// 78.""不存在该战队！"
        /// 79."超时未准备，您已被踢出房间!"
        /// </summary>
        /// <param name="userid">userid</param>
        /// <param name="style">style</param>
        /// <param name="tiptext">提示信息</param>
        /// <param name="node">标记</param>
        public static void SendErrorInfo_Socket(int userid, int style, int tiptext, ServerNode node)
        {
            PackHead head = PackHead.Create(GamePackAgreement.pack_error);
            head.userid = userid;
            TipInfo errPack = new TipInfo(style, tiptext);

            GameNet.SendPack_Userid(userid, head, errPack);
            head.Dispose();
        }

        #endregion


        /// <summary>
        /// 发送玩家所在游戏信息给用户
        /// </summary>
        /// <param name="userid">玩家userid</param>
        /// <param name="game_serid">所在游戏的服务器id</param>
        /// <param name="clickgame_serid">玩家点击的服务id</param>
        /// <param name="friendRoom">朋友房房号</param>
        /// <param name="style">类型1.提示进入  2.让客户端立即进入</param>
        /// <param name="SocketNode">SocketNode Socket节点</param>
        public static void SendInGameInfo(int userid, int game_serid, int clickgame_serid,
            int friendRoom, int style, ServerNode SocketNode)
        {
            if (SocketNode == null)
            {
                Debug.Warning("c85acbf3-d3c4-4d58-9805-92ab35bc4272:Socket is null");
                return;
            }

            PlayerGameInfo pgi = new PlayerGameInfo(game_serid, friendRoom, style, clickgame_serid);
            PackHead head = PackHead.Create(GamePackAgreement.InGameInfo);
            head.userid = userid;

            GameNet.SendPack_Userid(userid, head, pgi);
            head.Dispose();
        }

        /// <summary>
        /// 发送加入桌子结果
        /// </summary>
        /// <param name="id"></param>
        /// <param name="resultCode"></param>
        public static void SendJoinDeskResult(long id, int resultCode)
        {
            if (id <= 0)
            {
                return;
            }

            JoinDeskResult result = new JoinDeskResult();
            result.Id = id;
            result.ResultCode = resultCode;
            result.GameSerId = ServerConfigManager.Instance.GameId;

            PackHead head = PackHead.Create(ServerPackAgreement.JoinDeskResult);

            GlobalMQ.instance.DeliveryEveryOne((int)ModuleType.ClubModule, MQ.GlobalMQ.CreateMessage(head, result),
                true, false);
            head.Dispose();

            Debug.Info("通知加入桌子的结果!!!");
        }
    }
}