using CloudGaming.Code.Account;
using CloudGaming.Code.DataAccess;
using CloudGaming.DtoModel.Account.User;
using CloudGaming.DtoModel.RedemptionCode;
using CloudGaming.DtoModel.SevenSign;

using HuanMeng.DotNetCore.Redis;

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CloudGaming.Code.Other
{
    /// <summary>
    /// 兑换码
    /// </summary>
    public class RedemptionBLL : CloudGamingBase
    {
        public RedemptionBLL(IServiceProvider serviceProvider) : base(serviceProvider)
        {
        }

        /// <summary>
        /// 使用兑换码
        /// </summary>
        /// <param name="code"></param>
        /// <returns></returns>
        /// <exception cref="ArgumentNullException"></exception>
        public async Task<BaseResponse<bool>> UseRedemptionCodeAsync(string code)
        {
            if (string.IsNullOrEmpty(code))
            {
                throw new ArgumentNullException("兑换码不能为空");
            }
            var list = Cache.RedemptionCodeList;
            var red = list.Where(it => it.Code == code).FirstOrDefault();
            if (red == null)
            {
                throw new ArgumentNullException("兑换码不存在");
            }
            if (!red.IsActive)
            {
                throw new ArgumentNullException("兑换码已失效");
            }
            if (red.ExpirationDate < DateTime.Now)
            {
                throw new ArgumentNullException("兑换码已过期");
            }
            var usageCount = Dao.DaoPhone.Context.T_User_RedemptionUsage.Where(it => it.Code == code && it.Status == (int)RedemptionUsageStatus.领取成功 && it.UserId == _UserId).Count();
            if (usageCount > 0)
            {
                throw new ArgumentNullException("兑换码已使用过");
            }
        start:
            if (red.UsageLimit > 0)
            {
                var redemptionUsageCount = Dao.DaoPhone.Context.T_User_RedemptionUsage.Where(it => it.Code == code && it.Status == (int)RedemptionUsageStatus.领取成功).Count();
                if (redemptionUsageCount >= red.UsageLimit)
                {
                    throw new ArgumentNullException("兑换码已使用");
                }


                if (red.UsageLimit == 1)
                {
                    var lockStr = $"lock:RedemptionCode:{code}";
                    //加锁
                    if (!RedisCache.StringSetLock(lockStr, "", 2))
                    {
                        await Task.Delay(200);
                        goto start;
                    }
                    string msg = await SendReward(code, red);
                    await RedisCache.KeyDeleteAsync(lockStr);
                    return new BaseResponse<bool>(ResponseCode.Success, msg, true) { };
                }
            }
            string m = await SendReward(code, red);
            return new BaseResponse<bool>(ResponseCode.Success, m, true) { };
        }

        private async Task<string> SendReward(string code, RedemptionCodeCache? red)
        {
            T_User_RedemptionUsage t_User_RedemptionUsage = new T_User_RedemptionUsage()
            {
                Code = code,
                RedemptionCodeId = red.Id,
                Status = (int)RedemptionUsageStatus.领取成功,
                UsedDate = DateTime.Now,
                UserId = _UserId,
            };
            await Dao.DaoPhone.Context.T_User_RedemptionUsage.AddAsync(t_User_RedemptionUsage);
            await Dao.DaoPhone.Context.SaveChangesAsync();
            var msg = "兑换码领取成功！";
            //发放奖励
            if (red.RewardConfigs != null && red.RewardConfigs.Count > 0)
            {
                foreach (var raw in red.RewardConfigs)
                {
                    var isSuccess = await this.UserConsumeDiamondMoneyAsync((UserCurrencyType)raw.CurrencyType, raw.AwardNum, $"兑换码礼包");
                    if (!isSuccess)
                    {
                        t_User_RedemptionUsage.Status = (int)RedemptionUsageStatus.领取失败;
                        t_User_RedemptionUsage.Remarks = $"{msg},发放数量{raw.AwardNum}，发放类型{raw.CurrencyType}";
                        if (t_User_RedemptionUsage.Remarks.Length > 250)
                        {
                            t_User_RedemptionUsage.Remarks = t_User_RedemptionUsage.Remarks[^250..];
                        }
                        await Dao.DaoPhone.Context.SaveChangesAsync();
                        throw MessageBox.Show(ResponseCode.Error, "奖励发放失败");
                    }
                    msg += $"获得{(UserCurrencyType)raw.CurrencyType}*{raw.AwardNum}，";
                }
                msg = msg.TrimEnd('，');
                msg += "。";
                await this.SendUserMessageAsync("兑换码领取成功！", msg);
                t_User_RedemptionUsage.Remarks = msg;
                if (t_User_RedemptionUsage.Remarks.Length > 250)
                {
                    t_User_RedemptionUsage.Remarks = t_User_RedemptionUsage.Remarks[^250..];
                }
                await Dao.DaoPhone.Context.SaveChangesAsync();
            }

            return msg;
        }
    }
}
