using System;
using System.Collections.Generic;
using System.Linq;
using System.Data;
using System.Threading;
using MySystem.PxcModels;
using Library;
using LitJson;

namespace MySystem
{
    public class PosCouponPrizeService
    {
        public readonly static PosCouponPrizeService Instance = new PosCouponPrizeService();
        private PosCouponPrizeService()
        { }


        public void Start()
        {
            Thread th = new Thread(ready);
            th.IsBackground = true;
            th.Start();
        }
        
        private void ready()
        { 
            bool op = true;
            while (op)
            {
                string content = RedisDbconn.Instance.RPop<string>("PosCouponPrizeQueue");
                if (!string.IsNullOrEmpty(content))
                {
                    try
                    {
                        dosomething(int.Parse(function.CheckInt(content)));
                    }
                    catch(Exception ex)
                    {
                        function.WriteLog(DateTime.Now.ToString() + "\n" + ex.ToString(), "商城下单机具券发奖异常");
                    }
                }
                else
                {
                    Thread.Sleep(2000);
                }
            }
        }

        public void dosomething(int OrderId)
        { 
            WebCMSEntities db = new WebCMSEntities();
            OpModels.WebCMSEntities opdb = new OpModels.WebCMSEntities();
            Orders order = db.Orders.FirstOrDefault(m => m.Id == OrderId);
            if(order != null)
            {
                List<int> ChkIds = new List<int>(); //机具券商品Id集合
                ChkIds.Add(10);
                ChkIds.Add(11);
                ChkIds.Add(77);
                ChkIds.Add(78);
                ChkIds.Add(79);
                //判断是否是指定商品
                if(ChkIds.Contains(order.ProductId))
                {
                    int Kind = 0;
                    if (order.ProductId == 10)
                    {
                        Kind = 1;
                    }
                    else if (order.ProductId == 11)
                    {
                        Kind = 2;
                    }
                    int CouponCount = 0;
                    if(Kind == 1)
                    {
                        CouponCount = 3 * order.BuyCount;
                    }
                    else if(Kind == 2)
                    {
                        CouponCount = 2 * order.BuyCount;
                    }

                    UserRankItem orderUser = GetUserLevel(db, order.UserId);
                    string ParentNav = orderUser.ParentNav + "," + orderUser.Id + ",";
                    string[] ParentNavList = ParentNav.Trim(',').Replace(",,", ",").Split(',');
                    Array.Reverse(ParentNavList);
                    int index = 0;
                    bool DirectPrizeFlag = false; //推荐奖励发放标识
                    bool BackAccountFlag = false; //备用金返余额标识
                    bool BigLeaderFlag = false; //大盟主标记
                    decimal BuyPrize = 0; //购机奖励
                    foreach(string ParentId in ParentNavList)
                    {
                        UserRankItem parentUser = GetUserLevel(db, int.Parse(ParentId));
                        index += 1;
                        if(index == 1 && (orderUser.LeaderLevel > 0 || orderUser.OperateLevel > 0) && !DirectPrizeFlag)
                        {
                            DirectPrize(db, order.Id, order.UserId, order.BuyCount);
                            DirectPrizeFlag = true;
                        }
                        if(index > 1)
                        {
                            if(Utils.Instance.IsStandardUser(parentUser.Id) && !DirectPrizeFlag)
                            {
                                DirectPrize(db, order.Id, parentUser.Id, order.BuyCount);
                                DirectPrizeFlag = true;
                            }
                        }
                        if(parentUser.OperateLevel > 0 && CheckOpReserve(opdb, order.BuyCount, parentUser.Id))
                        {
                            //购机奖
                            decimal CurBuyPrize = GetBuyPrize(parentUser);
                            decimal GetPrize = CurBuyPrize - BuyPrize;
                            if(GetPrize > 0) OpAccount(db, order.Id, parentUser.Id, GetPrize, order.BuyCount, 128);
                            BuyPrize = CurBuyPrize;

                            if(!BackAccountFlag)
                            {
                                BackAccountFlag = true;
                                //扣减备用金
                                OperateAmountChange(opdb, parentUser.Id, GetWithdrawMoney(parentUser) * order.BuyCount, 2, 1, "商城购机", true);
                                //返回到余额
                                OperateAmountChange(opdb, parentUser.Id, GetWithdrawMoney(parentUser) * order.BuyCount, 1, 2, "商城购机", true);
                            }
                        }
                        else if(parentUser.LeaderLevel > 0 && CheckLeaderReserve(db, order.BuyCount, parentUser.Id))
                        {
                            //购机奖
                            decimal CurBuyPrize = GetBuyPrize(parentUser);
                            decimal GetPrize = CurBuyPrize - BuyPrize;
                            if(GetPrize > 0) OpAccount(db, order.Id, parentUser.Id, CurBuyPrize - BuyPrize, order.BuyCount, 118);
                            BuyPrize = CurBuyPrize;

                            if(!BackAccountFlag)
                            {
                                BackAccountFlag = true;
                                //扣减备用金
                                OpReserve(db, order.Id, parentUser.Id, GetWithdrawMoney(parentUser) * order.BuyCount, 2, order.UserId, "购机奖励");
                                //返回到余额
                                OpLeaderAccount(db, order, parentUser.Id, GetWithdrawMoney(parentUser), order.BuyCount);
                            }

                            //给券打大盟主标记
                            if(parentUser.LeaderLevel == 2 && !BigLeaderFlag)
                            {
                                BigLeaderFlag = true;
                                List<int> couponIds = db.PosCoupons.Where(m => m.IsLock == 0 && m.IsUse == 0 && m.UserId == 0 && m.QueryCount == Kind).OrderBy(m => m.Id).Take(CouponCount).ToList().Select(m => m.Id).ToList();
                                SetPosCouponLeaderFlag(db, parentUser.Id, order.BuyCount, couponIds);
                            }
                        }
                    }
                }
            }
            db.Dispose();
            opdb.Dispose();
        }

        /// <summary>
        /// 获取创客各种等级
        /// </summary>
        /// <param name="db"></param>
        /// <param name="UserId"></param>
        /// <returns></returns>
        public UserRankItem GetUserLevel(WebCMSEntities db, int UserId)
        {
            UserRankItem dic = new UserRankItem();
            DateTime now = DateTime.Now;
            Users user = db.Users.FirstOrDefault(m => m.Id == UserId) ?? new Users();
            UserRankWhite userWhite = db.UserRankWhite.FirstOrDefault(m => m.Id == UserId && m.UpdateDate > now) ?? new UserRankWhite();
            Leaders leader = db.Leaders.FirstOrDefault(m => m.Id == UserId && m.ExpiredDate > now) ?? new Leaders();
            dic.UserLevel = userWhite.Rank > user.UserLevel ? userWhite.Rank : user.UserLevel;
            dic.LeaderLevel = leader.LeaderLevel;
            dic.OperateLevel = user.UserType;
            dic.Id = user.Id;
            dic.ParentUserId = user.ParentUserId;
            dic.ParentNav = user.ParentNav;
            return dic;
        }

        /// <summary>
        /// 直推奖励
        /// </summary>
        /// <param name="db"></param>
        /// <param name="OrderId"></param>
        /// <param name="UserId"></param>
        /// <param name="Count"></param>
        public void DirectPrize(WebCMSEntities db, int OrderId, int UserId, int Count = 1)
        {
            UserAccount account = db.UserAccount.FirstOrDefault(m => m.Id == UserId);
            if (account == null)
            {
                account = db.UserAccount.Add(new UserAccount()
                {
                    Id = UserId,
                    UserId = UserId,
                }).Entity;
                db.SaveChanges();
            }
            decimal BeforeTotalAmount = account.TotalAmount; //变更前总金额
            decimal BeforeFreezeAmount = account.FreezeAmount; //变更前冻结金额
            decimal BeforeBalanceAmount = account.BalanceAmount; //变更前余额
            account.BalanceAmount += 100 * Count;
            account.TotalAmount += 100 * Count;
            decimal AfterTotalAmount = account.TotalAmount; //变更后总金额
            decimal AfterFreezeAmount = account.FreezeAmount; //变更后冻结金额
            decimal AfterBalanceAmount = account.BalanceAmount; //变更后余额
            UserAccountRecord userAccountRecord = db.UserAccountRecord.Add(new UserAccountRecord()
            {
                CreateDate = DateTime.Now,
                UpdateDate = DateTime.Now,
                UserId = UserId, //创客
                ChangeType = 112, //变动类型
                ChangeAmount = 100 * Count, //变更金额
                BeforeTotalAmount = BeforeTotalAmount, //变更前总金额
                AfterTotalAmount = AfterTotalAmount, //变更后总金额
                BeforeFreezeAmount = BeforeFreezeAmount, //变更前冻结金额
                AfterFreezeAmount = AfterFreezeAmount, //变更后冻结金额
                BeforeBalanceAmount = BeforeBalanceAmount, //变更前余额
                AfterBalanceAmount = AfterBalanceAmount, //变更后余额
                QueryCount = OrderId,
            }).Entity;
            db.SaveChanges();
        }
    
        /// <summary>
        /// 判断盟主储蓄金足够
        /// </summary>
        /// <param name="db"></param>
        /// <param name="Count"></param>
        /// <param name="UserId"></param>
        /// <returns></returns>
        public bool CheckLeaderReserve(WebCMSEntities db, int Count, int UserId)
        {
            UserAccount acccount = db.UserAccount.FirstOrDefault(m => m.Id == UserId) ?? new UserAccount();
            if(acccount.LeaderReserve >= 400 * Count)
            {
                return true;
            }
            return false;
        }

        /// <summary>
        /// 判断运营中心/合伙人额度足够
        /// </summary>
        /// <param name="db"></param>
        /// <param name="Count"></param>
        /// <param name="UserId"></param>
        /// <returns></returns>
        public bool CheckOpReserve(OpModels.WebCMSEntities db, int Count, int UserId)
        {
            OpModels.UserAccount account = db.UserAccount.FirstOrDefault(m => m.Id == UserId) ?? new OpModels.UserAccount();
            if(account.TotalAmt >= 400 * Count)
            {
                return true;
            }
            return false;
        }
        public bool CheckOpReserve(OpModels.WebCMSEntities db, decimal Amt, int UserId)
        {
            OpModels.UserAccount account = db.UserAccount.FirstOrDefault(m => m.Id == UserId) ?? new OpModels.UserAccount();
            if(account.TotalAmt >= Amt)
            {
                return true;
            }
            return false;
        }

        /// <summary>
        /// 扣减/增加盟主储蓄金
        /// </summary>
        /// <param name="db"></param>
        /// <param name="OrderId"></param>
        /// <param name="UserId"></param>
        /// <param name="Money"></param>
        /// <param name="ChangeType"></param>
        /// <param name="SourceUserId"></param>
        /// <param name="Remark"></param>
        public void OpReserve(WebCMSEntities db, int OrderId, int UserId, decimal Money, int ChangeType, int SourceUserId = 0, string Remark = "储备金购买")
        {
            UserAccount account = db.UserAccount.FirstOrDefault(m => m.Id == UserId);
            if (account == null)
            {
                account = db.UserAccount.Add(new UserAccount()
                {
                    Id = UserId,
                    UserId = UserId,
                }).Entity;
                db.SaveChanges();
            }
            decimal BeforeAmount = account.LeaderReserve; //变更前总金额
            if(ChangeType == 1)
            {
                account.LeaderReserve += Money;
            }
            else
            {
                account.LeaderReserve -= Money;
            }
            decimal AfterAmount = account.LeaderReserve; //变更后总金额
            LeaderReserveRecord add = db.LeaderReserveRecord.Add(new LeaderReserveRecord()
            {
                CreateDate = DateTime.Now,
                ChangeType = ChangeType,
                OrderId = OrderId,
                Remark = Remark,
                AfterAmt = AfterAmount,
                BeforeAmt = BeforeAmount,
                ChangeAmt = Money,
                TradeDate = DateTime.Now.ToString("yyyyMMdd"),
                TradeMonth = DateTime.Now.ToString("yyyyMM"),
                UserId = UserId,
                SourceUserId = SourceUserId,
                Sort = GetLeaderReserveRecordType(Remark),
            }).Entity;
            db.SaveChanges();
        }
        private int GetLeaderReserveRecordType(string Remark)
        {
            Dictionary<int, string> data = new Dictionary<int, string>();
            data.Add(11, "兑换机具券,机具券兑换,系统增加(盟主储蓄金),系统扣减(盟主储蓄金),储备金购买");
            data.Add(12, "系统增加(可提现余额),系统扣减(可提现余额)");
            data.Add(13, "推荐大盟主,推荐小盟主,商城购机,购机奖励");
            var item = data.FirstOrDefault(m => m.Value.Contains(Remark));
            if(item.Key > 0)
            {
                return item.Key;
            }
            return 0;
        }

        /// <summary>
        /// 操作盟主可提现余额
        /// </summary>
        /// <param name="db"></param>
        /// <param name="order"></param>
        /// <param name="UserId"></param>
        /// <param name="Money"></param>
        /// <param name="Count"></param>
        /// <param name="Kind"></param>
        public void OpLeaderAccount(WebCMSEntities db, Orders order, int UserId, decimal Money, int Count = 1)
        {
            UserAccount account = db.UserAccount.FirstOrDefault(m => m.Id == UserId);
            if (account == null)
            {
                account = db.UserAccount.Add(new UserAccount()
                {
                    Id = UserId,
                    UserId = UserId,
                }).Entity;
                db.SaveChanges();
            }
            int ChangeType = 0;
            if(Money == 400)
            {
                ChangeType = 117;
            }
            decimal BeforeLeaderBalanceAmount = account.LeaderBalanceAmount; //变更前余额
            account.LeaderBalanceAmount += Money * Count;
            decimal AfterLeaderBalanceAmount = account.LeaderBalanceAmount; //变更后余额
            LeaderAccountRecord leaderAccountRecord = db.LeaderAccountRecord.Add(new LeaderAccountRecord()
            {
                CreateDate = DateTime.Now,
                UpdateDate = DateTime.Now,
                UserId = UserId, //创客
                ChangeType = ChangeType, //变动类型
                ChangeAmount = Money * Count, //变更金额
                BeforeBalanceAmount = BeforeLeaderBalanceAmount, //变更前余额
                AfterBalanceAmount = AfterLeaderBalanceAmount, //变更后余额
                QueryCount = order.Id,
                Sort = order.UserId,
            }).Entity;
            db.SaveChanges();
        }

        /// <summary>
        /// 操作余额
        /// </summary>
        /// <param name="db"></param>
        /// <param name="order"></param>
        /// <param name="UserId"></param>
        /// <param name="Money"></param>
        /// <param name="Count"></param>
        public void OpAccount(WebCMSEntities db, int OrderId, int UserId, decimal Money, int Count = 1, int ChangeType = 0)
        {
            UserAccount account = db.UserAccount.FirstOrDefault(m => m.Id == UserId);
            if (account == null)
            {
                account = db.UserAccount.Add(new UserAccount()
                {
                    Id = UserId,
                    UserId = UserId,
                }).Entity;
                db.SaveChanges();
            }
            decimal BeforeTotalAmount = account.TotalAmount; //变更前总金额
            decimal BeforeFreezeAmount = account.FreezeAmount; //变更前冻结金额
            decimal BeforeBalanceAmount = account.BalanceAmount; //变更前余额
            account.BalanceAmount += Money * Count;
            account.TotalAmount += Money * Count;
            decimal AfterTotalAmount = account.TotalAmount; //变更后总金额
            decimal AfterFreezeAmount = account.FreezeAmount; //变更后冻结金额
            decimal AfterBalanceAmount = account.BalanceAmount; //变更后余额
            UserAccountRecord userAccountRecord = db.UserAccountRecord.Add(new UserAccountRecord()
            {
                CreateDate = DateTime.Now,
                UpdateDate = DateTime.Now,
                UserId = UserId, //创客
                ChangeType = ChangeType, //变动类型
                ChangeAmount = Money * Count, //变更金额
                BeforeTotalAmount = BeforeTotalAmount, //变更前总金额
                AfterTotalAmount = AfterTotalAmount, //变更后总金额
                BeforeFreezeAmount = BeforeFreezeAmount, //变更前冻结金额
                AfterFreezeAmount = AfterFreezeAmount, //变更后冻结金额
                BeforeBalanceAmount = BeforeBalanceAmount, //变更前余额
                AfterBalanceAmount = AfterBalanceAmount, //变更后余额
                QueryCount = OrderId,
            }).Entity;
            db.SaveChanges();
        }

        /// <summary>
        /// 操作运营中心/合伙人额度（TotalAmt未使用额度，ValidForGetAmount可提现额度）
        /// </summary>
        /// <param name="db"></param>
        /// <param name="UserId"></param>
        /// <param name="Money"></param>
        /// <param name="OperateType">（1增加，2减少）</param>
        /// <param name="AmountType">（1未使用额度，2可提现额度）</param>
        /// <param name="Remark"></param>
        /// <param name="record"></param>
        public void OperateAmountChange(OpModels.WebCMSEntities db, int UserId, decimal Money, int OperateType, int AmountType, string Remark = "", bool record = false)
        {
            OpModels.UserAccount account = db.UserAccount.FirstOrDefault(m => m.Id == UserId);
            if (account == null)
            {
                account = db.UserAccount.Add(new OpModels.UserAccount()
                {
                    Id = UserId,
                    UserId = UserId,
                }).Entity;
                db.SaveChanges();
            }
            decimal BeforeAmount = account.ValidAmount + account.TotalAmt + account.ValidForGetAmount; //变更前总金额
            if(OperateType == 1)
            {
                if(AmountType == 1)
                {
                    account.TotalAmt += Money;
                }
                else if(AmountType == 2)
                {
                    account.ValidForGetAmount += Money;
                }
                else
                {
                    account.ValidAmount += Money;
                }
            }
            else
            {
                if(AmountType == 1)
                {
                    account.TotalAmt -= Money;
                }
                else if(AmountType == 2)
                {
                    account.ValidForGetAmount -= Money;
                }
                else
                {
                    account.ValidAmount -= Money;
                }
            }
            decimal AfterAmount = account.ValidAmount + account.TotalAmt + account.ValidForGetAmount; //变更后总金额
            if(record)
            {
                OpModels.AmountRecord add = db.AmountRecord.Add(new OpModels.AmountRecord()
                {
                    CreateDate = DateTime.Now,
                    UpdateDate = DateTime.Now,
                    OperateType = OperateType,
                    AfterAmount = AfterAmount,
                    BeforeAmount = BeforeAmount,
                    UseAmount = Money,
                    UserId = UserId,
                    SeoDescription = Remark,
                    Version = AmountType,
                }).Entity;
            }
            db.SaveChanges();
        }

        /// <summary>
        /// 给券设置大盟主标记
        /// </summary>
        /// <param name="db"></param>
        /// <param name="LeaderUserId"></param>
        /// <param name="Count"></param>
        /// <param name="couponIds"></param>
        public int SetPosCouponLeaderFlag(WebCMSEntities db, int LeaderUserId, int Count, List<int> couponIds)
        {
            int SetCount = 0;
            UserAccount pacccount = db.UserAccount.FirstOrDefault(m => m.Id == LeaderUserId) ?? new UserAccount();
            foreach(int couponId in couponIds)
            {
                PosCoupons coupon = db.PosCoupons.FirstOrDefault(m => m.Id == couponId);
                if(coupon != null && pacccount.LeaderReserve >= 400 * Count)
                {
                    coupon.LeaderUserId = LeaderUserId;
                    SetCount += 1;
                }
            }
            db.SaveChanges();
            return SetCount;
        }

        /// <summary>
        /// 获取购机奖金额
        /// </summary>
        /// <param name="user"></param>
        /// <returns></returns>
        public decimal GetBuyPrize(UserRankItem user)
        {
            if(user.OperateLevel == 1) return 100;
            if(user.OperateLevel == 2) return 160;
            if(user.OperateLevel == 3) return 180;
            if(user.OperateLevel == 4) return 200;
            if(user.LeaderLevel > 0) return 100;
            return 0;
        }

        /// <summary>
        /// 获取可提现金额
        /// </summary>
        /// <param name="user"></param>
        /// <returns></returns>
        public decimal GetWithdrawMoney(UserRankItem user)
        {
            if(user.OperateLevel == 1) return 400;
            if(user.OperateLevel == 2) return 340;
            if(user.OperateLevel == 3) return 320;
            if(user.OperateLevel == 4) return 300;
            if(user.LeaderLevel > 0) return 400;
            return 0;
        }
    }
}