using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using Microsoft.EntityFrameworkCore;
using Siger.Middlelayer.Common;
using Siger.Middlelayer.Common.Extensions;
using Siger.Middlelayer.Common.Helpers;
using Siger.Middlelayer.Common.ModuleEnum;
using Siger.Middlelayer.Repository.Data.Tpm;
using Siger.Middlelayer.Repository.Entities;
using Siger.Middlelayer.Repository.Extensions;
using Siger.Middlelayer.Repository.Paged;
using Siger.Middlelayer.TpmRepository.Entities;
using Siger.Middlelayer.TpmRepository.Repositories.Interface;
using Siger.Middlelayer.TpmRepository.Request;
using Siger.Middlelayer.TpmRepository.Response;

namespace Siger.Middlelayer.TpmRepository.Repositories
{
    internal class PlanTimeRepository : TpmRepositoryBase<siger_project_plan_time>, IPlanTimeRepository
    {
        private readonly ApiTpmDbContext _context;
        public PlanTimeRepository(ApiTpmDbContext context) : base(context)
        {
            _context = context;
        }

        public IPagedCollectionResult<GetListPlanStatus> GetPagedlistPlanstatus(int mode, IEnumerable<int> machineIds, int projectId, int page, int pagesize)
        {
            var time = UnixTimeHelper.GetTodayUnix();
            var rowState = (int)RowState.Valid;
            var query = _context.siger_project_plan_time.Where(t => t.projectid == projectId && t.status == rowState &&
                                                                    (t.information == 3 || (t.instruction_time < time && t.information > 1)));
            var queryList = from t in query
                            join plan in _context.siger_project_plan on t.planid equals plan.id
                            where plan.status == rowState && plan.projectid == projectId
                            join pitem in _context.siger_project_plan_item on plan.itemid equals pitem.id
                            join machine in _context.siger_project_machine on plan.machineid equals machine.id
                            join lsm in _context.siger_project_machine_attribution on machine.id equals lsm.machine into lsm
                            from lsmachine in lsm.DefaultIfEmpty()
                            join ls in _context.siger_project_level_section on lsmachine.station equals ls.id into ls
                            from lsection in ls.DefaultIfEmpty()
                            where pitem.status == rowState && pitem.projectid == projectId
                            select new GetListPlanStatus
                            {
                                id = t.id,
                                mid = t.instruction_mid,
                                //name = users.name,
                                machineid = plan.machineid,
                                machinetitle = machine.title ?? "",
                                utime = UnixTimeHelper.ConvertIntDate(t.instruction_time),
                                sectionid = lsmachine.station > 0 ? lsmachine.station : 0,
                                information = t.information,
                                mode = pitem.mode,
                                instruction_time = t.instruction_time,
                                plan_mids = plan.instruction_mid
                            };

            Expression<Func<GetListPlanStatus, bool>> modeExpression = q => true;
            if (mode != 0)
            {
                modeExpression = q => q.mode == mode;
            }
            Expression<Func<GetListPlanStatus, bool>> machineIdsExpression = q => true;
            if (machineIds.Any())
            {
                machineIdsExpression = q => (machineIds.Contains(q.machineid));
            }

            var predicate = modeExpression.And(machineIdsExpression);

            var dataList = queryList.Where(predicate).GroupBy(t => t.id).Select(t => t.FirstOrDefault()).ToList();
            var machinelist = dataList.GroupBy(t => t.machineid).Distinct().ToList();
            var result = new List<GetListPlanStatus>();
            foreach (var p in machinelist)
            {
                if (p.Any())
                {
                    var min_times = p.OrderBy(t => t.instruction_time).ToList();
                    result.Add(min_times[0]);
                }
            }

            var totalCount = result.Count;
            var entities = result.Skip((page - 1) * pagesize).Take(pagesize).ToList();

            return new PagedCollectionResult<GetListPlanStatus>(entities, totalCount);
        }

        public IEnumerable<GetListPlanStatus> GetListPlanstatusInfo(int mode, int machineid, int information, int projectid)
        {
            var rowState = (int)RowState.Valid;
            var query = _context.siger_project_plan_time.Where(t => t.projectid == projectid && t.status == rowState).OrderByDescending(t => t.instruction_time);
            var queryList = from t in query
                            join plan in _context.siger_project_plan on t.planid equals plan.id
                            where plan.status == rowState && plan.projectid == projectid
                            join pitem in _context.siger_project_plan_item on plan.itemid equals pitem.id
                            where pitem.status == rowState && pitem.projectid == projectid
                            join u in _context.siger_project_user on t.instruction_mid equals u.mid into uu
                            from users in uu.DefaultIfEmpty()
                            select new GetListPlanStatus
                            {
                                id = t.id,
                                utime = UnixTimeHelper.ConvertIntDate(t.instruction_time),
                                information = t.information,
                                mode = pitem.mode,
                                instruction_time = t.instruction_time,
                                name = users.name,
                                machineid = pitem.machineid,
                                content = pitem.content
                            };

            Expression<Func<GetListPlanStatus, bool>> modeExpression = q => true;
            if (mode != 0)
            {
                modeExpression = q => q.mode == mode;
            }
            Expression<Func<GetListPlanStatus, bool>> informationExpression = q => true;
            if (information != 0)
            {
                informationExpression = q => q.information == information;
            }
            Expression<Func<GetListPlanStatus, bool>> machineidExpression = q => true;
            if (machineid != 0)
            {
                machineidExpression = q => q.machineid == machineid;
            }

            var predicate = modeExpression.And(informationExpression).And(machineidExpression);

            var dataList = queryList.Where(predicate).AsNoTracking().ToList();
            return dataList.GroupBy(t => t.id).Select(t => t.FirstOrDefault()).ToList();
        }

        public IEnumerable<GetListPlanStatus> GetPlanInformation(int mode, int machineid, int nowtime, int endtime, int projectid)
        {
            var rowState = (int)RowState.Valid;
            var query = _context.siger_project_plan_time.Where(t => t.projectid == projectid && t.status == rowState);
            var queryList = from t in query
                            join plan in _context.siger_project_plan on t.planid equals plan.id
                            where plan.status == rowState && plan.projectid == projectid
                            join pitem in _context.siger_project_plan_item on plan.itemid equals pitem.id
                            where pitem.status == rowState && pitem.projectid == projectid
                            select new GetListPlanStatus
                            {
                                id = t.id,
                                utime = UnixTimeHelper.ConvertIntDate(t.instruction_time),
                                information = t.information,
                                mode = pitem.mode,
                                instruction_time = t.instruction_time,
                                machineid = plan.machineid
                            };

            Expression<Func<GetListPlanStatus, bool>> modeExpression = q => true;
            if (mode > 0)
            {
                modeExpression = q => q.mode == mode;
            }
            Expression<Func<GetListPlanStatus, bool>> machineidExpression = q => true;
            if (machineid > 0)
            {
                machineidExpression = q => q.machineid == machineid;
            }
            Expression<Func<GetListPlanStatus, bool>> timeExpression = q => true;
            if (nowtime >= 0 && endtime > 0)
            {
                timeExpression = q => (q.instruction_time <= endtime && q.instruction_time >= nowtime);
            }

            var predicate = modeExpression.And(timeExpression).And(machineidExpression);

            var dataList = queryList.Where(predicate).ToList().OrderBy(t => t.instruction_time).ToList();
            return dataList.GroupBy(t => t.id).Select(t => t.FirstOrDefault()).ToList();
        }

        public IEnumerable<ResponseGetPlanForm> GetPlanFormTotal(IEnumerable<int> machineIds, int mode, int starttime, int projectid, int userid)
        {
            var rowState = (int)RowState.Valid;
            var res = new List<ResponseGetPlanForm>();
            if (machineIds == null)
            {
                //res.Add(new ResponseGetPlanForm { total1 = 0, total2 = 0, daytime = DateTime.Now.ToString(ParameterConstant.DateFormat) });
                return res;
            }
            var endtime = starttime + 3600 * 24 * 7 * 5;
            for (var stime = starttime; stime < endtime; stime += 3600 * 24 * 7)
            {
                var etime = stime + 3600 * 24 * 7 - 1;
                var queryList = (from t in _context.siger_project_plan_time
                                 where t.status == rowState && t.projectid == projectid && t.instruction_time <= etime &&
                                       t.instruction_time >= stime
                                 join plan in _context.siger_project_plan on t.planid equals plan.id
                                 where plan.status == rowState && plan.projectid == projectid && machineIds.Contains(plan.machineid)
                                 join pitem in _context.siger_project_plan_item on plan.itemid equals pitem.id
                                 where pitem.status == rowState && pitem.projectid == projectid && pitem.mode == mode
                                 join u in _context.siger_project_user on t.instruction_mid equals u.mid into uu
                                 from u in uu.DefaultIfEmpty()
                                 select new siger_project_plan_item
                                 {
                                     id = t.id,
                                     standard_time = pitem.standard_time
                                 }).GroupBy(t => t.id).Select(t => t.FirstOrDefault()).ToList();

                var query = (from t in _context.siger_project_plan_time
                             join plan in _context.siger_project_plan on t.planid equals plan.id
                             join pitem in _context.siger_project_plan_item on plan.itemid equals pitem.id
                             join u in _context.siger_project_user on t.instruction_mid equals u.mid into uu
                             where t.status == (int)RowState.Valid && t.projectid == projectid && pitem.mode == mode &&
                                   t.instruction_time <= etime && t.instruction_time >= stime
                                   && t.instruction_mid == userid
                             select new siger_project_plan_item
                             {
                                 id = t.id,
                                 standard_time = pitem.standard_time
                             }).GroupBy(t => t.id).Select(t => t.FirstOrDefault()).ToList();
                decimal total1 = queryList.Sum(t => t.standard_time > 0 ? t.standard_time : 0) / (decimal)60;
                decimal total2 = query.Sum(t => t.standard_time > 0 ? t.standard_time : 0) / (decimal)60;
                res.Add(new ResponseGetPlanForm
                {
                    total1 = Math.Round(total1, 1),
                    total2 = Math.Round(total2, 1),
                    daytime = UnixTimeHelper.ConvertIntDate(stime)
                });
            }

            return res;
        }

        public GetListPlanStatus GetOnePlanTime(int ptimeid, int projectid)
        {
            var rowState = (int)RowState.Valid;
            var query = from t in _context.siger_project_plan_time
                        where t.status == rowState && t.projectid == projectid && t.id == ptimeid
                        join plan in _context.siger_project_plan on t.planid equals plan.id
                        where plan.status == rowState && plan.projectid == projectid
                        join pitem in _context.siger_project_plan_item on plan.itemid equals pitem.id
                        where pitem.status == rowState && pitem.projectid == projectid
                        join m in _context.siger_project_machine on plan.machineid equals m.id
                        join u in _context.siger_project_user on t.instruction_mid equals u.mid into uu
                        from u in uu.DefaultIfEmpty()
                        select new GetListPlanStatus
                        {
                            id = t.id,
                            utime = UnixTimeHelper.ConvertIntDate(t.instruction_time),
                            information = t.information,
                            mode = pitem.mode,
                            instruction_time = t.instruction_time,
                            machineid = plan.machineid,
                            machinetitle = m.title,
                            mid = t.instruction_mid,
                            name = u.name ?? "",
                            sectionid = u.sectionid > 0 ? u.sectionid : 0,
                            instruction_time_str = t.instruction_time > 0 ? UnixTimeHelper.ConvertIntDate(t.instruction_time) : ""
                        };

            return query.FirstOrDefault() ?? new GetListPlanStatus();
        }

        public IEnumerable<GetListPlanStatus> GetPlanTimeItem(int information, int nowtime, int planid, int projectid)
        {
            var rowState = (int)RowState.Valid;
            var queryList = from t in _context.siger_project_plan_time
                            where t.status == rowState && t.projectid == projectid
                            join u in _context.siger_project_user on t.instruction_mid equals u.mid into uu
                            from users in uu.DefaultIfEmpty()
                            orderby t.instruction_time
                            select new GetListPlanStatus
                            {
                                id = t.id,
                                information = t.information,
                                instruction_time = t.instruction_time > 0 ? t.instruction_time : 0,
                                mid = t.instruction_mid,
                                name = users.name,
                                planid = t.planid,
                                instruction_time_str = t.instruction_time > 0 ? UnixTimeHelper.ConvertIntDate(t.instruction_time) : "",
                                sectionid = users.sectionid > 0 ? users.sectionid : 0
                            };
            Expression<Func<GetListPlanStatus, bool>> informationExpression = q => true;
            if (information != 0)
            {
                informationExpression = q => q.information == information;
            }
            Expression<Func<GetListPlanStatus, bool>> planidExpression = q => true;
            if (planid > 0)
            {
                planidExpression = q => q.planid == planid;
            }
            Expression<Func<GetListPlanStatus, bool>> nowtimeExpression = q => true;
            if (nowtime > 0)
            {
                nowtimeExpression = q => q.instruction_time >= nowtime;
            }

            var predicate = planidExpression.And(informationExpression).And(nowtimeExpression);

            return queryList.Where(predicate).AsNoTracking().ToList();
        }

        public IPagedCollectionResult<GetListThirtyPlanItem> GetPagedlistthirdPlanItem(listthirdPlanItem baseModel, IEnumerable<int> machineIds, int startTime, int endTime, int projectId, int page, int pagesize, int searchType)
        {
            var rowState = (int)RowState.Valid;
            IQueryable<siger_project_plan_time> query;
            if (searchType == 2)
            {
                query = _context.siger_project_plan_time.Where(t => t.projectid == projectId && t.status == rowState && t.information != 1);
            }
            else
            {
                query = _context.siger_project_plan_time.Where(t => t.projectid == projectId && t.status == rowState);
            }
            var userlist = _context.siger_project_user.Where(t => t.projectid == projectId && t.status == rowState).ToList();
            var queryList = from t in query
                            join plan in _context.siger_project_plan on t.planid equals plan.id
                            join pitem in _context.siger_project_plan_item on plan.itemid equals pitem.id
                            join machine in _context.siger_project_machine on plan.machineid equals machine.id
                            join u in userlist on t.instruction_mid equals u.mid into uu
                            from users in uu.DefaultIfEmpty()
                            where plan.status == rowState && plan.projectid == projectId && pitem.status == rowState &&
                                  pitem.projectid == projectId
                            select new GetListThirtyPlanItem
                            {
                                id = t.id,
                                planid = t.planid,
                                mid = t.instruction_mid,
                                name = plan.instruction_mid,
                                machineid = machine.id,
                                machinetitle = machine.title,
                                //dtime = t.instruction_time,
                                utime = UnixTimeHelper.ConvertIntDate(t.instruction_time),
                                information = t.information,
                                mode = pitem.mode,
                                instruction_time = t.instruction_time,
                                value_type = pitem.value_type,
                                severity_level = pitem.severity_level,
                                instruction_cycle = pitem.instruction_cycle,
                                standard_time = pitem.standard_time,
                                department = users.sectionid > 0 ? users.sectionid : 0,
                                content = pitem.content,
                                pid = t.id,
                                date_rang = plan.date_rang,
                                work_order = "P" + t.id.ToStr(),
                                instruction_time_end = plan.instruction_cycle * 86400 + t.instruction_time,
                                itemid = pitem.id,
                            };

            Expression<Func<GetListThirtyPlanItem, bool>> valuetypeExpression = q => true;
            if (baseModel.value_type != 0)
            {
                valuetypeExpression = q => q.value_type == baseModel.value_type;
            }
            Expression<Func<GetListThirtyPlanItem, bool>> machineIdsExpression = q => true;
            if (machineIds != null && machineIds.Any())
            {
                machineIdsExpression = q => (machineIds.Contains(q.machineid));
            }
            Expression<Func<GetListThirtyPlanItem, bool>> modeExpression = q => true;
            if (baseModel.mode != 0)
            {
                modeExpression = q => q.mode == baseModel.mode;
            }
            Expression<Func<GetListThirtyPlanItem, bool>> severitylevelExpression = q => true;
            if (baseModel.severity_level != 0)
            {
                severitylevelExpression = q => q.severity_level == baseModel.severity_level;
            }
            Expression<Func<GetListThirtyPlanItem, bool>> instructioncycleExpression = q => true;
            if (baseModel.instruction_cycle != 0)
            {
                instructioncycleExpression = q => q.instruction_cycle == baseModel.instruction_cycle;
            }
            Expression<Func<GetListThirtyPlanItem, bool>> daterangExpression = q => true;
            if (!string.IsNullOrWhiteSpace(baseModel.date_rang) && baseModel.date_rang != "0")
            {
                daterangExpression = q => q.date_rang == baseModel.date_rang.ToInt();
            }
            Expression<Func<GetListThirtyPlanItem, bool>> gtltExpression = q => true;
            if (baseModel.compare > 0)
            {
                if (baseModel.compare == 1) //小于
                {
                    gtltExpression = q => (q.standard_time <= baseModel.gt);
                }
                if (baseModel.compare == 2) //大于
                {
                    gtltExpression = q => (q.standard_time >= baseModel.gt);
                }
            }
            Expression<Func<GetListThirtyPlanItem, bool>> personExpression = q => true;
            if ((baseModel.person != 0 || baseModel.department > 0) && baseModel.persons != null)
            {
                personExpression = q => baseModel.persons.Contains(q.mid);
            }
            Expression<Func<GetListThirtyPlanItem, bool>> setimeExpression = q => true;
            if (startTime > 0 && endTime > 0)
            {
                setimeExpression = q => (q.instruction_time <= endTime && q.instruction_time >= startTime) || (q.instruction_time_end <= endTime && q.instruction_time_end >= startTime);
            }

            var predicate = valuetypeExpression.And(machineIdsExpression).And(modeExpression).And(severitylevelExpression).And(instructioncycleExpression)
                .And(daterangExpression).And(gtltExpression).And(personExpression).And(setimeExpression);

            var dataList = queryList.Where(predicate).OrderBy(t => t.instruction_time).ToList();
            var totalCount = dataList.Count;
            var res = dataList.Skip((page - 1) * pagesize).Take(pagesize).ToList();

            return new PagedCollectionResult<GetListThirtyPlanItem>(res, totalCount);
        }

        /// <summary>
        /// 兼容被禁用的已执行记录
        /// </summary>
        /// <param name="mode"></param>
        /// <param name="start_time"></param>
        /// <param name="end_time"></param>
        /// <param name="machineIds"></param>
        /// <param name="projectid"></param>
        /// <returns></returns>
        public IEnumerable<GetSeachPlanDay> SearchPlanDay(int mode, int start_time, int end_time, IEnumerable<int> machineIds, int projectid)
        {
            var rowState = (int)RowState.Valid;
            if (start_time <= 0 || end_time <= 0)
            {
                start_time = (int)UnixTimeHelper.ConvertDataTimeLong(DateTime.MinValue);
                end_time = (int)UnixTimeHelper.ConvertDataTimeLong(DateTime.MaxValue);
            }

            var query = _context.siger_project_plan_time.Where(t =>
                t.projectid == projectid && t.status > 0 && t.instruction_time <= end_time &&
                t.instruction_time >= start_time).ToList();
            var user = _context.siger_project_user.Where(t => t.projectid == projectid && t.status == rowState).ToList();
            var queryList = from plan in _context.siger_project_plan
                            join t in query on plan.id equals t.planid
                            join r in _context.siger_project_plan_record on t.id equals r.plan_time_id into rr
                            from r in rr.DefaultIfEmpty()
                            join u1 in user on r.actual_mid equals u1.mid into uu1
                            from u1 in uu1.DefaultIfEmpty()
                            join u in user on t.instruction_mid equals u.mid into uu
                            from u in uu.DefaultIfEmpty()
                            join lsm in _context.siger_project_machine_attribution on plan.machineid equals lsm.machine
                            join item in _context.siger_project_plan_item on plan.itemid equals item.id
                            where plan.status == rowState && plan.projectid == projectid &&
                                  item.status == rowState && item.projectid == projectid
                            select new GetSeachPlanDay
                            {
                                id = t.id,
                                instruction_time = t.instruction_time,
                                information = t.information,
                                mode = item.mode,
                                machineid = item.machineid,
                                finish_time = r.create_time > 0 ? r.create_time : 0,
                                mid = r.actual_mid > 0 ? r.actual_mid : (u.mid > 0 ? u.mid : 0),
                                name = r.actual_mid > 0 ? u1.name : u.name,
                                sectionid = lsm.station > 0 ? lsm.station : 0
                            };

            Expression<Func<GetSeachPlanDay, bool>> modeExpression = q => true;
            if (mode != 0)
            {
                modeExpression = q => q.mode == mode;
            }
            Expression<Func<GetSeachPlanDay, bool>> machineIdsExpression = q => true;
            if (machineIds != null && machineIds.Any())
            {
                machineIdsExpression = q => (machineIds.Contains(q.machineid));
            }

            var predicate = modeExpression.And(machineIdsExpression);

            return queryList.Where(predicate).GroupBy(t => t.id).Select(t => t.FirstOrDefault()).ToList();
        }

        public IEnumerable<GetListPlanStatus> GetPlanInformationByMachineIds(int mode, IEnumerable<int> machineIds, int nowtime, int endtime, int projectid)
        {
            var rowState = (int)RowState.Valid;
            //var query = _context.siger_project_plan_time.Where(t =>
            //    t.projectid == projectid && t.status == rowState && (t.information == (int)PlanStatus.Overdue ||
            //                                                         t.information == (int)PlanStatus.UnExecuted)).OrderBy(t => t.instruction_time);
            var queryList = from  plan in _context.siger_project_plan 
                            join  t in _context.siger_project_plan_time on plan.id equals t.planid
                            join pitem in _context.siger_project_plan_item on plan.itemid equals pitem.id
                            join m in _context.siger_project_machine on plan.machineid equals m.id 
                            where plan.projectid==projectid && plan.status==rowState && pitem.status == rowState 
                            select new GetListPlanStatus
                            {
                                id = t.id,
                                planid = plan.id,
                                utime = UnixTimeHelper.ConvertIntDate(t.instruction_time),
                                information = t.information,
                                mode = pitem.mode,
                                instruction_time = t.instruction_time,
                                machineid = plan.machineid,
                                machinetitle = m.title,
                                mid = t.instruction_mid
                            };

            Expression<Func<GetListPlanStatus, bool>> modeExpression = q => true;
            if (mode > 0)
            {
                modeExpression = q => q.mode == mode;
            }
            Expression<Func<GetListPlanStatus, bool>> machineidExpression = q => true;
            if (machineIds.Any())
            {
                machineidExpression = q => machineIds.Contains(q.machineid);
            }
            Expression<Func<GetListPlanStatus, bool>> timeExpression = q => true;
            if (nowtime >= 0 && endtime > 0)
            {
                timeExpression = q => q.instruction_time <= endtime && q.instruction_time >= nowtime;
            }

            var predicate = modeExpression.And(timeExpression).And(machineidExpression);

            return queryList.Where(predicate).ToList();
        }

        public IEnumerable<GetListPlanStatus> GetPlanInfoByTime(int start, int end, int projectid)
        {
            var rowState = (int)RowState.Valid;
            var query = _context.siger_project_plan_time.Where(t =>
                t.projectid == projectid && t.status == rowState && t.instruction_time >= start && t.instruction_time <= end).OrderBy(q => q.instruction_time).ToList();
            var queryList = from t in query
                            join plan in _context.siger_project_plan on t.planid equals plan.id
                            where plan.status == rowState && plan.projectid == projectid
                            select new GetListPlanStatus
                            {
                                id = t.id,
                                planid = plan.id,
                                utime = UnixTimeHelper.ConvertIntDate(t.instruction_time),
                                information = t.information,
                                instruction_time = t.instruction_time,
                                machineid = plan.machineid,
                                mid = t.instruction_mid,
                                time_status = t.information,
                                itemid = plan.itemid
                            };
            return queryList.ToList();
        }


        public IPagedCollectionResult<ResponsePlanMachineChanged> GetCalendarChanged(IEnumerable<int> machineIds, int start, int end, int pid, int page, int pagesize)
        {
            var query = _context.siger_project_plan_time.Where(f => f.projectid.Equals(pid) && f.status == (int)RowState.Valid && f.original_instruction_time != 0);
            var result = from q in query
                         join p in _context.siger_project_plan on q.planid equals p.id
                         join m in _context.siger_project_machine on p.machineid equals m.id
                         join u in _context.siger_project_user on q.editor equals u.mid
                         join i in _context.siger_project_plan_item on p.itemid equals i.id into temp
                         from i in temp.DefaultIfEmpty()
                         where p.status == (int)RowState.Valid && i.status == (int)RowState.Valid
                         && machineIds.Contains(p.machineid)
                         select new ResponsePlanMachineChanged
                         {
                             editor = q.editor,
                             edit_time = q.edit_time,
                             item = i.content,
                             machine = m.title,
                             now = q.instruction_time,
                             user = u.name,
                             original = q.original_instruction_time
                         };

            var totalCount = result.Count();
            var entities = result.Skip((page - 1) * pagesize).Take(pagesize).ToList();
            return new PagedCollectionResult<ResponsePlanMachineChanged>(entities, totalCount);
        }

        public IEnumerable<GetListThirtyPlanItem> GetPlanItems(IEnumerable<int> machineIds, int startTime, int endTime, int projectId)
        {
            var rowState = (int)RowState.Valid;
            var query = _context.siger_project_plan_time.Where(t => t.projectid == projectId && t.status == rowState).OrderBy(t => t.instruction_time);
            var userlist = _context.siger_project_user.Where(t => t.projectid == projectId && t.status == rowState).ToList();
            var queryList = from t in query
                            join plan in _context.siger_project_plan on t.planid equals plan.id
                            join pitem in _context.siger_project_plan_item on plan.itemid equals pitem.id
                            join machine in _context.siger_project_machine on plan.machineid equals machine.id
                            join u in userlist on t.instruction_mid equals u.mid into uu
                            from users in uu.DefaultIfEmpty()
                            where plan.status == rowState && plan.projectid == projectId && pitem.status == rowState &&
                                  pitem.projectid == projectId
                            select new GetListThirtyPlanItem
                            {
                                id = t.id,
                                planid = t.planid,
                                mid = t.instruction_mid,
                                name = users.name,
                                machineid = machine.id,
                                machinetitle = machine.title,
                                utime = UnixTimeHelper.ConvertIntDate(t.instruction_time),
                                information = t.information,
                                mode = pitem.mode,
                                instruction_time = t.instruction_time,
                                value_type = pitem.value_type,
                                severity_level = pitem.severity_level,
                                instruction_cycle = pitem.instruction_cycle,
                                standard_time = pitem.standard_time,
                                department = users.sectionid > 0 ? users.sectionid : 0,
                                content = pitem.content,
                                pid = t.id,
                                date_rang = plan.date_rang,
                            };

            Expression<Func<GetListThirtyPlanItem, bool>> machineIdsExpression = q => true;
            if (machineIds != null && machineIds.Any())
            {
                machineIdsExpression = q => (machineIds.Contains(q.machineid));
            }

            Expression<Func<GetListThirtyPlanItem, bool>> setimeExpression = q => true;
            if (startTime > 0 && endTime > 0)
            {
                setimeExpression = q => (q.instruction_time <= endTime && q.instruction_time >= startTime);
            }

            var predicate = machineIdsExpression.And(setimeExpression);

            return queryList.Where(predicate).ToList();
        }

        public IEnumerable<GetListThirtyPlanItem> GetDayPlanItem(int startTime, int endTime, int projectId)
        {
            var rowState = (int)RowState.Valid;
            var query = _context.siger_project_plan_time.Where(t => t.projectid == projectId && t.status == rowState).OrderBy(t => t.instruction_time);
            var userlist = _context.siger_project_user.Where(t => t.projectid == projectId && t.status == rowState).ToList();
            var queryList = from t in query
                            join plan in _context.siger_project_plan on t.planid equals plan.id
                            join pitem in _context.siger_project_plan_item on plan.itemid equals pitem.id
                            join machine in _context.siger_project_machine on plan.machineid equals machine.id
                            join u in userlist on t.instruction_mid equals u.mid into uu
                            from users in uu.DefaultIfEmpty()
                            where plan.status == rowState && plan.projectid == projectId && pitem.status == rowState &&
                                  pitem.projectid == projectId
                            select new GetListThirtyPlanItem
                            {
                                id = t.id,
                                planid = t.planid,
                                mid = t.instruction_mid,
                                name = plan.instruction_mid,
                                machineid = machine.id,
                                machinetitle = machine.title,
                                utime = UnixTimeHelper.ConvertIntDate(t.instruction_time),
                                information = t.information,
                                mode = pitem.mode,
                                instruction_time = t.instruction_time,
                                value_type = pitem.value_type,
                                severity_level = pitem.severity_level,
                                instruction_cycle = pitem.instruction_cycle,
                                standard_time = pitem.standard_time,
                                department = users.sectionid > 0 ? users.sectionid : 0,
                                content = pitem.content,
                                pid = t.id,
                                date_rang = plan.date_rang,
                                work_order = "P" + t.id.ToStr()
                            };

            Expression<Func<GetListThirtyPlanItem, bool>> setimeExpression = q => true;
            if (startTime > 0 && endTime > 0)
            {
                setimeExpression = q => (q.instruction_time <= endTime && q.instruction_time >= startTime);
            }

            return queryList.Where(setimeExpression).ToList();
        }
    }
}
