using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using Microsoft.EntityFrameworkCore;
using Siger.Middlelayer.AccRepository.Entities;
using Siger.Middlelayer.AccRepository.Repositories.Interface;
using Siger.Middlelayer.Common;
using Siger.Middlelayer.Repository.Data;
using Siger.Middlelayer.Repository.Extensions;
using Siger.Middlelayer.Repository.Paged;

namespace Siger.Middlelayer.AccRepository.Repositories
{
    internal class SigerTrBatchTraceDetailRepository : AccRepositoryBase<SigerTrBatchTraceDetail>, ISigerTrBatchTraceDetailRepository
    {
        private ApiAccDbContext accDbContext;
        public SigerTrBatchTraceDetailRepository(ApiAccDbContext context) : base(context)
        {
            accDbContext = context;
        }

        public IPagedCollectionResult<BatchTraceDetail> GetPagedList(int line, string starttime, string endtime, int projectid, int page, int pagesize)
        {
            Expression<Func<SigerTrBatchTraceDetail, bool>> Funcat = f => f.projectId == projectid && f.status == (int)RowState.Valid;
            Expression<Func<SigerTrBatchTraceDetail, bool>> FunLine = f => true;
            Expression<Func<SigerTrBatchTraceDetail, bool>> FunTransStartTime = f => true;
            Expression<Func<SigerTrBatchTraceDetail, bool>> FunTransEndTime = f => true;
            Expression<Func<SigerTrBatchTraceDetail, bool>> FunIsOk = f => true;
            if (line > 0)
                FunLine = f => f.Line == line.ToString();
            if (DateTime.TryParse(starttime, out DateTime stime))
                FunTransStartTime = f => f.TransDateTime >= stime;
            if (DateTime.TryParse(endtime, out DateTime etime))
                FunTransEndTime = f => f.TransDateTime <= etime;
            var predicate = Funcat.And(FunLine).And(FunTransStartTime).And(FunTransEndTime);

            var query = accDbContext.siger_tr_batch_trace_detail.Where(predicate);
            //疑问。在PHP里面这里连接工站表是用的Tr_CategoryItem的ID,可能有误
            #region php中的错误代码

            //select a.*,b.Line as Linename,c.Item as Stationname,d.Item as Itemname,e.name as username
            //            from Tr_Batch_Trace_Detail a
            //            left
            //            join Tr_Line b on a.Line = b.id
            //       left
            //            join Tr_CategoryItem c on c.id = a.Station
            //       left
            //            join Tr_CategoryItem d on d.id = a.Item
            //       left
            //            join siger_project_user e on e.mid = a.UID

            #endregion

            var querylist = from p in query
                            join l in accDbContext.siger_project_level_section on
                            new { lineid = p.Line, rowstate = (int)RowState.Valid } equals
                            new { lineid = l.id.ToString(), rowstate = l.status }
                            into ltemp
                            from l in ltemp.DefaultIfEmpty()
                            join s in accDbContext.siger_project_level_section on
                            new { stationid = p.Station, rowstate = (int)RowState.Valid } equals
                            new { stationid = s.id.ToString(), rowstate = s.status }
                            into stemp
                            from s in stemp.DefaultIfEmpty()
                            join d in accDbContext.siger_tr_categoryitem on
                            new { itemid = p.Item, rowstate = (int)RowState.Valid } equals
                            new { itemid = d.id.ToString(), rowstate = d.status }
                            into dtemp
                            from d in dtemp.DefaultIfEmpty()
                            join u in accDbContext.siger_project_user on
                            new { userid = p.UID, rowstate = (int)RowState.Valid } equals
                            new { userid = u.id.ToString(), rowstate = u.status }
                            into utemp
                            from u in utemp.DefaultIfEmpty()
                            select new BatchTraceDetail
                            {
                                line = p.Line,
                                line_value = l.title,
                                station=p.Station,
                                station_value=s.title,
                                item = p.Item,
                                item_value=d.Item,
                                qty=p.QTY,
                                uid=p.UID,
                                uid_value=u.name,
                                transdatetime=p.TransDateTime.ToString(ParameterConstant.DateTimeFormat),
                                begindatetime = p.BeginDateTime.ToString(ParameterConstant.DateTimeFormat),
                                enddatetime = p.EndDateTime.ToString(ParameterConstant.DateTimeFormat),                                
                            };

            var totalCount = querylist.Count();
            var entities = query.OrderByDescending(q => q.id).Skip((page - 1) * pagesize).Take(pagesize).AsNoTracking().ToList();
            return new PagedCollectionResult<BatchTraceDetail>(querylist, totalCount);
        }

        public IEnumerable<BatchTraceDetail> GetDataList(int line, string starttime, string endtime, int projectid)
        {
            Expression<Func<SigerTrBatchTraceDetail, bool>> Funcat = f => f.projectId == projectid && f.status == (int)RowState.Valid;
            Expression<Func<SigerTrBatchTraceDetail, bool>> FunLine = f => true;
            Expression<Func<SigerTrBatchTraceDetail, bool>> FunTransStartTime = f => true;
            Expression<Func<SigerTrBatchTraceDetail, bool>> FunTransEndTime = f => true;
            if (line > 0)
                FunLine = f => f.Line == line.ToString();
            if (DateTime.TryParse(starttime, out DateTime stime))
                FunTransStartTime = f => f.TransDateTime >= stime;
            if (DateTime.TryParse(endtime, out DateTime etime))
                FunTransEndTime = f => f.TransDateTime <= etime;
            var predicate = Funcat.And(FunLine).And(FunTransStartTime).And(FunTransEndTime);

            var query = accDbContext.siger_tr_batch_trace_detail.Where(predicate);

            var querylist = from p in query
                            join l in accDbContext.siger_project_level_section on
                            new { lineid = p.Line, rowstate = (int)RowState.Valid } equals
                            new { lineid = l.id.ToString(), rowstate = l.status }
                            into ltemp
                            from l in ltemp.DefaultIfEmpty()
                            join s in accDbContext.siger_project_level_section on
                            new { stationid = p.Station, rowstate = (int)RowState.Valid } equals
                            new { stationid = s.id.ToString(), rowstate = s.status }
                            into stemp
                            from s in stemp.DefaultIfEmpty()
                            join d in accDbContext.siger_tr_categoryitem on
                            new { itemid = p.Item, rowstate = (int)RowState.Valid } equals
                            new { itemid = d.id.ToString(), rowstate = d.status }
                            into dtemp
                            from d in dtemp.DefaultIfEmpty()
                            join u in accDbContext.siger_project_user on
                            new { userid = p.UID, rowstate = (int)RowState.Valid } equals
                            new { userid = u.id.ToString(), rowstate = u.status }
                            into utemp
                            from u in utemp.DefaultIfEmpty()
                            select new BatchTraceDetail
                            {
                                line = p.Line,
                                line_value = l.title,
                                station = p.Station,
                                station_value = s.title,
                                item = p.Item,
                                item_value = d.Item,
                                qty = p.QTY,
                                uid = p.UID,
                                uid_value = u.name,
                                transdatetime = p.TransDateTime.ToString(ParameterConstant.DateTimeFormat),
                                begindatetime = p.BeginDateTime.ToString(ParameterConstant.DateTimeFormat),
                                enddatetime = p.EndDateTime.ToString(ParameterConstant.DateTimeFormat),
                            };

            return querylist.ToList();
        }
    }
}
