using Mall.Common;
using Mall.Common.Enum.Goods;
using Mall.Common.Enum.User;
using Mall.Common.Plugin;
using Mall.Model.Entity.Finance;
using Mall.Model.Extend.Finance;
using Mall.Model.Extend.Product;
using Mall.Model.Extend.User;
using Mall.Repository;
using Mall.Repository.BaseSetUp;
using Mall.Repository.Finance;
using Mall.Repository.Product;
using Mall.Repository.User;
using Mall.WindowsService.Helper;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Mall.WindowsService.Module
{
    public class FinanceModule
    {
        /// <summary>
        /// 财务单据规则
        /// </summary>
        private static RB_Finance_ConfigurineRepository financeConfigurineRepository = new RB_Finance_ConfigurineRepository();

        /// <summary>
        /// 财务生成记录
        /// </summary>
        private static RB_Finance_RecordRepository financeRecordRepository = new RB_Finance_RecordRepository();
        /// <summary>
        /// 财务生成记录详情
        /// </summary>
        private static RB_Finance_RecordDetailRepository financeRecordDetailRepository = new RB_Finance_RecordDetailRepository();

        /// <summary>
        /// 订单详情
        /// </summary>
        private static RB_Goods_OrderDetailRepository goodsOrderDetailRepository = new RB_Goods_OrderDetailRepository();
        /// <summary>
        /// 订单
        /// </summary>
        private static RB_Goods_OrderRepository goods_OrderRepository = new RB_Goods_OrderRepository();
        /// <summary>
        /// 基础配置
        /// </summary>
        private static RB_MallBaseRepository mallBaseRepository = new RB_MallBaseRepository();
        /// <summary>
        /// 订单日志
        /// </summary>
        private static RB_Goods_LogRepository goods_LogRepository = new RB_Goods_LogRepository();
        /// <summary>
        /// 商品
        /// </summary>
        private static RB_GoodsRepository goodsRepository = new RB_GoodsRepository();
        /// <summary>
        /// 商品规格价格
        /// </summary>
        private static RB_Goods_SpecificationPriceRepository goods_SpecificationPriceRepository = new RB_Goods_SpecificationPriceRepository();
        /// <summary>
        /// 会员
        /// </summary>
        private static RB_Member_UserRepository member_UserRepository = new RB_Member_UserRepository();
        /// <summary>
        /// 用户积分
        /// </summary>
        private static RB_Member_IntegralRepository member_IntegralRepository = new RB_Member_IntegralRepository();
        /// <summary>
        /// 优惠卷
        /// </summary>
        private static RB_Member_CouponRepository member_CouponRepository = new RB_Member_CouponRepository();


        #region 收入

        /// <summary>
        /// 订单收入单据
        /// </summary>
        /// <returns></returns>
        public static bool OrderIncomeFinanceModule()
        {
            var flag = false;

            try
            {
                //先查询规则
                var financeConfigurineList = financeConfigurineRepository.GetList(new RB_Finance_Configurine_Extend { Type = 1 });

                //根据规则中的小程序，查询订单详情信息
                if (financeConfigurineList != null && financeConfigurineList.Any())
                {
                    foreach (var item in financeConfigurineList)
                    {
                        if (item.StartTime.HasValue && item.StartTime < System.DateTime.Now)//判断开始时间是否大于当前时间
                        {
                            //查询今天是否已经生成了财务单据
                            var addFinance = false;

                            DateTime startDate = System.DateTime.Now.AddDays(-1);
                            var recordModel = financeRecordRepository.GetList(new RB_Finance_Record_Extend { TenantId = item.TenantId, MallBaseId = item.MallBaseId }).OrderByDescending(x => x.CreateDate).FirstOrDefault();
                            if (recordModel == null)//今天没生成单据
                            {
                                if (Convert.ToDateTime(item.StartTime.Value.AddDays(item.IntervalDay ?? 0).ToString("yyyy-MM-dd 00:00:00")) <= Convert.ToDateTime(System.DateTime.Now.ToString("yyyy-MM-dd 00:00:00")))//判断开始时间加上执行周期是否等于当前日期
                                {
                                    startDate = item.StartTime.Value;
                                    addFinance = true;
                                }
                            }
                            else
                            {
                                if (Convert.ToDateTime(recordModel.CreateDate.Value.AddDays(item.IntervalDay ?? 0).ToString("yyyy-MM-dd 00:00:00")) <= Convert.ToDateTime(System.DateTime.Now.ToString("yyyy-MM-dd 00:00:00")))//判断最近一次执行的时间加上执行周期是否等于当前日期
                                {
                                    startDate = recordModel.CreateDate.Value;
                                    addFinance = true;
                                }
                            }
                            DateTime endDate = startDate.AddDays(item.IntervalDay ?? 0);//结束时间
                            if (addFinance)//满足今天执行的条件查询间隔周期的订单
                            {
                                StringBuilder builder = new StringBuilder();
                                builder.AppendFormat($@" SELECT a.*,b.OrderNo from rb_goods_orderdetail as a LEFT JOIN rb_goods_order as b on a.OrderId=b.OrderId
where b.TenantId={item.TenantId} and b.MallBaseId={item.MallBaseId}  and  DATE_FORMAT(b.CreateDate,'%y-%m-%d')>= DATE_FORMAT('{startDate}','%y-%m-%d') 
and  DATE_FORMAT(b.CreateDate,'%y-%m-%d')<DATE_FORMAT('{endDate}','%y-%m-%d') and b.OrderStatus in(2,3,4,5,6)  ");

                                Helper.LogHelper.Write("sql语句：" + builder.ToString());
                                var goodsDetailList = goodsOrderDetailRepository.Get<RB_Goods_OrderDetail_Extend>(builder.ToString()).ToList();

                                var result = new List<RB_Goods_OrderDetail_Extend>();

                                RB_Finance_Record_Extend record = new RB_Finance_Record_Extend();
                                record.MallBaseId = item.MallBaseId;
                                record.TenantId = item.TenantId;
                                record.Type = 1;
                                record.CreateDate = System.DateTime.Now;
                                record.RecordDetailList = new List<RB_Finance_RecordDetail>();
                                foreach (var orderGoodsItem in goodsDetailList)
                                {

                                    if (orderGoodsItem.Final_Price > 0)
                                    {
                                        var newOrderGoods = new RB_Goods_OrderDetail_Extend();
                                        newOrderGoods = orderGoodsItem;
                                        newOrderGoods.FinanceType = 1;
                                        result.Add(newOrderGoods);

                                    }
                                    if (orderGoodsItem.FreightMoney.HasValue && orderGoodsItem.FreightMoney.Value > 0)
                                    {
                                        var newOrderGoods = new RB_Goods_OrderDetail_Extend();
                                        newOrderGoods = orderGoodsItem;
                                        newOrderGoods.FinanceType = 2;
                                        result.Add(newOrderGoods);
                                    }


                                    RB_Finance_RecordDetail financeRecordDetail = new RB_Finance_RecordDetail
                                    {

                                        ID = 0,
                                        RecordId = 0,
                                        Type = record.Type,
                                        TenantId = record.TenantId,
                                        MallBaseId = record.MallBaseId,
                                        FinanceId = 0,
                                        CreateDate = record.CreateDate,
                                        Name = orderGoodsItem.GoodsName,
                                        OrderId = orderGoodsItem.OrderId ?? 0,
                                        OrderDetailId = orderGoodsItem.Id,
                                        GoodsPrice = ((orderGoodsItem.Final_Price ?? 0) - (orderGoodsItem.FreightMoney ?? 0)),
                                        FreightMoney = orderGoodsItem.FreightMoney,
                                        Unit_Price = orderGoodsItem.Unit_Price,
                                        Number = orderGoodsItem.Number
                                    };
                                    record.RecordDetailList.Add(financeRecordDetail);
                                }

                                var detailList = result.Select(x => new
                                {
                                    CostTypeId = x.FinanceType == 1 ? item.IncomeCostTypeId : item.FreightCostTypeId,
                                    Number = x.FinanceType == 1 ? x.Number : 1,
                                    OriginalMoney = x.FinanceType == 1 ? x.Unit_Price : x.FreightMoney,
                                    UnitPrice = x.FinanceType == 1 ? (((x.Final_Price ?? 0) - (x.FreightMoney ?? 0)) / (x.Number ?? 0)) : x.FreightMoney,
                                    Remark = x.GoodsName + x.OrderNo
                                });
                                var financeObj = new
                                {
                                    CreateBy = Config.NetworkDirector,
                                    item.IsPublic,
                                    BType = item.AccountType,
                                    AccountId = item.AccountId,
                                    WBMoney = result.Sum(x => x.Final_Price ?? 0),
                                    RB_Branch_Id = Config.RB_Branch_Id,
                                    RemitterName = item.RemitterName,
                                    TradeDate = System.DateTime.Now.ToString("yyyy-MM-dd"),
                                    AccountNumber = System.DateTime.Now.ToString("yyyyMMdd"),
                                    TemplateId = item.WorkFlowId,
                                    OrderSource = 16,
                                    Remark = System.DateTime.Now.ToString("yyyy年MM月dd日") + "自动生成财务单据",
                                    detailList,

                                };
                                string sign = EncryptionHelper.AesEncrypt(JsonHelper.Serialize(financeObj), Config.FinanceKey);
                                var resultInfo = new
                                {
                                    msg = sign,
                                };

                                string apiResult = Mall.Common.Plugin.HttpHelper.HttpPost(Config.IncomeFinanceApi, JsonHelper.Serialize(resultInfo), "");
                                JObject parmsJob = JObject.Parse(apiResult);
                                string resultCode = parmsJob.GetStringValue("resultCode");
                                int frid = parmsJob.GetInt("data", 0);
                                if (resultCode == "1" && frid > 0)//新增记录
                                {
                                    record.FinanceId = frid;
                                    int recordId = financeRecordRepository.Insert(record);
                                    Helper.LogHelper.Write("财务单据ID：" + frid + ",记录id：" + recordId + "订单数量：" + record.RecordDetailList.Count());
                                    record.RecordDetailList.ForEach(x => x.RecordId = recordId);
                                    record.RecordDetailList.ForEach(x => x.FinanceId = frid);
                                    flag = financeRecordDetailRepository.InsertBatch(record.RecordDetailList);
                                }

                                Helper.LogHelper.Write(apiResult);
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {

                Helper.LogHelper.Write(ex.Message);
            }

            return flag;
        }
        #endregion

        #region 成本

        #endregion

        #region 订单取消

        /// <summary>
        /// 自动取消订单
        /// </summary>
        /// <returns></returns>
        public static bool AutoCancelOrder()
        {
            try
            {
                var list = mallBaseRepository.GetListRepository(new Mall.Model.Extend.BaseSetUp.RB_MallBase_Extend() { });
                foreach (var item in list)
                {
                    if (item.CancelTime > 0)
                    {
                        //查询未付款的所有订单
                        var olist = goods_OrderRepository.GetCanCancelOrderList(item.CancelTime, item.TenantId, item.MallBaseId);
                        foreach (var qitem in olist)
                        {
                            try
                            {
                                Dictionary<string, object> keyValues = new Dictionary<string, object>() { };
                                keyValues.Add(nameof(RB_Goods_Order_Extend.OrderStatus), OrderStatusEnum.Cancel);
                                keyValues.Add(nameof(RB_Goods_Order_Extend.CancelTime), DateTime.Now);

                                List<WhereHelper> wheres = new List<WhereHelper>() {
                                new WhereHelper(){
                                     FiledName=nameof(RB_Goods_Order_Extend.OrderId),
                                      FiledValue=qitem.OrderId,
                                       OperatorEnum=OperatorEnum.Equal
                                },
                                new WhereHelper(){
                                     FiledName=nameof(RB_Goods_Order_Extend.UserId),
                                      FiledValue=qitem.UserId,
                                       OperatorEnum=OperatorEnum.Equal
                                },
                                new WhereHelper(){
                                     FiledName=nameof(RB_Goods_Order_Extend.TenantId),
                                      FiledValue=item.TenantId,
                                       OperatorEnum=OperatorEnum.Equal
                                },
                                new WhereHelper(){
                                     FiledName=nameof(RB_Goods_Order_Extend.MallBaseId),
                                      FiledValue=item.MallBaseId,
                                       OperatorEnum=OperatorEnum.Equal
                                }
                            };
                                bool flag = goods_OrderRepository.Update(keyValues, wheres);
                                if (flag)
                                {
                                    //回滚商品库存
                                    if (true)
                                    {
                                        int tenantId = item.TenantId;
                                        int mallBaseId = item.MallBaseId;
                                        int TotalIntegralNumber = 0;
                                        var detailList = goodsOrderDetailRepository.GetOrderDetailList(new RB_Goods_OrderDetail_Extend() { OrderId = qitem.OrderId, TenantId = tenantId, MallBaseId = mallBaseId });
                                        if (detailList.Any())
                                        {
                                            string goodsIds = string.Join(",", detailList.Select(x => x.GoodsId ?? 0).Distinct());
                                            var goodsList = goodsRepository.GetList(new RB_Goods_Extend() { GoodsIds = goodsIds, TenantId = tenantId, MallBaseId = mallBaseId });
                                            var speciPList = goods_SpecificationPriceRepository.GetList(new RB_Goods_SpecificationPrice_Extend() { GoodsIds = goodsIds, TenantId = tenantId, MallBaseId = mallBaseId });

                                            foreach (var ditem in detailList)
                                            {
                                                var gmodel = goodsList.Where(x => x.Id == ditem.GoodsId).FirstOrDefault();
                                                if (gmodel == null)
                                                {
                                                    continue;
                                                }
                                                if (string.IsNullOrEmpty(ditem.SpecificationSort))
                                                {
                                                    if (gmodel.IsCustomSpecification == 1)
                                                    {
                                                        continue;
                                                    }
                                                }
                                                else
                                                {
                                                    if (gmodel.IsCustomSpecification != 1)
                                                    {
                                                        continue;
                                                    }
                                                    var speciPModel = speciPList.Where(x => x.GoodsId == ditem.GoodsId && x.SpecificationSort == ditem.SpecificationSort).FirstOrDefault();
                                                    if (speciPModel == null)
                                                    {
                                                        continue;
                                                    }
                                                    //更新商品规格表库存 + 商品表总库存
                                                    Dictionary<string, object> keyValues2 = new Dictionary<string, object>() {
                                                    { nameof(RB_Goods_SpecificationPrice_Extend.InventoryNum), (speciPModel.InventoryNum??0)+(ditem.Number??0)}
                                                };
                                                    List<WhereHelper> wheres2 = new List<WhereHelper>() {
                                                    new WhereHelper(){
                                                            FiledName=nameof(RB_Goods_SpecificationPrice_Extend.Id),
                                                            FiledValue=speciPModel.Id,
                                                            OperatorEnum=OperatorEnum.Equal
                                                    }
                                                };
                                                    goods_SpecificationPriceRepository.Update(keyValues2, wheres2);
                                                }
                                                //更新商品表库存
                                                Dictionary<string, object> keyValues1 = new Dictionary<string, object>() {
                                                { nameof(RB_Goods_Extend.InventoryNum), (gmodel.InventoryNum??0)+(ditem.Number??0)}
                                            };
                                                List<WhereHelper> wheres1 = new List<WhereHelper>() {
                                                new WhereHelper(){
                                                        FiledName=nameof(RB_Goods_Extend.Id),
                                                        FiledValue=gmodel.Id,
                                                        OperatorEnum=OperatorEnum.Equal
                                                }
                                            };
                                                goodsRepository.Update(keyValues1, wheres1);
                                                goods_LogRepository.Insert(new Mall.Model.Entity.Product.RB_Goods_Log()
                                                {
                                                    Id = 0,
                                                    Type = 2,
                                                    SourceId = ditem.GoodsId,
                                                    Content = $"取消订单{qitem.OrderId}，还原商品库存:" + ditem.Number,
                                                    CreateDate = DateTime.Now,
                                                    MallBaseId = mallBaseId,
                                                    TenantId = tenantId
                                                });

                                                if (ditem.IntegralNumber > 0)
                                                {
                                                    TotalIntegralNumber += (ditem.IntegralNumber ?? 0);
                                                }
                                            }
                                        }
                                        var umodel = member_UserRepository.GetEntity(qitem.UserId);
                                        //积分抵扣回滚
                                        if (TotalIntegralNumber > 0)
                                        {
                                            Dictionary<string, object> keyValues1 = new Dictionary<string, object>() {
                                            { nameof(RB_Member_User_Extend.Integral),umodel.Integral + TotalIntegralNumber}
                                        };
                                            List<WhereHelper> wheres1 = new List<WhereHelper>() {
                                            new WhereHelper(){
                                                 FiledName=nameof(RB_Member_User_Extend.Id),
                                                  FiledValue=umodel.Id,
                                                   OperatorEnum=OperatorEnum.Equal
                                            }
                                        };
                                            bool flag2 = member_UserRepository.Update(keyValues1, wheres1);
                                            if (flag2)
                                            {
                                                member_IntegralRepository.Insert(new Mall.Model.Entity.User.RB_Member_Integral()
                                                {
                                                    Id = 0,
                                                    CreateDate = DateTime.Now,
                                                    Description = "订单取消返回积分抵扣，订单号：" + qitem.OrderNo,
                                                    Image = 0,
                                                    Integral = TotalIntegralNumber,
                                                    MallBaseId = item.MallBaseId,
                                                    PlatformType = qitem.OrderSource,
                                                    Remarks = "",
                                                    TenantId = item.TenantId,
                                                    Type = Common.Enum.MarketingCenter.RecordTypeEnum.Income,
                                                    UserId = qitem.UserId,
                                                    OrderId = qitem.OrderId
                                                });
                                            }
                                        }
                                        //优惠券回滚
                                        if (!string.IsNullOrEmpty(qitem.CouponsIds))
                                        {
                                            var cList = member_CouponRepository.GetList(new RB_Member_DiscountCoupon_Extend() { UseState = 1, Ids = qitem.CouponsIds, UserId = qitem.UserId, TenantId = item.TenantId, MallBaseId = item.MallBaseId });
                                            foreach (var citem in cList)
                                            {
                                                Dictionary<string, object> keyValues1 = new Dictionary<string, object>() {
                                                { nameof(RB_Member_DiscountCoupon_Extend.UseState),0}
                                            };
                                                List<WhereHelper> wheres1 = new List<WhereHelper>() {
                                                new WhereHelper(){
                                                     FiledName=nameof(RB_Member_DiscountCoupon_Extend.Id),
                                                      FiledValue=citem.Id,
                                                       OperatorEnum=OperatorEnum.Equal
                                                }
                                            };
                                                member_CouponRepository.Update(keyValues1, wheres1);
                                            }
                                        }
                                        //余额支付回滚

                                    }
                                    goods_LogRepository.Insert(new Mall.Model.Entity.Product.RB_Goods_Log()
                                    {
                                        Id = 0,
                                        Type = 1,
                                        SourceId = qitem.OrderId,
                                        Content = "订单超时，自动取消订单",
                                        CreateDate = DateTime.Now,
                                        MallBaseId = item.MallBaseId,
                                        TenantId = item.TenantId
                                    });
                                }
                            }
                            catch (Exception ex)
                            {
                                Helper.LogHelper.Write("AutoCancelOrder:" + ex.Message);
                                continue;
                            }
                        }
                    }
                }
                return true;
            }
            catch (Exception ex)
            {
                Helper.LogHelper.Write("AutoCancelOrder:" + ex.Message);
                return false;
            }
        }

        #endregion

        #region 自动收货

        /// <summary>
        /// 自动收货
        /// </summary>
        /// <returns></returns>
        public static bool AutoReceivingOrder()
        {
            try
            {
                var list = mallBaseRepository.GetListRepository(new Mall.Model.Extend.BaseSetUp.RB_MallBase_Extend() { });
                foreach (var item in list)
                {
                    if (item.AutoReceiving > 0)
                    {
                        //查询未付款的所有订单
                        var olist = goods_OrderRepository.GetCanReceivingOrderList(item.CancelTime, item.TenantId, item.MallBaseId);
                        foreach (var qitem in olist)
                        {
                            Dictionary<string, object> keyValues = new Dictionary<string, object>() { };
                            keyValues.Add(nameof(RB_Goods_Order_Extend.OrderStatus), OrderStatusEnum.Received);
                            keyValues.Add(nameof(RB_Goods_Order_Extend.ReceivingTime), DateTime.Now);

                            List<WhereHelper> wheres = new List<WhereHelper>() {
                            new WhereHelper(){
                                 FiledName=nameof(RB_Goods_Order_Extend.OrderId),
                                  FiledValue=qitem.OrderId,
                                   OperatorEnum=OperatorEnum.Equal
                            },
                            new WhereHelper(){
                                 FiledName=nameof(RB_Goods_Order_Extend.UserId),
                                  FiledValue=qitem.UserId,
                                   OperatorEnum=OperatorEnum.Equal
                            },
                            new WhereHelper(){
                                 FiledName=nameof(RB_Goods_Order_Extend.TenantId),
                                  FiledValue=item.TenantId,
                                   OperatorEnum=OperatorEnum.Equal
                            },
                            new WhereHelper(){
                                 FiledName=nameof(RB_Goods_Order_Extend.MallBaseId),
                                  FiledValue=item.MallBaseId,
                                   OperatorEnum=OperatorEnum.Equal
                            }
                        };
                            bool flag = goods_OrderRepository.Update(keyValues, wheres);
                            if (flag)
                            {

                                goods_LogRepository.Insert(new Mall.Model.Entity.Product.RB_Goods_Log()
                                {
                                    Id = 0,
                                    Type = 1,
                                    SourceId = qitem.OrderId,
                                    Content = "系统自动确认收货",
                                    CreateDate = DateTime.Now,
                                    MallBaseId = item.MallBaseId,
                                    TenantId = item.TenantId
                                });
                            }
                        }
                    }
                }
                return true;
            }
            catch (Exception ex)
            {
                Helper.LogHelper.Write("AutoCancelOrder:" + ex.Message);
                return false;
            }
        }

        #endregion

        #region 七天自动是否下线

        public static bool AutoReleaseTheOffline()
        {
            try
            {
                var list = mallBaseRepository.GetListRepository(new Mall.Model.Extend.BaseSetUp.RB_MallBase_Extend() { });
                foreach (var item in list)
                {
                    var ulist = member_UserRepository.AutoReleaseTheOffline(item.TenantId, item.MallBaseId);
                    foreach (var qitem in ulist)
                    {
                        Dictionary<string, object> keyValues = new Dictionary<string, object>() {
                            { nameof(RB_Member_User_Extend.SuperiorId),0},
                            { nameof(RB_Member_User_Extend.DownlineCondition),DistrbutorReferralsEnum.SCDJ},
                            { nameof(RB_Member_User_Extend.Remark),(qitem.Remark??"") +"  七天自动释放"},
                        };

                        List<WhereHelper> wheres = new List<WhereHelper>() {
                            new WhereHelper(){
                                 FiledName=nameof(RB_Member_User_Extend.Id),
                                  FiledValue=qitem.Id,
                                   OperatorEnum=OperatorEnum.Equal
                            },
                            new WhereHelper(){
                                 FiledName=nameof(RB_Goods_Order_Extend.TenantId),
                                  FiledValue=item.TenantId,
                                   OperatorEnum=OperatorEnum.Equal
                            },
                            new WhereHelper(){
                                 FiledName=nameof(RB_Goods_Order_Extend.MallBaseId),
                                  FiledValue=item.MallBaseId,
                                   OperatorEnum=OperatorEnum.Equal
                            }
                        };
                        member_UserRepository.Update(keyValues, wheres);
                    }
                }
                return true;
            }
            catch (Exception ex)
            {
                Helper.LogHelper.Write("AutoReleaseTheOffline:" + ex.Message);
                return false;
            }
        }

        #endregion

    }
}
