using BPA.MES.Base.Application.Services.ReportService.Dtos;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace BPA.MES.Base.Application.Services.ReportService
{

    [ApiDescriptionSettings("统计报表管理", Order = 2, Name = "Report", Tag = "报表信息", KeepName = true, SplitCamelCase = true, KeepVerb = true)]
    public class ReportService : IReportService, ITransient, IDynamicApiController
    {
        private readonly ISqlSugarClient _dbContext;
        public ReportService(ISqlSugarClient db)
        {
            _dbContext = db;
        }

        /// <summary>
        /// 获取成品生产统计
        /// </summary>
        /// <param name="inputDto"></param>
        /// <returns></returns>
        [HttpPost]
        public async  Task<List<ProductOutDto>> GetProductReport(ProductInputDto inputDto)
        {
            var res = await _dbContext.Queryable<Pztj_WorkInfoEntity, Pztj_WorkInfoStatusEntity,Pztj_FinalsInfoEntity>
            ((a, b,c) =>
                new JoinQueryInfos(
                    JoinType.Left, a.Id == b.WorkId,
                    JoinType.Left,a.FinalId==c.Id)
            )
                .Where((a,b,c)=>b.Status== WorkOrderStatusEnum.Completed)
                .WhereIF(!string.IsNullOrEmpty(inputDto.ProductName),(a,b,c)=>c.Name.Contains(inputDto.ProductName))
                .WhereIF(inputDto.StartTime.HasVal(),(a,b,c)=>b.CreateTime>=inputDto.StartTime.Value)
                .WhereIF(inputDto.EndTime.HasVal(), (a, b, c) => b.CreateTime >= inputDto.EndTime.Value)

                .Select((a,b,c) => new ProductOutDto()
            {
                Count = SqlFunc.AggregateSum(Convert.ToInt32(a.Number)),
                ProductId=a.FinalId,
                ProductName=c.Name

            }).ToListAsync();
            return res;
        }


        /// <summary>
        /// 获取物料统计
        /// </summary>
        /// <param name="inputDto"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<List<MaterialsOutDto>> GetMaterialsReport(MaterialsInputDto inputDto)
        {
            var result = new List<MaterialsOutDto>();
            var res = await _dbContext.Queryable<Pztj_WorkInfoEntity, Pztj_WorkInfoStatusEntity, Pztj_FinalsInfoEntity>
                ((a, b, c) =>
                    new JoinQueryInfos(
                        JoinType.Left, a.Id == b.WorkId,
                        JoinType.Left, a.FinalId == c.Id)
                )
                .Where((a, b, c) => b.Status != WorkOrderStatusEnum.Draft)
                .WhereIF(inputDto.StartTime.HasVal(), (a, b, c) => b.CreateTime >= inputDto.StartTime.Value)
                .WhereIF(inputDto.EndTime.HasVal(), (a, b, c) => b.CreateTime >= inputDto.EndTime.Value)
                .Select((a, b, c) => new 
                {
                    ProductId = a.FinalId,
                    Count = SqlFunc.AggregateSum(Convert.ToInt32(a.Number)),
                    c.RecipeId

                }).ToListAsync();
            var recipeId = res.Select(x => x.RecipeId).ToList();

            var recipes = await _dbContext.Queryable<RecipeMaterialEntity>()
                .Where(x => recipeId.Contains(x.RecipesId))
                .Select(x => new
                {
                    x.MaterialId,
                    x.Weight,
                    x.RecipesId
                }) .ToListAsync();

            var materialsId= recipes.Select(x => x.MaterialId).ToList();

            var materials = await _dbContext.Queryable<Pztj_MaterialsInfoEntity>()
                .Where(x=> materialsId.Contains(x.Id))
                .WhereIF(!string.IsNullOrEmpty(inputDto.MaterialsName),x=>x.Name.Contains(inputDto.MaterialsName))
                .ToListAsync();

            foreach (var item in materials)
            {
                var count = 0;
                foreach (var item2 in res.GroupBy(x=>x.RecipeId))
                {
                    var data = recipes.Where(x=>x.RecipesId==item2.Key &&x.MaterialId==item.Id).FirstOrDefault();
                    count=item2.First().Count*Convert.ToInt32(data==null? 0: data.Weight);

                }

                result.Add(new MaterialsOutDto()
                {
                    MaterialId=item.Id,
                    MaterialName=item.Name,
                    Count= count,
                });
            }

            return result;
        }

    }
}
