using System;
using System.Collections.Generic;
using System.Linq;
using Library;
using MySystem.PxcModels;

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

        /// <summary>
        /// 操作收支明细
        /// </summary>
        /// <param name="UserId"></param>
        /// <param name="Money"></param>
        /// <param name="ChangeType"></param>
        public void OpAccount(int UserId, decimal Money, int ChangeType, bool IsTotal = true)
        {
            WebCMSEntities db = new WebCMSEntities();
            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;
            if(IsTotal)
            {
                account.TotalAmount += Money;
            }
            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, //变更金额
                BeforeTotalAmount = BeforeTotalAmount, //变更前总金额
                AfterTotalAmount = AfterTotalAmount, //变更后总金额
                BeforeFreezeAmount = BeforeFreezeAmount, //变更前冻结金额
                AfterFreezeAmount = AfterFreezeAmount, //变更后冻结金额
                BeforeBalanceAmount = BeforeBalanceAmount, //变更前余额
                AfterBalanceAmount = AfterBalanceAmount, //变更后余额
            }).Entity;
            db.SaveChanges();
            db.Dispose();
        }

        public void ToChargeAmount(int UserId, decimal Money)
        {
            WebCMSEntities db = new WebCMSEntities();
            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();
            }
            account.ToChargeAmount += Money;
            db.SaveChanges();
            db.Dispose();
        }

        /// <summary>
        /// 判断是否达标创客
        /// </summary>
        /// <param name="UserId"></param>
        /// <returns></returns>
        public bool IsStandardUser(int UserId)
        {
            WebCMSEntities db = new WebCMSEntities();
            // Users user = db.Users.FirstOrDefault(m => m.Id == UserId) ?? new Users();
            UserRankItem user = PosCouponPrizeService.Instance.GetUserLevel(UserId);
            if(user.UserType == 1)
            {
                return true;
            }
            if(user.LeaderLevel > 0)
            {
                Leaders leader = db.Leaders.FirstOrDefault(m => m.Id == UserId) ?? new Leaders();
                if(leader.ExpiredDate > DateTime.Now)
                {
                    return true;
                }
            }
            MpMainModels.WebCMSEntities mpdb = new MpMainModels.WebCMSEntities();
            MpMainModels2.WebCMSEntities mpdb2 = new MpMainModels2.WebCMSEntities();
            int couponCount = db.PosCoupons.Count(m => m.UserId == UserId && m.IsUse == 0); //1. 个人名下电签兑换券 + 大机兑换券 ≥ 3
            // TODO:待确认条件
            if(couponCount >= 3)
            {
                db.Dispose();
                mpdb.Dispose();
                mpdb2.Dispose();
                return true;
            }
            else
            {
                List<int> ids = new List<int>();
                ids.Add(10);
                ids.Add(11);
                ids.Add(77);
                ids.Add(78);
                ids.Add(79);
                ids.Add(92);
                bool orderCheck = db.Orders.Any(m => m.UserId == UserId && ids.Contains(m.ProductId) && m.Status > 0); //1. 商城下单过id为10、11、77、78、79的商品
                if(orderCheck)
                {
                    db.Dispose();
                    mpdb.Dispose();
                    mpdb2.Dispose();
                    return true;
                }
                else
                {
                    //1. 激活POS机数量 + 激活来客吧商户数量 + 激活广电卡数量 ≥ 3
                    int ActiveCount = db.PosMachinesTwo.Count(m => m.BuyUserId == UserId && m.ActivationState == 1);
                    int ActMerchantCount = mpdb.MerchantDepositOrder.Count(m => m.UserId == UserId && m.Status > 0) + mpdb2.MerchantDepositOrder.Count(m => m.UserId == UserId && m.Status > 0);
                    if(ActiveCount + ActMerchantCount >= 3)
                    {
                        db.Dispose();
                        mpdb.Dispose();
                        mpdb2.Dispose();
                        return true;
                    }
                }
            }
            db.Dispose();
            mpdb.Dispose();
            mpdb2.Dispose();
            return false;
        }

        public bool IsStandardUser2(int UserId, DateTime OrderTime)
        {
            WebCMSEntities db = new WebCMSEntities();
            // Users user = db.Users.FirstOrDefault(m => m.Id == UserId) ?? new Users();
            UserRankItem user = PosCouponPrizeService.Instance.GetUserLevel(UserId);
            if(user.UserType == 1)
            {
                return true;
            }
            if(user.LeaderLevel > 0)
            {
                Leaders leader = db.Leaders.FirstOrDefault(m => m.Id == UserId) ?? new Leaders();
                if(leader.ExpiredDate > DateTime.Now)
                {
                    return true;
                }
            }
            MpMainModels.WebCMSEntities mpdb = new MpMainModels.WebCMSEntities();
            MpMainModels2.WebCMSEntities mpdb2 = new MpMainModels2.WebCMSEntities();
            int couponCount = db.PosCoupons.Count(m => m.CreateDate <= OrderTime && m.UserId == UserId && m.IsUse == 0); //1. 个人名下电签兑换券 + 大机兑换券 ≥ 3
            // TODO:待确认条件
            if(couponCount >= 3)
            {
                db.Dispose();
                mpdb.Dispose();
                mpdb2.Dispose();
                return true;
            }
            else
            {
                List<int> ids = new List<int>();
                ids.Add(10);
                ids.Add(11);
                ids.Add(77);
                ids.Add(78);
                ids.Add(79);
                bool orderCheck = db.Orders.Any(m => m.PayDate <= OrderTime && m.UserId == UserId && ids.Contains(m.ProductId) && m.Status > 0); //1. 商城下单过id为10、11、77、78、79的商品
                if(orderCheck)
                {
                    db.Dispose();
                    mpdb.Dispose();
                    mpdb2.Dispose();
                    return true;
                }
                else
                {
                    //1. 激活POS机数量 + 激活来客吧商户数量 + 激活广电卡数量 ≥ 3
                    int ActiveCount = db.PosMachinesTwo.Count(m => m.BuyUserId == UserId && m.ActivationState == 1 && m.ActivationTime <= OrderTime);
                    int ActMerchantCount = mpdb.MerchantDepositOrder.Count(m => m.UserId == UserId && m.Status > 0 && m.UpdateDate <= OrderTime) + mpdb2.MerchantDepositOrder.Count(m => m.UserId == UserId && m.Status > 0 && m.UpdateDate <= OrderTime);
                    if(ActiveCount + ActMerchantCount >= 3)
                    {
                        db.Dispose();
                        mpdb.Dispose();
                        mpdb2.Dispose();
                        return true;
                    }
                }
            }
            db.Dispose();
            mpdb.Dispose();
            mpdb2.Dispose();
            return false;
        }

        /// <summary>
        /// 预设职级
        /// </summary>
        /// <param name="UserId"></param>
        /// <param name="LeaderKind"></param>
        public void LeaderPreUserLevel(int UserId, int UserLevel, DateTime ExpiredDate)
        {
            WebCMSEntities db = new WebCMSEntities();
            UserRankWhite rank = db.UserRankWhite.FirstOrDefault(m => m.Id == UserId);
            if(rank == null)
            {
                rank = db.UserRankWhite.Add(new UserRankWhite()
                {
                    CreateDate = DateTime.Now, //设置时间
                    UserId = UserId, //用户
                    Id = UserId,
                }).Entity;
                db.SaveChanges();
            }
            rank.Rank = UserLevel;
            rank.UpdateDate = ExpiredDate;
            db.SaveChanges();
            db.Dispose();
        }


        #region 获取创客职级
        public int GetUserLevel(int Id)
        {
            WebCMSEntities db = new WebCMSEntities();
            DateTime now = DateTime.Now;
            List<int> Levels = new List<int>();
            Users user = db.Users.FirstOrDefault(m => m.Id == Id) ?? new Users();
            UserRankWhite userRank = db.UserRankWhite.FirstOrDefault(m => m.Id == Id && m.UpdateDate > now) ?? new UserRankWhite();
            LeaderRankWhite leaderRank = db.LeaderRankWhite.FirstOrDefault(m => m.Id == Id && m.UpdateDate > now) ?? new LeaderRankWhite();
            OperatorRankWhite operatorRank = db.OperatorRankWhite.FirstOrDefault(m => m.Id == Id && m.UpdateDate > now) ?? new OperatorRankWhite();
            Levels.Add(user.UserLevel);
            Levels.Add(userRank.Rank);
            Levels.Add(leaderRank.Rank);
            Levels.Add(operatorRank.Rank);
            db.Dispose();
            return Levels.Max();
        }
        #endregion


        #region 解析机具押金值，单位转换
        public string TransferDeposit(PosMachinesTwo newpos, string Deposit)
        {
            decimal DepositNumber = decimal.Parse(function.CheckNum(Deposit));
            if(DepositNumber == 0)
            {
                return "";
            }
            WebCMSEntities db = new WebCMSEntities();
            int BrandId = newpos.BrandId;
            KqProducts pro = db.KqProducts.FirstOrDefault(m => m.Id == BrandId) ?? new KqProducts();
            if(pro.NoticeMoneyUnit == 1 && DepositNumber > 1000)
            {
                DepositNumber = DepositNumber / 100;
            }
            if(pro.NoticeMoneyUnit == 2 && DepositNumber < 1000)
            {
                DepositNumber = DepositNumber * 100;
            }
            db.Dispose();
            return DepositNumber.ToString("f2");
        }
        #endregion


        #region 运营中心额度变更
        public void OperateAmountChange(OpModels.WebCMSEntities db, OpAmountItem param)
        {
            if(param.UseAmount <= 0 || param.UserId <= 0) return;
            Utils.WriteLog(Newtonsoft.Json.JsonConvert.SerializeObject(param), "运营中心额度变更测试");
            OpModels.UserAccount account = db.UserAccount.FirstOrDefault(m => m.Id == param.UserId);
            if (account == null)
            {
                account = db.UserAccount.Add(new OpModels.UserAccount()
                {
                    Id = param.UserId,
                    UserId = param.UserId,
                }).Entity;
                db.SaveChanges();
            }
            decimal BeforeAmount = account.ValidForGetAmount + account.TotalAmt + account.ValidAmount;
            if(param.NoAccount == 0)
            {
                if(param.OperateType == 0 && param.UseTotalAmt > 0 && param.UseValidForGetAmount > 0 && param.UseValidAmount == 0)
                {                
                    account.TotalAmt -= param.UseTotalAmt;
                    account.ValidForGetAmount += param.UseValidForGetAmount;
                }
                else
                {
                    if(param.OperateType == 1)
                    {
                        account.TotalAmt += param.UseTotalAmt;
                        account.ValidForGetAmount += param.UseValidForGetAmount;
                        account.ValidAmount += param.UseValidAmount;
                    }
                    else if(param.OperateType == 2)
                    {
                        account.TotalAmt -= param.UseTotalAmt;
                        account.ValidForGetAmount -= param.UseValidForGetAmount;
                        account.ValidAmount -= param.UseValidAmount;
                    }
                }
            }
            if(account.TotalAmt < 0) return;
            Utils.WriteLog("1", "运营中心额度变更测试");
            decimal AfterAmount = account.ValidForGetAmount + account.TotalAmt + account.ValidAmount;
            OpModels.AmountRecordNew add = db.AmountRecordNew.Add(new OpModels.AmountRecordNew()
            {
                CreateDate = DateTime.Now,
                UpdateDate = DateTime.Now,
                ChangeTypeId = param.ChangeType,
                Remark = param.Remark,
                AfterValidForGetAmount = account.ValidForGetAmount,
                AfterTotalAmt = account.TotalAmt,
                AfterValidAmount = account.ValidAmount,
                OperateType = param.OperateType,
                AfterAmount = AfterAmount,
                BeforeAmount = BeforeAmount,
                UseAmount = param.UseAmount,
                UserId = param.UserId,
                UseValidForGetAmount = param.UseValidForGetAmount,
                UseTotalAmt = param.UseTotalAmt,
                UseValidAmount = param.UseValidAmount,
                DataType = param.DataType,
                DataId = param.DataId,
            }).Entity;
            Utils.WriteLog("2", "运营中心额度变更测试");
            db.SaveChanges();
            Utils.WriteLog("3\n\n", "运营中心额度变更测试");
        }
        #endregion
    

        #region 推送订单信息

        public void SendMqOrder(Orders order)
        {
            string chk = RedisDbconn.Instance.Get<string>("KxsOrderQueueChk:" + order.Id + ":" + order.Status);
            if(!string.IsNullOrEmpty(chk))
            {
                return;
            }
            RedisDbconn.Instance.Set("KxsOrderQueueChk:" + order.Id + ":" + order.Status, DateTime.Now.ToString());
            RedisDbconn.Instance.SetExpire("KxsOrderQueueChk:" + order.Id + ":" + order.Status, 7200);
            string data = Newtonsoft.Json.JsonConvert.SerializeObject(new MqOrder()
            {
                id = order.Id,
                status = order.Status,
                createDate = order.CreateDate,
                snNos = order.SnNos,
                remark = order.Remark,
                buyCount = order.BuyCount,
                payStatus = order.PayStatus,
                productId = order.ProductId, 
                sendStatus = order.SendStatus,
                deliveryType = order.DeliveryType,
                refundStatus = order.RefundStatus,
                payMode = order.PayMode,
                sendDate = order.SendDate == null ? "" : order.SendDate.Value.ToString("yyyy-MM-ddTHH:mm:ss"),
                payDate = order.PayDate == null ? "" : order.PayDate.Value.ToString("yyyy-MM-ddTHH:mm:ss"),
                postalCode = order.PostalCode,
                address = order.Address,
                areas = order.Areas,
                totalPrice = order.TotalPrice,
                mobile = order.Mobile,
                realName = order.RealName,
                orderNo = order.OrderNo,
                userId = order.UserId,
                parentOrderId = order.ParentOrderId,
            });
            Utils.WriteLog(DateTime.Now.ToString() + "\n" + data, "订单推送MQ日志");
            RedisDbconn.Instance.AddList("KxsOrderQueue", data);
        }

        #endregion

        #region 推送激活数据信息

        public void SendActData(PosMachinesTwo pos)
        {
            string chk = RedisDbconn.Instance.Get<string>("KxsActQueueChk:" + pos.PosSn);
            if(!string.IsNullOrEmpty(chk))
            {
                return;
            }
            RedisDbconn.Instance.Set("KxsActQueueChk:" + pos.PosSn, DateTime.Now.ToString());
            RedisDbconn.Instance.SetExpire("KxsActQueueChk:" + pos.PosSn, 7200);
            int actType = pos.BrandId != 14 ? 1 : 2;
            if(Utils.Instance.IsWifi(pos.BrandId)) actType = 5;
            string data = "{";
            data += "\"userId\":\"" + pos.BuyUserId + "\",";
            data += "\"brandId\":\"" + pos.BrandId + "\",";
            string actTime = pos.ActivationTime == null ? "" : pos.ActivationTime.Value.ToString("yyyy-MM-ddTHH:mm:ss");
            data += "\"actTime\":\"" + actTime + "\",";
            data += "\"bindTime\":\"" + pos.BindingTime.Value.ToString("yyyy-MM-ddTHH:mm:ss") + "\",";
            data += "\"sn\":\"" + pos.PosSn + "\",";
            data += "\"actType\":\"" + actType + "\"";
            data += "}";
            Utils.WriteLog(DateTime.Now.ToString() + "\n" + data, "订单推送MQ日志");
            RedisDbconn.Instance.AddList("KxsActQueue", data);
        }

        #endregion 
    
    

        #region 推送奖励信息

        public void PrizePush(int UserId, decimal Prize)
        {
            WebCMSEntities db = new WebCMSEntities();
            Users user = db.Users.FirstOrDefault(m => m.Id == UserId) ?? new Users();
            if(!string.IsNullOrEmpty(user.DeviceType))
            {
                RedisDbconn.Instance.AddList("AliyunPushQueue", "{\"Account\":\"" + user.Mobile + "\",\"Device\":\"" + user.DeviceType.ToUpper() + "\",\"Title\":\"客小爽创客版\",\"Body\":\"奖励到账" + Prize.ToString("f2") +"元，打开收支明细查看！\"}");
            }
            db.Dispose();
        }

        #endregion 


        #region 记录奖励详细流程

        public void PrizeRecord(int Kind, string CodeNumber, string Detail)
        {
            PrizeFlowRecord item = new PrizeFlowRecord()
            {
                CreateDate = DateTime.Now,
                Kind = Kind,
                CodeNumber = CodeNumber,
                Detail = Detail,
            };
            RedisDbconn.Instance.AddList("PrizeFlowQueue", Newtonsoft.Json.JsonConvert.SerializeObject(item));
        }

        #endregion
    
    
        #region 判断好哒产品

        public bool IsHaoDa(int BrandId)
        {
            List<int> Check = new List<int>();
            Check.Add(18);
            Check.Add(19);
            Check.Add(20);
            Check.Add(21);
            Check.Add(29);
            Check.Add(36);
            return Check.Contains(BrandId);
        }

        #endregion

        #region 判断WIFI产品

        public bool IsWifi(int BrandId)
        {
            List<int> Check = new List<int>();
            Check.Add(23);
            Check.Add(24);
            Check.Add(25);
            Check.Add(26);
            Check.Add(32);
            return Check.Contains(BrandId);
        }

        #endregion

        #region 推送数据品牌列表

        public List<string> SaveDataBindIds()
        {
            List<string> ids = RedisDbconn.Instance.GetList<string>("SaveDataBindIds", 1, 1000);
            if(ids.Count > 0)
            {
                return ids;
            }
            WebCMSEntities db = new WebCMSEntities();
            ids = db.KqProducts.Where(m => m.SaveDataFlag == 1).ToList().Select(m => m.SpProductType).Distinct().ToList();
            db.Dispose();
            RedisDbconn.Instance.AddList("SaveDataBindIds", ids.ToArray());
            RedisDbconn.Instance.SetExpire("SaveDataBindIds", 1800);
            return ids;
        }

        #endregion 
    
    
    
    




        #region 打控制台日志

        public static void WriteLog(string msg, string filename = "message")
        {
            Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff") + "--" + filename + "--" + msg);
        }

        #endregion

        #region 推送数据时间判断

        public static bool PushTimeCheck()
        {
            if(DateTime.Now < DateTime.Parse(DateTime.Now.ToString("yyyy-MM-dd") + " 02:15:00") || (DateTime.Now > DateTime.Parse(DateTime.Now.ToString("yyyy-MM-dd") + " 02:26:00") && DateTime.Now < DateTime.Parse(DateTime.Now.ToString("yyyy-MM-dd") + " 14:15:00")) || DateTime.Now > DateTime.Parse(DateTime.Now.ToString("yyyy-MM-dd") + " 14:26:00"))
            {
                return true;
            }
            return false;
        }

        #endregion
    
    }
}