using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Microsoft.AspNetCore.Mvc;
using Siger.ApiCommon.Exceptions;
using Siger.ApiCommon.Filters;
using Siger.ApiCommon.Result;
using Siger.ApiCommon.Utilities;
using Siger.ApiTPM.Result;
using Siger.ApiTPM.Utilities;
using Siger.Middlelayer.Common;
using Siger.Middlelayer.Common.AppSettings;
using Siger.Middlelayer.Common.Extensions;
using Siger.Middlelayer.Common.Helpers;
using Siger.Middlelayer.Common.ModuleEnum;
using Siger.Middlelayer.Log;
using Siger.Middlelayer.Repository;
using Siger.Middlelayer.Repository.Paged;
using Siger.Middlelayer.Repository.Repositories.Interface;
using Siger.Middlelayer.TpmRepository.Entities;
using Siger.Middlelayer.TpmRepository.Repositories.Interface;
using Siger.Middlelayer.TpmRepository.Request;
using Siger.Middlelayer.TpmRepository.Response;
using Siger.Middlelayer.Utility.Helpers;
using Siger.Middlelayer.Utility.ImportEntities;
using MachineStatus = Siger.ApiTPM.Result.MachineStatus;
using UnixTimeHelper = Siger.Middlelayer.Common.Helpers.UnixTimeHelper;

namespace Siger.ApiTPM.Controllers
{
    public class RepairController : BaseController
    {
        private readonly ISigerProjectLevelSectionRepository _levelSectionRepository;
        private readonly ISigerProjectLevelSectionMachineRepository _levelSectionMachineRepository;
        private readonly ISigerProjectMachineRepository _machineRepository;
        private readonly ISigerProjectMachineTypeRepository _machineTypeRepository;
        private readonly IRepairRepository _repairRepository;
        private readonly ISparepartRepository _sparepartRepository;
        private readonly IFaultTypeRepository _faultTypeRepository;
        private readonly ISigerProjectUserRepository _projectUserRepository;
        private readonly IRepairListRepository _repairListRepository;
        private readonly ISigerProjectMachineAttributionRepository _machineAttributionRepository;
        private readonly IPlanRepository _planRepository;
        private readonly IUnitOfWork _unitOfWork;
        public RepairController(IUnitOfWork unitOfWork, ISigerProjectLevelSectionRepository levelSectionRepository,
            ISigerProjectLevelSectionMachineRepository levelSectionMachineRepository, IRepairRepository repairRepository,
            ISigerProjectMachineRepository machineRepository, ISparepartRepository sparepartRepository, IFaultTypeRepository faultTypeRepository,
            ISigerProjectMachineTypeRepository machineTypeRepository, ISigerProjectUserRepository projectUserRepository,
            IPlanRepository planRepository, IRepairListRepository repairListRepository, ISigerProjectMachineAttributionRepository machineAttributionRepository)
        {
            _unitOfWork = unitOfWork;
            _levelSectionRepository = levelSectionRepository;
            _levelSectionMachineRepository = levelSectionMachineRepository;
            _repairRepository = repairRepository;
            _machineRepository = machineRepository;
            _sparepartRepository = sparepartRepository;
            _faultTypeRepository = faultTypeRepository;
            _machineTypeRepository = machineTypeRepository;
            _projectUserRepository = projectUserRepository;
            _planRepository = planRepository;
            _repairListRepository = repairListRepository;
            _machineAttributionRepository = machineAttributionRepository;
        }

        [HttpGet]
        public IActionResult GetLevelSectionTreeForTpm()
        {
            var response = new LevelSectionTreeForTpmResult();

            var list = _levelSectionRepository.GetLevelSectionTree(ProjectId);

            var lastSections = _levelSectionMachineRepository.GetLastSection(ProjectId).ToList();
            var lastSectionIds = lastSections.Select(m => m.id).ToList();

            var levelSections = _machineAttributionRepository.GetList(q => list.Select(m => m.id).Contains(q.station) && q.attribution < 4).ToList();
            //_levelSectionMachineRepository.GetList(q => list.Select(m => m.id).Contains(q.section_id)).ToList();

            var machineIds = _machineRepository.GetList(q => q.projectid == ProjectId && q.status == (int)RowState.Valid
                                                             && q.attribution < 4).Select(m => m.id)
                .ToList();

            var machineStatusList = new List<int>();
            foreach (var levelSection in list)
            {
                if (lastSectionIds.Contains(levelSection.id))
                {
                    var isBindMachine = 0;
                    var machineStatus = 8;
                    var sections = lastSections.Where(q => q.id == levelSection.id).ToList();
                    if (sections.Any())
                    {
                        foreach (var section in sections)
                        {
                            var machines = levelSections.Where(t => t.station == section.id);
                            var machineList = new List<int>();
                            if (machines.Any())
                            {
                                foreach (var machine in machines)
                                {
                                    machineList.Add(machine.machine);
                                }
                            }
                            if (machineList.Any())
                            {
                                isBindMachine = 1;
                                var minStatus = _repairRepository.GetList(q => q.status > 0 && q.status < (int)MachineRepairStatus.Deleted && q.projectid == ProjectId
                                    && machineList.Contains(q.machineid)).OrderBy(q => q.status).ToList();
                                if (minStatus.Any())
                                {
                                    machineStatus = minStatus.First().status;
                                }
                                machineStatusList.Add(machineStatus);
                            }
                            else
                            {
                                machineStatusList.Add(0); // 未绑定
                            }
                        }
                    }
                    response.sectionTree.Add(new ResponseLevelSectionTree
                    {
                        id = levelSection.id,
                        name = levelSection.name,
                        open = true,
                        pid = levelSection.pid,
                        isBindMachine = isBindMachine,
                        machineStatus = machineStatus,
                        isleaf = true,
                        machineId = levelSections.FirstOrDefault(t => t.station == levelSection.id)?.machine ?? 0
                    });
                }
                else
                {
                    response.sectionTree.Add(new ResponseLevelSectionTree
                    {
                        id = levelSection.id,
                        name = levelSection.name,
                        open = true,
                        pid = levelSection.pid,
                        isleaf = false,
                        machineId = 0
                    });
                }
            }

            var attrbutionMachines = levelSections.Select(m => m.machine).Distinct().ToList();
            response.status.Add(new MachineStatus
            {
                icon = "glyphicon glyphicon-question-sign",
                color = "",
                name = "1135", //未绑定
                status = 0,
                //count = machineStatusList.Count(m => m == 0) //不在设备结构树里的设备
                count = machineIds.Count - attrbutionMachines.Count <= 0 ? 0 : machineIds.Count - attrbutionMachines.Count
            });
            response.status.Add(new MachineStatus
            {
                icon = "glyphicon glyphicon-exclamation-sign",
                color = "",
                name = "200032", //待接单
                status = 1,
                count = machineStatusList.Count(m => m == 1)
            });
            response.status.Add(new MachineStatus
            {
                icon = "glyphicon glyphicon-copy",
                color = "",
                name = "200033",//待签到
                status = 2,
                count = machineStatusList.Count(m => m == 2)
            });
            response.status.Add(new MachineStatus
            {
                icon = "glyphicon glyphicon-wrench",
                color = "",
                name = "200034",//维修中
                status = 3,
                count = machineStatusList.Count(m => m == 3)
            });
            response.status.Add(new MachineStatus
            {
                icon = "glyphicon glyphicon-wrench",
                color = "",
                name = "200035",//待复线
                status = 4,
                count = machineStatusList.Count(m => m == 4)
            });
            response.status.Add(new MachineStatus
            {
                icon = "glyphicon glyphicon-paste",
                color = "",
                name = "900704",//待反馈
                status = 5,
                count = machineStatusList.Count(m => m == 5)
            });
            response.status.Add(new MachineStatus
            {
                icon = "glyphicon glyphicon-thumbs-up",
                color = "",
                name = "100200",//正常
                status = 8,
                count = machineStatusList.Count(m => m == 8 || m == 6)
            });

            return new ObjectResult(response);
        }

        [HttpGet]
        public IActionResult GetUnFinishedRepairList()
        {
            var response = new List<ResponseUnFinishedRepair>();
            var repairs = _repairRepository.GetUnFinishedRepair(ProjectId);

            var machineIds = repairs.Select(m => m.machineId).Distinct();
            var stations = _levelSectionMachineRepository.GetMachinSectionInfos(machineIds, ProjectId).ToList();
            var machines = _machineRepository.GetList(q => machineIds.Contains(q.id) && q.projectid == ProjectId).ToList();
            foreach (var repair in repairs)
            {
                var data = Mapper<ResponseUnFinishedRepair, ResponseUnFinishedRepair>.Map(repair);
                var station = stations.FirstOrDefault(q => q.machineId == repair.machineId);
                var machine = machines.FirstOrDefault(q => q.id == repair.machineId);
                data.location = station == null ? "" : station.section_name + "-" + station.station_name;
                data.machinename = machine == null ? "" : machine.title;
                data.createtimeformat = UnixTimeHelper.ConvertStringDateTime(repair.createtime.ToString())
                    .ToString(ParameterConstant.YearMonthDayHourMinute);
                data.haslong = (int)((UnixTimeHelper.GetNow() - repair.createtime) / 60);

                var spars = repair.sparepart_number.Split(',');
                var sparInfos = new List<string>();
                foreach (var spar in spars)
                {
                    var sps = spar.Split('*');
                    if (sps.Length == 2)
                    {
                        var sp = _sparepartRepository.Get(int.Parse(sps[0]));
                        if (sp.status == (int)RowState.Valid)
                        {
                            sparInfos.Add($"{sp.title}({sp.code})*{sps[1]}");
                        }
                    }
                }

                data.spare = string.Join(',', sparInfos);
                response.Add(data);
            }

            return new ObjectResult(response);
        }

        [HttpGet]
        public IActionResult GetUnstandardRepairInfo(int machineType, string starttime, string endtime, int page, int pagesize)
        {
            if (machineType == 0)
            {
                throw new BadRequestException(RequestEnum.PleaseSelectMachineType);
            }
            var ids = _machineRepository.GetList(q =>
                q.typeid == machineType && q.projectid == ProjectId && q.status == (int)RowState.Valid).Select(m => m.id).ToList();

            if (!ids.Any())
            {
                return new ObjectResult(CommonEnum.Succefull);
            }

            var startTime = 0;
            var endTime = 0;
            if (!string.IsNullOrWhiteSpace(starttime))
            {
                startTime = UnixTimeHelper.GetUnixByDate(starttime);
                endTime = UnixTimeHelper.GetUnixByDate(DateTime.Parse(endtime).ToString(ParameterConstant.DateToEnd));
            }

            var datas = _repairRepository.GetPagedUnstandardRepairInfo(ids, startTime, endTime, ProjectId, page,
                pagesize);
            var response = new List<ResponseUnstandardRepairInfo>();
            foreach (var repair in datas.Data)
            {
                var data = Mapper<ResponseUnstandardRepairInfo, ResponseUnstandardRepairInfo>.Map(repair);
                data.reporttime = UnixTimeHelper.ConvertStringDateTime(repair.createtime.ToString())
                    .ToString(ParameterConstant.YearMonthDayHourMinute);
                data.add_repairmid_name = _repairRepository.GetUserNames(repair.add_repairmid_name.Split(','));
                data.stoptime = (repair.checktime - repair.createtime) / 60;

                var spars = repair.sparepartid.Split(',');
                var sparInfos = new List<string>();
                foreach (var spar in spars)
                {
                    var sps = spar.Split('*');
                    if (sps.Length == 2)
                    {
                        var sp = _sparepartRepository.Get(int.Parse(sps[0]));
                        if (sp.status == (int)RowState.Valid)
                        {
                            sparInfos.Add($"{sp.title}({sp.code})*{sps[1]}");
                        }
                    }
                }

                data.sparepart = string.Join(',', sparInfos);

                response.Add(data);
            }

            return new PagedObjectResult(response, datas.Total, page, pagesize);
        }

        [HttpGet]
        public IActionResult BatchDefineRepairFault(int id, int fault_id)
        {
            var repair = _repairRepository.Get(id);
            if (repair == null)
            {
                throw new BadRequestException(CommonEnum.RecordNotFound);
            }
            var query = _faultTypeRepository.Get(f => f.id.Equals(fault_id));
            if (query == null)
            {
                throw new BadRequestException(CommonEnum.RecordNotFound);
            }
            switch ((FaultType)query.typeid)
            {
                case FaultType.FailureMode:
                    repair.faultid = query.id;
                    break;
                case FaultType.FailureReason:
                    repair.real_faultid = query.id;
                    break;
                case FaultType.RepairMeasures:
                    repair.repair_process = query.id.ToString();
                    break;
            }
            _repairRepository.Update(repair);
            if (_unitOfWork.Commit() > 0)
            {
                return new ObjectResult(CommonEnum.Succefull);
            }
            throw new BadRequestException(CommonEnum.Fail);
        }

        [HttpPost]
        public IActionResult GetRepairListNew([FromBody]RequestGetRepairList request)
        {
            var response = new List<ResponseGetRepairList>();
            var list = GetRepairList(request, false);
            var tempData = list.Data;
            if (request.repairmid != 0)
            {
                tempData = tempData.Where(f => f.mids.Any(ff => ff == request.repairmid.ToStr()));
            }
            var repairs = tempData.Skip((request.page - 1) * request.pagesize).Take(request.pagesize);
            var machineIds = repairs.Select(m => m.machineId);
            var stations = _machineRepository.GetMachineStationInfos(machineIds, ProjectId).ToList();
            var faulttype = EnumHelper.EnumToList<FaultType>();
            foreach (var repair in repairs)
            {
                var userIds = repair.mids;
                userIds.Add(repair.completemid.ToString());

                var data = Mapper<ResponseGetRepairList, ResponseGetRepairList>.Map(repair);
                data.createtimeformat = UnixTimeHelper.ConvertStringDateTime(data.createtime.ToString()).ToString(ParameterConstant.YearMonthDayHourMinute);
                var station = stations.FirstOrDefault(q => q.machineId == repair.machineId);
                if (station != null)
                {
                    var sectionTitles = _machineRepository.GetParentSelfLevelSections(station.id, ProjectId).Select(t => t.title).ToList();
                    sectionTitles.Reverse();
                    sectionTitles.Add(station.station_name);
                    data.location = string.Join('-', sectionTitles);
                }
                else
                {
                    data.location = "";
                }
                //data.faultcontent = faulttype.FirstOrDefault(f => f.EnumValue.Equals(data.faulttype))?.Description ?? "";
              
                var machine = _machineRepository.Get(q => q.id == repair.machineId && q.status == (int)RowState.Valid);
                data.station = machine == null ? "" : machine.title;
                data.repairtime = Math.Round(repair.checktime == 0 ? 0 : (repair.checktime - repair.signtime) / (double)60, 1);
                data.taketime = Math.Round(repair.taketime == 0 ? 0 : (repair.taketime - repair.createtime) / 60, 1);
                data.totaltime = Math.Round(data.repairtime + data.taketime, 1);

                data.add_repairmid_name = _repairRepository.GetUserNames(userIds);
                data.repair_remark = repair.repair_remark;

                if (!string.IsNullOrWhiteSpace(repair.add_repairmid))
                {
                    var userId = repair.add_repairmid.Split(',').ToList().First();
                    var user = _projectUserRepository.Get(q => q.mid == userId.ToInt() && q.projectid == ProjectId);
                    data.add_repairmid_sectionid = user != null ? user.sectionid : 0;
                }
                var spars = repair.sparepartid.Split(',');
                var sparInfos = new List<string>();
                foreach (var spar in spars)
                {
                    var sps = spar.Split('*');
                    if (sps.Length == 2)
                    {
                        var sp = _sparepartRepository.Get(int.Parse(sps[0]));
                        if (sp.status == (int)RowState.Valid)
                        {
                            sparInfos.Add($"{sp.title}({sp.code})*{sps[1]}");
                        }
                    }
                }

                data.sparepart = string.Join(',', sparInfos);

                var temp = repair.taketime - repair.createtime;
                data.time1 = temp < 0 ? 0 : Math.Round(temp / 60, 1);
                data.user1 = _projectUserRepository.Get(f => f.mid == repair.takemid)?.name ?? "";
                temp = repair.signtime - repair.taketime;
                data.time2 = temp < 0 ? 0 : Math.Round(temp / 60, 1);
                data.user2 = _projectUserRepository.Get(f => f.mid == repair.signmid)?.name ?? "";
                temp = repair.completetime - repair.signtime;
                data.time3 = temp < 0 ? 0 : Math.Round(temp / 60, 1);
                data.user3 = _projectUserRepository.Get(f => f.mid == repair.completemid)?.name ?? "";
                temp = repair.checktime - repair.completetime;
                data.time4 = temp < 0 ? 0 : Math.Round(temp / 60, 1);
                data.user4 = _projectUserRepository.Get(f => f.mid == repair.checkmid)?.name ?? "";

                data.time6 = Math.Round(data.time1 + data.time2 + data.time3 + data.time4 + data.time5, 1);
                data.creator = _projectUserRepository.Get(f => f.mid == data.mid)?.name ?? "";
                response.Add(data);
            }

            return new PagedObjectResult(response, tempData.Count(), request.page, request.pagesize);
        }

        [HttpGet]
        public IActionResult GetRepairInfoDetail(int id)
        {
            var repair = _repairRepository.Get(id);
            if (repair == null)
            {
                throw new BadRequestException(CommonEnum.RecordNotFound);
            }

            var response = Mapper<siger_project_repair, ResponseGetRepairInfo>.Map(repair);
            response.repairtime = Math.Round(repair.checktime == 0 ? 0 : (repair.checktime - repair.signtime) / (double)60, 1);
            response.taketime = Math.Round(repair.taketime == 0 ? 0 : (repair.taketime - repair.createtime) / (double)60, 1);
            response.faultlist_id = repair.faultid; //故障类型
            response.faultcontent_id = repair.real_faultid; //失效模式
            response.sparepartout = repair.sparepartout;

            var spars = repair.sparepartid.Split(',');
            var sparInfos = new Dictionary<int, string>();
            foreach (var spar in spars)
            {
                var sps = spar.Split('*');
                if (sps.Length == 2)
                {
                    if (!sparInfos.ContainsKey(sps[0].ToInt()))
                    {
                        sparInfos.Add(sps[0].ToInt(), sps[1]);
                    }
                }
            }

            response.sparepartarr = sparInfos;

            var machine = _machineRepository.Get(repair.machineid);
            if (machine != null)
            {
                response.machinetype_id = machine.typeid;
            }

            return new ObjectResult(response);
        }

        [HttpPost]
        public IActionResult AddRepairRecord([FromBody] RequestAddRepairRecord request)
        {
            if (request.machineid.ToInt() == 0 || request.mid.ToInt() == 0 || string.IsNullOrWhiteSpace(request.repairmid)
                || request.signmid.ToInt() == 0 || request.checkmid.ToInt() == 0
                || string.IsNullOrWhiteSpace(request.fault_description) ||
                string.IsNullOrWhiteSpace(request.repair_process) ||
                string.IsNullOrWhiteSpace(request.real_faultid_desc))
            {
                throw new ServerException(600652);
            }

            if (string.IsNullOrWhiteSpace(request.createtime))
            {
                throw new ServerException(200102);
            }

            if (DateTime.Parse(request.createtime) > DateTime.Now)
            {
                throw new BadRequestException(RequestEnum.RepairTimeError);
            }

            if (request.taketime.ToInt() <= 0)
            {
                throw new ServerException(200103);
            }

            if (request.repairtime.ToInt() <= 0)
            {
                throw new ServerException(200104);
            }

            if (request.faultcontent_id.ToInt() == 0 && string.IsNullOrWhiteSpace(request.remark))
            {
                throw new ServerException(1195);
            }

            var reportTime = UnixTimeHelper.GetUnixByShortDate(request.createtime);
            var entity = new siger_project_repair
            {
                machineid = request.machineid.ToInt(),
                add_repairmid = request.repairmid,
                createtime = reportTime,
                checkmid = request.checkmid.ToInt(),
                signtime = reportTime + request.taketime.ToInt() * 60,
                repairtime = reportTime + request.taketime.ToInt() * 60 + request.repairtime.ToInt() * 60,
                checktime = reportTime + request.taketime.ToInt() * 60 + request.repairtime.ToInt() * 60,
                faultid = request.faultid.ToInt(),
                real_faultid = request.faultcontent_id.ToInt(),
                mid = request.mid.ToInt(),
                signmid = request.signmid.ToInt(),
                remark = request.remark,
                offlinestatus = request.offlinestatus.ToInt(),
                fault_description = request.fault_description,
                repair_process = request.repair_process,
                real_faultid_desc = request.real_faultid_desc,
                //repair_remark = request.repair_remark,
                status = (int)MachineRepairStatus.Completed,
                sparepartid = request.SparepartOut,
                fault_desc_img = request.fault_desc_img,
                images = request.images,
                projectid = ProjectId,
                taketime = reportTime + request.taketime.ToInt() * 60,
            };
            entity.completetime = entity.signtime;

            _repairRepository.Insert(entity);

            if (_unitOfWork.Commit() > 0)
            {
                return new ObjectResult(CommonEnum.Succefull);
            }
            throw new BadRequestException(CommonEnum.Fail);
        }

        [HttpPost]
        public IActionResult EditRepairInfo([FromBody] RequestEditRepairInfo request)
        {
            var repair = _repairRepository.Get(request.id);
            if (repair == null)
            {
                throw new BadRequestException(CommonEnum.RecordNotFound);
            }

            repair.add_repairmid = request.repairmid;
            repair.checkmid = request.checkmid.ToInt();
            //repair.signtime =
            //    repair.signtime <= 0 ? repair.createtime + request.taketime.ToInt() * 60 : repair.signtime;
            //repair.repairtime = repair.repairtime <= 0
            //    ? repair.createtime + request.taketime.ToInt() * 60 + request.repairtime.ToInt() * 60
            //    : repair.repairtime;
            //repair.checktime = repair.checktime <= 0
            //    ? repair.createtime + request.taketime.ToInt() * 60 + request.repairtime.ToInt() * 60
            //    : repair.checktime;
            repair.faultid = request.faultid.ToInt();
            repair.real_faultid = request.faultcontent_id.ToInt();
            repair.mid = request.mid.ToInt();
            repair.signmid = request.signmid.ToInt();
            repair.remark = request.remark;
            repair.offlinestatus = request.offlinestatus.ToInt();
            repair.fault_description = request.fault_description;
            repair.repair_process = request.repair_process;
            repair.real_faultid_desc = request.real_faultid_desc;
            repair.sparepartid = request.SparepartOut;
            if (!string.IsNullOrWhiteSpace(request.fault_desc_img))
            {
                repair.fault_desc_img = request.fault_desc_img;
            }
            if (!string.IsNullOrWhiteSpace(request.images))
            {
                repair.images = request.images;
            }
            //repair.taketime = repair.createtime + request.taketime.ToInt() * 60;

            _repairRepository.Update(repair);
            if (_unitOfWork.Commit() > 0)
            {
                return new ObjectResult(CommonEnum.Succefull);
            }
            throw new BadRequestException(CommonEnum.Fail);
        }

        [HttpPost]
        public IActionResult DeleteRepairOne([FromBody]RequestIdsArry arry)
        {
            if (!arry.ids.Any())
                throw new BadRequestException(RequestEnum.ParameterMiss);
            foreach (var id in arry.ids)
            {
                var repair = _repairRepository.Get(id);
                if (repair == null)
                {
                    throw new BadRequestException(CommonEnum.RecordNotFound);
                }
                repair.status = (int)MachineRepairStatus.Deleted;
                _repairRepository.Update(repair);
            }
            if (_unitOfWork.Commit() > 0)
            {
                return new ObjectResult(CommonEnum.Succefull);
            }
            throw new BadRequestException(CommonEnum.Fail);
        }

        private IPagedCollectionResult<ResponseGetRepairList> GetRepairList(RequestGetRepairList request, bool paged = true)
        {
            var machineTypeIds = new List<int>();
            var machineIds = _machineRepository.GetAttributionMachineIds(request.section_id.ToInt(), ProjectId);
            if (!machineIds.Any())
            {
                throw new BadRequestException(CommonEnum.RecordNotFound);
            }

            //取设备
            if (!string.IsNullOrWhiteSpace(request.type_id) && string.IsNullOrWhiteSpace(request.concrete_id))
            {
                machineTypeIds = _machineTypeRepository
                    .GetList(q => q.parentid == request.type_id.ToInt() && q.projectid == ProjectId && q.status == (int)RowState.Valid)
                    .Select(m => m.id).ToList();

                machineIds = _machineRepository.GetList(q =>
                    machineIds.Contains(q.id) && machineTypeIds.Contains(q.typeid) && q.status == (int)RowState.Valid
                    && q.projectid == ProjectId).Select(m => m.id).ToList();
            }
            else if (!string.IsNullOrWhiteSpace(request.concrete_id))
            {
                machineTypeIds = _machineTypeRepository
                    .GetList(q => q.id == request.concrete_id.ToInt() && q.projectid == ProjectId && q.status == (int)RowState.Valid)
                    .Select(m => m.id).ToList();

                machineIds = _machineRepository.GetList(q =>
                    machineIds.Contains(q.id) && machineTypeIds.Contains(q.typeid) && q.status == (int)RowState.Valid
                    && q.projectid == ProjectId).Select(m => m.id).ToList();
            }

            var startTime = string.IsNullOrWhiteSpace(request.startTime) ? 0 : UnixTimeHelper.GetUnixByShortDate(request.startTime);
            var endTime = string.IsNullOrWhiteSpace(request.endtime) ? 0 : UnixTimeHelper.GetUnixByShortDate(request.endtime);

            var repairs = _repairRepository.GetPagedRepairList(machineIds, startTime, endTime, request.repairname,
                request.repairid, request.fault_id.ToInt(), request.faulttype_id.ToInt(), request.status.ToInt(), request.compare.ToInt(), request.compare_time.ToDouble(), request.cost.ToInt(), ProjectId,
                request.andonType, request.page, request.pagesize, request.repairmid, request.workordertype, paged);

            return repairs;
        }

        /// <summary>
        /// 导出excel
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [HttpPost]
        public IActionResult GetRepairListExcel([FromBody]RequestGetRepairList request)
        {
            
            var rootDir = FileSystemHelper.GetPhysicalFolders(FileSystemHelper.CommonFileSetting.PhysicalFolder, FileSystemHelper.ExportFileName);

            var response = new List<ResponseGetRepairList>();
            var repairs = GetRepairList(request, false);
            if (!repairs.Data.Any())
            {
                throw new BadRequestException(CommonEnum.RecordNotFound);
            }
            var tempData = repairs.Data;
            if (request.repairmid != 0)
            {
                tempData = tempData.Where(f => f.mids.Any(ff => ff == request.repairmid.ToStr()));
            }
            var machineIds = repairs.Data.Select(m => m.machineId);
            var stations = _machineRepository.GetMachineStationInfos(machineIds, ProjectId).ToList();
            foreach (var repair in tempData)
            {
                var data = Mapper<ResponseGetRepairList, ResponseGetRepairList>.Map(repair);
                data.createtimeformat = UnixTimeHelper.ConvertStringDateTime(data.createtime.ToString()).ToString(ParameterConstant.YearMonthDayHourMinute);

                var station = stations.FirstOrDefault(q => q.machineId == repair.machineId);
                if (station != null)
                {
                    var sectionTitles = _machineRepository.GetParentSelfLevelSections(station.id, ProjectId).Select(t => t.title).ToList();
                    sectionTitles.Reverse();
                    sectionTitles.Add(station.station_name);
                    data.location = string.Join('-', sectionTitles);
                }
                else
                {
                    data.location = "";
                }

                var machine = _machineRepository.Get(q => q.id == repair.machineId && q.status == (int)RowState.Valid);
                data.station = machine == null ? "" : machine.title;

                var userIds = repair.add_repairmid_name.Split(',').ToList();
                userIds.Add(repair.completemid.ToString());
                userIds = userIds.Where(t => t.ToInt() > 0).Distinct().ToList();
                data.add_repairmid_name = string.Join(';', _repairRepository.GetUserNames(userIds).Split(',').ToList());

                var spars = repair.sparepartid.Split(',');
                var sparInfos = new List<string>();
                foreach (var spar in spars)
                {
                    var sps = spar.Split('*');
                    if (sps.Length == 2)
                    {
                        var sp = _sparepartRepository.Get(int.Parse(sps[0]));
                        if (sp.status == (int)RowState.Valid)
                        {
                            sparInfos.Add($"{sp.title}({sp.code})*{sps[1]}");
                        }
                    }
                }

                data.sparepart = string.Join(',', sparInfos);
                data.creator = _projectUserRepository.Get(f => f.mid == data.mid)?.name ?? "";
                response.Add(data);
            }

            var temporaryFileName = $"repair_{DateTime.Now:yyyyMMddHHmmss}.xlsx";
            var fileName = Path.Combine(rootDir, temporaryFileName);

            var helper = new EpPlusExcelHelper<RepairList>();
            try
            {
                var translateHelper = new TranslateHelper(_repairRepository.GetProjectLanguage(ProjectId) == (int)LanguageType.EN);
                var repairList = new List<RepairList>();
                foreach (var repair in response)
                {
                    var entity = new RepairList
                    {
                        Id = repair.work_order,
                        Station = repair.station,
                        Location = repair.location,
                        CreateTime = repair.createtimeformat,
                        Remark1 = repair.repair_remark,
                        //Process = repair.repair_process,
                        //Fault = repair.faulttype,
                        InvalidMode = repair.faulttype,
                        OffLineStatus = repair.offlinestatus == 1
                            ? translateHelper.GetTranslateText(TranslateEnEnum.Yes)
                            : translateHelper.GetTranslateText(TranslateEnEnum.No),
                        Creator = repair.creator,
                        Sparepart = repair.sparepart,
                        RepairTime = Math.Round(repair.repairtime == 0 ? 0 : (repair.completetime - repair.signtime) / (double)60, 1),
                        RepairUser = repair.add_repairmid_name,
                        Status = GetRepairStatus(repair.status, translateHelper),
                        Remark = repair.remark,
                        OrderTime = Math.Round(repair.taketime == 0 ? 0 : (repair.taketime - repair.createtime) / (double)60, 1),
                        OrderUser = _repairRepository.GetUserByMid(repair.takemid)?.name ?? "",
                        SignTime = Math.Round(repair.signtime >= repair.taketime ? (repair.signtime - repair.taketime) / (double)60 : 0, 1),
                        RecoverTime = Math.Round(repair.checktime >= repair.completetime ? (repair.checktime - repair.completetime) / (double)60 : 0, 1),
                        RecoverUser = _repairRepository.GetUserByMid(repair.checkmid)?.name ?? "",
                        ExceptionType = repair.andontypename,
                        CostName = repair.cost == 0 ? "" : GetCostName(repair.cost)
                    };
                    entity.TotalTime = entity.RepairTime + entity.OrderTime + entity.SignTime + entity.RecoverTime;
                    repairList.Add(entity);
                }

                helper.GenerateExcel(repairList, fileName);
                return new ObjectResult($"{FileSystemHelper.CommonFileSetting.RequestPath}/{FileSystemHelper.ExportFileName}/{temporaryFileName}");
            }
            catch (Exception e)
            {
                Logger.WriteLineError("Export repairs failed, error: " + e.Message);
                throw new BadRequestException(RequestEnum.ExportFailed);
            }
            finally
            {
                helper.Dispose();
            }
        }

        private string GetRepairStatus(int status, TranslateHelper translateHelper)
        {
            string repairstatus = string.Empty;
            switch (status)
            {
                //待接单
                case 1:
                    repairstatus = translateHelper.GetTranslateText(TranslateCnEnum.TobeTaken);
                    break;
                case 2://待签到
                    repairstatus = translateHelper.GetTranslateText(TranslateCnEnum.TobeSignedIn);
                    break;
                case 3://待维修
                    repairstatus = translateHelper.GetTranslateText(TranslateCnEnum.UnderRepair);
                    break;
                case 4://待复线
                    repairstatus = translateHelper.GetTranslateText(TranslateCnEnum.TobeRecovered);
                    break;
                case 5://待提交维修反馈
                    repairstatus = translateHelper.GetTranslateText(TranslateCnEnum.TobeFeedBack);
                    break;
                case 6://已完成
                    repairstatus = translateHelper.GetTranslateText(TranslateCnEnum.Completed);
                    break;
                default:
                    break;
            }

            return repairstatus;
        }

        /// <summary>
        /// 编辑维修反馈，不用推送消息，也不用筛选权限
        /// </summary>
        /// <param name="req"></param>
        /// <returns></returns>
        [HttpPost]
        public IActionResult EditRepairFeedback([FromBody]RequestEditRepairFeedback req)
        {
            if (string.IsNullOrEmpty(req.description) || string.IsNullOrEmpty(req.process) || string.IsNullOrEmpty(req.reason))
            {
                throw new ServerException(900037);
            }
            if (!string.IsNullOrEmpty(req.description) && RegexHelper.InputRegex(req.description) ||
                !string.IsNullOrEmpty(req.reason) && RegexHelper.InputRegex(req.reason) ||
                !string.IsNullOrEmpty(req.process) && RegexHelper.InputRegex(req.process) ||
                !string.IsNullOrEmpty(req.remark) && RegexHelper.InputRegex(req.remark))
            {
                throw new ServerException(800064);
            }

            var repair = _repairRepository.Get(t => t.id == req.repairid && t.projectid == ProjectId &&
                    (t.status == (int)MachineRepairStatus.Completed || t.status == (int)MachineRepairStatus.WaitingForFeedback));
            if (repair == null)
            {
                throw new BadRequestException(CommonEnum.RecordNotFound);
            }

            repair.repair_process = req.process ?? "";
            repair.repair_remark = req.remark ?? "";
            repair.fault_description = req.description;
            repair.real_faultid_desc = req.reason ?? "";
            repair.sparepartout = req.sparepart ?? "";
            var now = UnixTimeHelper.GetNow();
            if (repair.status == (int)MachineRepairStatus.WaitingForFeedback)
            {
                repair.status = (int)MachineRepairStatus.Completed;
                repair.repairmid = UserId;
                repair.repairtime = now;
            }

            var isTranslate = _repairRepository.GetProjectLanguage(ProjectId) == (int)LanguageType.EN;
            var translateHelper = new TranslateHelper(isTranslate);
            //信息记录
            var userType = "";
            var userName = "";
            var userInfo = _repairRepository.GetUserByMid(UserId);
            var userSectionType = _repairRepository.GetSectionByUserId(UserId);
            if (userSectionType != null)
            {
                if (userSectionType.type == (int)SectionType.Maintenance)
                {
                    userType = translateHelper.GetTranslateText(TranslateEnEnum.MaintenanceStaff);
                }
                else
                {
                    userType = translateHelper.GetTranslateText(TranslateEnEnum.ProductionStaff);
                }

            }

            if (userInfo != null)
            {
                userName = userInfo.name + "(" + userInfo.mobile + ")";
            }
            var repairListInfo = new siger_project_repair_list
            {
                repairid = req.repairid,
                projectid = ProjectId,
                mid = UserId,
                status = (int)MachineRepairStatus.WaitingForRenew,
                content = userType + userName + translateHelper.GetTranslateText(TranslateEnEnum.EditedMaintenanceFeedbackSheet),
                creattime = now,
                title = ((int)RepairListStatus.MaintenanceFeedBack).ToString()
            };

            _repairRepository.Update(repair);
            _repairListRepository.Insert(repairListInfo);

            if (_unitOfWork.Commit() > 0)
            {
                return new ObjectResult(CommonEnum.Succefull);
            }

            throw new BadRequestException(CommonEnum.Fail);
        }

        [HttpGet]
        public IActionResult GetMachineRepairInfo(int machineid)
        {
            var res = new ResponseGetMachineRepairInfo();
            var locationHelper = new MachineLocationHelper(ProjectId, _planRepository);
            var locations = locationHelper.GetPositionByMachineId(machineid);
            var machine = _machineRepository.Get(t => t.id == machineid);
            res.location = string.Join('-', locations);
            res.machinename = machine?.title ?? "";
            var repair = _repairRepository.GetList(t => t.machineid == machineid &&
                  t.projectid == ProjectId && t.status > 0 && t.status < (int)MachineRepairStatus.Completed).OrderByDescending(t => t.id).FirstOrDefault();
            if (repair != null)
            {
                var repairList = _repairListRepository.GetList(t => t.status == repair.status &&
                    t.projectid == ProjectId && t.repairid == repair.id).OrderBy(t => t.creattime).FirstOrDefault();
                res.message = repairList?.content ?? "";
                res.title = repairList?.title ?? "";
                res.time = repairList == null ? "" : UnixTimeHelper.ConvertIntDateTime(repairList.creattime);
                res.work_order = repair.id.ToStr();
            }
            res.status = repair?.status ?? 0;

            return new ObjectResult(res);
        }

        [HttpGet]
        public IActionResult GetMachineRepairState()
        {
            var responses = new List<ResponseGetMachineRepairState>();
            var lines = _levelSectionRepository.GetAccLines(ProjectId).ToList();
            if (!lines.Any())
            {
                return new ObjectResult(responses);
            }
            var machines = _machineRepository.GetList(q => q.projectid == ProjectId && q.status == (int)RowState.Valid && q.attribution < 4).ToList();
            var levelSections = _machineAttributionRepository.GetList(q => machines.Select(m => m.id).Contains(q.machine) && q.attribution < 4 && q.status == (int)RowState.Valid).ToList();
            var machineRepairs = _repairRepository.GetList(q => q.status > 0 && q.status < (int)MachineRepairStatus.Deleted && q.projectid == ProjectId
                                                           && machines.Select(m => m.id).Contains(q.machineid)).OrderBy(q => q.status).ToList();
            var levelSectionNames = _levelSectionMachineRepository.GetLastSection(ProjectId).ToList();
            foreach (var item in lines)
            {
                var response = new ResponseGetMachineRepairState
                {
                    line = _levelSectionRepository.GetSectionString(ProjectId, item.id).TrimStart(new char[] { '-', '>' })
                };
                var machineids = _machineRepository.GetAttributionMachineIds(item.id, ProjectId).OrderBy(m => m).Distinct().ToList();
                foreach (var machineid in machineids)
                {
                    var mach = machines.FirstOrDefault(q => q.id == machineid);
                    if (mach == null) continue;
                    var machine = new MachineRepairState
                    {
                        id = machineid,
                        name = mach.title
                    };
                    var section = levelSections.FirstOrDefault(q => q.machine == machineid);
                    if (section == null)
                    {
                        machine.state = 0; //未绑定
                    }
                    else
                    {
                        var sectionName = levelSectionNames.FirstOrDefault(q => q.id == section.station);
                        if (sectionName != null)
                        {
                            machine.section_name = sectionName.title;
                        }
                        //latest
                        var machineRepair = machineRepairs.Where(q => q.machineid == machineid).OrderByDescending(q => q.id).FirstOrDefault();
                        machine.state = (int)MachineRepairStatus.Completed;
                        if (machineRepair != null)
                        {
                            machine.state = machineRepair?.status ?? (int)MachineRepairStatus.Completed;
                        }
                    }
                    response.machine.Add(machine);
                }

                responses.Add(response);
            }

            return new ObjectResult(responses);
        }

    }
}