using System;
using System.Collections.Generic;
using Server.DB.Redis;
using GameData;
using MrWu.Debug;
using StackExchange.Redis;
using Server.Data.ClubDef;
using GameDAL.FriendRoom;
using System.Linq;
using System.Threading.Tasks;
using MrWu.Basic;

namespace Server {
    /// <summary>
    /// 玩法管理
    /// </summary>
    public class WayManager {

        /* 玩法只需要存储桌子的唯一码，具体的数据到Room 类里面拿
         * 
         * 1.加入玩法房间
         * 2.创建玩法房间
         * 3.退出玩法房间
         * 
         * 4.玩法被删除。-> 主动解散房间
         * 
         * 
         * 
         * 
         * */

        /// <summary>
        /// 数据库Idx
        /// </summary>
        public const int DbIdx = 6;

        /// <summary>
        /// 实例
        /// </summary>
        public static WayManager instance {
            get;
            private set;
        }

        private WayManager() { }

        static WayManager() {
            instance = new WayManager();
        }

        /// <summary>
        /// 数据库代理
        /// </summary>
        public IDatabaseProxy databaseProxy {
            get {
                return redisManager.Getdb(DbIdx);
            }
        }

        /// <summary>
        /// redis数据事务操作
        /// </summary>
        public IDatabase db {
            get {
                return redisManager.GetDataBase(DbStyle.main, DbIdx);
            }
        }

        /// <summary>
        /// 基本Key
        /// </summary>
        public const string BaseKey = "ClubWay:";

        /// <summary>
        /// 获取桌子信息的Key值
        /// </summary>
        /// <param name="clubid">竞技比赛id</param>
        /// <param name="wayid">玩法id</param>
        public string GetDeskInfoKey(int clubid, string wayid) {
            return $"{BaseKey}{clubid}:{wayid}";
        }

        /// <summary>
        ///保存玩法的桌子
        /// </summary>
        /// <param name="clubid">竞技比赛id</param>
        /// <param name="wayid">玩法id</param>
        /// <param name="weiyima">唯一码</param>
        public void SaveWayDesk(int clubid, string wayid, string weiyima) {


            string key = GetDeskInfoKey(clubid, wayid);

            //暂时 Hash 的 Value 不存放数据, 没啥可以存的。留给以后扩展
            databaseProxy.HashSet(key, weiyima, 0);

            // WayDeskChangeSend(clubid, wayid, weiyima, 0);
        }

        /// <summary>
        /// 删除玩法的桌子信息
        /// </summary>
        /// <param name="clubid"></param>
        /// <param name="wayid"></param>
        /// <param name="weiyima"></param>
        public void DelDeskInfo(int clubid, string wayid, string weiyima) {

            string key = GetDeskInfoKey(clubid, wayid);
            //WayDeskChangeSend(clubid, wayid, weiyima, 1);
            databaseProxy.HashDelete(key, weiyima);
        }

        /// <summary>
        /// 删除玩法
        /// </summary>
        /// <param name="clubid">竞技比赛id</param>
        /// <param name="wayid">玩法id</param>
        public void DelWay(int clubid, string wayid) {
            string key = GetDeskInfoKey(clubid, wayid);
            //写这两句是要干嘛 玩法是竞技比赛发起的，发给竞技比赛多余
            //var weiyimaList = GetDesksWeiYiMa(clubid, wayid).Select(p => p.Name).ToList();
            //weiyimaList.ForEach(weiyima => WayDeskChangeSend(clubid, wayid, weiyima, 1));
            databaseProxy.KeyDelete(key);
        }

        public Task<DeskInfo> LoadDeskInfoAsync(string weiyima)
        {
            return Task.Run(() => LoadDeskInfo(weiyima));
        }
        
        /// <summary>
        /// 加载桌子信息
        /// </summary>
        /// <param name="weiyima">唯一码</param>
        /// <returns></returns>
        public DeskInfo LoadDeskInfo(string weiyima)
        {
            
            //去Room 类里面找到加载DeskInfo 方法补充起来
            DeskInfo deskinfo = null;
            if(!Room.LoadRoom(weiyima, out deskinfo)) {
                Debug.Info("未加载成功!");
                return null;
            }
            if(deskinfo == null) { 
                Debug.Info("加载成功, 却没有桌子信息???");
                }   
            return  deskinfo;
        }

        // /// <summary>
        // /// 加载某个玩法的所有桌子信息
        // /// </summary>
        // /// <returns></returns>
        // public List<DeskInfo> LoadDeskInfo(int clubid, string wayid) {
        //     string key = GetDeskInfoKey(clubid, wayid);
        //
        //     return LoadDeskInfoInternal(key);
        // }

        public Task<List<DeskInfo>> LoadDeskInfoAsync(int clubId)
        {
            return Task.Run(() => LoadDeskInfo(clubId));
        }

        /// <summary>
        /// 获取竞技比赛的所有桌子
        /// </summary>
        /// <param name="clubid"></param>
        /// <returns></returns>
        public List<DeskInfo> LoadDeskInfo(int clubid) {
            string pattern = GetDeskInfoKey(clubid, "*");
            //获取此club所有玩法的key
            var clubKeys = redisManager.Keys(pattern, DbIdx, 1000,DbStyle.main);
            //将当前club的所有玩法及每玩法的所有桌;
            int len = clubKeys.Count;
            List<DeskInfo> infos = new List<DeskInfo>();
            for (int i = 0; i < len; i++) {
                infos.AddRange(LoadDeskInfoInternal(clubKeys[i]));
            }
            return infos;
        }


        List<DeskInfo> LoadDeskInfoInternal(RedisKey key) {
            List<DeskInfo> desks = new List<DeskInfo>();
            //获取此key下所有唯一码
            var weiyimaArray = databaseProxy.HashGetAll(key);

            int len = weiyimaArray.Length;
            DeskInfo info;
            for (int i = 0; i < len; i++) {
                info = LoadDeskInfo(weiyimaArray[i].Name);
                if (info != null)
                    desks.Add(info);
            }
            return desks;
            // return weiyimaArray.Select(weiyima => LoadDeskInfo(weiyima)).Where(deskInfo => deskInfo != null).ToList();
        }

        /// <summary>
        /// 获取这个玩法的所有的桌子的唯一码
        /// </summary>
        /// <param name="clubid"></param>
        /// <param name="wayid"></param>
        /// <returns>唯一码 玩家人数</returns>
        public HashEntry[] GetDesksWeiYiMa(int clubid, string wayid) {
            return databaseProxy.HashGetAll(GetDeskInfoKey(clubid, wayid));
        }

        /// <summary>
        /// 竞技比赛玩家变化
        /// </summary>
        /// <param name="clubid">竞技比赛id</param>
        /// <param name="wayid">玩法id</param>
        /// <param name="weiyima">桌子的唯一码</param>
        /// <param name="isInc">是否是增量 true 增 false 减</param>
        public ClubWayPlayer ClubWayPlayerChange(int clubid, string wayid, string weiyima, bool isInc) {

            //组建ClubWayPlayer
            string key = GetDeskInfoKey(clubid, wayid);

            ClubWayPlayer cwp = new ClubWayPlayer();
            cwp.clubid = clubid;
            cwp.wayid = wayid;
            cwp.weiyima = weiyima;
            if (isInc)
                cwp.playerCnt = (int)databaseProxy.HashIncrement(key, weiyima);
            else
                cwp.playerCnt = (int)databaseProxy.HashDecrement(key, weiyima);
            //cwp.playerCnt = (int)databaseProxy.HashIncrement(GetDeskInfoKey(clubid, wayid), weiyima, isInc ? 1 : -1);
            return cwp;

            /*
            ClubWayPlayer cwp = new ClubWayPlayer();
            cwp.clubid = clubid;
            cwp.wayid = wayid;

            string key = GetKey(clubid, wayid);
            var datas = redisManager.db.SortedSetRangeByRankWithScores(key, 0, -1, Order.Descending);
            if (datas == null) {
                cwp.deskCnt = 0;
                cwp.playerCnt = 0;

            } else {
                int len = datas.Length;
                for (int i = 0; i < len; i++) {
                    if (datas[i].Score < minCnt) {
                        cwp.playerCnt = (int)datas[i].Score;
                        break;
                    }
                }
                cwp.deskCnt = len;
            }
            return cwp;
            */
        }


        /// <summary>
        /// 玩法的桌子变化 数据发送
        /// </summary>
        /// <param name="clubid">竞技比赛id</param>
        /// <param name="wayid">玩法id</param>
        /// <param name="weiyima">桌子的唯一码</param>
        /// <param name="style">类型 0新增 1删除 2更新</param>
        public void WayDeskChangeSend(int clubid, string wayid, string weiyima, int style) {
            //组建 WayDeskChange 包裹发送给竞技比赛

            var wdc = new Data.WayDeskChange {
                clubid = clubid,
                wayid = wayid,
                deskweiyima = weiyima,
                style = style
            };

            PackHead head = PackHead.Create(Pack.ServerPackAgreement.WayDeskChange);
            MQ.GlobalMQ.instance.DeliveryEveryOne((int)Data.Module.ModuleType.ClubModule, MQ.GlobalMQ.CreateMessage(head, wdc), true);
            head.Dispose();
        }
    }
}
