using ObjectModel.Club;
using Server.DB.Redis;
using StackExchange.Redis;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace GameDAL.Club
{
    /// <summary>
    /// 俱乐部比赛数据库操作对象
    /// 先从redis获取数据，没有在从数据库获取并保存到redis
    /// </summary>
    public static class ClubMatchManagerDal
    {
        public static readonly string clubMatchKeyPrefix = "ClubMatch";
        public static readonly DbStyle redisdb = DbStyle.main;
        public static readonly int dbidx = 7;
        static TimeSpan expiry = TimeSpan.FromDays(3);

        static RedisKey GetTopOneClubMatch2Key(int clubId) => $"{clubMatchKeyPrefix}:GetTopOneClubMatch2:{clubId}";

        // /// <summary>
        // /// 返回比赛数据
        // /// </summary>
        // /// <param name="clubId">俱乐部Id</param>
        // /// <param name="list">需要返回的数据</param>
        // /// <param name="statusFlag">1进行中  2已结束</param>
        // /// <returns></returns>
        // public static ClubMatch GetClubMatchByClubId(int clubId, out List<ClubMatchUserScore> list, int statusFlag = 1)
        // {
        //     list = null;
        //     var result = redisdb.GetOrAdd(GetClubMatchByClubIdKey(clubId), statusFlag, () =>
        //     {
        //         var clubMatch = ClubMatchManagerAdo.GetClubMatchByClubId(clubId, out var list2, statusFlag);
        //         var ts = clubMatch != null ? expiry : TimeSpan.FromMinutes(10);
        //         return Tuple.Create(Tuple.Create(clubMatch ?? new ClubMatch(), list2 ?? new List<ClubMatchUserScore>()), ts);
        //     }, dbidx, false);
        //     if (result.Item1.ClubMatchId == 0)
        //     {
        //         return null;
        //     }
        //     list = result.Item2;
        //     return result.Item1;
        // }

        // static RedisKey GetClubMatchByClubIdKey(int clubId) => $"{clubMatchKeyPrefix}:ClubMatchByClubId:{clubId}";

        /// <summary>
        /// 保存比赛数据库到数据库
        /// 这里要做 比赛玩法保存的逻辑,
        /// 保存完以后把自增Id赋值
        /// </summary>
        public static bool SaveClubMatch(ClubMatch model)
        {
            if (model == null) return false;
            var succ = ClubMatchManagerAdo.SaveClubMatch(model);
            if (succ)
            {
                RemoveCachingOfClubMatch(model.ClubId, model.ClubMatchId);
            }
            return succ;
        }

        public static async Task<bool> SaveClubMatchAsync(ClubMatch model)
        {
            return await Task.Run(() => SaveClubMatch(model));
        }

        /// <summary>
        /// 只更新ClubMatchModel
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public static bool UpdateClubMatchModel(ClubMatch model)
        {
            if (model == null || model.ClubMatchId <= 0) return false;
            var succ = ClubMatchManagerAdo.UpdateClubMatchModel(model);
            if (succ)
            {
                RemoveCachingOfClubMatch(model.ClubId, model.ClubMatchId);
            }
            return succ;
        }

        /// <summary>
        /// 移除缓存的比赛数据
        /// </summary>
        /// <param name="clubId"></param>
        /// <param name="clubMatchId"></param>
        static void RemoveCachingOfClubMatch(int clubId, int clubMatchId)
        {
            var key1 = GetClubMatchesKey(clubId);
            var key2 = GetTopOneClubMatchKey(clubId);
            redisdb.GetRedisDataBase(dbidx).KeyDelete(new[] { key1, key2 });
        }

        // /// <summary>
        // /// 获取俱乐部的比赛，，要把比赛玩法的数据组合进来返回
        // /// </summary>
        // /// <param name="clubId">俱乐部Id</param>
        // /// <param name="date">截止时间与比赛开始比较</param>
        // /// <returns></returns>
        // public static List<ClubMatch> GetClubMatches(int clubId, DateTime date)
        // {
        //     return redisdb.GetOrAdd(GetClubMatchesKey(clubId), date.ToString("yyyyMMdd"), () =>
        //     {
        //         var list = ClubMatchManagerAdo.GetClubMatches(clubId, date);
        //         var ts = list.Count > 0 ? expiry : TimeSpan.FromMinutes(10);
        //         return Tuple.Create(list, ts);
        //     }, dbidx, false);
        // }

        #region 获取最近5局的一个比赛信息

        public static void DeleteGetClubMatchesByTopRedis(int clubId)
        {
            string key = $"GetClubMatchesByTop:{clubId}";
            redisManager.Getdb(dbidx).KeyDelete(key);
        }

        public static Task<List<ClubMatch>> GetClubMatchesByTopAsync(int clubId, int top = 5)
        {
            return Task.Run(() => GetClubMatchesByTop(clubId, top));
        }

        public static List<ClubMatch> GetClubMatchesByTop(int clubId,int top =5)
        {
            string key = $"GetClubMatchesByTop:{clubId}";
            return redisdb.GetOrAdd(key, string.Empty, () =>
            {
                var list = ClubMatchManagerAdo.GetClubMatches(clubId, top);
                var ts = TimeSpan.FromHours(12);
                return Tuple.Create(list, ts);
            }, dbidx, false);
        }

        #endregion

        static RedisKey GetClubMatchesKey(int clubId) => $"{clubMatchKeyPrefix}:ClubMatches:{clubId}";

        // /// <summary>
        // /// 获取俱乐部比赛最近几条 ，要把比赛玩法的数据组合进来返回
        // /// </summary>
        // /// <param name="clubId"></param>
        // /// <param name="top"></param>
        // /// <returns></returns>
        // public static List<ClubMatch> GetTopOneClubMatch(int clubId, int top = 1)
        // {
        //     return redisdb.GetOrAdd(GetTopOneClubMatchKey(clubId), top, () =>
        //     {
        //         var list = ClubMatchManagerAdo.GetTopOneClubMatch(clubId, top);
        //         var ts = list.Count > 0 ? expiry : TimeSpan.FromMinutes(10);
        //         return Tuple.Create(list, ts);
        //     }, dbidx, false);
        // }
        static RedisKey GetTopOneClubMatchKey(int clubId) => $"{clubMatchKeyPrefix}:TopOneClubMatch:{clubId}";

        // /// <summary>
        // /// 获取某个玩家的比赛的积分记录
        // /// </summary>
        // /// <param name="clubId"></param>
        // /// <param name="clubMatchId"></param>
        // /// <param name="userId"></param>
        // /// <param name="IsNow">是否是当前的比赛。true是 false不是。如果是当前比赛过期时间只能设置分钟如5分钟，结束的比赛过期时间可以设置长一点如3天</param>
        // /// <returns></returns>
        // public static List<ClubMatchScoreNotes> GetClubMatchScoreNotes(int clubId, int clubMatchId, int userId, bool IsNow = false)
        // {
        //     return redisdb.GetOrAdd(RedisType.List, GetClubMatchScoreNotesKey(clubId, clubMatchId, userId), () =>
        //     {
        //         var list = ClubMatchManagerAdo.GetClubMatchScoreNotes(clubId, clubMatchId, userId);
        //         var ts = IsNow ? TimeSpan.FromMinutes(5) : list.Count > 0 ? expiry : TimeSpan.FromMinutes(3);
        //         return Tuple.Create(list, ts);
        //     }, dbidx, false);
        // }
        
        // static RedisKey GetClubMatchScoreNotesKey(int clubId, int clubMatchId, int userId) => $"{clubMatchKeyPrefix}:ClubMatchScoreNotes:{clubId}:{clubMatchId}:{userId}";

        // /// <summary>
        // /// 保存玩家分值日志
        // /// </summary>
        // /// <param name="model"></param>
        // public static void SaveClubMatchScoreNotes(ClubMatchScoreNotes model)
        // {
        //     ClubMatchManagerAdo.SaveClubMatchScoreNotes(model);
        //     RemoveCachingOfClubMatchScoreNotes(model.ClubId, model.ClubMatchId, model.UserId);
        // }

        // /// <summary>
        // /// 批量保存玩家分值日志
        // /// </summary>
        // /// <param name="model"></param>
        // public static void SaveClubMatchScoreNotesList(List<ClubMatchScoreNotes> model)
        // {
        //     if (model.Count > 0)
        //     {
        //         ClubMatchManagerAdo.SaveClubMatchScoreNotesList(model);
        //         RemoveCachingOfClubMatchScoreNotes(model[0].ClubId, model[0].ClubMatchId, model.Select(p => p.UserId).ToArray());
        //     }
        // }

        // /// <summary>
        // /// 移除缓存的玩家分值日志
        // /// </summary>
        // /// <param name="clubId"></param>
        // /// <param name="clubMatchId"></param>
        // /// <param name="userIds"></param>
        // static void RemoveCachingOfClubMatchScoreNotes(int clubId, int clubMatchId, params int[] userIds)
        // {
        //     var keys = userIds.Select(p => GetClubMatchScoreNotesKey(clubId, clubMatchId, p)).ToArray();
        //     redisdb.GetRedisDataBase(dbidx).KeyDelete(keys);
        // }

        // /// <summary>
        // /// 获取比赛记录
        // /// </summary>
        // /// <param name="clubId"></param>
        // /// <param name="clubMatchId"></param>
        // /// <param name="IsNow">是否是当前的比赛。true是 false不是。如果是当前比赛过期时间只能设置分钟如5分钟，结束的比赛过期时间可以设置长一点如3天</param>
        // /// <returns></returns>
        // public static List<ClubMatchNotes> GetClubMatchNotes(int clubId, int clubMatchId, bool IsNow = false)
        // {
        //     return redisdb.GetOrAdd(RedisType.List, GetClubMatchNotesKey(clubId, clubMatchId), () =>
        //     {
        //         var list = ClubMatchManagerAdo.GetClubMatchNotes(clubId, clubMatchId);
        //         var ts = IsNow ? TimeSpan.FromMinutes(5) : list.Count > 0 ? expiry : TimeSpan.FromMinutes(3);
        //         return Tuple.Create(list, ts);
        //     }, dbidx, false);
        // }
        // static RedisKey GetClubMatchNotesKey(int clubId, int clubMatchId) => $"{clubMatchKeyPrefix}:ClubMatchNotes:{clubId}:{clubMatchId}";

        // /// <summary>
        // /// 返回俱乐部的比赛日志
        // /// </summary>
        // /// <param name="clubId">记录表的Id</param>
        // /// <param name="createTime">返回该时间之后的日志 按时间倒序排序</param>
        // /// <returns></returns>
        // public static List<ClubMatchNotes> GetClubMatchNotesByClubId(int clubId, DateTime createTime)
        // {
        //     return redisdb.GetOrAdd(GetClubMatchNotesByClubIdKey(clubId), createTime.ToString("yyyyMMdd"), () =>
        //     {
        //         var list = ClubMatchManagerAdo.GetClubMatchNotesByClubId(clubId, createTime);
        //         var ts = TimeSpan.FromMinutes(5); //这个是累积实时的，故过期时间短
        //         return Tuple.Create(list, ts);
        //     }, dbidx, false);
        // }
        // static RedisKey GetClubMatchNotesByClubIdKey(int clubId) => $"{clubMatchKeyPrefix}:GetClubMatchNotesByClubId:{clubId}";

        // /// <summary>
        // /// 返回俱乐部的比赛日志
        // /// </summary>
        // public static List<ClubMatchNotes> GetClubMatchNotesByClubIdType(int clubId, int type ,DateTime createTime)
        // {
        //     return redisdb.GetOrAdd(GetClubMatchNotesByClubIdKeyType(clubId,type), createTime.ToString("yyyyMMdd"), () =>
        //     {
        //         var list = ClubMatchManagerAdo.GetClubMatchNotesByClubIdType(clubId, type, createTime);
        //         var ts = TimeSpan.FromMinutes(5); //这个是累积实时的，故过期时间短
        //         return Tuple.Create(list, ts);
        //     }, dbidx, false);
        // }
        //static RedisKey GetClubMatchNotesByClubIdKeyType(int clubId,int type) => $"{clubMatchKeyPrefix}:GetClubMatchNotesByClubId:{clubId}_t{type}";

        // public static void RemoveGetClubMatchNotesByClubIdKeyType(int clubId,int type)
        // {
        //     var key = GetClubMatchNotesByClubIdKeyType(clubId, type);
        //     redisdb.GetRedisDataBase(dbidx).KeyDelete(key);
        // }

        // /// <summary>
        // /// 保存俱乐部日志记录
        // /// </summary>
        // /// <param name="model"></param>
        // public static void SaveClubMatchNotes(ClubMatchNotes model)
        // {
        //     ClubMatchManagerAdo.SaveClubMatchNotes(model);
        //     RemoveCachingOfClubMatchNotes(model.ClubId, model.ClubMatchId);
        // }
        //
        // /// <summary>
        // /// 移除缓存的群主俱乐部日志记录
        // /// </summary>
        // /// <param name="clubId"></param>
        // /// <param name="clubMatchId"></param>
        // static void RemoveCachingOfClubMatchNotes(int clubId, int clubMatchId)
        // {
        //     var key1 = GetClubMatchNotesKey(clubId, clubMatchId);
        //     var key2 = GetClubMatchNotesByClubIdKey(clubId);
        //     redisdb.GetRedisDataBase(dbidx).KeyDelete(new[] { key1, key2 });
        // }

        /// <summary>
        /// 获取所有玩家的比赛积分 过期时间3天
        /// </summary>
        /// <param name="clubId"></param>
        /// <param name="clubMatchId"></param>
        /// <returns></returns>
        public static List<ClubMatchUserScore> GetClubMatchUserScores(int clubId, int clubMatchId)
        {
            return redisdb.GetOrAdd(RedisType.List, GetClubMatchUserScoresKey(clubId, clubMatchId), () =>
            {
                //去数据库查询历史数据， 在放到 Redis 中
                var list = ClubMatchManagerAdo.GetClubMatchUserScores(clubId, clubMatchId);
                var ts = list.Count > 0 ? expiry : TimeSpan.FromMinutes(10);
                return Tuple.Create(list, ts);
            }, dbidx, false);
        }
        
        static RedisKey GetClubMatchUserScoresKey(int clubId, int clubMatchId) => $"{clubMatchKeyPrefix}:ClubMatchUserScores:{clubId}:{clubMatchId}";

        // /// <summary>
        // /// 获取单个玩家的比赛积分
        // /// </summary>
        // /// <param name="clubId"></param>
        // /// <param name="clubMatchId"></param>
        // /// <param name="userId"></param>
        // /// <returns></returns>
        // public static ClubMatchUserScore GetClubMatchUserScore(int clubId, int clubMatchId, int userId)
        // {
        //     var userScore = redisdb.GetOrAdd(RedisType.String, GetClubMatchUserScoreKey(clubId, clubMatchId, userId), () =>
        //     {
        //         var item = ClubMatchManagerAdo.GetClubMatchUserScore(clubId, clubMatchId, userId);
        //         var ts = item != null ? expiry : TimeSpan.FromMinutes(10);
        //         return Tuple.Create(item ?? new ClubMatchUserScore(), ts);
        //     }, dbidx, false);
        //     return userScore.ClubMatchId != 0 ? userScore : null;
        // }
        // static RedisKey GetClubMatchUserScoreKey(int clubId, int clubMatchId, int userId) => $"{clubMatchKeyPrefix}:ClubMatchUserScore:{clubId}:{clubMatchId}:{userId}";


        // /// <summary>
        // /// 保存玩家记录
        // /// </summary>
        // /// <param name="model"></param>
        // public static void SaveClubMatchUserScore(ClubMatchUserScore model)
        // {
        //     if (ClubMatchManagerAdo.SaveClubMatchUserScore(model))
        //     {
        //         RemoveCachingOfClubMatchUserScore(model.ClubId, model.ClubMatchId, model.UserId);
        //     }
        // }

        /// <summary>
        /// 批量保存玩家记录
        /// </summary>
        /// <param name="models"></param>
        public static void SaveSaveClubMatchUserScores(List<ClubMatchUserScore> models)
        {
            if (models == null || models.Count < 1) return;
            if (models.Count > 0)
            {
                if (ClubMatchManagerAdo.SaveClubMatchUserScores(models))
                {
                    RemoveCachingOfClubMatchUserScore(models[0].ClubId, models[0].ClubMatchId, models.Select(p => p.UserId).ToArray());
                }
            }
        }

        /// <summary>
        /// 移除缓存的玩家记录
        /// </summary>
        /// <param name="clubId"></param>
        /// <param name="clubMatchId"></param>
        /// <param name="userIds"></param>
        static void RemoveCachingOfClubMatchUserScore(int clubId, int clubMatchId, params int[] userIds)
        {
            var keys = new List<RedisKey>();
            keys.Add(GetClubMatchUserScoresKey(clubId, clubMatchId));
            redisdb.GetRedisDataBase(dbidx).KeyDelete(keys.ToArray());
        }
    }
}
