using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Siger.ApiCommon.Result;
using Siger.ApiTPM.Utilities;
using Siger.Middlelayer.Common;
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.Entities;
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.ApiCommon.Filters;
using Siger.Middlelayer.Redis.Repositories;
using Siger.Middlelayer.Dapper;

namespace Siger.ApiTPM.Controllers
{
    /// <summary>
    /// 安灯基础设置
    /// </summary>
    public class AndonController : BaseController
    {
        private readonly IUnitOfWork _unitOfWork;
        private readonly ISigerAndonProcessRepository _andonProcessRepository;
        private readonly ISigerAndonExpectionTypeRepository _andonExpectionType;
        private readonly ISigerAndonInfoRepository _andonInfoRepository;
        private readonly ISigerAndonInfoDetailRepository _andonInfoDetailRepository;
        private readonly IPlanReportLevelRepository _planReportLevelRepository;
        private readonly ISigerProjectMachineAttributionRepository _machineAttributionRepository;
        private readonly ISigerProjectMachineRepository _machineRepository;
        private readonly ISigerAndonStationConfigRepository _andonStationConfigRepository;
        private readonly ISigerProjectUserRepository _projectUserRepository;
        private readonly ISigerProjectProductReport _projectProductReport;
        private readonly ISigerUserRepository _userRepository;
        private readonly ISigerProjectLevelSectionRepository _levelSectionRepository;

        private readonly IRepairRepository _repairRepository;
        private readonly IPlanRepository _planRepository;
        private readonly IWorkingRelationMachineRepository _workingRelationMachine;
        private readonly IWorkingRelationUserRepository _workingRelationUser;
        private readonly IRepairListRepository _repairListRepository;
        private readonly IRepairReportRepository _repairReportRepository;
        private readonly IWorkingCalendarRepository _calendarRepository;
        private readonly ISigerProjectShiftRepository _projectShiftRepository;
        private readonly ISigerSystemConfigRepository _systemConfigRepository;
        private readonly ISigerAppMessageRepository _sigerAppMessage;
        private readonly ISigerAppProjectConfigRepository _configRepository;
        private readonly ISigerAppMuteRepository _appMuteRepository;


        public AndonController(IUnitOfWork unitOfWork, ISigerAndonProcessRepository andonProcessRepository
            , ISigerAndonExpectionTypeRepository andonExpectionType, ISigerAndonInfoRepository andonInfoRepository, ISigerProjectLevelSectionRepository levelSectionRepository
            , ISigerAndonInfoDetailRepository andonInfoDetailRepository, IPlanReportLevelRepository planReportLevelRepository, ISigerProjectMachineAttributionRepository machineAttributionRepository
            , ISigerProjectMachineRepository machineRepository, ISigerAndonStationConfigRepository andonStationConfigRepository, ISigerProjectUserRepository projectUserRepository, ISigerProjectProductReport projectProductReport,
            ISigerUserRepository userRepository, IRepairRepository repairRepository, IRepairListRepository repairListRepository, IRepairReportRepository repairReportRepository,
            IWorkingCalendarRepository calendarRepository, ISigerProjectShiftRepository projectShiftRepository, ISigerSystemConfigRepository systemConfigRepository, ISigerAppMessageRepository sigerAppMessage,
            ISigerAppProjectConfigRepository configRepository, ISigerAppMuteRepository appMuteRepository, IPlanRepository planRepository ,IWorkingRelationMachineRepository workingRelationMachine,IWorkingRelationUserRepository workingRelationUser)
        {
            _unitOfWork = unitOfWork;
            _andonProcessRepository = andonProcessRepository;
            _andonExpectionType = andonExpectionType;
            _andonInfoRepository = andonInfoRepository;
            _levelSectionRepository = levelSectionRepository;
            _andonInfoDetailRepository = andonInfoDetailRepository;
            _planReportLevelRepository = planReportLevelRepository;
            _machineAttributionRepository = machineAttributionRepository;
            _machineRepository = machineRepository;
            _andonStationConfigRepository = andonStationConfigRepository;
            _projectUserRepository = projectUserRepository;
            _projectProductReport = projectProductReport;
            _userRepository = userRepository;
            _repairRepository = repairRepository;
            _repairListRepository = repairListRepository;
            _repairReportRepository = repairReportRepository;
            _calendarRepository = calendarRepository;
            _projectShiftRepository = projectShiftRepository;
            _systemConfigRepository = systemConfigRepository;
            _sigerAppMessage = sigerAppMessage;
            _configRepository = configRepository;
            _appMuteRepository = appMuteRepository;
            _planRepository = planRepository;
            _workingRelationMachine = workingRelationMachine;
            _workingRelationUser = workingRelationUser;
            //_machineSetRepository = machineSetRepository;
        }
        /// <summary>
        /// 异常记录查询
        /// </summary>
        /// <param name="req"></param>
        /// <returns></returns>
        [HttpPost]
        public IActionResult GetAndonInfo([FromBody]RequestAndon req)
        {
            var ret = _andonInfoRepository.GetData(req, ProjectId);
            if (req.userid != 0)//app 专用
            {
                var group = _projectUserRepository.Get(f => f.mid == req.userid)?.usergroupid ?? "0";
                var groupid = group.ToInt();
                if (groupid != 0)
                {
                    var expections = _andonExpectionType.GetList(f => f.projectid == ProjectId && f.status != 0 && f.usergroup == groupid || f.usergroup == groupid).ToList();
                    var expectionids = expections.Select(s => s.id).ToList();
                    foreach (var item in expections)
                    {
                        var sons = _andonExpectionType.GetExpectionSonLevel(item.parent, ProjectId);
                        if (sons.Any())
                        {
                            expectionids.AddRange(sons.Select(s => s.id).ToList());
                        }
                    }
                    expectionids = expectionids.Distinct().ToList();
                    var data = ret.Data.Where(f => expectionids.Contains(f.expection_type));
                    return new PagedObjectResult(data, data.Count());
                }
            }
            return new PagedObjectResult(ret.Data, ret.Total);
        }
        /// <summary>
        /// 获取安灯触发次数及时长
        /// </summary>
        /// <param name="req"></param>
        /// <returns></returns>
        [HttpPost]
        public IActionResult GetCostTimeByMachineid([FromBody]RequestAndon req)
        {
            var ret = _andonInfoRepository.GetCostTimeByMachineid(req, ProjectId);
            return new ObjectResult(ret);
        }
        /// <summary>
        /// 获取所有安灯状态信息
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public IActionResult GetAndonTypeInfo()
        {
            var ret = new List<ResponseAndonStatus>();
            var type = EnumHelper.EnumToList<AndonState>();
            var userInfo = _andonProcessRepository.GetUserByMid(UserId);
            foreach (var item in type)
            {
                if (item.EnumValue > 5)//排除已完成的状态
                {
                    continue;
                }
                var andonList = _andonInfoRepository.GetList(f => f.status == item.EnumValue && f.projectid.Equals(ProjectId)).ToList();
                var ids = new List<int>();
                foreach (var andonData in andonList)
                {
                    var groupids = _planReportLevelRepository.GetList(f => f.status == (int)RowState.Valid && f.process_code.Equals(andonData.process_code) && f.level.Equals(andonData.cruent_level)).Select(s => s.usergroup_id).ToList();
                    //排除未绑定岗位的记录
                    if (!groupids.Any())
                    {
                        continue;
                    }
                    if (groupids.Contains(userInfo.usergroupid.ToInt()))
                    {
                        if (_andonProcessRepository.CheckInfo(ProjectId, userInfo.mid, userInfo.usergroupid.ToInt(), andonData.machine))
                        {
                            ids.Add(andonData.id);
                        }
                    }
                }
                var andonStatus = new ResponseAndonStatus
                {
                    status = item.EnumValue
                };
                if (ids.Any())
                {
                    var conditions = new RequestAndon { ids = ids, page = 1, pagesize = 9999 };
                    var data = _andonInfoRepository.GetData(conditions, ProjectId);
                    andonStatus.data = data.Data.ToList();
                    andonStatus.count = data.Total;
                }
                ret.Add(andonStatus);
            }
            return new ObjectResult(ret);
        }
        /// <summary>
        /// 安灯状态一览
        /// </summary>
        /// <param name="line"></param>
        /// <param name="type"></param>
        /// <returns></returns>
        [HttpGet]
        public IActionResult GetAndonData(int line, int type)
        {
            var ret = new ResponseAndonStateCount();
            var state = new List<ResponseAndonStateData>();
            var lines = new List<siger_project_level_section>();
            if (line == 0)
            {
                lines = _levelSectionRepository.GetAccLines(ProjectId).ToList();
            }
            else
            {
                lines = _levelSectionRepository.GetList(f => f.status == (int)RowState.Valid && f.projectid.Equals(ProjectId) && f.id.Equals(line)).ToList();
            }
            if (!lines.Any())
            {
                throw new BadRequestException(CommonEnum.NoData);
            }
            var sections = _levelSectionRepository.GetList(f => f.projectid == ProjectId && f.status != 0).ToList();
            var attributions = _machineAttributionRepository.GetList(f => f.projectid == ProjectId && f.status != 0).ToList();
            var andonData = _andonInfoRepository.GetList(f => f.projectid.Equals(ProjectId) && f.status != (int)RowState.Invalid && f.status < (int)AndonState.Complete);
            var totalMachine = 0;
            foreach (var item in lines)
            {
                var machineids = _machineRepository.GetAttributionMachineIds(item.id, ProjectId);
                //remove attribution>1
                var attrData = _machineAttributionRepository.GetList(f => machineids.Contains(f.machine) && f.attribution == 1).Select(s => s.machine).Distinct().ToList();
                var machines = _machineRepository.GetList(f => attrData.Contains(f.id));
                totalMachine += machines.Count();
                var lineData = new ResponseAndonStateData
                {
                    line = _levelSectionRepository.GetSectionString(ProjectId, item.id).TrimStart(new char[] { '-', '>' })
                };
                foreach (var machine in machines)
                {
                    var andon = andonData.FirstOrDefault(f => f.machine.Equals(machine.id));
                    var data = new ResponseAndonState
                    {
                        name = machine.title,
                        state = (int)AndonState.Normal,
                        id = machine.id,
                    };
                    data.station_value = attributions.FirstOrDefault(f => f.machine == machine.id)?.station ?? 0;
                    data.station = sections.FirstOrDefault(f => f.id == data.station_value)?.title ?? "";
                    if (andon != null)//排除出异常状态，其他的都是安灯状态
                    {
                        switch (andon.status)
                        {
                            case (int)AndonState.Abnormal:
                                data.state = (int)AndonState.Abnormal;
                                ret.abnormal += 1;
                                break;
                            default:
                                data.state = (int)AndonState.WaitHandle;
                                ret.andon += 1;
                                break;
                        }
                    }
                    lineData.machine.Add(data);
                }
                state.Add(lineData);
            }
            //filter type
            if (type != 0)
            {
                foreach (var item in state)
                {
                    item.machine = item.machine.Where(f => f.state == type).ToList();
                }
            }
            ret.state = state;
            ret.normal = totalMachine - ret.abnormal - ret.andon;
            return new ObjectResult(ret);
        }
        /// <summary>
        /// 安灯状态详情
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpGet]
        public IActionResult GetAndonDataDetail(int id)
        {
            var ret = _andonInfoDetailRepository.GetList(f => f.andon_id.Equals(id) && f.status != (int)RowState.Invalid && f.projectid == ProjectId, "createtime");
            return new ObjectResult(ret);
        }
        /// <summary>
        /// 触发安灯
        /// </summary>
        /// <param name="req"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<IActionResult> AndonTrigger([FromBody]RequestAndonTrigger req)
        {
            //触发安灯情况
            var stationModel = _machineAttributionRepository.Get(f => f.status == (int)RowState.Valid && f.machine.Equals(req.machine) && f.attribution == 1);
            if (stationModel == null)
            {
                throw new BadRequestException(TpmEnum.MachineNotFind);
            }
            var isExist = _andonInfoRepository.Get(f => f.projectid == ProjectId && f.status > (int)AndonState.Abnormal && f.status < (int)AndonState.Approve && f.machine == req.machine && f.expection_type == req.expection);
            if (isExist != null)
            {
                throw new BadRequestException(TpmEnum.AndonExist);
            }
            #region init helper
            var condition = new AppRepairCondition
            {
                projectId = ProjectId,
                userId = UserId,
                planRepository = _planRepository,
                repairListRepository = _repairListRepository,
                repairRepository = _repairRepository,
                sigerUserRepository = _userRepository,
                unitOfWork = _unitOfWork,
                appMuteRepository = _appMuteRepository,
                calendarRepository = _calendarRepository,
                configRepository = _configRepository,
                machineRepository = _machineRepository,
                projectShiftRepository = _projectShiftRepository,
                projectUserRepository = _projectUserRepository,
                repairReportRepository = _repairReportRepository,
                sigerAppMessage = _sigerAppMessage,
                systemConfigRepository = _systemConfigRepository,
                //machineSetRepository= _machineSetRepository
                workingRelationUser=_workingRelationUser,
                workingRelationMachine=_workingRelationMachine
            };
            var repairhelper = new AppRepairHelper(condition);
            #endregion
            var expectionList = _andonExpectionType.GetList(f => f.projectid == ProjectId && f.status != 0).ToList();
            var status = (int)AndonState.WaitHandle;
            var now = UnixTimeHelper.GetNow();
            var nowtime = DateTime.Now;
            if (req.status != 0)
            {
                status = req.status;
            }
            var cid = CompanyId;
            var pid = ProjectId;
            var uid = UserId;
            var order = _andonInfoRepository.WorkOrderGenerator(pid);
            var locationAlarm = new LocationAlarmRepository(cid, pid);

            //排除异常状态尚未触发安灯的信息
            if (req.id != 0)
            {
                var andonModel = _andonInfoRepository.Get(f => f.id.Equals(req.id));
                if (andonModel == null)
                {
                    throw new BadRequestException(TpmEnum.AndonNotFound);
                }
                if (req.status == (int)AndonState.WaitHandle)
                {
                    //检查异常类型
                    var expection = expectionList.FirstOrDefault(f => f.status == (int)RowState.Valid && f.projectid.Equals(pid) && f.id.Equals(req.expection));
                    if (expection == null)
                    {
                        throw new BadRequestException(TpmEnum.ExpectionNotFound);
                    }
                    var pro = expection.process_code;
                    andonModel.create_time = UnixTimeHelper.GetNow();
                    andonModel.projectid = pid;
                    andonModel.status = status;
                    andonModel.creator = uid;
                    andonModel.station = stationModel.station;
                    andonModel.process_code = pro;
                    andonModel.is_shutdown = req.is_shutdown;
                    andonModel.machine = req.machine;
                    andonModel.expection_type = req.expection;
                    andonModel.cruent_level = 1;
                    andonModel.remark = req.remark;
                }
                if (status >= 9997)
                {
                    andonModel.status = 0;//invalid andon data
                }
                else
                {
                    andonModel.status = status;
                }
                _andonInfoRepository.Update(andonModel);

                var uname = _andonInfoDetailRepository.GetUserByMid(uid)?.name ?? "";
                _andonInfoDetailRepository.Insert(new siger_andon_info_detail
                {
                    andon_id = req.id,
                    createtime = UnixTimeHelper.GetNow(),
                    projectid = pid,
                    status = status,
                    user = uname,
                    remark = req.remark
                });

                if (_unitOfWork.Commit() > 0)
                {
                    if (status == (int)AndonState.CancleAndon || status == 0 || status == (int)AndonState.CancleAbnormal)
                    {
                        #region cancel tpm repair
                        var repair = _repairRepository.Get(f => f.work_order == andonModel.work_order);
                        if (repair != null)
                        {
                            var tag = repairhelper.CloseRepair(new RequestDataByRepairId { repairid = repair.id, remark = req.remark });
                            if (!tag)
                            {
                                Logger.WriteLineError($"安灯工单{andonModel.work_order}取消tpm-repair失败");
                            }
                        }
                        #endregion
                        #region delete alarm data
                        var alarmData = locationAlarm.GetAbnormalDataByOrder(pid, andonModel.work_order).FirstOrDefault();
                        if (alarmData != null)
                        {
                            var flag = locationAlarm.DeleteLocationAlarm(alarmData.id);
                            if (!flag)
                            {
                                Logger.WriteLineError($"安灯工单{alarmData.workOrderId}删除LocationAlarm失败");
                            }
                        }
                        else
                        {
                            Logger.WriteLineError($"安灯工单{andonModel.work_order}查询LocationAlarm失败");
                        }
                        #endregion
                    }
                    else if (status == (int)AndonState.WaitHandle)
                    {
                        #region update alarm data
                        var alarmData = locationAlarm.GetAbnormalDataByOrder(pid, andonModel.work_order).FirstOrDefault();
                        var typeid = 0;
                        var expections = _andonExpectionType.GetExpectionParent(req.expection, pid, expectionList);
                        var sss = expections.ToList(); 
                        if (expections.Any(f => f.level == 1))
                        {
                            typeid = expections.First(f => f.level == 1).id;
                        }
                        else
                        {
                            Logger.WriteLineError($"安灯工单{alarmData.workOrderId}的异常类型{req.expection}没找到一级异常类型！");
                        }
                        if (alarmData != null && typeid != 0)
                        {
                            alarmData.end_time = nowtime;
                            alarmData.start_time = nowtime;
                            alarmData.trigger = 1;
                            alarmData.type = typeid;
                            var flag = locationAlarm.UpdateLocationAlarmById(alarmData);
                            if (!flag)
                            {
                                Logger.WriteLineError($"安灯工单{alarmData.workOrderId}删除LocationAlarm失败");
                            }
                        }
                        #endregion
                    }
                    return new ObjectResult(CommonEnum.Succefull);
                }
            }

            //检查异常类型
            var expectionModel = expectionList.FirstOrDefault(f => f.status == (int)RowState.Valid && f.projectid.Equals(pid) && f.id.Equals(req.expection));
            if (expectionModel == null)
            {
                throw new BadRequestException(TpmEnum.ExpectionNotFound);
            }
            var process = expectionModel.process_code ?? "";
            var model = new siger_andon_info
            {
                projectid = pid,
                status = status,
                creator = uid,
                station = stationModel.station,
                process_code = process,
                is_shutdown = req.is_shutdown,
                machine = req.machine,
                expection_type = req.expection,
                cruent_level = 1,
                remark = req.remark,
                work_order = order,
                create_time = now
            };
            if (expectionModel.is_passprocess == 1)
            {
                status = (int)AndonState.Complete;
                model.status = status;
                model.handle_time = now;
                //init 签到时间和签到人 解除时间 解除人
                model.handler = uid;
                model.complete_time = now;
            }
            //add 2020-05-13 设置计划停机，在输入开始时间和结束时间后提交完成，取消复线动作。
            var start = req.start;
            var end = req.end;
            if (start > 0 && end > 0 && start <= end)
            {
                var tempdata = _andonInfoRepository.GetList(f => f.expection_type == expectionModel.id && f.machine == model.machine && f.status != 0, "create_time").ToList();
                //计划停机拦截（不是最优解）
                if (tempdata.Any(f => f.create_time > start && f.create_time < end) || tempdata.Any(f => f.approve_time > start && f.approve_time < end)
                    || tempdata.Any(f => f.create_time <= start && f.approve_time >= end) || tempdata.Any(f => f.create_time >= start && f.approve_time <= end))
                {
                    throw new BadRequestException(TpmEnum.StopMachineExist);
                }
                status = (int)AndonState.Recovery;
                model.status = status;
                model.create_time = start;
                model.handle_time = start;
                model.complete_time = end;
                model.approve_time = end;
            }
            _andonInfoRepository.Insert(model);
            //detail
            var username = _andonInfoDetailRepository.GetUserByMid(uid)?.name ?? "";
            if (_unitOfWork.Commit() > 0)
            {
                var info = _andonInfoRepository.Get(f => f.work_order.Equals(order) && f.status != (int)RowState.Invalid && f.projectid == ProjectId);
                if (info == null)
                {
                    throw new BadRequestException(CommonEnum.Fail);
                }
                _andonInfoDetailRepository.Insert(new siger_andon_info_detail
                {
                    andon_id = info.id,
                    createtime = now,
                    projectid = pid,
                    status = status,
                    user = username,
                    remark = req.remark
                });
                if (_unitOfWork.Commit() > 0)
                {
                    #region create tpm repair
                    var parent = _andonExpectionType.GetExpectionParent(expectionModel.id, pid, expectionList).FirstOrDefault(f => f.level == 1)?.type ?? 0;
                    if (parent == 1)
                    {
                        var tag = await repairhelper.SubmitRepairAsync(new RequestSubmitRepair { machineid = req.machine, offlinestatus = req.is_shutdown, work_order = info.work_order, expection_id = req.expection, remark = req.remark });
                        if (!tag)
                        {
                            Logger.WriteLineError($"安灯工单{info.work_order}创建tpm-repair失败");
                        }
                    }
                    #endregion
                    #region create alarm data

                    Logger.WriteLineInfo("-----------------------------create alarm data-------------------------------------");
                    var typeid = 0;
                    var expections = _andonExpectionType.GetExpectionParent(info.expection_type, pid, expectionList);
                    if (expections.Any(f => f.level == 1))
                    {
                        typeid = expections.First(f => f.level == 1).id;
                    }
                    else
                    {
                        Logger.WriteLineError($"安灯工单{info.work_order}的异常类型{info.expection_type}没找到一级异常类型！");
                    }
                    Logger.WriteLineInfo($"typeid{typeid}");
                    if (typeid != 0)
                    {
                        Logger.WriteLineInfo("-----------------------------InsertLocationAlarm-------------------------------------");
                        var result = locationAlarm.InsertLocationAlarm(new Middlelayer.Dapper.ResultData.LocationAlarm
                        {
                            abnormal_time = now,
                            end_time = expectionModel.is_caloee == 0 ? UnixTimeHelper.ConvertStringDateTime(req.end.ToStr()) : nowtime,
                            start_time = expectionModel.is_caloee == 0 ? UnixTimeHelper.ConvertStringDateTime(req.start.ToStr()) : nowtime,
                            machine = info.machine.ToStr(),
                            pid = pid,
                            type = typeid,
                            status = expectionModel.is_caloee == 0 ? 0 : 1,
                            workOrderId = info.work_order,
                            trigger = 1,
                            sectionID = _levelSectionRepository.Get(f => f.id == info.station)?.parentid ?? 0,
                        });
                        if (!result)
                        {
                            Logger.WriteLineError($"InsertLocationAlarm Failed work_order:{info.work_order}");
                            Logger.WriteLineError("-----------------------------InsertLocationAlarmFailed-------------------------------------");
                        }
                        Logger.WriteLineInfo("-----------------------------InsertLocationAlarmSuccess-------------------------------------");
                    }
                    #endregion
                    //add 2020-05-13 设置计划停机，把大数据产量表中对应时间内的损失type和工单号改为计划停的type和工单号。
                    if (expectionModel.is_passprocess == 1 && start > 0 && end > 0 && start <= end && expectionModel.is_caloee == 0)
                    {
                        var locationYield = new LocationYieldRepository(cid, pid);
                        await locationYield.UpdateLocationYieldStopMachineAsync(info.machine, info.expection_type, start, end, info.work_order);
                    }
                    return new ObjectResult(CommonEnum.Succefull);
                }
            }
            throw new BadRequestException(CommonEnum.Fail);
        }

        /// <summary>
        /// 处理安灯
        /// </summary>
        /// <param name="req"></param>
        /// <returns></returns>
        [HttpPost]
        public IActionResult HandleAndon([FromBody]RequestHandleAndon req)
        {
            var pid = ProjectId;
            var cid = CompanyId;
            var uid = UserId;
            var locationAlarm = new LocationAlarmRepository(cid, pid);
            var andon = _andonInfoRepository.Get(f => f.id == req.id);
            var expectionList = _andonExpectionType.GetList(f => f.projectid == ProjectId && f.status != 0).ToList();
            if (andon == null)
            {
                throw new BadRequestException(CommonEnum.RecordNotFound);
            }
            
            var expections = _andonExpectionType.GetExpectionParent(andon.expection_type, pid, expectionList);
            var currentexpection = expectionList.FirstOrDefault(f => f.id == andon.expection_type);
            if (expections.Any(f => f.type == 1) || currentexpection?.type == 1)//拦截tpm异常
            {
                if (andon.status == (int)AndonState.Handling || andon.status == (int)AndonState.WaitHandle)//签到恢复拦截
                {
                    throw new BadRequestException(TpmEnum.AndonStatusCanNotHandle);
                }
                if (req.type == (int)AndonState.Recovery || req.type == (int)AndonState.CanNotRecovery || req.type == (int)AndonState.Com_Approve)
                {
                    #region init tpm repair helper
                    var condition = new AppRepairCondition
                    {
                        projectId = ProjectId,
                        userId = UserId,
                        planRepository = _planRepository,
                        repairListRepository = _repairListRepository,
                        repairRepository = _repairRepository,
                        sigerUserRepository = _userRepository,
                        unitOfWork = _unitOfWork,
                        appMuteRepository = _appMuteRepository,
                        calendarRepository = _calendarRepository,
                        configRepository = _configRepository,
                        machineRepository = _machineRepository,
                        projectShiftRepository = _projectShiftRepository,
                        projectUserRepository = _projectUserRepository,
                        repairReportRepository = _repairReportRepository,
                        sigerAppMessage = _sigerAppMessage,
                        systemConfigRepository = _systemConfigRepository,
                        andonInfoRepository = _andonInfoRepository,
                        expectionTypeRepository = _andonExpectionType,
                        //machineSetRepository = _machineSetRepository，
                        workingRelationMachine=_workingRelationMachine,
                        workingRelationUser=_workingRelationUser
                    };
                    var repairhelper = new AppRepairHelper(condition);
                    #endregion
                    //tpm handle
                    var repair = _repairRepository.Get(f => f.work_order == andon.work_order && f.status == (int)MachineRepairStatus.WaitingForRenew);
                    if (repair != null)
                    {
                        //1复线2让步3拒绝
                        var checkstatus = 3;
                        switch (req.type)
                        {
                            case (int)AndonState.Recovery:
                                checkstatus = 1;
                                break;
                            case (int)AndonState.Com_Approve:
                                checkstatus = 2;
                                break;
                            default:
                                checkstatus = 3;
                                break;
                        }
                        repairhelper.RecoveryLine(new RequestRepairExecution { repairid = repair.id, repairstatus = (int)MachineRepairStatus.WaitingForRenew, appraise = "5", checkstatus = checkstatus, is_shutdown = req.is_shutdown.ToInt() });
                        //if (checkstatus == 2)
                        //{
                        //    var tag = repairhelper.SubmitRepair(new RequestSubmitRepair { machineid = andon.machine, offlinestatus = andon.is_shutdown, expection_id = req.expection });
                        //    if (!tag)
                        //    {
                        //        Logger.WriteLineError($"安灯工单{andon.work_order}创建tpm-repair失败");
                        //    }
                        //}
                    }
                }
            }
            
            var result = _andonInfoRepository.HandleAndon(req, pid, cid, uid);
            if (!result)
            {
                throw new BadRequestException(CommonEnum.Fail);
            }
            var model = _andonInfoRepository.Get(f => f.status != (int)RowState.Invalid && f.status < (int)AndonState.Approve && f.projectid.Equals(pid) && f.id.Equals(req.id));
            var bottleData = _andonStationConfigRepository.Get(f => f.status != 0 && f.station_type == 1 && f.project_id == pid && f.machine_id == model.machine);
            if (!string.IsNullOrEmpty(req.product_code) && bottleData != null)
            {
                var cycletime = _projectProductReport.ProductWorkingHours(pid, req.product_code);
                var repository = new QMSYieldFixedConfigRepository(cid, pid, true);
                repository.SetConfig(model.machine.ToStr(), new Middlelayer.Redis.RedisEntities.QMSYieldFixedConfig { cycletime = cycletime, productname = req.product_code.Trim() });
            }
            if (_unitOfWork.Commit() > 0)
            {
                #region update alarm data
                if (req.type == (int)AndonState.Recovery || req.type == (int)AndonState.Com_Approve)
                {
                    var alarmData = locationAlarm.GetAbnormalDataByOrder(pid, andon.work_order).OrderByDescending(o => o.id).FirstOrDefault();
                    if (alarmData != null)
                    {
                        alarmData.start_time = UnixTimeHelper.ConvertStringDateTime(andon.create_time.ToStr());
                        alarmData.end_time = UnixTimeHelper.ConvertStringDateTime(andon.approve_time.ToStr());
                        alarmData.status = 0;
                        var flag = locationAlarm.UpdateLocationAlarmById(alarmData);
                        Logger.WriteLineError(!flag
                            ? $"update alarm data 安灯工单{alarmData.workOrderId}删除LocationAlarm失败"
                            : $"update alarm data 安灯工单{alarmData.workOrderId}插入LocationAlarm成功");
                    }
                    else
                    {
                        Logger.WriteLineError($"update alarm data 安灯工单{andon.work_order}删除LocationAlarm失败,原因是记录未找到！");
                    }
                }
                #endregion
                return new ObjectResult(CommonEnum.Succefull);
            }
            throw new BadRequestException(CommonEnum.Fail);
        }
        /// <summary>
        /// 待办事项查询
        /// </summary>
        /// <param name="req"></param>
        /// <returns></returns>
        [HttpPost]
        public IActionResult GetTodoList([FromBody]RequestAndon req)
        {
            var ids = new List<int>();
            var userInfo = _andonProcessRepository.GetUserByMid(UserId);
            var andonList = _andonInfoRepository.GetList(f => f.status < (int)AndonState.Complete && f.projectid.Equals(ProjectId)).ToList();
            foreach (var andonData in andonList)
            {
                var groupids = _planReportLevelRepository.GetList(f => f.status == (int)RowState.Valid && f.process_code.Equals(andonData.process_code) && f.level.Equals(andonData.cruent_level)).Select(s => s.usergroup_id).ToList();
                //排除未绑定岗位的记录
                if (!groupids.Any())
                {
                    continue;
                }
                if (groupids.Contains(userInfo.usergroupid.ToInt()))
                {
                    if (_andonProcessRepository.CheckInfo(ProjectId, userInfo.mid, userInfo.usergroupid.ToInt(), andonData.machine))
                    {
                        ids.Add(andonData.id);
                    }
                }
            }
            if (ids.Any())
            {
                var conditions = new RequestAndon { ids = ids, page = req.page, pagesize = req.pagesize };
                var ret = _andonInfoRepository.GetData(conditions, ProjectId);
                return new PagedObjectResult(ret.Data, ret.Total);
            }
            return new PagedObjectResult(new List<ResponseAndon>(), 0);
        }
        /// <summary>
        /// 异常触发
        /// </summary>
        /// <param name="req"></param>
        /// <returns></returns>
        [NoTokenValidateFilter]
        [HttpPost]
        public IActionResult AndonAbnormal([FromBody]RequestAndonAbonrmal req)
        {
            var pid = req.pid;
            var order = _andonInfoRepository.WorkOrderGenerator(pid);
            var station = _machineAttributionRepository.Get(f => f.status == (int)RowState.Valid && f.projectid.Equals(pid) & f.machine.Equals(req.machine));
            var adminuser = _userRepository.GetList(f => f.type == (int)UserType.Admin).Select(s => s.id).ToList();
            var projectuser = _projectUserRepository.Get(f => adminuser.Contains(f.mid) && f.projectid == pid);
            Logger.WriteLineInfo($"{req.machine}{UnixTimeHelper.ConvertStringDateTime(req.abnormal_time.ToStr())}{req.type}{req.parameter}");
            _andonInfoRepository.Insert(new siger_andon_info
            {
                abnormal_time = (int)req.abnormal_time,
                machine = req.machine,
                station = station?.station ?? 0,
                status = (int)AndonState.Abnormal,
                expection_type = 0,
                process_code = "",
                projectid = pid,
                remark = req.parameter,
                work_order = order
            });

            if (_unitOfWork.Commit() > 0)
            {
                var andondata = _andonInfoRepository.Get(f => f.work_order == order && f.projectid == pid);
                _andonInfoDetailRepository.Insert(new siger_andon_info_detail
                {
                    andon_id = andondata.id,
                    createtime = andondata.abnormal_time,
                    projectid = pid,
                    remark = req.parameter,
                    user = projectuser.name
                });
                if (_unitOfWork.Commit() > 0)
                {
                    return new ObjectResult(CommonEnum.Succefull);
                }
            }
            throw new BadRequestException(CommonEnum.Fail);
        }

        [HttpGet]
        public IActionResult GetErrorsByLevel(int level = 0, int type = 0)
        {
            var query = _andonExpectionType.GetList(q =>
                    (level == 0 || q.level == level) && q.projectid == ProjectId && q.status == (int)RowState.Valid)
                .Select(m => new
                {
                    m.id,
                    m.name,
                    m.type
                }).ToList();
            if (type != 0)
            {
                var ret = new List<siger_andon_expection_type>();
                var firstids = _andonExpectionType.GetList(f => f.projectid == ProjectId && f.status != 0 && f.level == 1 && f.type == type).Select(s => s.id).ToList();
                foreach (var id in firstids)
                {
                    var list = _andonExpectionType.GetExpectionSonSelfLevel(id, ProjectId);
                    if (list.Any())
                    {
                        ret.AddRange(list);
                    }
                }
                return new ObjectResult(ret.Where(f => f.level == level));
            }
            return new ObjectResult(query);
        }
        /// <summary>
        /// 删除andon
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpGet]
        public IActionResult DeleteAndon(int id)
        {
            var now = UnixTimeHelper.GetNow();
            var andonInfo = _andonInfoRepository.Get(f => f.id == id && f.projectid == ProjectId && f.status != 0);
            if (andonInfo == null)
            {
                throw new BadRequestException(CommonEnum.Fail);
            }
            if (andonInfo.create_time <= now)
            {
                throw new BadRequestException(TpmEnum.CancleAndonFailed);
            }
            andonInfo.status = 0;
            _andonInfoRepository.Update(andonInfo);
            var details = _andonInfoDetailRepository.GetList(f => f.andon_id == id).ToList();
            foreach (var detail in details)
            {
                detail.status = 0;
                _andonInfoDetailRepository.Update(detail);
            }
            if (_unitOfWork.Commit() > 0)
            {
                return new ObjectResult(CommonEnum.Succefull);
            }
            throw new BadRequestException(CommonEnum.Fail);
        }
    }
}