using System;
using System.Collections.Generic;
using System.Diagnostics;
using Newtonsoft.Json;

namespace GameData
{
    // 如果房间半个小时未开战,如果房间开战12小时未打完,自动解散

    /// <summary>
    /// 房间数据
    /// </summary>
    public class DeskInfo
    {
        /// <summary>
        /// 唯一码   其他模块应持有这个
        /// </summary>
        public string weiyima;

        /// <summary>
        /// 房间号  不是唯一的,同一时间运算的是唯一的  6为数房间码
        /// </summary>
        public string roomNum;

        /// <summary>
        /// 房间规则
        /// </summary>
        public DeskRule rule;

        /// <summary>
        /// 当前数量的场数 1开始
        /// </summary>
        public int nowCnt;

        /// <summary>
        /// 结束的数量
        /// </summary>
        public int overCnt;

        /// <summary>
        /// 游戏服务器的版本
        /// </summary>
        public int serverVer;

        /// <summary>
        /// 创建房间的类型   0普通开  1代开房间  5竞技比赛创建房间
        /// </summary>
        public int creatStyle;

        /// <summary>
        /// 创建房间的id 如果是普通创建的房间 则此id为玩家的userid   竞技比赛创建则为竞技比赛id
        /// </summary>
        public int creatUserid;

        /// <summary>
        /// 玩法的id
        /// </summary>
        public string wayid;

        /// <summary>
        /// 创建房间的房卡数量
        /// </summary>
        public int fangka;

        /// <summary>
        /// 玩家数据
        /// </summary>
        public PlayerData[] pls;

        /// <summary>
        /// 当前的玩家数量
        /// </summary>
        public int nowPlayerCnt
        {
            get
            {
                if (pls == null)
                    return 0;
                int cnt = 0;
                int len = pls.Length;
                for (int i = 0; i < len; i++)
                {
                    if (pls[i] != null)
                        cnt++;
                }
                return cnt;
            }
        }

        /// <summary>
        /// 请求解散的次数 可以补存数据库，因为不是很重要
        /// </summary>
        public int RequestDissolveCnt;

        /// <summary>
        /// 玩家座位 当前的座位编号  --里面存储的座位
        /// </summary>
        public int[] seat;

        /// <summary>
        /// 是否请求解散中
        /// </summary>
        public bool isDising = false;

        /// <summary>
        /// 解散超时时间
        /// </summary>
        public const int DisTimeOut = 60;

        /// <summary>
        /// 解散倒计时
        /// </summary>
        public int DisCount;

        /// <summary>
        /// 0表示没投票  1表示同意 -1表示拒绝->与pls 顺序一致
        /// </summary>
        public int[] plsDis;

        /// <summary>
        /// 立即开战
        /// </summary>
        public int[] OnceFight;

        /// <summary>
        /// 用来存储额外的内容
        /// </summary>
        public int[] Ex;

        /// <summary>
        /// 每局明细
        /// </summary>
        public List<Bureau> burs = new List<Bureau>();

        /// <summary>
        /// 一局打完总的结算，如果有封顶的话，里面计算好了封顶之后的分值
        /// </summary>
        public List<SummaryBureau> SumBurs = new List<SummaryBureau>();

        /// <summary>
        /// 创建时间
        /// </summary>
        public DateTime CreateTime;

        /// <summary>
        /// 是否关闭
        /// </summary>
        public int isClose;

        /// <summary>
        /// 关闭时间
        /// </summary>
        public DateTime closeTime;

        /// <summary>
        /// 解散的ID
        /// </summary>
        public int DisUserId = 0;

        /// <summary>
        /// 子游戏服务器使用,服务器数据!  --此处可优化,发给客户端的数据中，可以不带此数据
        /// </summary>
        [JsonIgnore] public string otherdata;

        /// <summary>
        /// 是否未开战过
        /// </summary>
        public bool noWar
        {
            get { return overCnt == 0 && nowCnt == 0; }
        }

        /// <summary>
        /// 是不是所有的场次都结束了
        /// </summary>
        public bool isAllOver
        {
            get
            {
                if (rule == null)
                {
                    return true;
                }

                return rule.warCnt <= overCnt;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        public DeskInfo()
        {
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="maxCnt"></param>
        public DeskInfo(int maxCnt)
        {
            this.rule = new DeskRule(maxCnt);
        }

        /// <summary>
        /// 房间信息初始化创建时调用
        /// </summary>s
        public void Init(int ver)
        {
            nowCnt = 0;
            overCnt = 0;
            serverVer = ver;
            pls = new PlayerData[rule.maxCnt];
            seat = new int[rule.maxCnt];
            plsDis = new int[rule.maxCnt];
            OnceFight = new int[rule.maxCnt];
            for (int i = 0; i < rule.maxCnt; i++)
            {
                seat[i] = -1;
            }

            CreateTime = DateTime.Now;
            isClose = 0;

            //年月日时分秒毫秒房间号

            int rmNum = int.Parse(roomNum);
            string str = "000000" + rmNum;
            int len = str.Length;
            str = str.Substring(len - 6);

            weiyima = CreateTime.ToString("yyyyMMddHHmmssffff") + str;
        }

        /// <summary>
        /// 开战-未战斗完毕的时间
        /// </summary>
        public DateTime wartimeOutDis;

        /// <summary>
        /// 为开战超时时间
        /// </summary>
        public DateTime jointimeOutDis;

#if UNITY_5_3_OR_NEWER

        [JsonIgnore]
        public string roomNumStr
        {
            get { return GetFullRoomNum(roomNum); }
        }

        public static string GetFullRoomNum(string roomNum)
        {
            if (roomNum == null)
            {
                roomNum = string.Empty;
            }
            
            string str = "000000" + roomNum;
            return str.Substring(str.Length - 6);
        }

#endif

        /// <summary>
        /// 检查是否需要自动解散
        /// </summary>
        /// <returns></returns>
        public int CheckDisBank()
        {
            DateTime time = DateTime.Now;
            if (time > wartimeOutDis)
            {
                //最多保留24小时
                return 1; //超时未打完
            }

            if (noWar && time > jointimeOutDis)
            {
                //未开战超时
                return 2; //超时未满员
            }

            return 0;
        }

        /// <summary>
        /// 添加玩家
        /// </summary>
        /// <param name="pl"></param>
        public int AddPlayer(playerData pl)
        {
            bool isManager = creatUserid == pl.userid && (creatStyle == 0 || creatStyle == 1);

            PlayerData rpl = new PlayerData(pl, isManager);

            int len = pls.Length;
            for (int i = 0; i < len; i++)
            {
                if (pls[pl.seat] == null)
                {
                    pls[pl.seat] = rpl;
                    seat[pl.seat] = pl.seat;
                    OnceFight[pl.seat] = 0;
                    return pl.seat;
                }
            }

            for (int i = 0; i < len; i++)
            {
                OnceFight[i] = 0;
            }

            return -1;
        }

        /// <summary>
        /// 移除玩家
        /// </summary>
        /// <param name="userid">userid</param>
        /// <param name="pl">用户</param>
        public int RemovePlayer(int userid, ref PlayerData pl)
        {
            int len = pls.Length;
            int result = -1;
            //这个len 不能改
            for (int i = 0; i < len; i++)
            {
                if (pls[i] != null && pls[i].userid == userid)
                {
                    //Debug.Log("移除玩家 fangzhu:" + pls[i].fangzhu);
                    if (pls[i].fangzhu == 0)
                    {
                        pls[i] = null;
                        seat[i] = -1;
                        pl = pls[i];
                        result = i;
                        break;
                    }
                }
            }

            if (result > -1)
            {
                for (int i = 0; i < OnceFight.Length; i++)
                {
                    OnceFight[i] = 0;
                }
            }

            return result;
        }

        public long GetTotalScore(int seat)
        {
            long totalScore = 0;
            foreach (var bur in burs)
            {
                if (bur.seat == null || bur.playScore == null) return totalScore;
                for (int i = 0; i < bur.seat.Length; i++)
                {
                    if (seat == bur.seat[i])
                    {
                        totalScore += bur.playScore[i];
                    }
                }
            }
            return totalScore;
        }

        /// <summary>
        /// 获取朋友房打完玩家最终成绩,如果有封顶，则该结果已经计算完了封顶逻辑
        /// </summary>
        /// <param name="seat"></param>
        /// <returns></returns>
        public decimal GetOverScore(int seat)
        {
            //Log.Debug("朋友房:" + SumBurs.Count);

            if (SumBurs == null || SumBurs.Count <= 0) return 0;
            var ps = SumBurs.Find(x => x.seat == seat);
            if (ps == null) return 0;
            return ps.Score;
        }

        /// <summary>
        /// 创建局明细
        /// </summary>
        /// <returns></returns>
        public Bureau CreateBureau(int idx)
        {
            return new Bureau(idx, new long[rule.maxCnt], seat);
        }

        /// <summary>
        /// 压缩人数
        /// </summary>
        public bool CompressionPlayer()
        {
            int nowplcnt = nowPlayerCnt;
            if (nowplcnt < 1 || nowplcnt >= rule.maxCnt)
                return false;

            rule.minCnt = nowplcnt;
            rule.maxCnt = nowplcnt;

            var oldpls = pls;

            pls = new PlayerData[nowplcnt];
            plsDis = new int[nowplcnt];
            seat = new int[nowplcnt];
            OnceFight = new int[nowplcnt];

            //这里座位重新编排 数据库没有重新编排
            for (int i = 0; i < nowplcnt; i++)
            {
                for (int j = 0; j < oldpls.Length; j++)
                {
                    if (oldpls[j] != null)
                    {
                        pls[i] = oldpls[j];
                        seat[i] = i;
                        oldpls[j] = null;
                        break;
                    }
                }
            }

            return true;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            string str = "";
            str += "唯一吗:" + weiyima + Environment.NewLine;
            str += "房间号:" + roomNum + Environment.NewLine;
            str += "服务器版本:" + serverVer + Environment.NewLine;
            str += "创建类型:" + creatStyle + Environment.NewLine;
            str += "创建者id:" + creatUserid + Environment.NewLine;
            str += "房卡:" + fangka + Environment.NewLine;
            str += "创建时间:" + CreateTime + Environment.NewLine;

            str += "房间规则:" + Environment.NewLine;
            str += rule.ToString() + Environment.NewLine;

            int len = 0;
            if (seat != null)
            {
                str += "玩家座位:";
                len = seat.Length;
                for (int i = 0; i < len; i++)
                {
                    str += string.Format("{0}:{1}  ", i, seat[i]);
                }
            }

            str += Environment.NewLine;

            len = pls.Length;
            for (int i = 0; i < len; i++)
            {
                str += "玩家:" + i + Environment.NewLine;
                if (pls[i] == null)
                {
                    str += "该位置没有人!" + Environment.NewLine;
                    continue;
                }

                str += Environment.NewLine;

                if (pls == null) continue;
                str += pls[i].ToString();
            }
            if (burs != null && burs.Count > 0)
            {
                len = burs.Count;
                for (int i = 0; i < len; i++)
                {
                    str += Environment.NewLine;
                    str += "局数详情" + i + ":" + Environment.NewLine;

                    str += burs[i].ToString();
                }
            }
            return str;
        }


        /// <summary>
        /// 查找玩家所在的位置
        /// </summary>
        /// <param name="userid"></param>
        /// <returns></returns>
        public int FindPlayer(int userid)
        {
            int seat = -1;
            int len = pls.Length;
            for (int i = 0; i < len; i++)
            {
                if (pls[i] != null && pls[i].userid == userid)
                {
                    seat = this.seat[i];
                    break;
                }
            }

            return seat;
        }

        /// <summary>
        /// 朋友房中的玩家
        /// </summary>
        public class PlayerData
        {
            /// <summary>
            /// 玩家的userid
            /// </summary>
            public int userid;

            /// <summary>
            /// 玩家的昵称
            /// </summary>
            public string nickName;

            /// <summary>
            /// 玩家的性别
            /// </summary>
            public int sex;

            /// <summary>
            /// 玩家的头像
            /// </summary>
            public string photo;

            /// <summary>
            /// 玩家是否是房主
            /// </summary>
            public int fangzhu;

            /// <summary>
            /// ip
            /// </summary>
            public string ip;

            /// <summary>
            /// 玩家在哪个俱乐部，联赛用
            /// </summary>
            public int ClubId;

            /// <summary>
            /// 
            /// </summary>
            public PlayerData()
            {
            }

            /// <summary>
            /// 
            /// </summary>
            /// <param name="pl"></param>
            /// <param name="isManager"></param>
            public PlayerData(GameData.playerData pl, bool isManager)
            {
                userid = pl.userid;
                nickName = pl.nickname;
                sex = pl.sex;
                fangzhu = isManager ? 1 : 0;
                ip = pl.ip;
                ClubId = pl.ClubId;
            }

            /// <summary>
            /// 
            /// </summary>
            /// <returns></returns>
            public override string ToString()
            {
                string str = "";
                str += "玩家userid:" + userid + Environment.NewLine;
                str += "昵称:" + nickName + Environment.NewLine;
                str += "玩家性别:" + sex + Environment.NewLine;
                str += "是否是房主:" + fangzhu + Environment.NewLine;
                str += "玩家ip:" + ip + Environment.NewLine;
                return str;
            }
        }

        /// <summary>
        /// 朋友房的总结算
        /// </summary>
        public class SummaryBureau
        {
            public int seat;
            public decimal Score;
        }

        /// <summary>
        /// 局明细
        /// </summary>
        public class Bureau
        {
            /// <summary>
            /// 当前局
            /// </summary>
            public int id;

            /// <summary>
            /// 玩家分数
            /// </summary>
            public long[] playScore;

            /// <summary>
            /// 玩家的座位
            /// </summary>
            public int[] seat;

            /// <summary>
            /// 
            /// </summary>
            /// <param name="id">当前局的id 索引</param>
            /// <param name="playScore">这一局玩家的分数</param>
            /// <param name="seat">玩家的座位</param>
            public Bureau(int id, long[] playScore, int[] seat)
            {
                this.id = id;
                this.playScore = playScore;
                this.seat = seat;
            }

            /// <summary>
            /// 
            /// </summary>
            public Bureau()
            {
            }

            /// <summary>
            /// 
            /// </summary>
            /// <returns></returns>
            public override string ToString()
            {
                string str = "";
                str += "id:" + id + Environment.NewLine;
                str += "score:";
                int len = playScore.Length;
                for (int i = 0; i < len; i++)
                {
                    str += playScore[i] + ",";
                }

                str += Environment.NewLine;

                str += "seat:";

                for (int i = 0; i < len; i++)
                {
                    str += seat[i] + ",";
                }

                return str;
            }
        }

        /// <summary>
        /// 根据解散类型获取解散备注
        /// </summary>
        /// <param name="style">解散类型</param>
        /// <returns></returns>
        public static string GetDisBankMemo(int style)
        {
            if(style >= 100000)
            {
                return "玩家解散";
            }
            switch (style)
            {
                case 0: //正常打完
                    return "正常打完结束";
                case 1: //正常打完
                    return "全部打完结束";
                //下面都是异常
                case 2:
                    return "玩家解散";
                case 3:
                    return "超时解散";
                case 4:
                    return "超时解散";
                case 5:
                    return "房主解散";
                case 6:
                    return "玩法删除解散";
                case 7:
                    return "管理员解散";
                case 8:
                    return "积分不够解散";
                case 9:
                    return "托管解散";
                default:
                    return string.Empty;
            }
        }
    }
}