using CrazyStudio.Core.Common.Eitities.Page;
using Org.BouncyCastle.Asn1.X9;
using SqlSugar;
using SqlSugar.SplitTableExtensions;
using System;
using System.Collections.Generic;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using XPrintServer.Business.Enums;
using XPrintServer.Business.Services.Interface;
using XPrintServer.DataModel;
using XPrintServer.DataModel.Models;

namespace XPrintServer.Business.Services
{
    public class OrderInfoService : SqlSugarRepository<Order>, IBusinessService
    {
        public OrderInfoService(ConnectionConfig config) : base(config)
        {
        }

        public async Task AddOrderInfos(List<OrderInfo> orderInfos)
        {
            if (orderInfos.Any())
            {
                for (int i = 0; i < orderInfos.Count; i++)
                {
                    orderInfos[i].CreateTime = DateTime.Now;
                }
                await Context.Insertable(orderInfos).SplitTable().ExecuteCommandAsync().ConfigureAwait(false);
            }
        }

        public ISugarQueryable<T> SplitTableForTime<T>(ISugarQueryable<T> query, DateTime? startTime = null, DateTime? endTime = null)
        {
            if (startTime == null)
            {
                query = query.SplitTable();
                //.OrderBy(m => m.Id)
            }
            else if (startTime != null)
            {
                if (endTime == null)
                {
                    endTime = DateTime.Now;
                }
                query = query.SplitTable(startTime.Value, endTime.Value);
                //.OrderBy(m => m.Id)
            }
            else
            {
                query = query.SplitTable();
            }
            return query;
        }

        public async Task<PageResult<OrderInfo>> GetOrderInfoListForTime(PageOrderStatusData pageData, DateTime? startTime = null, DateTime? endTime = null)
        {
            var infoQuery = Context.Queryable<OrderInfo>();
            infoQuery = SplitTableForTime(infoQuery);


            //var orderQuery = Context.Queryable<Order>().WhereIF(pageData.Status != OrderStatus.None, (order) => order.OrderStatus == (int)pageData.Status);
            //orderQuery = SplitTableForTime(orderQuery);

            //infoQuery = infoQuery.InnerJoin(orderQuery, (info, order) => info.OrderId == order.Id);


            var infoList = await infoQuery!

                .WhereIF(pageData.StartTime != null, i => i.SubmitTime >= pageData.StartTime)
                .WhereIF(pageData.EndTime != null, i => i.SubmitTime <= pageData.EndTime)
                .Where(i => i.ResourceStatus != (int)ResourceStatus.Delete)

                .Select(info => info).OrderByDescending(info => info.SubmitTime).ToPageListAsync(pageData.Page, pageData.PageSize).ConfigureAwait(false);
            return new PageResult<OrderInfo>
            {
                Data = infoList,
                PageSize = pageData.PageSize,
                Total = await infoQuery!.Select(info => info).CountAsync().ConfigureAwait(false)
            };
        }

        /// <summary>
        /// 根据OrderId获取未生产完成的资源列表
        /// </summary>
        /// <param name="orderIds"></param>
        /// <returns></returns>
        public async Task<List<Guid>> GetNoProductionOrderIdsListForOrderId(HashSet<Guid> orderIds)
        {
            var infoQuery = Context.Queryable<OrderInfo>();
            infoQuery = SplitTableForTime(infoQuery);


            var orderQuery = Context.Queryable<Order>().Where((order) => orderIds.Contains(order.Id));
            orderQuery = SplitTableForTime(orderQuery);

            infoQuery = infoQuery.LeftJoin(orderQuery, (info, order) => info.OrderId == order.Id);


            var infoList = await infoQuery!.Where(info => info.ResourceStatus == (int)ResourceStatus.WaitProduction || info.ResourceStatus == (int)ResourceStatus.InProduction).Select(info => info.OrderId).ToListAsync().ConfigureAwait(false);
            return infoList;
        }



        /// <summary>
        /// 批量更改支付资源状态为已指定状态
        /// </summary>
        /// <param name="orderInfoIds">返回全部资源生产完成的订单</param>
        /// <returns></returns>
        public async Task<HashSet<Guid>> BatchChangeOrderInfoStatusToProductionFinish(HashSet<Guid> orderInfoIds, ResourceStatus resourceStatus = ResourceStatus.ProductionFinish)
        {
            var orderInfos = await Context.Queryable<OrderInfo>().Where(o => orderInfoIds.Contains(o.Id)).SplitTable().ToListAsync().ConfigureAwait(false);

            HashSet<Guid> orderIds = new HashSet<Guid>();
            for (int i = 0; i < orderInfos.Count; i++)
            {
                var info = orderInfos[i];
                if (info.ResourceStatus == (int)ResourceStatus.WaitProduction || info.ResourceStatus == (int)OrderStatus.InProduction || info.ResourceStatus == (int)OrderStatus.ProductionFinish)//order.OrderStatus == (int)OrderStatus.Unpaid Debug
                {
                    info.ResourceStatus = (int)resourceStatus;
                    if (!orderIds.Contains(info.OrderId))
                    {
                        orderIds.Add(info.OrderId);
                    }
                }
            }

            await Context.Updateable(orderInfos).SplitTable().ExecuteCommandAsync().ConfigureAwait(false);
            var waitProductionOrderIds = await GetNoProductionOrderIdsListForOrderId(orderIds);
            //资源列表订单id集合，除去未生产完成的，剩下的是已经全部资源生产完成的订单
            var finishOrderIds = orderIds.Except(waitProductionOrderIds);

            return finishOrderIds.ToHashSet();
        }
    }
}
