using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.AspNetCore.Mvc;
using Siger.ApiCommon.Result;
using Siger.Middlelayer.Common;
using Siger.Middlelayer.Common.Extensions;
using Siger.Middlelayer.Common.Helpers;
using Siger.Middlelayer.Dapper;
using Siger.Middlelayer.Log;
using Siger.Middlelayer.Redis.Model;
using Siger.Middlelayer.Redis.Repositories;
using Siger.Middlelayer.Redis.Utility;
using Siger.Middlelayer.Repository;
using Siger.Middlelayer.ToolRepository.Entities;
using Siger.Middlelayer.ToolRepository.Repositories.Interface;
using Siger.Middlelayer.Repository.Repositories.Interface;
using Siger.Middlelayer.ToolRepository.Request;
using Siger.Middlelayer.ToolRepository.Response;
using System.Threading.Tasks;
namespace Siger.ApiTools.Controllers
{
    public class ToolLifeController : BaseController
    {
        private readonly IUnitOfWork _unitOfWork;
        readonly ISigerToolChangeRecordRepository sigerToolChangeRecordRepository;
        readonly ISigerProjectToolCutterLocationTrueRepository sigerProjectToolCutterLocationTrueRepository;
        readonly ISigerProjectToolChangeExtendRepository _sigerProjectToolChangeExtend;
        readonly ISigerProjectToolSpindleTrueRepository _sigerProjectToolSpindleTrueRepository;
        readonly ISigerProjectToolRepository _sigerProjectToolRepository;
        readonly ISigerProjectMachineRepository _sigerProjectMachine;
        public ToolLifeController(ISigerProjectToolSpindleTrueRepository sigerProjectToolSpindleTrueRepository, ISigerToolChangeRecordRepository sigerToolChangeRecordRepository, ISigerProjectToolChangeExtendRepository sigerProjectToolChangeExtend, ISigerProjectToolCutterLocationTrueRepository sigerProjectToolCutterLocationTrueRepository, ISigerProjectToolRepository sigerProjectToolRepository,
            ISigerProjectMachineRepository sigerProjectMachine ,IUnitOfWork unitOfWork)
        {
            _unitOfWork = unitOfWork;
            this.sigerToolChangeRecordRepository = sigerToolChangeRecordRepository;
            this.sigerProjectToolCutterLocationTrueRepository = sigerProjectToolCutterLocationTrueRepository;
            this._sigerProjectToolChangeExtend = sigerProjectToolChangeExtend;
            this._sigerProjectToolSpindleTrueRepository = sigerProjectToolSpindleTrueRepository;
            this._sigerProjectToolRepository = sigerProjectToolRepository;
            _sigerProjectMachine = sigerProjectMachine;
        }

        /// <summary>
        /// 监控换刀记录表
        /// </summary>
        [HttpGet]
        public IActionResult GetMysqlInfos()
        {
            var endTime = UnixTimeHelper.ConvertDataTimeLong(DateTime.Now);
            var startTime = endTime - 6;
            if (sigerToolChangeRecordRepository.IsExist(f => f.projectid == ProjectId && f.status == (int)RowState.Valid &&
                                                     f.change_time >= startTime && f.change_time <= endTime))
            {
                return new ObjectResult(CommonEnum.Succefull);
            }
            return new InformationResult(0);
        }
        [HttpGet]
        public async Task<IActionResult> GetToolLifeListV2(int sectionId)
        {


            var cutterCfg = await _sigerProjectToolSpindleTrueRepository.GetMonitorData(ProjectId, sectionId);
            if (!cutterCfg.Any())
                throw new BadRequestException(CommonEnum.RecordNotFound);

            var MachineState = new CNCEquipmentStateRepository(CompanyId, ProjectId, false);
            var MachineUsage = new ToolMachineCycleUsageRepository(CompanyId, ProjectId, false);

            var response = new List<ResponseToolLifeList>();
            foreach (var cutter in cutterCfg)
            {
                var curState = MachineState.GetCNCEquipmentState(cutter.MachineId);
                if (curState == null)
                    continue;
                var machineSectionDsc = _sigerProjectMachine.GetLineLevelTitlebByMachine(cutter.MachineId, ProjectId);

                var toolLifeInfo = new ResponseToolLifeList
                {
                    machineId = cutter.MachineId,
                    machine_name = cutter.MachineName,
                    machine_code = cutter.MachineCode,
                    section_dsc = machineSectionDsc,
                    spindle_name = cutter.SpindleName,
                    cutter_location_name = cutter.CutterName,
                };
                //tool 1.5.1
                var predictedLife = 0;
                var cutterTrue = sigerProjectToolCutterLocationTrueRepository.Get(f => f.spindleid == cutter.SpindleId && f.name == cutter.CutterName && f.is_processing_program != (int)ProcessProgram.NoConfig && f.programno == curState.PN && f.subprogramno == curState.SPN && f.status == (int)RowState.Valid);
                if (cutterTrue != null)
                {
                    //   记录最后一次
                    string procProgram = string.Empty;
                    if (cutterTrue.is_processing_program == (int)ProcessProgram.MainProgram)
                        procProgram = ProgramType.mainProgram + curState.PN;
                    else
                        procProgram = ProgramType.subProgram + curState.SPN;

                    MachineState.SetLastProcess(curState.MachineId, procProgram);
                    predictedLife = MachineUsage.GetPredictedToollife(cutter.MachineId, procProgram, cutter.SpindleName, cutter.CutterName);
                }
                else
                {
                    // 取最后一次
                    var procProgram = MachineState.GetLastProcess(cutter.MachineId);
                    if (!string.IsNullOrWhiteSpace(procProgram))
                    {
                        var pnType = procProgram.Substring(0, 1);
                        var redisPro = procProgram.Substring(1, procProgram.Length - 1);

                        if (pnType == ProgramType.mainProgram)
                            cutterTrue = await sigerProjectToolCutterLocationTrueRepository.GetAsync(f => f.spindleid == cutter.SpindleId && f.name == cutter.CutterName && f.is_processing_program != (int)ProcessProgram.NoConfig && f.programno == redisPro && f.status == (int)RowState.Valid);
                        else
                            cutterTrue = await sigerProjectToolCutterLocationTrueRepository.GetAsync(f => f.spindleid == cutter.SpindleId && f.name == cutter.CutterName && f.is_processing_program != (int)ProcessProgram.NoConfig && f.subprogramno == redisPro && f.status == (int)RowState.Valid);

                        predictedLife = MachineUsage.GetPredictedToollife(cutter.MachineId, procProgram, cutter.SpindleName, cutter.CutterName);
                    }
                }
                if (cutterTrue != null)
                {
                    if (cutterTrue.toolid > 0)
                    {
                        var tool = _sigerProjectToolRepository.Get(f => f.id == cutterTrue.toolid);
                        toolLifeInfo.tool_name = tool == null ? "NA" : tool.name;
                        toolLifeInfo.drawingcode = tool == null ? "NA" : tool.drawingcode;
                    }
                    toolLifeInfo.id = cutterTrue.id;
                    toolLifeInfo.IsProcess = cutterTrue.is_processing_program;
                    toolLifeInfo.programno = cutterTrue.programno;
                    toolLifeInfo.subprogramno = cutterTrue.subprogramno;
                    toolLifeInfo.predictedResiduallife = predictedLife;
                    toolLifeInfo.ratedlife = cutterTrue.ratedlife;
                    var usage = MachineUsage.GetCycleUsage(cutter.MachineId, cutterTrue.is_processing_program == (int)ProcessProgram.MainProgram ? cutterTrue.programno : cutterTrue.subprogramno, cutter.SpindleName, cutter.CutterName);
                    if (usage != null)
                    {
                        if (usage.tc == 0 && usage.tl == 0)
                            toolLifeInfo.use_life = usage.usage;
                        else
                        {
                            toolLifeInfo.ratedlife = usage.tl;
                            toolLifeInfo.use_life = usage.tc;
                        }
                    }
                    if (toolLifeInfo.ratedlife != null && toolLifeInfo.ratedlife > 0)
                    {
                        toolLifeInfo.surplus_life = toolLifeInfo.ratedlife.Value - toolLifeInfo.use_life;
                        toolLifeInfo.percent = Math.Round((decimal)(toolLifeInfo.surplus_life / toolLifeInfo.ratedlife * 100), 1);
                    }
                    else
                    {
                        toolLifeInfo.percent = 0;
                    }

                    //百分比框背景颜色
                    if (toolLifeInfo.percent <= 20)
                        toolLifeInfo.surplus_type = "danger";
                    else if (toolLifeInfo.percent > 20 && toolLifeInfo.percent < 40)
                        toolLifeInfo.surplus_type = "warning";
                    else
                        toolLifeInfo.surplus_type = "success";
                    //百分比框字体颜色
                    toolLifeInfo.surplus_font_color = toolLifeInfo.percent <= 15 ? "#555" : "#fff";

                    if (toolLifeInfo.percent < 0)
                        toolLifeInfo.percent = 0;
                    //剩余时间
                    var dieTime = DateTime.Now.AddSeconds(toolLifeInfo.surplus_life * toolLifeInfo.cyc_time);
                    var tspan = dieTime - DateTime.Now;
                    string diff = tspan.Days + "天" + tspan.Hours + "小时" + tspan.Minutes + "分";
                    toolLifeInfo.cyc_time_str = toolLifeInfo.surplus_life <= 0 ? "0" : diff;
                    response.Add(toolLifeInfo);

                }

            }

            MachineState.Dispose();
            MachineUsage.Dispose();

            var responseOderby = response.OrderBy(d => d.percent);
            return new ObjectResult(responseOderby);

        }
        /// <summary>
        /// 剩余寿命列表
        /// </summary>
        [HttpGet]
        public IActionResult GetToolLifeList(int sectionId, int page, int pagesize)
        {
            var response = new List<ResponseToolLifeList>();
            //查找当前设备的运行状态
            var MachineState = new CNCEquipmentStateRepository(CompanyId, ProjectId, false);
            var MachineUsage = new ToolMachineCycleUsageRepository(CompanyId, ProjectId, false);
            var machineIds = _sigerProjectMachine.GetMachineEntityBySection(sectionId, ProjectId).Select(s => s.id);
            var lstState = MachineState.GetCNCEquipmentStates(machineIds);
            if (!lstState.Any())
                throw new BadRequestException(RequestEnum.MachineNotFound);

            var ToolInfos = _sigerProjectToolSpindleTrueRepository.GetMonitorData(ProjectId, lstState);

            var machineGrop = ToolInfos.GroupBy(g => g.MachineID);
            var toolDraw = _sigerProjectToolRepository.getlistToolByProject(ProjectId);
            foreach (var m in machineGrop)
            {
                double.TryParse(MachineState.BlxCCTime(m.Key), out double cctime);
                var machinelst = m.ToList();

                var spindleGroup = machinelst.GroupBy(g => g.SpindleName);
                foreach (var sp in spindleGroup)
                {
                    var toolsByspindle = sp.ToList();
                    var ToolMonitors = toolsByspindle.GroupBy(g => g.Toollocation);
                    foreach (var tool in ToolMonitors)
                    {
                        var procProgram = string.Empty;
                        var toollst = tool.ToList();
                        //配置主程序
                        var monitor = toollst.Find(f => f.IsProces == (int)ProcessProgram.MainProgram && f.cncProgram == f.Program && f.TooLife > 0);
                        if (monitor != null)
                        {
                            procProgram = ProgramType.mainProgram + monitor.cncProgram;
                            MachineState.SetLastProcess(monitor.MachineID, procProgram);
                        }
                        else
                        { //配置子程序
                            monitor = toollst.Find(f => f.IsProces == (int)ProcessProgram.ChildProgram && f.cncSubProgram == f.SubProgram && f.TooLife > 0);
                            if (monitor != null)
                            {
                                procProgram = ProgramType.subProgram + monitor.cncSubProgram;
                                MachineState.SetLastProcess(monitor.MachineID, procProgram);
                            }
                        }
                        if (monitor == null)
                        {
                            //最近配置
                            procProgram = MachineState.GetLastProcess(toollst.First().MachineID);
                            if (string.IsNullOrEmpty(procProgram))
                                continue;

                            var pnType = procProgram.Substring(0, 1);
                            var _redipn = procProgram.Substring(1, procProgram.Length - 1);
                            if (pnType == ProgramType.mainProgram)
                                monitor = toollst.Find(f => f.Program == _redipn);
                            else
                                monitor = toollst.Find(f => f.SubProgram == _redipn);
                        }
                        if (monitor == null)
                            continue;

                        var toolLife = new ResponseToolLifeList
                        {
                            id = monitor.id,
                            machine_name = monitor.MachineName,
                            machine_code = monitor.MachineCode,
                            machineId = monitor.MachineID,
                            tool_name = monitor.ToolName,
                            drawingcode = monitor.DrawingCode,
                            spindle_name = monitor.SpindleName == null ? "NA" : monitor.SpindleName,
                            cutter_location_name = monitor.Toollocation,
                            ratedlife = monitor.TooLife == null ? 0 : monitor.TooLife,
                            description = monitor.Desc == null ? "NA" : monitor.Desc,
                            cyc_time = cctime
                        };

                        toolLife.section_dsc = _sigerProjectMachine.GetLineLevelTitlebByMachine(monitor.MachineID, ProjectId);
                        if (monitor.IsProces == (int)ProcessProgram.MainProgram)
                            toolLife.programno = monitor.Program.ToStr();
                        else
                            toolLife.programno = monitor.SubProgram.ToStr();

                        var usage = MachineUsage.GetCycleUsage(monitor.MachineID, procProgram, monitor.SpindleName, monitor.Toollocation);
                        if (usage != null)
                        {
                            if (usage.tc == 0 && usage.tl == 0)
                                toolLife.use_life = usage.usage;
                            else
                            {
                                toolLife.ratedlife = usage.tl;
                                toolLife.use_life = usage.tc;
                            }
                        }
                        //tool 1.5.1
                        var predictedLife = MachineUsage.GetPredictedToollife(monitor.MachineID, procProgram, monitor.SpindleName, monitor.Toollocation);

                        toolLife.predictedResiduallife = predictedLife;

                        if (toolLife.ratedlife != null && toolLife.ratedlife > 0)
                        {
                            toolLife.surplus_life = toolLife.ratedlife.Value - toolLife.use_life;
                            toolLife.percent = Math.Round((decimal)(toolLife.surplus_life / toolLife.ratedlife * 100), 1);
                        }
                        else
                        {
                            toolLife.percent = 0;
                        }

                        //百分比框背景颜色
                        if (toolLife.percent <= 20)
                            toolLife.surplus_type = "danger";
                        else if (toolLife.percent > 20 && toolLife.percent < 40)
                            toolLife.surplus_type = "warning";
                        else
                            toolLife.surplus_type = "success";
                        //百分比框字体颜色
                        toolLife.surplus_font_color = toolLife.percent <= 15 ? "#555" : "#fff";
                        //剩余时间
                        var dieTime = DateTime.Now.AddSeconds(toolLife.surplus_life * toolLife.cyc_time);
                        var tspan = dieTime - DateTime.Now;
                        string diff = tspan.Days + "天" + tspan.Hours + "小时" + tspan.Minutes + "分";
                        toolLife.cyc_time_str = toolLife.surplus_life <= 0 ? "0" : diff;
                        response.Add(toolLife);
                    }
                }
            }
            MachineState.Dispose();
            MachineUsage.Dispose();

            var responseOderby = response.OrderBy(d => d.percent);
            return new PagedObjectResult(responseOderby.Skip((page - 1) * pagesize).Take(pagesize), responseOderby.Count(), page, pagesize);
        }

        [HttpPost]
        public IActionResult GetToolLifeEx([FromBody]RequestTool request)
        {
            var response = new List<ResponseToolLifeList>();
            //查找当前设备的运行状态
            var MachineState = new CNCEquipmentStateRepository(CompanyId, ProjectId, false);
            var MachineUsage = new ToolMachineCycleUsageRepository(CompanyId, ProjectId, false);
            var machineIds = _sigerProjectMachine.GetMachineEntityBySection(request.section, ProjectId).Select(s => s.id);
            var equipmentStates = MachineState.GetCNCEquipmentStates(machineIds);
            if (!equipmentStates.Any())
                throw new BadRequestException(RequestEnum.MachineNotFound);
            var toolInfos = _sigerProjectToolSpindleTrueRepository.GetMonitorData(ProjectId, equipmentStates);
            var tempMachines = toolInfos.Select(s => s.MachineID).Distinct();
            foreach (var machineId in tempMachines)//设备
            {
                var tempSpindle = toolInfos.Where(f => f.MachineID == machineId).Select(s=>s.SpindleName).Distinct();
                foreach (var spindleName in tempSpindle)//主轴
                {
                    var tempLocation = toolInfos.Where(f => f.MachineID == machineId && f.SpindleName == spindleName).Select(s=>s.Toollocation).Distinct();
                    foreach (var location in tempLocation)//刀位
                    {
                        //预选定数据
                        var toolList = toolInfos.Where(f => f.MachineID == machineId && f.SpindleName == spindleName && f.Toollocation == location).ToList();
                        var procProgram = string.Empty;
                        //配置主程序
                        var monitor = toolList.Find(f => f.IsProces == (int)ProcessProgram.MainProgram && f.cncProgram == f.Program && f.TooLife > 0);
                        if (monitor != null)
                        {
                            procProgram = ProgramType.mainProgram + monitor.cncProgram;
                            MachineState.SetLastProcess(monitor.MachineID, procProgram);
                        }
                        else
                        { //配置子程序
                            monitor = toolList.Find(f => f.IsProces == (int)ProcessProgram.ChildProgram && f.cncSubProgram == f.SubProgram && f.TooLife > 0);
                            if (monitor != null)
                            {
                                procProgram = ProgramType.subProgram + monitor.cncSubProgram;
                                MachineState.SetLastProcess(monitor.MachineID, procProgram);
                            }
                        }
                        if (monitor == null)
                        {
                            //最近配置
                            procProgram = MachineState.GetLastProcess(machineId);
                            if (string.IsNullOrEmpty(procProgram))
                                continue;
                            var programType = procProgram.Substring(0, 1);
                            var programName = procProgram.Substring(1, procProgram.Length - 1);
                            if (programType == ProgramType.mainProgram)
                                monitor = toolList.Find(f => f.Program == programName);
                            else
                                monitor = toolList.Find(f => f.SubProgram == programName);
                        }
                        if (monitor == null)
                            continue;
                        //add
                        var toolLife = new ResponseToolLifeList
                        {
                            id = monitor.id,
                            machine_name = monitor.MachineName,
                            machine_code = monitor.MachineCode,
                            machineId = monitor.MachineID,
                            tool_name = monitor.ToolName,
                            drawingcode = monitor.DrawingCode,
                            spindle_name = monitor.SpindleName == null ? "NA" : monitor.SpindleName,
                            cutter_location_name = monitor.Toollocation,
                            ratedlife = monitor.TooLife == null ? 0 : monitor.TooLife,
                            description = monitor.Desc == null ? "NA" : monitor.Desc,
                            cyc_time = MachineState.BlxCCTime(machineId).ToDouble(),
                            section_dsc= _sigerProjectMachine.GetLineLevelTitlebByMachine(machineId, ProjectId),
                            programno= monitor.IsProces == (int)ProcessProgram.MainProgram? monitor.Program.ToStr() : monitor.SubProgram.ToStr(),
                        };
                        var usage = MachineUsage.GetCycleUsage(monitor.MachineID, procProgram, monitor.SpindleName, monitor.Toollocation);
                        if (usage != null)
                        {
                            if (usage.tc == 0 && usage.tl == 0)
                                toolLife.use_life = usage.usage;
                            else
                            {
                                toolLife.ratedlife = usage.tl;
                                toolLife.use_life = usage.tc;
                            }
                        }

                        if (toolLife.ratedlife != null && toolLife.ratedlife > 0)
                        {
                            toolLife.surplus_life = toolLife.ratedlife.Value - toolLife.use_life;
                            toolLife.percent = Math.Round((decimal)(toolLife.surplus_life / toolLife.ratedlife * 100), 1);
                        }
                        else
                        {
                            toolLife.percent = 0;
                        }

                        //百分比框背景颜色
                        if (toolLife.percent <= 20)
                            toolLife.surplus_type = "danger";
                        else if (toolLife.percent > 20 && toolLife.percent < 40)
                            toolLife.surplus_type = "warning";
                        else
                            toolLife.surplus_type = "success";
                        //百分比框字体颜色
                        toolLife.surplus_font_color = toolLife.percent <= 15 ? "#555" : "#fff";
                        //剩余时间
                        var dieTime = DateTime.Now.AddSeconds(toolLife.surplus_life * toolLife.cyc_time);
                        var tspan = dieTime - DateTime.Now;
                        string diff = tspan.Days + "天" + tspan.Hours + "小时" + tspan.Minutes + "分";
                        toolLife.cyc_time_str = toolLife.surplus_life <= 0 ? "0" : diff;
                        response.Add(toolLife);
                    }
                }
            }
            MachineState.Dispose();
            MachineUsage.Dispose();
            return new PagedObjectResult(response.OrderBy(o=>o.percent).Skip((1-request.page)*request.pagesize).Take(request.pagesize), response.Count, request.page, request.pagesize);
        }

        [HttpPost]
        public IActionResult ToolChangeEditTwo([FromBody]RequestToolChangeAdd req)
        {
            var record = new siger_tool_change_record
            {
                equip_code = req.machine_code,
                equip_name = req.machine_name,
                tool_name = req.tool_name,
                tool_drawno = req.drawingcode,
                tool_no = req.cutter_location_name,
                rating_life = req.ratedlife.ToInt(),
                residual_life = req.residual_life.ToInt(),
                true_residual_life = req.surplus_life.ToInt(),
                change_user = UserId.ToString(),
                change_time = string.IsNullOrEmpty(req.change_time)
                    ? UnixTimeHelper.GetUnixByShortDate(DateTime.Now.ToString(ParameterConstant.DateTimeFormat))
                    : UnixTimeHelper.GetUnixByShortDate(req.change_time),
                comment = req.comment,
                status = (int) RowState.Valid,
                projectid = ProjectId,
                mainaxis = req.spindle_name,
                supplier = req.supplier,
                machine_id = req.machine_id.ToInt(),
                change_reason = req.change_reason,
                url_path = req.cover,
                programno =req.programno,
            };
            sigerToolChangeRecordRepository.Insert(record);
            //GrayImage info
            _sigerProjectToolChangeExtend.Insert(new SigerProjectToolChangeExtend
            {
                MachineID = int.Parse(req.machine_id),
                Spindle = int.Parse(req.spindle_name),
                Tool = int.Parse(req.cutter_location_name),
                Program = req.programno,
                ChangeTime = UnixTimeHelper.GetUnixByShortDate(req.change_time),
                Project = ProjectId,
                Date = DateTime.Parse(DateTime.Now.ToShortDateString())

            });
            if (_unitOfWork.Commit() > 0)
            {
                try
                {
                    var redis = new ChangeToolRepository(CompanyId, ProjectId);
                    //1.5.2
                    var dapper = new ToolAlarmRepository(CompanyId, ProjectId);
                    var pn = req.programno;
                    var actime = DateTime.Now;
                    var spTime = dapper.GetSlicePeriod(pn, int.Parse(req.machine_id));
                    if (spTime != null)
                    {
                        var spTimeS = UnixTimeHelper.GetUnixByShortDate(spTime.starttime.ToStr());
                        var spTimeE = UnixTimeHelper.GetUnixByShortDate(spTime.endtime.ToStr());
                        var ChangeTime = UnixTimeHelper.GetUnixByShortDate(req.change_time);

                        if (ChangeTime >= spTimeS && ChangeTime <= spTimeE)
                            actime = UnixTimeHelper.ConvertStringDateTime(ChangeTime.ToStr());
                        else
                            actime = UnixTimeHelper.ConvertStringDateTime(spTimeE.ToStr());
                    }

                    var model = Mapper<siger_tool_change_record, RedisChangeRecordModel>.Map(record);
                    redis.AddChangeToolsRecord(model, actime);
                }
                catch (Exception exception)
                {
                    Logger.WriteLineError("Sync add ToolChangeRecord failed :error:" + exception.Message);
                }
                return new ObjectResult(CommonEnum.Succefull);
            }
            throw new BadRequestException(CommonEnum.Fail);
        }

        [HttpGet]
        public IActionResult CheckProgramNo(int id,string changetime)
        {
            var toolInfo = sigerProjectToolCutterLocationTrueRepository.GetToolLifeEntity(id);
            if (toolInfo == null)
            {
                throw new BadRequestException(CommonEnum.RecordNotFound);
            }
            

            var redisRepository = new ToolMachineCycleUsageRepository(CompanyId, ProjectId);
            var machineRepository = new CNCEquipmentStateRepository(CompanyId, ProjectId);
            var machine = machineRepository.GetCNCEquipmentState(toolInfo.machine_Id);
            if (machine == null)
            {
                throw new BadRequestException(RequestEnum.MachineNotFound);
            }
            var procProgram = string.Empty;
            if (toolInfo.IsProcess == (int)ProcessProgram.MainProgram)
                procProgram = ProgramType.mainProgram + toolInfo.programno;
            else
                procProgram = ProgramType.subProgram + toolInfo.subprogramno;

            toolInfo.programno = procProgram; //重置usage

            var usage = redisRepository.GetCycleUsage(toolInfo.machine_Id, procProgram, toolInfo.spindle_name, toolInfo.cutter_location_name);
            if (usage != null)
            {
                if (usage.tl==0 && usage.tc==0)
                {
                    toolInfo.use_life = usage.usage;
                    toolInfo.cycTime = usage.cycleTime;
                }
                else
                {
                    toolInfo.use_life = usage.tc;
                    toolInfo.ratedlife = usage.tl;
                }
            }
          

            if (toolInfo.ratedlife != null)
            {
                toolInfo.surplus_life = (double) toolInfo.ratedlife - toolInfo.use_life;
            }
            if (DateTime.TryParse(changetime, out DateTime nowTime))
                toolInfo.now_time = nowTime.ToString(ParameterConstant.DateTimeFormat);
            else
                toolInfo.now_time = DateTime.Now.ToString(ParameterConstant.DateTimeFormat);

            var dapper = new ToolAlarmRepository(CompanyId, ProjectId);
            var actime = DateTime.Now;
            var processPn = ProcessProgramHelper.ReplaceProgram(toolInfo.programno);
            var spTime = dapper.GetSlicePeriod(processPn, toolInfo.machine_Id);
            if (spTime != null)
            {
                var spTimeS = UnixTimeHelper.GetUnixByShortDate(spTime.starttime.ToStr());
                var spTimeE = UnixTimeHelper.GetUnixByShortDate(spTime.endtime.ToStr());
                var ChangeTime = UnixTimeHelper.GetUnixByShortDate(toolInfo.now_time);

                if (ChangeTime >= spTimeS && ChangeTime <= spTimeE)
                    actime = UnixTimeHelper.ConvertStringDateTime(ChangeTime.ToStr());
                else
                    actime = UnixTimeHelper.ConvertStringDateTime(spTimeE.ToStr());
            }
            toolInfo.LastCycleTime = actime.ToString(UnixTimeHelper.DateTimeFormat);
            return new ObjectResult(toolInfo);
        }

        [HttpPost]
        public IActionResult ToolChangeEdit([FromBody]RequestToolChangeEdit req)
        {
            var record = new siger_tool_change_record
            {
                equip_code = req.machine_code,
                equip_name = req.machine_name,
                tool_name = req.tool_name,
                tool_drawno = req.drawingcode,
                tool_no = req.cutter_location_name,
                rating_life = req.ratedlife.ToInt(),
                residual_life = req.residual_life.ToInt(),
                true_residual_life = req.surplus_life.ToInt(),
                change_user = UserId.ToString(),
                change_time = string.IsNullOrEmpty(req.change_time)
                    ? UnixTimeHelper.GetUnixByShortDate(DateTime.Now.ToString(ParameterConstant.DateTimeFormat))
                    : UnixTimeHelper.GetUnixByShortDate(req.change_time),
                comment = req.comment,
                status = (int)RowState.Valid,
                projectid = ProjectId,
                mainaxis = req.spindle_name,
                supplier = req.supplier,
                machine_id = req.machine_id.ToInt(),
                change_reason = req.change_reason,
                url_path = req.cover,
                programno = ProcessProgramHelper.ReplaceProgram(req.programno),
            };
            sigerToolChangeRecordRepository.Insert(record);
            //GrayImage info
            _sigerProjectToolChangeExtend.Insert(new SigerProjectToolChangeExtend
            {
                MachineID = int.Parse(req.machine_id),
                Spindle = int.Parse(req.spindle_name),
                Tool = int.Parse(req.cutter_location_name),
                Program = ProcessProgramHelper.ReplaceProgram(req.programno),
                ChangeTime = UnixTimeHelper.GetUnixByShortDate(req.change_time),
                Project = ProjectId,
                Date = DateTime.Parse(DateTime.Now.ToShortDateString())

            });
            if (_unitOfWork.Commit() > 0)
            {
                SyncChange(record, CompanyId, ProjectId, req.programno);
                return new ObjectResult(CommonEnum.Succefull);
            }
            throw new BadRequestException(CommonEnum.Fail);
        }
        private void SyncChange(siger_tool_change_record record,int cid,int pid,string program)
        {
            try
            {
                var redis = new ChangeToolRepository(cid, pid);
                //1.5.2
                var dapper = new ToolAlarmRepository(cid, pid);
                var pn = ProcessProgramHelper.ReplaceProgram(record.programno);
                var actime = UnixTimeHelper.ConvertStringDateTime( record.change_time.ToStr());
                var spTime = dapper.GetSlicePeriod(pn, record.machine_id);
                if (spTime != null)
                {
                    var spTimeS = UnixTimeHelper.GetUnixByShortDate(spTime.starttime.ToStr());
                    var spTimeE = UnixTimeHelper.GetUnixByShortDate(spTime.endtime.ToStr());
                    var ChangeTime = record.change_time;

                    if (ChangeTime >= spTimeS && ChangeTime <= spTimeE)
                        actime = UnixTimeHelper.ConvertStringDateTime(ChangeTime.ToStr());
                    else
                        actime = UnixTimeHelper.ConvertStringDateTime(spTimeE.ToStr());
                }

                var model = Mapper<siger_tool_change_record, RedisChangeRecordModel>.Map(record);
                redis.AddChangeToolsRecord(model, actime);

                var redisUsage = new ToolMachineCycleUsageRepository(cid, pid);
                var changeTime = DateTime.Now.ToString(UnixTimeHelper.DateTimeFormat);

                redisUsage.ResetToolUsage(record.machine_id,program, record.mainaxis, record.tool_no, changeTime);
            }
            catch (Exception exception)
            {
                Logger.WriteLineError("Sync reset ToolChangeRecord failed :error:" + exception.Message);
            }
        }
    }
}