using System;
using System.Collections.Generic;
using System.Linq;
using System.Data;
using MySystem.Models.Main;
using Library;
using System.Threading;
using Microsoft.Extensions.Hosting;
using System.Threading.Tasks;

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

        #region 消费队列(执行消费退款金额的统计)
        public void StartListenTrade()
        {
            Thread th = new Thread(StartListenTradeDo);
            th.IsBackground = true;
            th.Start();
        }
        public void StartListenTradeDo()
        {
            while (true)
            {
                string orderidstring = RedisDbconn.Instance.RPop<string>("ConsumerOrdersHd:Divi:1:List");
                if (!string.IsNullOrEmpty(orderidstring))
                {
                    ReturnStat(orderidstring, 1);
                }
                else
                {
                    Thread.Sleep(60000);
                }
            }
        }

        public void StartListenWxTrade()
        {
            Thread th = new Thread(StartListenWxTradeDo);
            th.IsBackground = true;
            th.Start();
        }
        public void StartListenWxTradeDo()
        {
            while (true)
            {
                string orderidstring = RedisDbconn.Instance.RPop<string>("ConsumerOrdersHd:Divi:2:List");
                if (!string.IsNullOrEmpty(orderidstring))
                {
                    ReturnStat(orderidstring, 2);
                }
                else
                {
                    Thread.Sleep(10000);
                }
            }
        }

        public void ReturnStat(string orderidstring, int PayMode)
        {
            int OrderId = int.Parse(function.CheckInt(orderidstring));
            WebCMSEntities db = new WebCMSEntities();
            using (var tran = db.Database.BeginTransaction())
            {
                try
                {
                    ConsumerOrders order = db.ConsumerOrders.FirstOrDefault(m => m.Id == OrderId);
                    if (order != null)
                    {
                        decimal PayMoney = order.PayMoney;
                        int MerchantId = order.MerchantId;
                        MerchantInfo merchant = db.MerchantInfo.FirstOrDefault(m => m.Id == MerchantId);
                        if (merchant != null)
                        {
                            int UserId = merchant.UserId;
                            List<CustomTagSet> customTagSets = db.CustomTagSet.ToList(); //获取公用配置参数集和
                            //获取参数
                            CustomTagSet profitPercentSet = customTagSets.FirstOrDefault(m => m.Tags == "CusumerProfitPercent") ?? new CustomTagSet();
                            decimal profitPercent = decimal.Parse(function.CheckNum(profitPercentSet.Contents)); //基于收款金额的总分润比例;
                            CustomTagSet cusumerFeePercentSet = customTagSets.FirstOrDefault(m => m.Tags == "CusumerFeePercent") ?? new CustomTagSet();
                            decimal cusumerFeePercent = decimal.Parse(function.CheckNum(cusumerFeePercentSet.Contents)); //费率;
                            CustomTagSet minProfitSet = customTagSets.FirstOrDefault(m => m.Tags == "MinProfit") ?? new CustomTagSet();
                            decimal minProfit = decimal.Parse(function.CheckNum(minProfitSet.Contents)); //最小分润值;

                            MerchantParamSet set = Newtonsoft.Json.JsonConvert.DeserializeObject<MerchantParamSet>(order.SeoDescription);
                            int DiviPersons = set.DiviPersons; //单笔订单分红人数
                            decimal DiviPercent = set.DiviPercent; //单人最大分红比例
                            int ProfitDays = set.ProfitDays; //分红期限（天）
                            decimal GetPercent = set.GetPercent / 100; //商家实收比例
                            decimal MinPayMoney = set.MinPayMoney; //订单参与门槛
                            int IsAll = set.IsAll; //是否收全额
                            // decimal TotalActual = 0;
                            if (IsAll == 0 && PayMoney >= MinPayMoney && GetPercent < 1)
                            {
                                // PayMoney * (1 - 0.1 - 0.0038 - 0.01);
                                decimal DiviMoney = PayMoney * (1 - GetPercent - cusumerFeePercent - profitPercent);
                                if (DiviMoney > 0)
                                {
                                    RedisDbconn.Instance.AddRightList("ConsumerOrdersHd:Divi:" + PayMode + ":" + order.MerchantId, order);
                                    DiviMoney = DiviMoney / DiviPersons;
                                    List<int> deletes = new List<int>();
                                    long CurDiviPersons = DiviPersons;
                                    long QueueCount = RedisDbconn.Instance.Count("ConsumerOrdersHd:Divi:" + PayMode + ":" + MerchantId);
                                    long CurQueueCount = QueueCount;
                                    if (CurDiviPersons >= CurQueueCount)
                                    {
                                        CurDiviPersons = CurQueueCount;
                                    }
                                    if (DiviPersons < QueueCount)
                                    {
                                        QueueCount = DiviPersons;
                                    }
                                    decimal OtherMoney = 0; // 退款金额>最大退款金额-当前退款金额，次金额应归还给商户

                                    // 减去自己付的订单
                                    int OutCount = 0; // 出局人数
                                    while (CurDiviPersons > 0)
                                    {
                                        ConsumerOrders suborder = RedisDbconn.Instance.RPop<ConsumerOrders>("ConsumerOrdersHd:Divi:" + PayMode + ":" + MerchantId);
                                        if (suborder != null)
                                        {
                                            MerchantParamSet subset = Newtonsoft.Json.JsonConvert.DeserializeObject<MerchantParamSet>(order.SeoDescription);
                                            int subProfitDays = subset.ProfitDays; //分红期限（天）
                                            bool IsOut = suborder.UpdateDate.Value.AddDays(subProfitDays) < DateTime.Now ? true : false;
                                            if (suborder.CurDivi < suborder.MaxDivi && !IsOut)
                                            {
                                                //如果没过期并且当前退款金额没超过最大退款金额，就执行
                                                decimal GetMoney = suborder.MaxDivi - suborder.CurDivi;
                                                decimal DiffMoney = 0;
                                                if (GetMoney >= DiviMoney)
                                                {
                                                    GetMoney = DiviMoney;
                                                }
                                                else
                                                {
                                                    DiffMoney = DiviMoney - GetMoney;
                                                }
                                                if (GetMoney > minProfit)
                                                {
                                                    suborder.CurDivi += GetMoney;
                                                    if (DiffMoney > 0)
                                                    {
                                                        OtherMoney += DiffMoney;
                                                    }
                                                    ConsumerProfit cprofit = db.ConsumerProfit.Add(new ConsumerProfit()
                                                    {
                                                        CreateDate = DateTime.Now,
                                                        ConsumerId = suborder.ConsumerId,
                                                        MerchantId = suborder.MerchantId,
                                                        OrderId = suborder.Id,
                                                        GetMoney = Math.Round(GetMoney, 2),
                                                        QueryCount = PayMode,
                                                        Sort = OrderId,
                                                        SeoTitle = suborder.OrderNo,
                                                        SeoKeyword = suborder.PayMoney.ToString(),
                                                    }).Entity;
                                                    db.SaveChanges();
                                                    MerchantAddInfo merchantAdd = db.MerchantAddInfo.FirstOrDefault(m => m.Id == suborder.MerchantId) ?? new MerchantAddInfo();
                                                    
                                                    //聚合支付退款
                                                    decimal RefundAmount = GetMoney * 100;
                                                    RefundAmount = Math.Round(RefundAmount, 2);
                                                    var info = HaoDaHelper.Instance.AggregatedPayRefund(merchantAdd.OutMchtNo, merchantAdd.StoreNo, "HDTK" + DateTime.Now.ToString("yyyyMMddHHmmssfff") + function.get_Random(8), suborder.OrderNo, RefundAmount.ToString("f0"));

                                                    merchant.ActCurrentAmount += Math.Round(GetMoney, 2); //活动已返金额
                                                    db.SaveChanges();
                                                    if (suborder.CurDivi < suborder.MaxDivi)
                                                    {
                                                        RedisDbconn.Instance.AddList("ConsumerOrdersHd:Divi:" + PayMode + ":" + MerchantId, suborder);
                                                    }
                                                    else
                                                    {
                                                        OutCount += 1;
                                                    }
                                                    Thread.Sleep(1000);
                                                }
                                            }
                                            else
                                            {
                                                //否者计算人数不计入退款名额
                                                CurDiviPersons += 1;
                                            }
                                        }
                                        CurDiviPersons -= 1;
                                        QueueCount = RedisDbconn.Instance.Count("ConsumerOrdersHd:Divi:" + PayMode + ":" + MerchantId);
                                        if (QueueCount == 0)
                                        {
                                            CurDiviPersons = 0;
                                        }
                                    }
                                }
                            }
                        }
                    }
                    tran.Commit();
                }
                catch (Exception ex)
                {
                    LogHelper.Instance.WriteLog(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + ":" + ex.ToString(), "自定义分润程序监听队列异常");
                    tran.Rollback();
                }
            }
            db.Dispose();
        }
        #endregion
    }
}