using Siger.Middlelayer.CncRepository.Entities;
using Siger.Middlelayer.CncRepository.Repositories.Interface;
using Siger.Middlelayer.CncRepository.Response;
using Siger.Middlelayer.Repository.Paged;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using Siger.Middlelayer.Repository.Extensions;
using Siger.Middlelayer.Common.Helpers;
using Siger.Middlelayer.Common.Extensions;
using Microsoft.EntityFrameworkCore;
using Siger.Middlelayer.CncRepository.Request;
using Siger.Middlelayer.Common.ModuleEnum;
using Siger.Middlelayer.Common;
using NPOI.SS.Formula.Functions;

namespace Siger.Middlelayer.CncRepository.Repositories
{
    /// <summary>
    /// 计划内派工实现类
    /// </summary>
    internal class ProjectProductPlanDispatchReponsitory : CncRepositoryBase<siger_project_product_plan_dispatch>, IProjectProductPlanDispatchReponsitory
    {
        private readonly ApiCncDbContext _context;
        public ProjectProductPlanDispatchReponsitory(ApiCncDbContext context) : base(context)
        {
            _context = context;
        }

        /// <summary>
        /// 计划内派工查询
        /// </summary>
        /// <param name="ordernumber">订单号</param>
        /// <param name="product_name">产品名称</param>
        /// <param name="code">工单号</param>
        /// <param name="projectid">项目id</param>
        /// <param name="page">第几页</param>
        /// <param name="pagesize">每页条数</param>
        /// <returns></returns>
        public IPagedCollectionResult<ResponseProductPlanDispatch> GetPagedProductPlanDispatch(string ordernumber, string product_name, string code, int projectid, 
            int page, int pagesize)
        {
            var entity = from  p in _context.siger_project_product_plan 
                         where p.projectid== projectid && p.status >(int)PlanDispatch.UnIssue
                         select new ResponseProductPlanDispatch
                         {
                             id = p.id,
                             planid=p.id,
                             product_name = p.product_name,
                             product_code = p.product_code,
                             ordernumber = p.ordernumber,
                             code = p.code,
                             draw_number = p.draw_number,
                             producted_number = p.producted_number,
                             install_count=p.install_count,
                             delivery_time = UnixTimeHelper.ConvertIntDate(p.delivery_time),
                             workorder_status= p.delivery_time <= UnixTimeHelper.ConvertDataTimeLong(DateTime.Now.ToString())&& p.status!=(int)PlanDispatch.Finished ? (int)PlanDispatch.Overdue : p.status,
                             plan_starttime= UnixTimeHelper.ConvertIntDate(p.plan_starttime),
                             plan_endtime=UnixTimeHelper.ConvertIntDate(p.plan_endtime),
                             actual_completiontime=UnixTimeHelper.ConvertIntDate(p.finish_time),
                             ok_number=p.producted_number -p.nok_number,
                             nok_number=p.nok_number,
                             batches_number=0,
                             //完成率，ok和nok之和除以总数
                            // completion_rate=p.producted_number==0?0:p.producted_number/ p.quantity,
                             create_time =UnixTimeHelper.ConvertIntDateTime(p.create_time),
                             scheduled_quantity=0,
                             

                         };
            Expression<Func<ResponseProductPlanDispatch, bool>> orderNumberExpression = q => true;
            if (!string.IsNullOrEmpty(ordernumber))
            {
                orderNumberExpression = q => (q.ordernumber.Contains(ordernumber));
            }
            Expression<Func<ResponseProductPlanDispatch, bool>> productNameExpression = q => true;
            if (!string.IsNullOrEmpty(product_name))
            {
                productNameExpression = q => q.product_name.Contains(product_name);
            }
            Expression<Func<ResponseProductPlanDispatch, bool>> codeExpression = q => true;
            if (!string.IsNullOrWhiteSpace(code))
            {
                codeExpression = q => q.code.Contains(code);
            }
            var predicate = orderNumberExpression.And(productNameExpression).And(codeExpression).And(codeExpression);
            var totalCount = entity.Count(predicate);
            var entities = entity.Where(predicate).OrderByDescending(q => q.create_time)
                .Skip((page - 1) * pagesize).Take(pagesize).AsNoTracking().ToList();
            return new PagedCollectionResult<ResponseProductPlanDispatch>(entities, totalCount);
        }

        /// <summary>
        /// 派工
        /// </summary>
        /// <param name="request">接收参数</param>
        /// <param name="dispatch">计划内派工数据</param>
        /// <param name="projectId">项目id</param>
        /// <param name="userid">当前登陆人</param>
        /// <returns></returns>
        public bool AddWorkOrderTask(RequestProductPlanDispatch request, siger_project_product_plan_dispatch dispatch, int projectId,int userid)
        {
            var orderNumbers = request.orders.Select(m => m.orderNumber).Distinct();
            var scheduled_quantity = 0;
            foreach (var orderNumber in orderNumbers)
            {
                var detail = request.orders.First(m => m.orderNumber == orderNumber);
                var planDetail = new siger_project_product_plan_detail
                {
                    addTime = DateTime.Now,
                    levelId = 0,
                    orderNumber = orderNumber,
                    planId = request.planId,
                    projectId = projectId,
                    quantity = detail.count,
                    creator_mid= userid
                };
                scheduled_quantity += detail.count;
                _context.siger_project_product_plan_detail.Add(planDetail);
                if (_context.SaveChanges() <= 0)
                {
                    return false;
                }
            }
            if (dispatch != null)
            {
                dispatch.workorder_status = ((int)PlanDispatch.HasPlan).ToStr();
                dispatch.scheduled_quantity = dispatch.scheduled_quantity+scheduled_quantity;
                _context.siger_project_product_plan_dispatch.Update(dispatch);
            }

            if (_context.SaveChanges() <= 0)
            {
                return false;
            }
            return true;
        }

        /// <summary>
        /// 获取终止弹框数据
        /// </summary>
        /// <param name="code">工令号</param>
        /// <param name="projectId">项目id</param>
        /// <returns></returns>
        public IEnumerable<ResponseStopSchedule> GetStopScheduleData(string code,int projectId) 
        {
            var query = from p in _context.siger_project_product_plan
                        join d in _context.siger_project_product_plan_detail on p.id equals d.planId
                        join u in _context.siger_project_user on d.creator_mid equals u.mid
                        where p.projectid==projectId && p.code==code && p.status >(int)PlanDispatch.UnIssue && p.status <5
                        select new ResponseStopSchedule
                        {
                            id=d.id,
                            orderNumber=d.orderNumber,
                            name=u.name,
                            time=d.addTime.ToString(),
                            state=d.producted_number >0? EnumHelper.GetEnumDesc(PlanStopState.Producing): EnumHelper.GetEnumDesc(PlanStopState.ToProduced),
                            install_count=p.install_count,
                            producted_num=d.producted_number,
                          
                            ngCount=d.nok_number,
                            last_number=d.quantity-d.producted_number
                        };
            return query;

        }

        public IEnumerable<ResponseProductionSchedule> GetProductionScheduleDetails(string ordernumber, int projectid) 
        {
            var data = from spd in _context.siger_project_product_plan_dispatch
                       join sd in _context.siger_project_product_plan_detail on spd.plan_id equals sd.planId
                       join sr in _context.siger_project_product_report on sd.orderNumber equals sr.code
                       join spr in _context.siger_project_product_route on sr.route_id equals spr.id
                       where spd.ordernumber==ordernumber && spd.projectid==projectid &&
                       spd.status==(int)RowState.Valid && sd.status==(int)RowState.Valid && spr.status==(int)RowState.Valid
                       select new ResponseProductionSchedule
                       {
                           route_name= spr.name,
                           oknumber=sr.actual_output,
                           noknumber=sr.nok_number,
                       };
            var dataSum= data.ToList().GroupBy(c => new { c.route_name })
                 .Select(
                             c => new ResponseProductionSchedule
                             {
                                 route_name = c.Key.route_name,
                                 oknumber = c.Sum(x => x.oknumber),
                                 noknumber = c.Sum(x => x.noknumber),
                             }
                          );
            return dataSum;
        }
    }
}
