using Mall.Repository.Product;
using System;
using System.Collections.Generic;
using System.Text;
using System.Linq;
using Mall.Model.Entity.Product;
using VT.FW.DB;
using Mall.Model.Query;
using Newtonsoft.Json;
using Mall.Module.MarketingCenter;
using Mall.Common;
using Mall.Repository.User;
using Mall.Model.Extend.User;

namespace Mall.WindowsService.Module
{
    /// <summary>
    /// 用户订单统计
    /// </summary>
    public class UserStatisticsModule
    {
        /// <summary>
        /// 统计处理
        /// </summary>
        public readonly StatisticsModule statisticsModule = new StatisticsModule();
        /// <summary>
        /// 订单统计
        /// </summary>
        public readonly RB_User_StatisticsRepository user_StatisticsRepository = new RB_User_StatisticsRepository();
        /// <summary>
        /// 会员
        /// </summary>
        private readonly RB_Member_UserRepository member_UserRepository = new RB_Member_UserRepository();
        /// <summary>
        /// 分销商
        /// </summary>
        private readonly RB_Distributor_InfoRepository distributor_InfoRepository = new RB_Distributor_InfoRepository();

        /// <summary>
        /// 更新用户最近订单统计
        /// </summary>
        /// <returns></returns>
        public bool UpdateToDayUserStatistics(string StartTime, string EndTime)
        {
            if (string.IsNullOrEmpty(StartTime))
            {
                StartTime = DateTime.Now.AddMonths(-6).ToString("yyyy-MM") + "-01";
            }
            if (string.IsNullOrEmpty(EndTime))
            {
                EndTime = DateTime.Now.ToString("yyyy-MM-dd");
            }
            //查询时间范围  更新最近一个月的数据
            OrderStatistics_Query demodel = new OrderStatistics_Query
            {
                StartDate = StartTime,
                EndDate = EndTime,
                TenantId = 1,
                MallBaseId = 1
            };
            demodel.TenantId = 1;//可写配置文件   默认电商系统的
            demodel.MallBaseId = 1;
            List<OrderStatistics_Query> list = new List<OrderStatistics_Query>();
            List<OrderStatistics_Query> listCancel = new List<OrderStatistics_Query>();
            List<OrderStatistics_Query> listAftersale = new List<OrderStatistics_Query>();

            list = statisticsModule.GetFXOrderProfitLossList_V2(demodel);
            if (list != null && list.Any())
            {
                string ids = string.Join(",", list.Select(x => x.Id));
                demodel.Ids = ids;
                listCancel = statisticsModule.GetFXAllCancelOrderProfitLossList_V2(demodel);
                listAftersale = statisticsModule.GetFXAllAftersaleOrderProfitLossList_V2(demodel);
            }

            foreach (var item in list)
            {
                if (item.OrderStatus == 7)
                {
                    item.FXCommission = 0;
                    item.LiveCommission = 0;
                    item.RemitFXCommission = 0;
                    item.RefundActual = item.RefundActual > 0 ? item.RefundActual : item.AllPrice;
                }

                if (item.OrderSource == Common.Enum.User.UserSourceEnum.ERP)
                {
                    item.ReturnServiceCharge = 0;
                    item.ServiceCharge = 0;
                }
                else
                {
                    if (item.RefundActual > 0 && (item.OrderSource.HasValue && item.OrderSource != Common.Enum.User.UserSourceEnum.ERP))
                    {
                        if (listCancel != null && listCancel.Any(x => x.Id == item.Id))//存在取消中
                        {
                            item.ReturnServiceCharge = item.ServiceCharge;
                        }
                        else if (listAftersale != null && listAftersale.Any(x => x.Id == item.Id))//存在取消中
                        {
                            item.ReturnServiceCharge = Math.Round((item.RefundActual * (Convert.ToDecimal(Config.SettlementRate) / 100)), 2, MidpointRounding.AwayFromZero);
                        }
                    }
                }


                item.CostMoney = ((item.OrderClassify == 1 && item.CarType != 5) ? item.CostMoney : (item.CostMoney * item.Number));
                item.ALLCommission = item.CostMoney + item.GoodsFreight + item.InsuranceCostMoney + item.FXCommission + item.LiveCommission + item.RefundActual + item.YFMoney;
                item.NoPaid = item.ALLCommission;
                item.RemitFXCommission = item.RemitFXCommission + (!string.IsNullOrWhiteSpace(item.LiveFinanceIds) ? item.LiveCommission : 0);
                item.Paid = item.RefundActual + item.RemitFXCommission + item.CostMoney + item.GoodsFreight + item.PayMoney;
                item.GrossProfit = item.AllPrice + item.YSMoney - item.ALLCommission - item.ServiceCharge + item.ReturnServiceCharge;//这里排除了手续费的  以便跟简易报表一致

                if (item.AllPrice == 0)
                {
                    item.GrossProfitRate = 0;
                }
                else
                {
                    item.GrossProfitRate = ((item.AllPrice + item.YSMoney) == 0 ? 0 : Math.Round((item.GrossProfit / (item.AllPrice + item.YSMoney)), 4, MidpointRounding.AwayFromZero) * 100);
                }
            }

            //查询订单统计
            var slist = user_StatisticsRepository.GetList(new RB_User_Statistics_Extend() { TenantId = demodel.TenantId, MallBaseId = demodel.MallBaseId, StartTime = StartTime, EndTime = EndTime });

            #region 遍历日期
            string SDate = StartTime;
            while (true)
            {
                if (SDate == EndTime)
                {
                    break;
                }
                RB_User_Statistics_Extend usmodel = new RB_User_Statistics_Extend()
                {
                    Date = Convert.ToDateTime(SDate),
                    TenantId = demodel.TenantId,
                    MallBaseId = demodel.MallBaseId,
                    CreateDate = DateTime.Now,
                    UpdateDate = DateTime.Now
                };

                #region 拉取统计数据
                var dayList = list.Where(x => x.PaymentTime.ToString("yyyy-MM-dd") == SDate && x.OrderStatus != 7).ToList();
                int CancelNum = list.Where(x => x.PaymentTime.ToString("yyyy-MM-dd") == SDate && x.OrderStatus == 7).Count();

                usmodel.CancelOrderNum = CancelNum;//取消订单数量
                usmodel.PeopleNum = dayList.Select(x => x.UserId).Distinct().Count();//付款人数
                usmodel.OrderNum = dayList.Select(x => x.OrderId).Distinct().Count();//付款单数
                usmodel.PayMoney = dayList.Sum(x => x.AllPrice);//付款金额
                usmodel.BuyNum = dayList.Sum(x => x.Number);//购买件数
                usmodel.AvgOrderNum = usmodel.PeopleNum <= 0 ? 0 : Math.Round(Convert.ToDecimal(usmodel.OrderNum) / usmodel.PeopleNum, 2, MidpointRounding.AwayFromZero);//平均每人购买单数
                usmodel.AvgBuyNum = usmodel.PeopleNum <= 0 ? 0 : Math.Round(Convert.ToDecimal(usmodel.BuyNum) / usmodel.PeopleNum, 2, MidpointRounding.AwayFromZero);//平均每人购买件数
                usmodel.AvgUnitPrice = usmodel.OrderNum <= 0 ? 0 : Math.Round(usmodel.PayMoney / usmodel.OrderNum, 2, MidpointRounding.AwayFromZero);//平均每单单价
                usmodel.AvgBuyPrice = usmodel.PeopleNum <= 0 ? 0 : Math.Round(usmodel.PayMoney / usmodel.PeopleNum, 2, MidpointRounding.AwayFromZero);//平均每人购买单价

                usmodel.MemberNum = member_UserRepository.GetMemberUserTotalNumForDay(demodel.TenantId, demodel.MallBaseId, SDate);//当日会员累计数
                usmodel.PaymentNum = member_UserRepository.GetMemberUserPayNumForDay(demodel.TenantId, demodel.MallBaseId, SDate);//当日会员累计数
                usmodel.MOrderRate = usmodel.MemberNum <= 0 ? 0 : Math.Round(Convert.ToDecimal(usmodel.PaymentNum) / usmodel.MemberNum, 4, MidpointRounding.AwayFromZero) * 100;//会员下单转换比例

                //复购人数
                string UserIds = string.Join(",", dayList.Select(x => x.UserId).Distinct());
                if (!string.IsNullOrEmpty(UserIds))
                {
                    usmodel.ReBuyNum = member_UserRepository.GetMemberReBuyNumForNowDay(demodel.TenantId, demodel.MallBaseId, SDate, UserIds);//今日复购数量
                }
                usmodel.ReBuyRate = usmodel.PaymentNum <= 0 ? 0 : Math.Round(Convert.ToDecimal(usmodel.ReBuyNum) / usmodel.PaymentNum, 4, MidpointRounding.AwayFromZero) * 100;
                usmodel.NewPeopleNum = usmodel.PeopleNum - usmodel.ReBuyNum;

                //今日数量
                var newList = distributor_InfoRepository.GetNewUserForNowDay(new RB_Distributor_Info_Extend() { TenantId = demodel.TenantId, MallBaseId = demodel.MallBaseId, AuditStatus = Common.Enum.User.DistributorAuditStatusEnum.Audited }, SDate);
                usmodel.PXNum = newList.Where(x => x.FXGradeId == 1).Count();
                usmodel.VipNum = newList.Where(x => x.FXGradeId == 2).Count();
                usmodel.YXNum = newList.Where(x => x.FXGradeId == 3).Count();
                usmodel.JXNum = newList.Where(x => x.FXGradeId == 4).Count();

                #region 累计数量  当月最后一天来查询
                if (SDate == Convert.ToDateTime(Convert.ToDateTime(SDate).ToString("yyyy-MM") + "-01").AddMonths(1).AddDays(-1).ToString("yyyy-MM-dd"))
                {
                    var cutList = distributor_InfoRepository.GetMemberDistributorNumberForCutOff(new RB_Distributor_Info_Extend() { TenantId = demodel.TenantId, MallBaseId = demodel.MallBaseId, AuditStatus = Common.Enum.User.DistributorAuditStatusEnum.Audited }, SDate);
                    usmodel.PXLJNum = cutList.Where(x => x.FXGradeId == 1)?.FirstOrDefault()?.SortNum ?? 0;
                    usmodel.VipLJNum = cutList.Where(x => x.FXGradeId == 2)?.FirstOrDefault()?.SortNum ?? 0;
                    usmodel.YXLJNum = cutList.Where(x => x.FXGradeId == 3)?.FirstOrDefault()?.SortNum ?? 0;
                    usmodel.JXLJNum = cutList.Where(x => x.FXGradeId == 4)?.FirstOrDefault()?.SortNum ?? 0;
                }
                #endregion

                //利润
                usmodel.Profit = dayList.Sum(x => x.GrossProfit);
                //usmodel.ProfitRate = dayList.Count() > 0 ? dayList.Sum(x => x.GrossProfitRate) / dayList.Count() : 0;
                //直接根据一天的来计算  ((item.AllPrice + item.YSMoney) == 0 ? 0 : Math.Round((item.GrossProfit / (item.AllPrice + item.YSMoney)), 4, MidpointRounding.AwayFromZero) * 100);
                usmodel.ProfitRate = dayList.Count() > 0 ? (dayList.Sum(x => x.AllPrice + x.YSMoney) == 0 ? 0 : Math.Round(dayList.Sum(x => x.GrossProfit) / dayList.Sum(x => x.AllPrice + x.YSMoney), 4, MidpointRounding.AwayFromZero) * 100) : 0;
                #endregion
                var sModel = slist.Where(x => x.Date == Convert.ToDateTime(SDate)).FirstOrDefault();
                if (sModel == null)
                {
                    //新增
                    user_StatisticsRepository.Insert(usmodel);
                    //Console.WriteLine(SDate + "新增：" + JsonConvert.SerializeObject(usmodel));
                }
                else
                {
                    //修改
                    usmodel.Id = sModel.Id;
                    usmodel.CreateDate = sModel.CreateDate;
                    user_StatisticsRepository.Update(usmodel);
                    //Console.WriteLine(SDate + "修改：" + JsonConvert.SerializeObject(usmodel));
                }
                SDate = Convert.ToDateTime(SDate).AddDays(1).ToString("yyyy-MM-dd");
            }
            #endregion

            return true;
        }
    }
}
