using System;
using System.Collections.Generic;
using System.Linq;
using Server.DB.Redis;
using System.Text;
using StackExchange.Redis;
using MrWu.Debug;

namespace GameDAL {
    /// <summary>
    /// 俱乐部房卡折扣记录
    /// </summary>
    public static class ClubRCDiscountRedisUtil {

        private const int DbIdx = 5;
        private static IDatabaseProxy dbp => redisManager.Getdb(DbIdx);
        private static IDatabase db => redisManager.GetDataBase(DbStyle.main, DbIdx);
        private const string baseKey = "ClubRCDiscount";

        #region 直充俱乐部折扣
        
        private static string GetClubKey() {
            return $"{baseKey}:Club";
        }

        /// <summary>
        /// 获取所有的折扣信息
        /// </summary>
        public static List<string> GetClubAll()
        {
            string key = GetClubKey();
            var allEntry = dbp.HashGetAll(key);
            List<string> list = allEntry.Select(x=>$"{x.Name}, {Convert.ToSingle(x.Value)}").ToList();
            return list;
        }
        
        public static List<(int Id, float Discount)> GetClubAllEntry()
        {
            string key = GetClubKey();
            var allEntry = dbp.HashGetAll(key);
            List<(int, float)> list = new List<(int, float)>();
            foreach (var item in allEntry)
            {
                list.Add((int.Parse(item.Name), float.Parse(item.Value)));
            }
            return list.ToList();
        }

        /// <summary>
        /// 添加折扣
        /// </summary>
        public static bool AddClub(int clubId, float discount) {
            string key = GetClubKey();
            return dbp.HashSet(key, clubId, discount);
        }

        /// <summary>
        /// 移除折扣
        /// </summary>
        public static bool RemoveClub(int clubId) {
            string key = GetClubKey();
            return dbp.HashDelete(key, clubId);
        }
        
        /// <summary>
        /// 获取折扣
        /// </summary>
        public static float GetClub(int clubId) {
            string key = GetClubKey();
            var value = dbp.HashGet(key, clubId);
            if (value.HasValue && float.TryParse(value, out var discount))
            {
                return discount;
            }
            return 0.7f;
        }
        
        #endregion

        #region 玩家房卡折扣
        private static string GetPlayerKey() {
            return $"{baseKey}:Player";
        }

        /// <summary>
        /// 获取所有的折扣信息
        /// </summary>
        public static List<string> GetPlayerAll()
        {
            string key = GetPlayerKey();
            var allEntry = dbp.HashGetAll(key);
            List<string> list = allEntry.Select(x=>$"{x.Name}, {Convert.ToSingle(x.Value)}").ToList();
            return list;
        }

        public static List<(int Id, float Discount)> GetPlayerAllEntry()
        {
            string key = GetPlayerKey();
            var allEntry = dbp.HashGetAll(key);
            List<(int, float)> list = new List<(int, float)>();
            foreach (var item in allEntry)
            {
                list.Add((int.Parse(item.Name), float.Parse(item.Value)));
            }
            return list.ToList();
        }

        /// <summary>
        /// 添加折扣
        /// </summary>
        public static bool AddPlayer(int userId, float discount) {
            string key = GetPlayerKey();
            return dbp.HashSet(key, userId, discount);
        }

        /// <summary>
        /// 移除折扣
        /// </summary>
        public static bool RemovePlayer(int userId) {
            string key = GetPlayerKey();
            return dbp.HashDelete(key, userId);
        }
        
        /// <summary>
        /// 获取折扣
        /// </summary>
        public static float GetPlayer(int userId) {
            string key = GetPlayerKey();
            var value = dbp.HashGet(key, userId);
            if (value.HasValue && float.TryParse(value, out var discount))
            {
                return discount;
            }
            return 1;
        }

        #endregion

        #region 玩家俱乐部房卡转入限制
        private static string GetPlayerClubLimitKey(int userId) {
            return $"{baseKey}:PlayerClubLimit:{userId}";
        }

        /// <summary>
        /// 添加玩家俱乐部转入限制
        /// </summary>
        public static bool AddPlayerClubLimit(int userId, int clubId) {
            string key = GetPlayerClubLimitKey(userId);
            return dbp.SetAdd(key,clubId);
        }
        
        public static bool AddPlayerClubLimit(int userId, List<int> ids) {
            string key = GetPlayerClubLimitKey(userId);
            dbp.KeyDelete(key);
            RedisValue[] redisValues = ids.Select(id => (RedisValue)id).ToArray();
            if (redisValues.Length == 0)
                return true;
            return dbp.SetAdd(key, redisValues) > 0;
        }
        
        public static bool RemovePlayerClubLimit(int userId) {
            string key = GetPlayerClubLimitKey(userId);
            return dbp.KeyDelete(key);
        }
        
        /// <summary>
        /// 是否允许转入房卡
        /// </summary>
        public static bool IsPlayerClubGiveEnable(int userId, int clubId) {
            string key = GetPlayerClubLimitKey(userId);
            if (!dbp.KeyExists(key)) return true; // 不存在key就没有限制，都可以转入
            return dbp.SetContains(key, clubId); // 存在key，只能转入对应的俱乐部
        }
        
        /// <summary>
        /// 获取玩家俱乐部转入限制
        /// </summary>
        public static List<int> GetPlayerClubLimit(int userId)
        {
            string key = GetPlayerClubLimitKey(userId);
            if (!dbp.KeyExists(key)) return new List<int>();
            return dbp.SetMembers(key).Select(x=>int.Parse(x)).ToList();
        }

        #endregion

        #region 工具方法
        
        public static (int TotalNum, int GiveNum) CalPlayerCardWithDiscount(int userId, int cardCnt)
        { 
            var discount = GetPlayer(userId);
            if (discount <=0 || discount >= 1) return (cardCnt, 0);
            var totalNum = (int)Math.Round(cardCnt / discount);
            var giveNum = totalNum - cardCnt;
            return (totalNum, giveNum);
        }

        public static (int TotalNum, int GiveNum) CalClubCardWithDiscount(int clubId, int cardCnt)
        { 
            var discount = GetClub(clubId);
            if (discount <= 0 || discount >= 1) return (cardCnt, 0);
            var totalNum = (int)Math.Round(cardCnt / discount);
            var giveNum = totalNum - cardCnt;
            return (totalNum, giveNum);
        }

        #endregion
    }
}
