using Hncore.Infrastructure.Common;
using Hncore.Infrastructure.EntitiesExtension;
using Hncore.Infrastructure.Extension;
using Hncore.Infrastructure.WebApi;
using Hncore.Pass.BaseInfo.Service;
using Hncore.Pass.Vpn.Domain;
using Hncore.Pass.Vpn.Model;
using Hncore.Pass.Vpn.Request.Product;
using Hncore.Pass.Vpn.Service;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Threading.Tasks;
using BaseUserService = Hncore.Pass.BaseInfo.Service.UserService;
namespace Hncore.Pass.Vpn.Controllers
{
    [ApiVersion("1.0")]
    [Route("api/course/v{version:apiVersion}/order/[action]")]
    public class ProductOrderController : HncoreControllerBase
    {
        private ProductService m_ProductService;
        private ProductOrderService m_ProductOrderService;
        private BaseUserService m_BaseUserService;

        private ManageService m_ManageService;
        public ProductOrderController(ProductService _ProductServic
              , ProductOrderService _ProductOrderService
            , BaseUserService _BaseUserService
            , ManageService _ManageService)
        {
            m_ProductService = _ProductServic;         
            m_ProductOrderService = _ProductOrderService;      
            m_BaseUserService=_BaseUserService;
            m_ManageService = _ManageService;
    }

        /// <summary>
        /// 详情
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [HttpGet]
        public async Task<ApiResult> Get([FromQuery]int id)
        {
            var data = await m_ProductService.GetById(id);
            return Success(data);
        }

        /// <summary>
        /// 分页查询
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [HttpGet]
        public async Task<ApiResult> Page([FromQuery]OrderQueryRequest request)
        {
            Expression<Func<ProductOrderEntity, bool>> expr = m =>( m.OrderState == OrderStatus.PayOk || m.OrderState == OrderStatus.Complete) && m.OrderType != OrderType.Refund;
            if (request.KeyWord.Has())
            {               
                expr = expr.And(m =>
                  m.ProductName.Contains(request.KeyWord)
                ||m.Accounts.Contains(request.KeyWord)               
                ||m.OrderNo.Contains(request.KeyWord)
                ||m.UserName.Contains(request.KeyWord)
                ||m.PackageName.Contains(request.KeyWord));
            }
            if (request.ProductIds != null && request.ProductIds.Count > 0)
            {
                expr = expr.And(m =>request.ProductIds.Contains((int)m.ProductId));
            }
            if (request.PackageNames != null && request.PackageNames.Count > 0)
            {
                expr = expr.And(m =>request.PackageNames.Contains((string)m.PackageName));
            }
            if (request.OrderTypes != null && request.OrderTypes.Count > 0)
            {
                expr = expr.And(m => request.OrderTypes.Contains((int)m.OrderType));
            }
            if (request.BTime.HasValue && request.ETime.HasValue)
            {
                expr = expr.And(m => m.UpdateTime >= request.BTime && m.UpdateTime <= request.ETime);
            }
            var ret = await m_ProductOrderService.PageDesc(request.PageIndex, request.PageSize, expr, true,m=>m.CreateTime);

            // ret.List.ForEach(
            //     m => {m.UserName = m.UserName.Substring(0,3) + "***";
            // });

            var data = ret.ToApiResult();
            return data;
        }

        [HttpGet]
        public ApiResult Statistics([FromQuery]OrderQueryRequest request)
        {
            var ret = m_ProductOrderService.Statistics(request.BTime, request.ETime, Convert.ToInt32(request.ProductId));
            return Success(ret);
        }


        [HttpGet]
        public ApiResult SellerStatistics([FromQuery]OrderQueryRequest request)
        {
            var ret = m_ProductOrderService.SellerStatistics(request.BTime, request.ETime,request.Channel);
            return Success(ret);
        }


        [HttpGet]
        public async Task<ApiResult> UserConsumeStatistics([FromQuery]UserConsumeRequest request)
        {
          
            var loginInfo = this.Request.GetManageUserInfo();
            int id = loginInfo.OperaterId;
            var managerInfo =await m_ManageService.GetById(loginInfo.OperaterId);
            if (managerInfo.IsRoot == 1) id = 0;
            var ret = m_ProductOrderService.UserConsumeStatistics(request.PageIndex, request.PageSize, request.KeyWord, request.bTime1, request.eTime1, request.bTime2, request.eTime2, id, request.SortLable, request.SortOrder,request.Profile);
            return ret.ToApiResult();
        }

        [HttpGet]
        public async Task<ApiResult> RefundOrders([FromQuery]OrderQueryRequest request)
        {
            Expression<Func<ProductOrderEntity, bool>> expr = m => m.OrderType == OrderType.Refund;
            if (request.KeyWord.Has())
            {
                expr = expr.And(m => m.Accounts.Contains(request.KeyWord)
                || m.OrderNo.Contains(request.KeyWord)
                || m.UserName.Contains(request.KeyWord)
                || m.PackageName.Contains(request.KeyWord));
            }
            if (request.ProductId.HasValue)
            {
                expr = expr.And(m => m.ProductId == request.ProductId);
            }
            if (request.OrderTypes != null && request.OrderTypes.Count > 0)
            {
                expr = expr.And(m => request.OrderTypes.Contains((int)m.OrderType));
            }
            if (request.BTime.HasValue && request.ETime.HasValue)
            {
                expr = expr.And(m => m.UpdateTime >= request.BTime && m.UpdateTime <= request.ETime);
            }
            var ret = await m_ProductOrderService.PageDesc(request.PageIndex, request.PageSize, expr, true,m=>m.Id);
           // ret.List.ForEach(
            //    m => {m.UserName = m.UserName.Substring(0,3) + "***";
            //});
            var data = ret.ToApiResult();
            return data;
        }

        [HttpGet,AllowAnonymous]
        public async Task<ApiResult> OpenRefundOrders([FromQuery]RefundOrderQueryRequest request)
        {
            // Expression<Func<ProductOrderEntity, bool>> expr = m => m.OrderType == OrderType.Refund;
            // if (request.KeyWord.Has())
            // {
            //     expr = expr.And(m => m.Accounts.Contains(request.KeyWord)
            //     || m.OrderNo.Contains(request.KeyWord)
            //     || m.UserName.Contains(request.KeyWord)
            //     || m.PackageName.Contains(request.KeyWord));
            // }
            // if (request.ProductIds!=null&& request.ProductIds.Count>0)
            // {
            //     expr = expr.And(m => request.ProductIds.Contains(m.ProductId));
            // }

            // if (request.BTime.HasValue && request.ETime.HasValue)
            // {
            //     expr = expr.And(m => m.UpdateTime > request.BTime && m.UpdateTime < request.ETime);
            // }

            // var ret = await m_ProductOrderService.PageDesc(request.PageIndex, request.PageSize, expr, true, m => m.Id);
            // var data = ret.ToApiResult();
            return null;
        }





        [UserAuth]
        public async Task<ApiResult> CreateOrder(CreateOrderRequest request)
        {
            var userInfo = this.Request.GetUserInfo();            
            var ret = await m_ProductOrderService.CreateOrder(request, userInfo.UserId);
            if (ret.Code != ResultCode.C_SUCCESS)
            {
                return ret;
            }         
            return Success();
        }

        [UserAuth]
        public async Task<ApiResult> Refund(string account)
        {
            var userInfo = this.Request.GetUserInfo();
            return await m_ProductOrderService.Refund(userInfo.UserId, account);
        }

        [UserAuth]
        public async Task<ApiResult> CaclRefund(string account)
        {
            var userInfo = this.Request.GetUserInfo();
            return await m_ProductOrderService.CaclRefund(userInfo.UserId, account);
        }


        ///// <summary>
        ///// 支付(微信公众号、小程序支付,创建流水记录。)
        ///// </summary>
        ///// <param name="param"></param>
        ///// <returns></returns>
        //[HttpPost, UserAuth]
        //public async Task<ApiResult> CreatePayOrder([FromBody] CreateOrderRequest request)
        //{

        //    var userInfo = this.Request.GetUserInfo();
        //    var ret = await m_ProductOrderService.CreateOrder(request, userInfo.UserId);
        //    if (ret.Code != ResultCode.C_SUCCESS)
        //    {
        //        return ret;
        //    }      
        //    var req = new PayRequest()
        //    {
        //        OrderNO = ret.Data.OrderNo,
        //        PayEnvironment = request.PayEnvironment,
        //        PaymentType = request.PaymentType
        //    };

        //    return await CreatePaymentOrder(req, ret.Data, userInfo);
        //}

        //[UserAuth]
        //public async Task<ApiResult> Pay(PayRequest request)
        //{
        //    var order = await m_CourseOrderService.GetByOrderNo(request.OrderNO);
        //    var userInfo = this.Request.GetUserInfo();
        //    return await CreatePaymentOrder(request, order, userInfo);
        //}


        /// <summary>
        /// 支付部分
        /// </summary>
        /// <param name="param"></param>
        /// <param name="UserInfo"></param>
        /// <param name="OpenId"></param>
        /// <returns></returns>
        //private async Task<ApiResult> CreatePaymentOrder(PayRequest request, ProductOrderEntity orderData, AppUserInfo UserInfo)
        //{
        //    string callBackUrl = $"{m_Configuration["Service_BaseUrl"]}/api/courseOrder/v1/WxOrderCallBack?orderId={orderData.OrderNo}&payType={(int)request.PaymentType}";
        //    string attach = orderData.ToJson();
        //    decimal payAmount = orderData.OrderAmount * 100.0M;
        //    string orderDesc = "购买课程支付";
        //    var resp = new CreatePaymentOrderResponse<CourseOrderEntity>()
        //    {
        //        OrderInfo = orderData
        //    };
        //    var weChatPayRequest = new WechatJsPayCreateOrderRequest()
        //    {
        //        Attach = attach,
        //        Body = orderDesc,
        //        CallbackUrl = callBackUrl + "&paymentType=" + (int)Payment.Enum.PaymentType.OnlinePayWechart,
        //        OrderId = orderData.OrderNo,
        //        OrderType = orderData.OrderType,
        //        TenantId = orderData.TenantId,
        //        PayEnvironment = request.PayEnvironment,
        //        PaymentType = request.PaymentType,
        //        TotalFee = Convert.ToInt32(payAmount),
        //        UserOpenId = UserInfo.OpenId,
        //        AppId = UserInfo.AppId,
        //        StoreId = UserInfo.StoreId
        //    };

        //    var wechatJsPayResp = await m_ServiceHttpClient.WechatJsPayCreateOrder(weChatPayRequest);
        //    if (wechatJsPayResp.Code == ResultCode.C_SUCCESS)
        //    {
        //        try
        //        {
        //            //{"tradeNO":"2019102522001433001406080254","status":"0"}
        //            var payOrderInfo = wechatJsPayResp.Data.ToString().FromJsonToOrDefault<WxPayOrderInfo>();

        //            if (payOrderInfo != null && payOrderInfo.package.Has())
        //            {
        //                string[] tmp2param = payOrderInfo.package.Split('=');
        //                if (tmp2param != null && tmp2param.Length == 2)
        //                {
        //                    orderData.TradeNo = tmp2param[1];
        //                    await m_CourseOrderService.Update(orderData);
        //                }
        //            }
        //            resp.PayInfo = wechatJsPayResp.Data.ToString();
        //            return Success(resp);
        //        }
        //        catch (Exception ex)
        //        {
        //            LogHelper.Error("课程支付获取微信支付订单信息转换出错：" + ex.Message, ex);
        //            return new ApiResult(ResultCode.C_UNKNOWN_ERROR, "交易失败");
        //        }
        //    }
        //    return new ApiResult(ResultCode.C_UNKNOWN_ERROR, wechatJsPayResp.Message);
        //}

        //[InternalApiAuth]
        //public async Task<string> WxOrderCallBack([FromQuery]string orderId = "", [FromQuery] int paymentType = 0)
        //{
        //    if (string.IsNullOrWhiteSpace(orderId) || paymentType <= 0)
        //    {
        //        return "faild";
        //    }
        //    var order = await m_CourseOrderService.GetByOrderNo(orderId);
        //    if (order == null)
        //        return "faild";

        //    order.OrderState = OrderStatus.PayOk;
        //    order.PayType = paymentType;
        //    await m_CourseOrderService.Update(order);
        //    return "faild";
        //}

        [HttpGet]
        public async Task<IActionResult> Export([FromQuery]OrderQueryRequest request)
        {
            Expression<Func<ProductOrderEntity, bool>> expr = m =>( m.OrderState == OrderStatus.PayOk || m.OrderState == OrderStatus.Complete) && m.OrderType != OrderType.Refund;
            if (request.KeyWord.Has())
            {               
                expr = expr.And(m =>
                  m.ProductName.Contains(request.KeyWord)
                ||m.Accounts.Contains(request.KeyWord)               
                ||m.OrderNo.Contains(request.KeyWord)
                ||m.UserName.Contains(request.KeyWord)
                ||m.PackageName.Contains(request.KeyWord));
            }

            if (request.ProductId != null)
            {
                expr = expr.And(m =>request.ProductId == m.ProductId);
            }
            if (request.PackageNames != null && request.PackageNames.Count > 0)
            {
                expr = expr.And(m =>request.PackageNames.Contains((string)m.PackageName));
            }
            if (request.OrderTypes != null && request.OrderTypes.Count > 0)
            {
                expr = expr.And(m => request.OrderTypes.Contains((int)m.OrderType));
            }
            if (request.BTime.HasValue && request.ETime.HasValue)
            {
                expr = expr.And(m => m.UpdateTime >= request.BTime && m.UpdateTime <= request.ETime);
            }
            var ret = await m_ProductOrderService.PageDesc(request.PageIndex, 10000, expr, true,m=>m.Id);


            var data = new ExcelData<ProductOrderEntity>
            {
                SheetName = DateTime.Now.ToString("yyyy-MM-dd"),
                Data = ret.List
            };

            var title = new List<ExcelTitle>(){
                    new ExcelTitle { Property = "UpdateTime", Title = "支付日期" , Format=(val)=>((DateTime) val).ToString("yyyy-MM-dd HH:mm:ss")  },
                    new ExcelTitle { Property = "OrderNo", Title = "订单号" },
                    new ExcelTitle { Property = "OrderType", Title = "类型", Format=(val)=>((OrderType)val).GetEnumDisplayName() },
                    new ExcelTitle { Property = "UserName", Title = "用户" },
                    new ExcelTitle { Property = "ProductName", Title = "产品" },
                    new ExcelTitle { Property = "PackageName", Title = "套餐" },
                    new ExcelTitle { Property = "DayPrice", Title = "单价" },
                    new ExcelTitle { Property = "ConnectCount", Title = "连接数",Expr=(p)=>((ProductOrderEntity)p).ConnectCount*((ProductOrderEntity)p).AccountCount},
                    new ExcelTitle { Property = "Accounts", Title = "账号" },
                    new ExcelTitle { Property = "OrderAmount", Title = "订单金额" },
                    new ExcelTitle { Property = "CouponAmount", Title = "优惠金额" },
                    new ExcelTitle { Property = "AccountPayAmount", Title = "余额支付" },
                    new ExcelTitle { Property = "OtherPayAmount", Title = "在线支付" },
                    new ExcelTitle { Property = "PaymentAmount", Title = "实付" },
                    new ExcelTitle { Property = "PayType", Title = "付款方式" , Format=(val)=>((PayType)val).GetEnumDisplayName() },
                    new ExcelTitle { Property = "TradeNo", Title = "支付流水号" },
                    new ExcelTitle { Property = "Remark", Title = "备注" },
                };
            var fileBytes = ExcelHelper.ExportListToExcel(data, title);

            var fileName = $"{DateTime.Now.ToString("yyyyMMdd")}订单明细.xlsx";
            Response.Headers.Add("X-Suggested-Filename", fileName.UrlEncode());
            return File(fileBytes, "application/octet-stream", fileName);

        }

        [HttpGet]
        public async Task<IActionResult> ExportRefundOrders([FromQuery]OrderQueryRequest request)
        {
            Expression<Func<ProductOrderEntity, bool>> expr = m => m.OrderType == OrderType.Refund;
            if (request.KeyWord.Has())
            {
                expr = expr.And(m =>
                    m.OrderName.Contains(request.KeyWord)
                 || m.OrderNo.Contains(request.KeyWord)
                 || m.UserName.Contains(request.KeyWord)
                 || m.PackageName.Contains(request.KeyWord));
            }
            if (request.OrderTypes != null && request.OrderTypes.Count > 0)
            {
                expr = expr.And(m => request.OrderTypes.Contains((int)m.OrderType));
            }
            if (request.BTime.HasValue && request.ETime.HasValue)
            {
                expr = expr.And(m => m.UpdateTime >= request.BTime && m.UpdateTime <= request.ETime);
            }
            var ret = await m_ProductOrderService.Page(request.PageIndex, 50000, expr, true);


            var data = new ExcelData<ProductOrderEntity>
            {
                SheetName = DateTime.Now.ToString("yyyy-MM-dd"),
                Data = ret.List
            };


            Func<ProductOrderEntity, object> refundTypeFormat = (order) =>
               {
                   switch (order.OrderState)
                   {
                       case OrderStatus.RequestRefund:
                           return "未自动退款";
                       case OrderStatus.UserRefundOver:
                           return "已人工处理";
                       case OrderStatus.AutoRefundOver:
                           return "已自动退款";
                       default:
                           return "";
                   }
               };

            var title = new List<ExcelTitle>(){
                    new ExcelTitle { Property = "CreateTime", Title = "创建日期" ,Format=(val)=>((DateTime) val).ToString("yyyy-MM-dd hh:mm:ss") },
                    //new ExcelTitle { Property = "OrderNo", Title = "订单号" },
                   // new ExcelTitle { Property = "OrderType", Title = "类型", Format=(val)=>((OrderType)val).GetEnumDisplayName() },
                   new ExcelTitle { Property = "UserName", Title = "用户" },
                    new ExcelTitle { Property = "ProductName", Title = "产品" },
                    new ExcelTitle { Property = "PackageName", Title = "套餐" },
                    new ExcelTitle { Property = "ConnectCount", Title = "连接数",Expr=(p)=>((ProductOrderEntity)p).ConnectCount*((ProductOrderEntity)p).AccountCount},
                    new ExcelTitle { Property = "Accounts", Title = "账号" },
                    new ExcelTitle { Property = "PaymentAmount", Title = "实付金额" },
                    new ExcelTitle { Property = "RefundAmount", Title = "退款金额" },
                    new ExcelTitle { Property = "RefundRestTime", Title = "剩余时间" },
                    new ExcelTitle { Property = "BackAmount", Title = "返点" },
                    new ExcelTitle { Property = "RefundRestTime", Title = "自动退款",Expr=(p)=>((ProductOrderEntity)p).IsAutoRefund.HasValue&&((ProductOrderEntity)p).IsAutoRefund==1?"是":"否" },                 
                    new ExcelTitle { Property = "RefundRestTime", Title = "退款状态",Expr=(p)=>refundTypeFormat((ProductOrderEntity)p) },

                };
            var fileBytes = ExcelHelper.ExportListToExcel(data, title);

            var fileName = $"{DateTime.Now.ToString("yyyyMMdd")}退款明细.xlsx";
            Response.Headers.Add("X-Suggested-Filename", fileName.UrlEncode());
            return File(fileBytes, "application/octet-stream", fileName);

        }


        [HttpGet,AllowAnonymous]
        public async Task<IActionResult> OpenExportRefundOrders([FromQuery]OrderQueryRequest request)
        {
            Expression<Func<ProductOrderEntity, bool>> expr = m => m.OrderType == OrderType.Refund;
            if (request.KeyWord.Has())
            {
                expr = expr.And(m =>
                    m.OrderName.Contains(request.KeyWord)
                 || m.OrderNo.Contains(request.KeyWord)
                 || m.UserName.Contains(request.KeyWord)
                 || m.PackageName.Contains(request.KeyWord));
            }
            if (request.OrderTypes != null && request.OrderTypes.Count > 0)
            {
                expr = expr.And(m => request.OrderTypes.Contains((int)m.OrderType));
            }
            if (request.BTime.HasValue && request.ETime.HasValue)
            {
                expr = expr.And(m => m.UpdateTime >= request.BTime && m.UpdateTime <= request.ETime);
            }
            var ret = await m_ProductOrderService.Page(request.PageIndex, 10000, expr, true);


            var data = new ExcelData<ProductOrderEntity>
            {
                SheetName = DateTime.Now.ToString("yyyy-MM-dd"),
                Data = ret.List
            };


            Func<ProductOrderEntity, object> refundTypeFormat = (order) =>
            {
                switch (order.OrderState)
                {
                    case OrderStatus.RequestRefund:
                        return "未自动退款";
                    case OrderStatus.UserRefundOver:
                        return "已人工处理";
                    case OrderStatus.AutoRefundOver:
                        return "已自动退款";
                    default:
                        return "";
                }
            };

            var title = new List<ExcelTitle>(){
                    new ExcelTitle { Property = "CreateTime", Title = "创建日期" ,Format=(val)=>((DateTime) val).ToString("yyyy-MM-dd hh:mm:ss") },
                    //new ExcelTitle { Property = "OrderNo", Title = "订单号" },
                    //new ExcelTitle { Property = "OrderType", Title = "类型", Format=(val)=>((OrderType)val).GetEnumDisplayName() },
                    //new ExcelTitle { Property = "UserName", Title = "用户" },
                    new ExcelTitle { Property = "ProductName", Title = "产品" },
                    new ExcelTitle { Property = "PackageName", Title = "套餐" },
                    new ExcelTitle { Property = "ConnectCount", Title = "连接数",Expr=(p)=>((ProductOrderEntity)p).ConnectCount*((ProductOrderEntity)p).AccountCount},
                    new ExcelTitle { Property = "Accounts", Title = "账号" },
                    new ExcelTitle { Property = "RefundRestTime", Title = "剩余时间" }     
                };
            var fileBytes = ExcelHelper.ExportListToExcel(data, title);

            var fileName = $"{DateTime.Now.ToString("yyyyMMdd")}退款明细.xlsx";
            Response.Headers.Add("X-Suggested-Filename", fileName.UrlEncode());
            return File(fileBytes, "application/octet-stream", fileName);

        }

        [HttpPost]
        public async Task<ApiResult> RefundProcess([FromBody]RefundProcessRequest request)
        {
           var entity=await m_ProductOrderService.GetById(request.Id);
            if (entity.OrderState != OrderStatus.RequestRefund)
            {
                return Error("无需处理");
            }
            entity.Remark += request.Remark;
            entity.OrderState = OrderStatus.UserRefundOver;          
            await m_ProductOrderService.Update(entity);
            return Success();
        }

        [HttpGet]
        public async Task<ApiResult> CouponOrders([FromQuery] CouponOrderQueryRequest request)
        {
            var data = await this.m_ProductOrderService
                 .Query(m => m.CouponId == request.CouponId
                  && m.OrderState == OrderStatus.Complete)
                 .ListPagerAsync(request.PageSize, request.PageIndex, true);
            return data.ToApiResult();
        }

        [HttpGet]
        public async Task<ApiResult> TakeOrder([FromQuery]string phone, [FromQuery] decimal amount)
        {
            var manager = this.Request.GetManageUserInfo();

            var datas = await this.m_ProductOrderService
                .Query(m => m.UserName == phone
                 && m.OrderState == OrderStatus.Complete
                 && m.OrderAmount == amount
                 && string.IsNullOrEmpty(m.Channel))
                .OrderByDescending(m => m.Id)
                .ToListAsync();
            var data = datas.Where(m => (DateTime.Now - m.UpdateTime).TotalMinutes < 60).FirstOrDefault();
            if (data != null)
            {
                data.Channel = manager.LoginName;
                await m_ProductOrderService.Update(data);
                return Success();
            }
            return Error("没有订单");
        }


        [HttpGet]
        public async Task<ApiResult> SellerOrders([FromQuery]OrderQueryRequest request)
        {
            var manager = this.Request.GetManageUserInfo();

            var managerEntity = await m_ManageService.GetById(manager.OperaterId);
            Expression<Func<ProductOrderEntity, bool>> expr = m => !string.IsNullOrEmpty(m.Channel);
            if (managerEntity != null && managerEntity.IsRoot == 0)
            {
                expr = m => m.Channel == manager.LoginName;
            }
           
            if (request.KeyWord.Has())
            {               
                expr = expr.And(m => m.Accounts.Contains(request.KeyWord)|| m.OrderNo.Contains(request.KeyWord)|| m.UserName.Contains(request.KeyWord));                        
            }
            if (request.ProductId.HasValue)
            {
                expr = expr.And(m => m.ProductId == request.ProductId);
            }
            if (request.OrderTypes != null && request.OrderTypes.Count > 0)
            {
                expr = expr.And(m => request.OrderTypes.Contains((int)m.OrderType));
            }
            if (request.BTime.HasValue && request.ETime.HasValue)
            {
                expr = expr.And(m => m.UpdateTime >= request.BTime && m.UpdateTime <= request.ETime);
            }

            var ret = await this.m_ProductOrderService.PageDesc(request.PageIndex, request.PageSize, expr, true, m => m.Id);
            // ret.List.ForEach(
            //     m => {m.UserName = m.UserName.Substring(0,3) + "***";
            // });
            return ret.ToApiResult();
        }

        [HttpGet]
        public async Task<IActionResult> ExportSellerOrders([FromQuery]OrderQueryRequest request)
        {
            var manager = this.Request.GetManageUserInfo();

            var managerEntity = await m_ManageService.GetById(manager.OperaterId);
            Expression<Func<ProductOrderEntity, bool>> expr = m => !string.IsNullOrEmpty(m.Channel);
            if (managerEntity != null && managerEntity.IsRoot == 0)
            {
                expr = m => m.Channel == manager.LoginName;
            }

            if (request.KeyWord.Has())
            {
                expr = expr.And(m => m.Accounts.Contains(request.KeyWord) || m.OrderNo.Contains(request.KeyWord) || m.UserName.Contains(request.KeyWord));
            }
            if (request.ProductId.HasValue)
            {
                expr = expr.And(m => m.ProductId == request.ProductId);
            }
            if (request.OrderTypes != null && request.OrderTypes.Count > 0)
            {
                expr = expr.And(m => request.OrderTypes.Contains((int)m.OrderType));
            }
            if (request.BTime.HasValue && request.ETime.HasValue)
            {
                expr = expr.And(m => m.UpdateTime >= request.BTime && m.UpdateTime <= request.ETime);
            }

            var ret = await this.m_ProductOrderService.PageDesc(request.PageIndex,10000, expr, true, m => m.Id);

            var data = new ExcelData<ProductOrderEntity>
            {
                SheetName = DateTime.Now.ToString("yyyy-MM-dd"),
                Data = ret.List
            };


            Func<ProductOrderEntity, object> refundTypeFormat = (order) =>
            {
                switch (order.OrderState)
                {
                    case OrderStatus.RequestRefund:
                        return "未自动退款";
                    case OrderStatus.UserRefundOver:
                        return "已人工处理";
                    case OrderStatus.AutoRefundOver:
                        return "已自动退款";
                    default:
                        return "";
                }
            };

            var title = new List<ExcelTitle>(){
                    new ExcelTitle { Property = "CreateTime", Title = "创建日期" ,Format=(val)=>((DateTime) val).ToString("yyyy-MM-dd HH:mm:ss") },
                    new ExcelTitle { Property = "OrderNo", Title = "订单号" },
                    new ExcelTitle { Property = "OrderType", Title = "类型", Format=(val)=>((OrderType)val).GetEnumDisplayName() },
                    new ExcelTitle { Property = "UserName", Title = "用户" },
                    new ExcelTitle { Property = "ProductName", Title = "产品" },
                    new ExcelTitle { Property = "PackageName", Title = "套餐" },
                    new ExcelTitle { Property = "ConnectCount", Title = "连接数",Expr=(p)=>((ProductOrderEntity)p).ConnectCount*((ProductOrderEntity)p).AccountCount},
                    new ExcelTitle { Property = "DayPrice", Title = "单价" },
                    new ExcelTitle { Property = "Accounts", Title = "账号" },
                    new ExcelTitle { Property = "OrderAmount", Title = "订单金额" },
                    new ExcelTitle { Property = "CouponAmount", Title = "优惠金额" },
                    new ExcelTitle { Property = "AccountPayAmount", Title = "余额支付" },
                    new ExcelTitle { Property = "OtherPayAmount", Title = "在线支付" },
                    new ExcelTitle { Property = "PaymentAmount", Title = "实付" },
                    new ExcelTitle { Property = "PayType", Title = "付款方式", Format=(val)=>((PayType)val).GetEnumDisplayName() },
                    new ExcelTitle { Property = "PaymentAmount", Title = "支付流水号" },
                    new ExcelTitle { Property = "Channel", Title = "销售人" },

                };
            var fileBytes = ExcelHelper.ExportListToExcel(data, title);

            var fileName = $"{DateTime.Now.ToString("yyyyMMdd")}销售明细.xlsx";
            Response.Headers.Add("X-Suggested-Filename", fileName.UrlEncode());
            return File(fileBytes, "application/octet-stream", fileName);
        }

        public async Task<ApiResult> UserCountStatistics(DateTime? bTime, DateTime? eTime)
        {

            var manager = this.Request.GetManageUserInfo();

            var managerInfo = await m_ManageService.GetById(manager.OperaterId);

            var countInfo = m_ProductOrderService.UserCountStatistics(bTime, eTime);

            var totalCountInfo = m_ProductOrderService.UserCountStatistics(null, null);

            var amountInfo = m_ProductOrderService.SellAmountStatistics(bTime, eTime);

            var query = from count in totalCountInfo
                        join amount in amountInfo on count.RealName equals amount.RealName
                        join newCount in countInfo on count.RealName equals newCount.RealName
                        select new ManagerSellStatisticModel { RealName = count.RealName, Amount = amount.Amount, UserCount = count.UserCount, NewUserCount = newCount.UserCount };


            if (managerInfo.IsRoot != 1)
            {
                query = query.Where(m => m.RealName == managerInfo.RealName);
            }

            var totalOrderAmount = m_ProductOrderService.Query(true).Where(m => m.OrderState == OrderStatus.PayOk || m.OrderState == OrderStatus.Complete).Sum(m => m.OrderAmount);

            var totalUser = m_BaseUserService.Query(true).Count();

            var ret = new
            {
                OrderAmount = totalOrderAmount,
                UserTotal = totalUser,
                List = query.ToList()
            };

            return Success(ret);

        }

        [HttpGet]
        public async Task<IActionResult> ExportUserConsumeStatistics([FromQuery]UserConsumeRequest request)
        {

            var loginInfo = this.Request.GetManageUserInfo();
            int id = loginInfo.OperaterId;
            var managerInfo = await m_ManageService.GetById(loginInfo.OperaterId);
            if (managerInfo.IsRoot == 1) id = 0;
            var ret = m_ProductOrderService.ExportUserConsumeStatisticsData(request.KeyWord, request.bTime1, request.eTime1, request.bTime2, request.eTime2, id, request.SortLable, request.SortOrder, request.Profile);


            var data = new ExcelData<UserConsumeStatisticsModel>
            {
                SheetName = DateTime.Now.ToString("yyyy-MM-dd"),
                Data = ret
            };

            var title = new List<ExcelTitle>(){
                    new ExcelTitle { Property = "Profile", Title = "状态" , Expr=(p)=>((UserConsumeStatisticsModel)p).UserInfo.Profile},
                    new ExcelTitle { Property = "UserName", Title = "用户" },
                    new ExcelTitle { Property = "CreateTime", Title = "注册时间", Format=(val)=>((DateTime)val).ToString("yyyy-MM-dd") },
                    new ExcelTitle { Property = "PrevMonthAmount", Title = "消费金额A" },
                    new ExcelTitle { Property = "MonthAmount", Title = "消费金额B" },
                    new ExcelTitle { Property = "AddAmount", Title = "对比增长金额" },
                    new ExcelTitle { Property = "TotalAccountCount", Title = "账户总数" },                  
                    new ExcelTitle { Property = "UsingAccountCount", Title = "过期个数" },
                    new ExcelTitle { Property = "UserName", Title = "联系信息" , Expr=(p)=>{
                      var user=((UserConsumeStatisticsModel)p).UserInfo;
                      var subret=new List<string>();
                      if(user.Wx.Has()) subret.Add($"微信:{user.Wx}");
                      if(user.QQ.Has()) subret.Add($"QQ:{user.QQ}");
                      if(user.Wx.Has()) subret.Add($"淘宝:{user.TaoBao}");
                      if(user.Wx.Has()) subret.Add($"旺旺:{user.WangWang}");
                      return string.Join(",",subret);
                    } }
                };
            var fileBytes = ExcelHelper.ExportListToExcel(data, title);

            var fileName = $"{DateTime.Now.ToString("yyyyMMdd")}消费统计.xlsx";
            Response.Headers.Add("X-Suggested-Filename", fileName.UrlEncode());
            return File(fileBytes, "application/octet-stream", fileName);

        }

    }
}
