using Microsoft.EntityFrameworkCore;
using Siger.Middlelayer.Common;
using Siger.Middlelayer.Common.Extensions;
using Siger.Middlelayer.QmsRepository.Entities;
using Siger.Middlelayer.QmsRepository.Repositories.Interface;
using Siger.Middlelayer.QmsRepository.Response;
using Siger.Middlelayer.Repository.Extensions;
using Siger.Middlelayer.Repository.Paged;
using Siger.Middlelayer.Share.Models.Dashboard;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;

namespace Siger.Middlelayer.QmsRepository.Repositories
{
    internal class CheckSnTraceMaterialRepository : QMSRepositoryBase<siger_check_sn_trace_material>, ICheckSnTraceMaterialRepository
    {
        private readonly ApiQmsDbContext _context;
        public CheckSnTraceMaterialRepository(ApiQmsDbContext context) : base(context)
        {
            _context = context;
        }

        /// <summary>
        /// 获取进料数据
        /// </summary>
        /// <param name="project"></param>
        /// <param name="begin"></param>
        /// <param name="end"></param>
        /// <returns></returns>
        public IEnumerable<QmsMetarialData> GetMetarialData(int project, DateTime begin, DateTime end)
        {
            var query = from m in _context.siger_check_sn_trace_material
                        join l in _context.siger_project_level_section on m.SectionID equals l.id
                        join p in _context.siger_project_level_section on l.parentid equals p.id
                        join u in _context.siger_project_user on m.UserID equals u.mid

                        where m.projectid == project && m.CreateTime >= begin && m.CreateTime <= end
                        select new QmsMetarialData
                        {
                             Section=m.SectionID,
                             SectionDesc = p.title,
                             UserId=m.UserID,
                             UserName=u.name
                        };

            return query;
        }

        public IPagedCollectionResult<ResponseIncomingMaterial> GetPagedList(List<int> sectionid, int materialid, int supplierid, string result,
                string batchnumber, string starttime, string endtime, int page, int pagesize, int projectid, string toexcel)
        {
            var query = _context.siger_check_sn_trace_material.Where(q => q.projectid == projectid && q.status == (int)RowState.Valid);
            var querylist = from q in query
                            join p in _context.siger_tr_materials on q.MaterialID equals p.id
                            join s in _context.siger_project_level_section on q.SectionID equals s.id
                            join c in _context.siger_wms_bussinese_contacts on q.SupplierID equals c.id into cc
                            from c in cc.DefaultIfEmpty()
                            join u in _context.siger_user on q.UserID equals u.id into uu
                            from u in uu.DefaultIfEmpty()
                            select new ResponseIncomingMaterial
                            {
                                id = q.id,
                                materialid = q.MaterialID,
                                materialpn = p.pn,
                                materialname = p.name,
                                materialspec = p.spec,
                                sectionid = q.SectionID,
                                sectionname = s.title ?? "",
                                supplierid = q.SupplierID,
                                suppliername = c.name ?? "",
                                batchnumber = q.BatchNumber,
                                totalquantity = q.TotalQuantity,
                                randomchecknumber = q.RandomCheckNumber,
                                result = q.Result,
                                check_mid = q.UserID,
                                check_user = u.nickname ?? "",
                                check_datetime = q.CreateTime,
                                check_time = q.CreateTime.ToString(ParameterConstant.DateTimeFormat),
                                date = q.ArrivalDate.HasValue && q.ArrivalDate != DateTime.MinValue ?
                                    q.ArrivalDate.Value.ToString(ParameterConstant.DateFormat) : "",
                                po = q.PO,
                                remark = q.Remark
                            };

            Expression<Func<ResponseIncomingMaterial, bool>> sectionExpression = q => true;
            if (sectionid.Any())
            {
                sectionExpression = q => sectionid.Contains(q.sectionid);
            }
            Expression<Func<ResponseIncomingMaterial, bool>> supplierExpression = q => true;
            if (supplierid > 0)
            {
                supplierExpression = q => q.supplierid == supplierid;
            }
            Expression<Func<ResponseIncomingMaterial, bool>> materialExpression = q => true;
            if (materialid > 0)
            {
                materialExpression = q => q.materialid == materialid;
            }
            Expression<Func<ResponseIncomingMaterial, bool>> resultExpression = q => true;
            if (!string.IsNullOrEmpty(result))
            {
                resultExpression = q => q.result.ToUpper() == result;
            }
            Expression<Func<ResponseIncomingMaterial, bool>> batchnumberExpression = q => true;
            if (!string.IsNullOrEmpty(batchnumber))
            {
                batchnumberExpression = q => q.batchnumber == batchnumber;
            }
            Expression<Func<ResponseIncomingMaterial, bool>> timeExpression = q => true;
            if (!string.IsNullOrEmpty(starttime) && !string.IsNullOrEmpty(endtime))
            {
                var stime = starttime.ToDateTime();
                var etime = endtime.ToDateTime();
                timeExpression = q => (q.check_datetime <= etime && q.check_datetime >= stime);
            }
            var expression = sectionExpression.And(supplierExpression).And(materialExpression)
                .And(resultExpression).And(batchnumberExpression).And(timeExpression);
            var totalCount = querylist.Count(expression);
            if (toexcel.ToInt() == 1)
            {
                var entities = querylist.Where(expression).OrderByDescending(t => t.id).ToList();
                return new PagedCollectionResult<ResponseIncomingMaterial>(entities, totalCount);
            }
            else
            {
                var entities = querylist.Where(expression).OrderByDescending(t => t.id)
                    .Skip((page - 1) * pagesize).Take(pagesize).AsNoTracking().ToList();
                return new PagedCollectionResult<ResponseIncomingMaterial>(entities, totalCount);
            }
        }
    }
}
