/*
 * 由SharpDevelop创建。
 * 用户： Administrator
 * 日期: 2018-11-14
 * 时间: 9:50
 * 
 * 要改变这种模板请点击 工具|选项|代码编写|编辑标准头文件
 */
using System;
using Server.Module;
using Newtonsoft.Json;
using GameData;
using MrWu.Debug;
using System.ComponentModel;
using StackExchange.Redis;
using Server.DB.Redis;
using System.Text;
using Server.Data.Module;
using System.Collections.Generic;
using MrWu.Basic;
using Game.Shadow;
using GameMessage;
using ObjectModel.Game;
using ObjectModel.Backend;

namespace Server.Data
{
    /// <summary>
    /// 游戏服务器使用的玩家数据 异步的
    /// </summary>

    public class PlayerDataAsyc : playerData
    {
#if DEBUG
        /// <summary>
        /// 是否测试
        /// </summary>
        public bool IsTest;
#endif       
        
        /// <summary>
        /// 是否是鬼 
        /// </summary>
        [JsonIgnore]
        public bool isRobot
        {
            get
            {
                return userid < 0;
            }
        }

        /// <summary>
        /// 战斗输赢
        /// </summary>
        public long WarMoney;

        /// <summary>
        /// 连续赢的次数
        /// </summary>
		[JsonIgnore]
        public int MVPCount;

        /// <summary>
        /// Socket模块 靠这个发包
        /// </summary>
        [JsonIgnore]
        public ServerNode socketUtil
        {
            get;
            set;
        }

        /// <summary>
        /// 排队中的时间
        /// </summary>
        [JsonIgnore]
        public int queuetime;

        /// <summary>
        /// 当前的影子
        /// </summary>
        [JsonIgnore]
        public PlayerDataAsyc currShadow = null;

        /// <summary>
        /// 玩家的影子
        /// </summary>
        [JsonIgnore]
        public PlayerDataAsyc[] shadows
        {
            get
            {
                return m_shadows;
            }
            set
            {   //跟踪处理影子
                m_shadows = value;
                if (value == null)
                    doShadows += "0";
                else
                    doShadows += "1";
            }
        }

        [JsonIgnore]
        private PlayerDataAsyc[] m_shadows;

        /// <summary>
        /// 处理影子
        /// </summary>
        [JsonIgnore]
        public string doShadows = string.Empty;

        /// <summary>
        /// 影子基本信息
        /// </summary>
        [JsonIgnore]
        public Shadow[] shadowsInfo = null;

        /// <summary>
        /// 可以排队一起的人
        /// </summary>
        [JsonIgnore]
        public readonly HashSet<PlayerDataAsyc> QueueSet = new HashSet<PlayerDataAsyc>();

        /// <summary>
        /// 玩家的游戏币变化值
        /// </summary>
        [JsonIgnore]
        public long moneyChange;

        /// <summary>
        /// 经验变化值
        /// </summary>
        [JsonIgnore]
        public int expChange;

        /// <summary>
        /// 客户端版本
        /// </summary>
        [JsonIgnore]
        public int ClientVer;

        /// <summary>
        /// 比赛内存
        /// </summary>
        [JsonIgnore]
        public Object MatchObj;

        /// <summary>
        /// 陪打比赛的桌子
        /// </summary>
        [JsonIgnore]
        public int MatchDesk = -1;

        /// <summary>
        /// true不能放弃比赛 false 可以放弃比赛
        /// </summary>
        [JsonIgnore]
        public bool IsExitMatch = true;

        /// <summary>
        /// 报名的人满赛Id
        /// </summary>
        [JsonIgnore]
        public int MatchId = -1;

        /// <summary>
        /// 是否掉线，比赛用,true是掉线
        /// </summary>
        [JsonIgnore]
        public bool IsDisConnMatch = false;

        /// <summary>
        /// 掉线时间 10秒内部不托管
        /// </summary>
        [JsonIgnore]
        public int OutLineTime = 0;
        
        /// <summary>
        /// 玩家登录钱备份
        /// </summary>
        [JsonIgnore]
        public long MoneyBak = 0;
        /// <summary>
        /// 玩家在游戏中的输赢钱
        /// </summary>
        [JsonIgnore]
        public long WinMoney = 0;
        /// <summary>
        /// 打了几局
        /// </summary>
        [JsonIgnore]
        public int Pan = 0;
        /// <summary>
        /// 比赛报名的钱
        /// </summary>
        [JsonIgnore]
        public int BiSiMoney = 0;

        ///// <summary>
        ///// 是否是报名了IPTV海选  true是  false不是
        ///// </summary>
        //[JsonIgnore]
        //public bool IsIPTVMatch = false;

        /// <summary>
        /// 托管次数 --每次开战重置
        /// </summary>
        [JsonIgnore]
        public byte DePositCount = 0;

        /// <summary>
        /// 托管了多少秒 --每次开战重置
        /// </summary>
        [JsonIgnore]
        public int DePositSecon = 0;

        /// <summary>
        /// 托管开始时间 --每次取消的时候根据这个开始时间和当下取消的时间来计算托管了多少秒 
        /// </summary>
        [JsonIgnore]
        public DateTime DePositTime;

        /// <summary>
        /// 是否是等待操作的状态
        /// </summary>
        [JsonIgnore]
        public bool WaitOperation;
        
        /// <summary>
        /// 自动托管倒计时
        /// </summary>
        [JsonIgnore]
        public int AutoDepositTime;

        /// <summary>
        /// 推广级别 0没有级别 1A级 2B级
        /// </summary>
        [JsonIgnore]
        public byte TuiGuangLeve = 0;

        /// <summary>
        /// 获取玩家的对战数据
        /// </summary>
        [JsonIgnore]
        public UserWarDataModel WarData = null;

        /// <summary>
        /// 玩家的推广人的信息
        /// </summary>
        [JsonIgnore]
        public BMAdminModel TuiGuangUser = null;

        /// <summary>
        /// 是否参加比赛 true是  false没有参加
        /// </summary>
        public bool IsJoinMatch
        {
            get
            {
                return MatchObj != null;
            }
        }

        /// <summary>
        /// 更新影子数据
        /// </summary>
        /// <param name="idx"></param>
        /// <param name="forceShadow">强制使用影子</param>
        public void UpdateShadow(int idx, bool forceShadow = false)
        {
            try
            {
                if(idx < 0 ){return;}
                if (currShadow == null)
                {
                    currShadow = new PlayerDataAsyc();
                    currShadow.userid = userid;
                }

                currShadow.id = id;
                currShadow.state = state;
                currShadow.outline = outline;
                currShadow.gameid = gameid;
                currShadow.roomid = roomid;
                currShadow.friendRoomNum = friendRoomNum;
                currShadow.tingid = tingid;
                currShadow.deskid = deskid;
                currShadow.seat = seat;
                currShadow.fangka = fangka;
                currShadow.coupon = coupon;
                currShadow.exp = exp;
                currShadow.readCtDown = readCtDown;
                currShadow.mettle = mettle;
                currShadow.pi = pi;
                currShadow.PlatEnum = PlatEnum;
                currShadow.MatchRoll = MatchRoll;
                currShadow.SetDeposit(isDePosit);
                currShadow.gold = gold;
                currShadow.HeadType = HeadType;
                currShadow.ip = ip;
                currShadow.device = device;

                PlayerDataAsyc target = null;
                
                if (this.friendRoomNum > 0)
                {
                    forceShadow = false;
                }
                
                if (!forceShadow && (this.friendRoomNum > 0 || (idx == roomid && !this.isRobot)))
                    target = this;
                else
                    target = shadows[idx];
                    
                currShadow.nickname = target.nickname;
                currShadow.area = target.area;
                currShadow.money = target.money;
                currShadow.avatar = target.avatar;
                currShadow.sex = target.sex;
                currShadow.MatchObj = target.MatchObj;
                currShadow.RaceBeiLv = target.RaceBeiLv;
                currShadow.RegTime = target.RegTime;
                currShadow.userType = target.userType;
                currShadow.ClubScore    = target.ClubScore;
                currShadow.ClubId = target.ClubId;
            }
            catch (Exception e)
            {
                Debug.Error($"idx:{idx},friendRoom:{this.friendRoomNum},shadows count:{(shadows == null ? 0 : shadows.Length)},msg:{e.Message},code:{e.StackTrace}");
            }
        }

        /// <summary>
        /// 机器人放回时做初始化
        /// </summary>
        public void RobotInit()
        {
            deskid = -1;
            seat = -1;
        }

        /// <summary>
        /// 
        /// </summary>
        public PlayerDataAsyc() : base() { }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="pl"></param>
        public PlayerDataAsyc(playerData pl)
        {
            this.id = pl.id;
            this.userid = pl.userid;
            this.sex = pl.sex;
            this.area = pl.area;
            this.nickname = pl.nickname;
            this.money = pl.money;
            this.gold = pl.gold;
            this.coupon = pl.coupon;
            this.ip = pl.ip;
            this.exp = pl.exp;
            this.fangka = pl.fangka;
            this.outline = pl.outline;
            this.fangka = pl.fangka;
            this.userType = pl.userType;
            this.gameid = pl.gameid;
            this.roomid = pl.roomid;
            this.tingid = pl.tingid;
            this.deskid = pl.deskid;
            this.seat = pl.seat;
            //this.readCtDown = pl.readCtDown;
            this.avatar = pl.avatar;
            this.SetDeposit(pl.isDePosit);
            this.isastable = pl.isastable;
            this.friendRoomNum = pl.friendRoomNum;
            this.friendWeiYiMa = pl.friendWeiYiMa;
            // this.hairStyle = pl.hairStyle;
            //this.faceStyle = pl.faceStyle;
            //this.clothes = pl.clothes;
            //this.pet = pl.pet;
            this.mettle = pl.mettle;
            this.daili = pl.daili;
            this.PlatEnum = pl.PlatEnum;
            this.pi = pl.pi;
            //  Debug.Error($"this.MatchRoll:{this.MatchRoll} ,pl.MatchRoll:{pl.MatchRoll}");
            this.MatchRoll = pl.MatchRoll;
            this.RegTime = pl.RegTime;
            this.platTag = pl.platTag;
            this.HeadType = pl.HeadType;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            StringBuilder sb = new StringBuilder();
            int weight = -15;
            sb.AppendLine(BaseFun.Align("id", id, weight));
            sb.AppendLine(BaseFun.Align("userid", userid, weight));
            sb.AppendLine(BaseFun.Align("性别", sex, weight));
            sb.AppendLine(BaseFun.Align("地区", area, weight));
            sb.AppendLine(BaseFun.Align("昵称", nickname, weight));
            sb.AppendLine(BaseFun.Align("游戏币", money, weight));
            sb.AppendLine(BaseFun.Align("金币", gold, weight));
            sb.AppendLine(BaseFun.Align("奖券", coupon, weight));
            sb.AppendLine(BaseFun.Align("ip:", ip, weight));
            sb.AppendLine(BaseFun.Align("经验:", exp, weight));
            sb.AppendLine(BaseFun.Align("玩家状态", state, weight));
            sb.AppendLine(BaseFun.Align("离线", outline, weight));
            sb.AppendLine(BaseFun.Align("房卡", fangka, weight));
            sb.AppendLine(BaseFun.Align("用户类型", userType, weight));
            sb.AppendLine(BaseFun.Align("游戏", gameid, weight));
            sb.AppendLine(BaseFun.Align("城堡", roomid, weight));
            sb.AppendLine(BaseFun.Align("厅", tingid, weight));
            sb.AppendLine(BaseFun.Align("桌子", deskid, weight));
            sb.AppendLine(BaseFun.Align("座位", seat, weight));
            sb.AppendLine(BaseFun.Align("头像", avatar, weight));
            sb.AppendLine(BaseFun.Align("挂机", isGuaji, weight));
            sb.AppendLine(BaseFun.Align("托管", isDePosit, weight));
            sb.AppendLine(BaseFun.Align("不稳定", isastable, weight));
            sb.AppendLine(BaseFun.Align("桌上状态", dskState, weight));
            sb.AppendLine(BaseFun.Align("房间号", friendRoomNum, weight));
            sb.AppendLine(BaseFun.Align("唯一码", friendWeiYiMa, weight));
            // sb.AppendLine(BaseFun.Align("发型id", hairStyle, weight));
            // sb.AppendLine(BaseFun.Align("脸型id", faceStyle, weight));
            // sb.AppendLine(BaseFun.Align("衣服id", clothes, weight));
            // sb.AppendLine(BaseFun.Align("宠物id", pet, weight));
            sb.AppendLine(BaseFun.Align("性格", mettle, weight));

            if (WarData != null)
            {
                sb.AppendLine(BaseFun.Align("赢的局数", WarData.WinCount, weight));
                sb.AppendLine(BaseFun.Align("输的局数", WarData.LoseCount, weight));
                sb.AppendLine(BaseFun.Align("总局数", WarData.GameTotal, weight));
            }
            
            sb.AppendLine(BaseFun.Align("客户端版本", ClientVer, weight));
            sb.AppendLine(BaseFun.Align("金砖", MatchRoll, weight));
            sb.AppendLine(BaseFun.Align("代理", daili, weight));
            sb.AppendLine(BaseFun.Align("是否有比赛", MatchObj == null, weight));

            sb.AppendLine(BaseFun.Align("平台", device.plat, weight));
            sb.AppendLine(BaseFun.Align("虚拟机", device.wmsty, weight));
            sb.AppendLine(BaseFun.Align("登录类型", device.loginsty, weight));
            sb.AppendLine(BaseFun.Align("纬度", device.weidu, weight));
            sb.AppendLine(BaseFun.Align("经度", device.jingdu, weight));
            sb.AppendLine(BaseFun.Align("wifiname", device.wifissd, weight));
            sb.AppendLine(BaseFun.Align("wifimac", device.wifimac, weight));
            sb.AppendLine(BaseFun.Align("phone_imei", device.phone_imei, weight));
            sb.AppendLine(BaseFun.Align("address", device.address, weight));


            sb.AppendLine(BaseFun.Align("连接时间", connectionTime, weight));
            sb.AppendLine(BaseFun.Align("接收包数量", recvCount, weight));
            sb.AppendLine(BaseFun.Align("发送包数量", sendCount, weight));

            return sb.ToString();
        }
        [JsonIgnore]
        DateTime connectionTime { get; } = DateTime.Now;

        /// <summary>
        /// 接收包数量
        /// </summary>
        [JsonIgnore]
        public long recvCount { get; set; } = 0;

        /// <summary>
        /// 发送包数量
        /// </summary>
        [JsonIgnore]
        public long sendCount { get; set; } = 0;

        /// <summary>
        /// 作弊等级 0-4越来越高
        /// </summary>
        [JsonIgnore]
        private int CheatingLevel;


        public PlayerDataAsyc Clone()
        {
            return (PlayerDataAsyc)this.MemberwiseClone();
        }
    }
}
