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.Repository.Response;
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 RepairRepository : TpmRepositoryBase<siger_project_repair>, IRepairRepository
    {
        private readonly ApiTpmDbContext _context;
        public RepairRepository(ApiTpmDbContext context) : base(context)
        {
            _context = context;
        }

        public IEnumerable<ResponseUnFinishedRepair> GetUnFinishedRepair(int projectId)
        {
            var query = from q in _context.siger_project_repair
                        join u in _context.siger_user on q.mid equals u.id
                        join f in _context.siger_project_machine_fault on q.faultid equals f.id into ftemp
                        from ff in ftemp.DefaultIfEmpty()
                        join fp in _context.siger_project_machine_fault on q.real_faultid equals fp.id into fptemp
                        from ffp in fptemp.DefaultIfEmpty()
                        where q.projectid == projectId && q.status > (int)RowState.Invalid &&
                              q.status < (int)MachineRepairStatus.Completed
                        select new ResponseUnFinishedRepair
                        {
                            machineId = q.machineid,
                            createtime = q.createtime,
                            fault_description = q.fault_description,
                            faultcontent = ffp != null ? ffp.title : "",
                            faulttype = ff != null ? ff.title : "",
                            id = q.id,
                            remark = q.remark,
                            status = q.status,
                            repair_process = q.repair_process,
                            real_faultid_desc = q.real_faultid_desc,
                            reportname = u.nickname,
                            sparepart_number = q.sparepartid,
                        };
            return query.AsEnumerable();
        }

        public IEnumerable<ResponseUnFinishedRepair> GetRepairs(int projectId)
        {
            var query = from q in _context.siger_project_repair
                        join m in _context.siger_project_machine on q.machineid equals m.id
                        join lm in _context.siger_project_machine_attribution on q.machineid equals lm.machine
                        join lv in _context.siger_project_level_section on lm.station equals lv.id 
                        join plv in _context.siger_project_level_section on lv.parentid equals plv.id
                        join fp in _context.siger_andon_expection_type on q.expection_id equals fp.id into fptemp
                        from ffp in fptemp.DefaultIfEmpty()
                        where q.projectid == projectId && q.status > (int)RowState.Invalid &&
                              q.status < (int)MachineRepairStatus.WaitingForFeedback && lm.status==(int)RowState.Valid
                        select new ResponseUnFinishedRepair
                        {
                            id = q.id,
                            machinename = $"{plv.title}-{lv.title}",
                            machineId = q.machineid,
                            createtime = q.createtime,
                            createtimeformat = UnixTimeHelper.ConvertIntDateTime(q.createtime),
                            expection = ffp != null ? ffp.id : 0,
                            status = q.status,
                        };
            return query.OrderByDescending(q => q.createtime).Skip(0).Take(50);

        }

        public IEnumerable<ResponseAllRepairs> GetAllRepairs(int projectId, int monthstart, int monthend)
        {
            var query = from q in _context.siger_project_repair
                        join m in _context.siger_project_machine on q.machineid equals m.id
                        join t in _context.siger_project_machine_type on m.typeid equals t.id
                        where q.projectid == projectId && q.status > (int)MachineRepairStatus.WaitingForOrders &&
                              q.status <= (int)MachineRepairStatus.Completed
                              && q.createtime >= monthstart && q.createtime <= monthend
                        select new ResponseAllRepairs
                        {
                            machineId = q.machineid,
                            type_name = t.title,
                            create_time = q.createtime,
                            repirtime = q.checktime - q.taketime < 0 ? 0 : q.checktime - q.taketime,
                            expection_id = q.expection_id
                        };
            return query.AsEnumerable();
        }

        public IEnumerable<ResponseAllRepairs> GetAllFinishedRepairs(int projectId, int monthstart, int monthend)
        {
            var query = from q in _context.siger_project_repair
                        join m in _context.siger_project_machine on q.machineid equals m.id
                        join t in _context.siger_project_machine_type on m.typeid equals t.id
                        where q.projectid == projectId && q.status == (int)MachineRepairStatus.Completed
                              && q.createtime >= monthstart && q.createtime <= monthend
                        select new ResponseAllRepairs
                        {
                            machineId = q.machineid,
                            type_name = t.title,
                            create_time = q.createtime,
                            repirtime = q.completetime - q.signtime < 0 ? 0 : q.completetime - q.signtime,
                            expection_id = q.expection_id,
                        };
            return query.AsEnumerable();
        }

        public IPagedCollectionResult<ResponseUnstandardRepairInfo> GetPagedUnstandardRepairInfo(IEnumerable<int> machineIds, int startTime, int endTime, int projectId,
            int page, int pagesize)
        {
            var queryList = from q in _context.siger_project_repair
                            join u in _context.siger_user on q.repairmid equals u.id into user
                            from uu in user.DefaultIfEmpty()
                            join m in _context.siger_project_machine on q.machineid equals m.id into machine
                            from mm in machine.DefaultIfEmpty()
                            where q.status == 6 && q.projectid == projectId && q.real_faultid == 0 && machineIds.Contains(q.machineid)
                            select new ResponseUnstandardRepairInfo
                            {
                                id = q.id,
                                remark = q.remark,
                                fault_description = q.fault_description,
                                createtime = q.createtime,
                                nickname = uu != null ? uu.nickname : "",
                                repair_process = q.repair_process,
                                real_faultid_desc = q.real_faultid_desc,
                                sparepartid = q.sparepartid,
                                add_repairmid_name = q.add_repairmid,
                                checktime = q.checktime
                            };

            Expression<Func<ResponseUnstandardRepairInfo, bool>> startTimeExpression = q => true;
            if (startTime != 0)
            {
                startTimeExpression = q => q.createtime >= startTime;
            }
            Expression<Func<ResponseUnstandardRepairInfo, bool>> endTimeExpression = q => true;
            if (endTime != 0)
            {
                endTimeExpression = q => q.createtime <= endTime;
            }

            var predicate = startTimeExpression.And(endTimeExpression);

            var totalCount = queryList.Count(predicate);
            var entities = queryList.Where(predicate).Skip((page - 1) * pagesize).Take(pagesize).AsNoTracking().ToList();

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

        public IPagedCollectionResult<ResponseGetRepairList> GetPagedRepairList(IEnumerable<int> machineIds, int startTime, int endTime,
            string userName, string repairid, int fault_id, int faulttype_id, int status, int compare, double compare_time, int cost,
            int projectId, int andonType, int page, int pagesize, int repairMid, int workordertype, bool paged = true)
        {
            var queryList = from q in _context.siger_project_repair
                            //join f in _context.siger_project_machine_fault on q.real_faultid equals f.id into ftemp
                            //from ff in ftemp.DefaultIfEmpty()
                            join r in _context.siger_project_machine_fault on q.fault_description equals r.id.ToString() into rtemp
                            from rr in rtemp.DefaultIfEmpty()
                            join f in _context.siger_project_machine_fault on q.real_faultid equals f.id into ftemp
                            from ff in ftemp.DefaultIfEmpty()
                            join an in _context.siger_andon_expection_type on q.expection_id equals an.id into andon
                            from ann in andon.DefaultIfEmpty()
                            where q.projectid == projectId && q.status != (int)RowState.Invalid && q.status != (int)MachineRepairStatus.Deleted
                                  && machineIds.Contains(q.machineid)
                            select new ResponseGetRepairList
                            {
                                machineId = q.machineid,
                                createtime = q.createtime,
                                fault_id =ff !=null?ff.id:0,
                                faultcontent=ff !=null?ff.title:"",
                                faulttype_id = rr != null ? rr.fault_type : 0,
                                fault_description_id = q.fault_description.ToInt(),
                                fault_description = rr != null ? rr.title : "",
                                faulttype = rr != null ? rr.title : "",
                                id = q.id,
                                remark = q.remark,
                                status = q.status,
                                repair_process = q.repair_process,
                                real_faultid_desc = q.real_faultid_desc,
                                sparepartid = q.sparepartid,
                                images = q.images,
                                fault_desc_img = q.fault_desc_img,
                                repairtime = q.repairtime.ToString().ToDouble(),
                                taketime = q.taketime.ToString().ToDouble(),
                                checktime = q.checktime,
                                offlinestatus = q.offlinestatus,
                                signtime = q.signtime,
                                add_repairmid_name = q.add_repairmid,
                                add_repairmid = q.add_repairmid,
                                repair_remark = q.repair_remark,
                                completetime = q.completetime,
                                takemid = q.takemid,
                                checkmid = q.checkmid,
                                repairmid = q.repairmid,
                                completemid = q.completemid,
                                cost = q.cost_purpose,
                                andontype = q.expection_id,
                                andontypename = ann != null ? ann.name : "",
                                mid = q.mid,
                                work_order = string.IsNullOrEmpty(q.work_order) ? q.id.ToStr() : q.work_order,
                                signmid = q.signmid,
                                work_type = q.work_type
                            };
            Expression<Func<ResponseGetRepairList, bool>> startTimeExpression = q => true;
            if (startTime != 0)
            {
                startTimeExpression = q => q.createtime >= startTime;
            }
            Expression<Func<ResponseGetRepairList, bool>> endTimeExpression = q => true;
            if (endTime != 0)
            {
                endTimeExpression = q => q.createtime <= endTime;
            }
            Expression<Func<ResponseGetRepairList, bool>> statusExpression = q => true;
            if (status != 0)
            {
                statusExpression = q => q.status == status;
            }
            Expression<Func<ResponseGetRepairList, bool>> idExpression = q => true;
            if (!string.IsNullOrWhiteSpace(repairid))
            {
                idExpression = q => q.work_order.Contains(repairid);
            }
            Expression<Func<ResponseGetRepairList, bool>> faultIdExpression = q => true;
            if (fault_id != 0)
            {
                faultIdExpression = q => q.fault_id == fault_id;
            }
            Expression<Func<ResponseGetRepairList, bool>> faulttypeIdExpression = q => true;
            if (faulttype_id != 0)
            {
                faulttypeIdExpression = q => q.faulttype_id == faulttype_id;
            }
            Expression<Func<ResponseGetRepairList, bool>> compareExpression = q => true;
            if (compare_time != 0)
            {
                if (compare == 2)
                {
                    compareExpression = q => (q.completetime - q.signtime) > compare_time * 60;
                }
                if (compare == 1)
                {
                    compareExpression = q => (q.completetime - q.signtime) < compare_time * 60;
                }
            }
            Expression<Func<ResponseGetRepairList, bool>> userIdExpression = q => true;
            if (!string.IsNullOrWhiteSpace(userName))
            {
                var users = _context.siger_user.Where(q => q.status == (int)RowState.Valid).ToList();
                userIdExpression = q => GetUserNames(users, q.add_repairmid_name).Contains(userName);
            }
            Expression<Func<ResponseGetRepairList, bool>> costExpression = q => true;
            if (cost > 0)
            {
                costExpression = q => q.cost == cost;
            }
            Expression<Func<ResponseGetRepairList, bool>> andontypeExpression = q => true;
            if (andonType > 0)
            {
                var types = GetExpectionSonLevel(andonType, projectId).Select(m => m.id).ToList();
                andontypeExpression = q => types.Contains(q.andontype) || q.andontype == andonType;
            }

            Expression<Func<ResponseGetRepairList, bool>> midExpression = q => true;
            if (repairMid != 0)
            {
                midExpression = q => q.repairmid == repairMid;
            }
            Expression<Func<ResponseGetRepairList, bool>> ordertypeExpression = q => true;
            if (workordertype != 0)
            {
                ordertypeExpression = q => q.work_type == workordertype;
            }
            var predicate = startTimeExpression.And(endTimeExpression).And(statusExpression).And(idExpression)
                .And(faultIdExpression).And(faulttypeIdExpression).And(compareExpression).And(userIdExpression)
                .And(costExpression).And(andontypeExpression).And(midExpression).And(ordertypeExpression);

            var entities = new List<ResponseGetRepairList>();
            var totalCount = queryList.Count(predicate);
            if (paged)
            {
                entities = queryList.Where(predicate).OrderByDescending(m => m.id).Skip((page - 1) * pagesize).Take(pagesize).AsNoTracking().ToList();
            }
            else
            {
                entities = queryList.Where(predicate).OrderByDescending(m => m.id).AsNoTracking().ToList();
            }
            var allexceptionids = entities.Where(q => q.andontype > 0).Select(m => m.andontype).Distinct().ToList();
            var exceptions = _context.siger_andon_expection_type.Where(q => allexceptionids.Contains(q.id)).ToList();
            var parentIds = exceptions.Select(q => q.parent).Distinct().ToList();
            var parentExceptions = _context.siger_andon_expection_type.Where(q => parentIds.Contains(q.id)).ToList();
            foreach (var entity in entities)
            {
                var exception = exceptions.FirstOrDefault(q => q.id == entity.andontype);
                if (exception == null)
                {
                    continue;
                }
                switch (exception.level)
                {
                    case 1:
                    case 2:
                        entity.andontypename = exception.name;
                        break;
                    case 3:
                        {
                            var parentexpectiondata = parentExceptions.FirstOrDefault(q => q.id == exception.parent);
                            if (parentexpectiondata != null)
                            {
                                entity.andontypename = parentexpectiondata.name;
                            }
                            break;
                        }
                }
            }

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

        public string GetUserNames(IEnumerable<string> userIds)
        {
            var userNames = new List<string>();
            var users = _context.siger_user.Where(q => userIds.Contains(q.id.ToString()) && q.status == (int)RowState.Valid);
            foreach (var sigerUser in users.ToList())
            {
                userNames.Add(string.IsNullOrWhiteSpace(sigerUser.realname) ? sigerUser.nickname : sigerUser.realname);
            }

            return string.Join(",", userNames);
        }

        private string GetUserNames(IEnumerable<siger_user> allUsers, string ids)
        {
            var userIds = ids.Split(',').ToList();
            var userNames = new List<string>();
            var users = allUsers.Where(q => userIds.Contains(q.id.ToString())).ToList();
            foreach (var sigerUser in users)
            {
                userNames.Add(string.IsNullOrWhiteSpace(sigerUser.nickname) ? sigerUser.realname : sigerUser.nickname);
            }

            return string.Join(",", userNames);
        }

        public IEnumerable<RepairListForMTTR> GetRepairsForMTTR(IEnumerable<int> machineIds, int startTime, int endTime, int faulttype_id,
            int fault_id, int offline, int projectId)
        {
            var queryList = from q in _context.siger_project_repair
                            join f in _context.siger_project_machine_fault on q.real_faultid equals f.id into ftemp
                            from ff in ftemp.DefaultIfEmpty()
                            where q.projectid == projectId && q.status == (int)MachineRepairStatus.Completed
                                  && machineIds.Contains(q.machineid) && q.checktime > 0
                            select new RepairListForMTTR
                            {
                                createtime = q.createtime,
                                faultid = ff != null ? ff.id : 0,
                                faulttypeid = ff != null ? ff.fault_type:0,
                                fault_description = q.fault_description,
                                fault_content = ff != null ? ff.title : "",
                                id = q.id,
                                remark = q.remark,
                                repair_process = q.repair_process,
                                real_faultid_desc = q.real_faultid_desc,
                                sparepartid = q.sparepartid,
                                repairtime = q.checktime == 0 ? 0 : q.checktime - q.createtime,
                                offlinestatus = q.offlinestatus,
                                checktime = q.checktime,
                                machineid = q.machineid,
                                name = q.add_repairmid,
                                repairmid = q.repairmid,
                                workorder = q.work_order,
                                expection = q.expection_id
                            };
            Expression<Func<RepairListForMTTR, bool>> startTimeExpression = q => true;
            if (startTime != 0)
            {
                startTimeExpression = q => q.createtime >= startTime;
            }
            Expression<Func<RepairListForMTTR, bool>> endTimeExpression = q => true;
            if (endTime != 0)
            {
                endTimeExpression = q => q.createtime <= endTime;
            }
            Expression<Func<RepairListForMTTR, bool>> faultIdExpression = q => true;
            if (fault_id != 0)
            {
                faultIdExpression = q => q.faultid == fault_id;
            }
            Expression<Func<RepairListForMTTR, bool>> faulttypeIdExpression = q => true;
            if (faulttype_id != 0)
            {
                faulttypeIdExpression = q => q.faulttypeid == faulttype_id;
            }
            Expression<Func<RepairListForMTTR, bool>> offlineExpression = q => true;
            if (offline != 0)
            {
                offlineExpression = q => q.offlinestatus == offline;
            }

            var predicate = startTimeExpression.And(endTimeExpression).And(faultIdExpression).And(faulttypeIdExpression).And(offlineExpression);

            var entities = queryList.Where(predicate).OrderByDescending(m => m.createtime).AsNoTracking().ToList();
            return entities;
        }

        public IEnumerable<RepairListForMTTR> GetRepairsForMTTR(RequestRepairDataTrendMTTREx condition, int projectId)
        {
            var queryList = from q in _context.siger_project_repair
                            join f in _context.siger_project_machine_fault on q.faultid equals f.id into ftemp
                            from ff in ftemp.DefaultIfEmpty()
                            where q.projectid == projectId && q.status == (int)MachineRepairStatus.Completed && q.createtime >= condition.start && q.createtime <= condition.end && q.checktime > 0
                            && condition.mids.Contains(q.machineid)
                            select new RepairListForMTTR
                            {
                                createtime = q.createtime,
                                faultid = ff != null ? ff.id : 0,
                                faulttypeid = ff != null ? ff.fault_type:0,
                                fault_description = q.fault_description,
                                fault_content = ff != null ? ff.title : "",
                                id = q.id,
                                remark = q.remark,
                                repair_process = q.repair_process,
                                real_faultid_desc = q.real_faultid.ToStr(),
                                sparepartid = q.sparepartid,
                                repairtime = q.completetime == 0 ? 0 : q.completetime - q.signtime,
                                offlinestatus = q.offlinestatus,
                                checktime = q.checktime,
                                machineid = q.machineid,
                                name = q.add_repairmid,
                                repairmid = q.repairmid,
                                workorder = q.work_order
                            };

            Expression<Func<RepairListForMTTR, bool>> offlineExpression = q => true;
            if (!string.IsNullOrEmpty(condition.offlinestatus))
            {
                offlineExpression = f => f.offlinestatus == condition.offlinestatus.ToInt();
            }
            Expression<Func<RepairListForMTTR, bool>> midExpression = q => true;
            if (condition.mid != 0)
            {
                midExpression = q => q.repairmid == condition.mid;
            }
            Expression<Func<RepairListForMTTR, bool>> departExpression = q => true;
            if (condition.department != 0)
            {
                var userids = _context.siger_project_user.Where(f => f.projectid == projectId && f.status != 0 && f.sectionid == condition.department).Select(s => s.mid).ToList();
                midExpression = q => userids.Contains(q.repairmid);
            }
            var predicate = midExpression.And(departExpression).And(offlineExpression);
            var entities = queryList.Where(predicate).OrderByDescending(m => m.createtime).AsNoTracking().ToList();
            return entities;
        }

        public IEnumerable<RepairListForMTTR> GetAppRepairsForMTTR(IEnumerable<int> machineIds, int startTime, int endTime, int projectId)
        {
            var queryList = from q in _context.siger_project_repair
                            join f in _context.siger_project_machine_fault on q.faultid equals f.id into ftemp
                            from ff in ftemp.DefaultIfEmpty()
                            join fp in _context.siger_project_machine_fault on ff.parentid equals fp.id into fptemp
                            from ffp in fptemp.DefaultIfEmpty()
                            where q.projectid == projectId && q.status == (int)MachineRepairStatus.Completed
                                  && machineIds.Contains(q.machineid) && q.checktime > 0
                            select new RepairListForMTTR
                            {
                                createtime = q.createtime,
                                faultid = ff != null ? ff.id : 0,
                                faulttypeid = ffp != null ? ffp.id : 0,
                                fault_description = q.fault_description,
                                fault_content = ff != null ? ff.title : "",
                                id = q.id,
                                remark = q.remark,
                                repair_process = q.repair_process,
                                real_faultid_desc = q.real_faultid_desc,
                                sparepartid = q.sparepartid,
                                repairtime = q.checktime == 0 ? 0 : q.checktime - q.createtime,
                                offlinestatus = q.offlinestatus,
                                checktime = q.checktime,
                                machineid = q.machineid,
                                name = q.add_repairmid
                            };
            Expression<Func<RepairListForMTTR, bool>> startTimeExpression = q => true;
            if (startTime != 0)
            {
                startTimeExpression = q => q.createtime >= startTime;
            }
            Expression<Func<RepairListForMTTR, bool>> endTimeExpression = q => true;
            if (endTime != 0)
            {
                endTimeExpression = q => q.createtime <= endTime;
            }

            var predicate = startTimeExpression.And(endTimeExpression);

            var entities = queryList.Where(predicate).OrderByDescending(m => m.id).AsNoTracking().ToList();
            return entities;
        }

        public IEnumerable<GetStatusRepairList> GetRepairListByMachineArr(IEnumerable<int> machineIds, int status, int projectId, int userId)
        {
            var query = from q in _context.siger_project_repair
                        join u in _context.siger_project_user on q.mid equals u.mid
                        //join adduser in _context.siger_project_repair_add_user on q.id equals adduser.repairid into ftemp
                        //from adduser in ftemp.DefaultIfEmpty()
                        //join machine in _context.siger_project_machine on q.machineid equals machine.id
                        //join mt in _context.siger_project_machine_attribution on q.machineid equals mt.machine
                        //join lv in _context.siger_project_level_section on mt.station equals lv.id
                        //join plv in _context.siger_project_level_section on lv.parentid equals plv.id
                        where q.projectid == projectId && q.status > 0 && q.status < (int)MachineRepairStatus.Deleted
                        //&& machineIds.Contains(q.machineid) || (q.mid == userId || q.takemid == userId || q.signmid == userId ||
                        //  q.repairmid == userId || q.completemid == userId || adduser.mid == userId) &&
                        //&& machineIds.Contains(q.machineid) &&
                          && u.status == (int)RowState.Valid 
                        select new GetStatusRepairList
                        {
                            repairid = q.id,
                            createtime = q.createtime,
                            taketime = q.taketime,
                            signtime = q.signtime,
                            checktime = q.checktime,
                            repairtime = q.repairtime,
                            faultid = q.faultid,
                            real_raultid = q.real_faultid,
                            machineid = q.machineid,
                            //levelLocation =$"{plv.title}-{lv.title}-{machine.title}",
                            completemid = q.completemid,
                            completetime = q.completetime,
                            offlinestatus = q.offlinestatus,
                            mid = q.mid,
                            add_repairmid = q.add_repairmid,
                            repairmid = q.repairmid,
                            takemid = q.takemid,
                            signmid = q.signmid,
                            checkmid = q.checkmid,
                            report_level = q.report_level,
                            fault_description = q.fault_description,
                            images = q.images,
                            username = u.name,
                            work_code = u.work_code,
                            status = q.status,
                            repairremark = q.repair_remark,
                            createtimeformat = UnixTimeHelper.ConvertIntDateTime(q.createtime),
                            sparepartid = q.sparepartid,
                            work_order = q.id.ToStr(),
                            expection = q.expection_id,
                            remark = q.remark,
                            usermids = new List<int> { q.mid, q.takemid, q.signmid, q.checkmid, q.completemid, q.repairmid }
                        };

            Expression<Func<GetStatusRepairList, bool>> typeExpression = q => true;
            if (status > 0)
            {
                typeExpression = q => q.status == status;
            }
            Expression<Func<GetStatusRepairList, bool>> machinesExpression = q => true;
            if (machineIds.Any())
            {
                machinesExpression = q => machineIds.Contains(q.machineid);
            }
            var condition = typeExpression.And(machinesExpression);
            var dataList = query.Where(condition).OrderBy(t => t.status).ThenBy(d=>d.createtime);
            return dataList;
            //return dataList.GroupBy(t => t.repairid).Select(t => t.FirstOrDefault());
        }


        public IEnumerable<FaultTypeModel> GetFaultTypeList(int typeid, int projectId)
        {
            var res = new List<FaultTypeModel>();
            var faultquery1 = _context.siger_project_machine_fault.Where(t => t.status == (int)RowState.Valid && t.typeid == typeid && t.projectid == projectId && t.parentid == 0).ToList();
            if (faultquery1.Any())
            {
                var faultquery2 = _context.siger_project_machine_fault.Where(t => t.status == (int)RowState.Valid && t.typeid == typeid && t.projectid == projectId && t.parentid != 0).ToList();
                if (faultquery2.Any())
                {
                    foreach (var fault1 in faultquery1)
                    {
                        var faultcontentlist = new List<FaultContentModel>();
                        foreach (var fault2 in faultquery2)
                        {
                            faultcontentlist.Add(new FaultContentModel
                            {
                                faultcontent = fault2.title,
                                faultcontentid = fault2.id
                            });
                        }
                        res.Add(new FaultTypeModel
                        {
                            faulttype = fault1.title,
                            faultid = fault1.id,
                            faultcontentlist = faultcontentlist
                        });
                    }
                }
            }

            return res.AsEnumerable();
        }

        public GetStatusRepairList GetRepairInfoByID(int repairid, int projectId)
        {
            var query = from q in _context.siger_project_repair
                        join u in _context.siger_project_user on q.mid equals u.mid
                        //join machine in _context.siger_project_machine on q.machineid equals machine.id into fptemp
                        //from machine in fptemp.DefaultIfEmpty()
                        where q.status != 0 && q.projectid == projectId && /*machine.status == (int)RowState.Valid &&*/
                              u.status == (int)RowState.Valid && q.id == repairid
                        select new GetStatusRepairList
                        {
                            repairid = q.id,
                            createtime = q.createtime,
                            taketime = q.taketime,
                            signtime = q.signtime,
                            checktime = q.checktime,
                            repairtime = q.repairtime,
                            faultid = q.faultid,
                            real_raultid = q.real_faultid,
                            machineid = q.machineid,
                            completemid = q.completemid,
                            completetime = q.completetime,
                            offlinestatus = q.offlinestatus,
                            mid = q.mid,
                            add_repairmid = q.add_repairmid,
                            repairmid = q.repairmid,
                            takemid = q.takemid,
                            signmid = q.signmid,
                            checkmid = q.checkmid,
                            report_level = q.report_level,
                            fault_description = q.fault_description,
                            images = q.images,
                            username = u.name,
                            work_code = u.work_code,
                            status = q.status,
                            repairremark = q.repair_remark,
                            sparepartid = q.sparepartid,
                            createtimeformat = UnixTimeHelper.ConvertIntDateTime(q.createtime),
                            serial_number = q.createtime.ToStr(),
                            fault_desc_img = q.fault_desc_img,
                            repair_process = q.repair_process,
                            remark = q.remark,
                            cost = q.cost_purpose,
                            work_order = q.id.ToStr(),
                            usermids = new List<int> { q.mid, q.takemid, q.signmid, q.checkmid, q.completemid, q.repairmid }
                        };

            return query.FirstOrDefault();
        }

        /// <summary>
        /// 根据repairid判断该工单上报等级
        /// </summary>
        public LevelByRepair LevelByRepair(int repairId, int projectId)
        {
            var query = from r in _context.siger_project_repair
                        join m in _context.siger_project_machine on r.machineid equals m.id
                        where r.status < 6 && r.status != 0 && r.id == repairId && r.projectid == projectId
                        select new LevelByRepair
                        {
                            id = r.id,
                            machineid = r.machineid,
                            createtime = r.createtime,
                            faultid = r.faultid,
                            projectid = m.projectid,
                            mid = r.mid,
                            remark = r.remark,
                            status = r.status,
                            images = r.images,
                            takemid = r.takemid,
                            refuse_recovery_info = r.refuse_recovery_info,
                            refuse_repair_info = r.refuse_repair_info,
                            signmid = r.signmid,
                            signtime = r.signtime,
                            taketime = r.taketime,
                            repairmid = r.repairmid,
                            repairtime = r.repairtime,
                            checkmid = r.checkmid,
                            checktime = r.checktime,
                            fault_description = r.fault_description,
                            fault_desc_img = r.fault_desc_img,
                            real_faultid = r.real_faultid,
                            real_faultid_desc = r.real_faultid_desc,
                            last_repair_record = r.last_repair_record,
                            repair_process = r.repair_process,
                            repair_remark = r.repair_remark,
                            report_level = r.report_level,
                            add_repairmid = r.add_repairmid,
                            sparepartid = r.sparepartid,
                            sparepartout = r.sparepartout,
                            offlinestatus = r.offlinestatus,
                            completemid = r.completemid,
                            completetime = r.completetime
                        };

            return query.FirstOrDefault();
        }

        public IEnumerable<siger_project_repair_cooperate_reason> GetCooperateReasonList(int projectid, int languageType)
        {
            return _context.siger_project_repair_cooperate_reason.Where(t =>
                t.status == (int)RowState.Valid && t.projectid == projectid && t.language == languageType);
        }

        public List<ResponseRepairWorkCount> GetRepairWorkCount(long start, long end, int pid)
        {
            var ret = new List<ResponseRepairWorkCount>();
            // 1待接单，2已接单;待签到，3待维修，4签到;待复线，5维修完成,待反馈，6已完成，7已完成，0->删除
            var query = from r in _context.siger_project_repair
                        join t in _context.siger_andon_expection_type on r.expection_id equals t.id
                        join usg in _context.siger_project_usergroup on t.usergroup equals usg.id into utemp
                        from usg in utemp.DefaultIfEmpty()
                        where r.projectid == pid && r.status > 1 && r.createtime >= start && r.createtime <= end
                        select new TempRepairList
                        {
                            id = r.id,
                            creatmid = r.mid,
                            takemid=r.takemid,
                            signmid = r.signmid,
                            complatemid = r.completemid,
                            excptype=r.expection_id,
                            typeStation=usg!=null?usg.title:"",
                            status=r.status
                        };

            var excpType = query.GroupBy(g => g.excptype).ToList();
            foreach(var type in excpType)
            {
                var typeObj = type.FirstOrDefault();
                var typelist = type.ToList();
                var mode1 = new ResponseRepairWorkCount
                {
                    title = typeObj.typeStation,
                    handle = typelist.Count(),
                    handle_count = typelist.GroupBy(g=>g.takemid).Count(),
                    sign = typelist.Count(),
                    sign_count = typelist.GroupBy(g => g.signmid).Count(),
                    complete = typelist.Count(),
                    complete_count = typelist.GroupBy(g => g.complatemid).Count(),
                };
                ret.Add(mode1);
            }
            return ret;
        }
    }
}
