using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Siger.ApiCommon.Result;
using Siger.Middlelayer.CncRepository.Entities;
using Siger.Middlelayer.CncRepository.Repositories.Interface;
using Siger.Middlelayer.CncRepository.Request;
using Siger.Middlelayer.CncRepository.Response;
using Siger.Middlelayer.Common;
using Siger.Middlelayer.Common.Extensions;
using Siger.Middlelayer.Common.Helpers;
using Siger.Middlelayer.Common.ModuleEnum;
using Siger.Middlelayer.Dapper;
using Siger.Middlelayer.Dapper.ResultData;
using Siger.Middlelayer.Repository;
using Siger.Middlelayer.Repository.Extensions;
using Siger.Middlelayer.Repository.Repositories.Interface;
using Siger.Middlelayer.Utility.Helpers;

namespace Siger.ApiCNC.Controllers
{
    public class MachineWordingModeController : BaseController
    {
        private readonly IUnitOfWork _unitOfWork;
        private readonly ISigerProjectMachineRepository _machineRepository;
        private readonly ISigerProjectMachineTypeRepository _machineTypeRepository;
        private readonly IMachineWordingModeRepository _wordingModeRepository;
        private readonly ISigerProjectShiftRepository _sigerProjectShiftRepository;
        public MachineWordingModeController(IUnitOfWork unitOfWork, IMachineWordingModeRepository wordingModeRepository,
            ISigerProjectMachineRepository machineRepository, ISigerProjectMachineTypeRepository machineTypeRepository, ISigerProjectShiftRepository sigerProjectShiftRepository)
        {
            _unitOfWork = unitOfWork;
            _wordingModeRepository = wordingModeRepository;
            _machineRepository = machineRepository;
            _machineTypeRepository = machineTypeRepository;
            _sigerProjectShiftRepository = sigerProjectShiftRepository;
        }

        [HttpPost]
        public IActionResult WorkingModeList([FromBody] RequestWorkingModeList request)
        {
            Expression<Func<siger_project_machine_wordingmode, bool>> defaultExpression = q => q.projectid == ProjectId && q.status == (int)RowState.Valid && q.parentid > 0;
            Expression<Func<siger_project_machine_wordingmode, bool>> fTypeExpression = q => true;
            Expression<Func<siger_project_machine_wordingmode, bool>> cTypeExpression = q => true;
            var fType = request.machineFtype1.ToInt();
            if (fType != 0)
            {
                fTypeExpression = q => q.machineftype1Id == fType;
            }
            var cType = request.machineCtype1.ToInt();
            if (cType != 0)
            {
                cTypeExpression = q => q.machinectype1Id == cType;
            }

            var expression = defaultExpression.And(fTypeExpression).And(cTypeExpression);

            var query = _wordingModeRepository.GetPagedList(request.page, request.pagesize, expression);
            var response = new List<siger_project_machine_wordingmode>();
            foreach (var mode in query.Data)
            {
                var workmode = Mapper<siger_project_machine_wordingmode, siger_project_machine_wordingmode>.Map(mode);
                if (mode.parentid > 0)
                {
                    var parent = _wordingModeRepository.Get(t => t.id == workmode.parentid && t.status == (int)RowState.Valid && t.projectid == ProjectId);
                    workmode.parentname = parent?.workingmodename ?? "";
                }
                response.Add(workmode);
            }
            return new PagedObjectResult(response, query.Total, request.page, request.pagesize);
        }

        [HttpGet]
        public IActionResult ShowWorkingModeList(int machineID)
        {
            var machine = _machineRepository.Get(machineID);
            if (machine == null || machine.status != (int)RowState.Valid)
            {
                throw new BadRequestException(RequestEnum.MachineNotFound);
            }

            var query = _wordingModeRepository.GetWorkModeList(ProjectId).ToList();
            return new ObjectResult(query);
        }

        [HttpGet]
        public IActionResult ShowParentWorkModeList()
        {
            var query = _wordingModeRepository.GetList(q => q.projectid == ProjectId && q.status == (int)RowState.Valid && q.parentid == 0);
            var queryList = query.Select(m => new
            {
                m.id,
                m.workingmodename
            }).ToList();
            return new ObjectResult(queryList);
        }

        [HttpPost]
        public IActionResult WorkingModeAdd([FromBody] RequestAddWorkingMode request)
        {
            var ctype = request.machineCtype1Id.ToInt();
            var ftype = request.machineFType1Id.ToInt();
            var parentId = request.parentId.ToInt();

            if (parentId == 0 && string.IsNullOrWhiteSpace(request.parentMode))
            {
                throw new BadRequestException(RequestEnum.ParameterError);
            }
            var entity = _wordingModeRepository.Get(q => q.projectid == ProjectId && (q.workingmodename == request.WorkingMode && q.parentid > 0 ||
                q.workingmodename == request.parentMode && q.parentid == 0 && !string.IsNullOrWhiteSpace(request.parentMode))
                && q.status == (int)RowState.Valid);
            if (entity != null)
            {
                throw new ServerException(800266);
            }

            if (!string.IsNullOrWhiteSpace(request.parentMode))
            {
                var parentWorkMode = new siger_project_machine_wordingmode
                {
                    machinectype1Id = ctype,
                    machineftype1Id = ftype,
                    notelist = request.note,
                    projectid = ProjectId,
                    workingmodename = request.parentMode,
                    add_time = UnixTimeHelper.GetNow(),
                    machinectype1name = request.machineCtype1Name,
                    machineftype1name = request.machineFType1Name
                };
                _wordingModeRepository.Insert(parentWorkMode);
                if (_unitOfWork.Commit() <= 0)
                {
                    throw new BadRequestException(CommonEnum.Fail);
                }
                parentId = parentWorkMode.id;
            }
            else if (parentId > 0)
            {
                var parentMode = _wordingModeRepository.Get(t => t.id == parentId && t.projectid == ProjectId && t.status == (int)RowState.Valid);
                if (parentMode == null)
                {
                    throw new BadRequestException(RequestEnum.NoParentStorageType);
                }
                else if (parentMode.parentid > 0)
                {
                    throw new BadRequestException(RequestEnum.StorageType2More);
                }
            }

            var mode = new siger_project_machine_wordingmode
            {
                parentid = parentId,
                machinectype1Id = ctype,
                machineftype1Id = ftype,
                notelist = request.note,
                projectid = ProjectId,
                workingmodename = request.WorkingMode,
                add_time = UnixTimeHelper.GetNow(),
                machinectype1name = request.machineCtype1Name,
                machineftype1name = request.machineFType1Name
            };
            _wordingModeRepository.Insert(mode);
            if (_unitOfWork.Commit() > 0)
            {
                return new ObjectResult(CommonEnum.Succefull);
            }
            throw new BadRequestException(CommonEnum.Fail);
        }

        [HttpGet]
        public IActionResult WorkingModeAlertEdit(int id)
        {
            var mode = _wordingModeRepository.Get(id);
            if (mode == null || mode.status != (int)RowState.Valid)
            {
                throw new BadRequestException(CommonEnum.RecordNotFound);
            }
            return new ObjectResult(mode);
        }

        [HttpPost]
        public IActionResult WorkingModeEdit([FromBody] RequestEditWorkingMode request)
        {
            var parentId = request.parentId.ToInt();
            if (parentId == 0 && string.IsNullOrWhiteSpace(request.parentMode))
            {
                throw new BadRequestException(RequestEnum.ParameterError);
            }

            var entity = _wordingModeRepository.Get(q => q.projectid == ProjectId && (q.workingmodename == request.workingmodename && q.id != request.id &&
                    q.parentid > 0 || q.workingmodename == request.parentMode && q.parentid == 0 && !string.IsNullOrWhiteSpace(request.parentMode) &&
                    q.workingmodename != request.parentMode) && q.status == (int)RowState.Valid);
            if (entity != null)
            {
                throw new ServerException(800266);
            }

            var mode = _wordingModeRepository.Get(request.id);
            if (mode == null || mode.status != (int)RowState.Valid)
            {
                throw new BadRequestException(CommonEnum.RecordNotFound);
            }

            if (!string.IsNullOrWhiteSpace(request.parentMode))
            {
                var parentEntity = new siger_project_machine_wordingmode();
                var parentMode = _wordingModeRepository.Get(t => t.id == mode.parentid && t.projectid == ProjectId && t.status == (int)RowState.Valid);
                if (parentMode != null)
                {
                    parentEntity = _wordingModeRepository.Get(q => q.projectid == ProjectId && q.workingmodename == request.parentMode &&
                              q.status == (int)RowState.Valid && q.workingmodename != parentMode.workingmodename);
                }
                else
                {
                    parentEntity = _wordingModeRepository.Get(q => q.projectid == ProjectId && q.workingmodename == request.parentMode &&
                              q.status == (int)RowState.Valid);
                }
                if (parentEntity != null)
                {
                    throw new ServerException(800266);
                }
                if (parentMode?.workingmodename != request.parentMode)
                {
                    var machineCType = _machineTypeRepository.Get(t => t.id == mode.machinectype1Id);
                    var machineFType = _machineTypeRepository.Get(t => t.id == mode.machineftype1Id);
                    var parentWorkMode = new siger_project_machine_wordingmode
                    {
                        machinectype1Id = mode.machinectype1Id,
                        machineftype1Id = mode.machineftype1Id,
                        notelist = request.notelist,
                        workingmodename = request.parentMode,
                        projectid = ProjectId,
                        add_time = UnixTimeHelper.GetNow(),
                        machinectype1name = machineCType?.title ?? "",
                        machineftype1name = machineFType?.title ?? ""
                    };
                    _wordingModeRepository.Insert(parentWorkMode);
                    if (_unitOfWork.Commit() <= 0)
                    {
                        throw new BadRequestException(CommonEnum.Fail);
                    }
                    parentId = parentWorkMode.id;
                }
            }
            else if (parentId > 0)
            {
                var parentMode = _wordingModeRepository.Get(t => t.id == parentId && t.projectid == ProjectId && t.status == (int)RowState.Valid);
                if (parentMode == null)
                {
                    throw new BadRequestException(RequestEnum.NoParentStorageType);
                }
                else if (parentMode.parentid > 0 && mode.parentid != mode.id)
                {
                    throw new BadRequestException(RequestEnum.StorageType2More);
                }
                var sonMode = _wordingModeRepository.Get(t => t.parentid == mode.id && t.projectid == ProjectId && t.status == (int)RowState.Valid);
                if (sonMode != null && mode.parentid != mode.id)
                {
                    throw new BadRequestException(RequestEnum.StorageType2More);
                }
            }

            mode.parentid = parentId;
            mode.notelist = request.notelist;
            mode.workingmodename = request.workingmodename;
            mode.edit_time = UnixTimeHelper.GetNow();
            _wordingModeRepository.Update(mode);
            if (_unitOfWork.Commit() > 0)
            {
                return new ObjectResult(CommonEnum.Succefull);
            }
            throw new BadRequestException(CommonEnum.Fail);
        }

        [HttpPost]
        public IActionResult WorkingModeDel(int id)
        {
            var mode = _wordingModeRepository.Get(id);
            if (mode == null || mode.status != (int)RowState.Valid)
            {
                throw new BadRequestException(CommonEnum.RecordNotFound);
            }

            var sonModes = _wordingModeRepository.GetList(t => t.parentid == mode.parentid && t.projectid == ProjectId && t.status == (int)RowState.Valid);
            var sonMode = sonModes.FirstOrDefault();
            if (sonModes.Count() == 1 && sonMode.id == mode.id)
            {
                var parentMode = _wordingModeRepository.Get(t => t.id == mode.parentid && t.projectid == ProjectId && t.status == (int)RowState.Valid);
                if (parentMode != null)
                {
                    parentMode.status = (int)RowState.Invalid;
                    _wordingModeRepository.Update(parentMode);
                }
            }

            mode.status = (int)RowState.Invalid;
            _wordingModeRepository.Update(mode);

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

        [HttpPost]
        public IActionResult WorkingModeDels(string ids)
        {
            if (string.IsNullOrWhiteSpace(ids))
            {
                throw new BadRequestException(RequestEnum.ParameterError);
            }

            foreach (var id in ids.Split(','))
            {
                var mode = _wordingModeRepository.Get(id.ToInt());
                if (mode == null || mode.status != (int)RowState.Valid)
                {
                    throw new BadRequestException(CommonEnum.RecordNotFound);
                }

                var sonModes = _wordingModeRepository.GetList(t => t.parentid == mode.parentid && t.projectid == ProjectId && t.status == (int)RowState.Valid);
                var sonMode = sonModes.FirstOrDefault();
                if (sonModes.Count() == 1 && sonMode.id == mode.id)
                {
                    var parentMode = _wordingModeRepository.Get(t => t.id == mode.parentid && t.projectid == ProjectId && t.status == (int)RowState.Valid);
                    if (parentMode != null)
                    {
                        parentMode.status = (int)RowState.Invalid;
                        _wordingModeRepository.Update(parentMode);
                    }
                }

                mode.status = (int)RowState.Invalid;
                _wordingModeRepository.Update(mode);
            }

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

        [HttpPost]
        public async Task<IActionResult> SetWorkingMode([FromBody] RequestSetWorkingMode request)
        {
            var dateTimes = request.time.Split(" - ");
            var success = DateTime.TryParse(dateTimes[0], out var dtStart);
            if (!success)
            {
                throw new BadRequestException(CncEnum.DateTimeFormatError);
            }
            success = DateTime.TryParse(dateTimes[1], out var dtEnd);
            if (!success)
            {
                throw new BadRequestException(CncEnum.DateTimeFormatError);
            }

            var mode = _wordingModeRepository.Get(q => q.id == request.modeId);
            if (mode == null || mode.status != (int)RowState.Valid)
            {
                throw new BadRequestException(RequestEnum.WorkingModeIsEmpty);
            }

            var repositoey = new SliceSateRepository(CompanyId, ProjectId);
            var result = await repositoey.UpdateMachineSliceWorkModeAsync(request.machineId, request.modeId, mode.workingmodename, request.userName,
                request.remark, dtStart.ToString(ParameterConstant.DateTimeFormat), dtEnd.ToString(ParameterConstant.DateTimeFormat));

            if (result <= 0)
            {
                throw new BadRequestException(CommonEnum.Fail);
            }
            return new ObjectResult(CommonEnum.Succefull);
        }

        [HttpPost]
        public async Task<IActionResult> WorkingModeAnalysis([FromBody] RequestWorkingModeAnalysis request)
        {
            //xID - 0:时间 1：层级 2：故障代码
            //yID - 只有时长
            //patchID - xID=0时 0:天 1：周 2：月；xID=4时 patchID为levelID；xID=5时，pactchid为errorCode；xID=5时，按照故障类型
            if (!DateTime.TryParse(request.startTime, out var dtStart))
            {
                throw new ServerException(500146);
            }

            if (!DateTime.TryParse(request.endTime, out var dtEnd))
            {
                throw new ServerException(500146);
            }

            dtEnd = dtEnd.AddDays(1).AddSeconds(-1);
            if (dtStart > dtEnd)
            {
                throw new ServerException(100158);
            }

            var machineIds = new List<int>();
            var sectionId = request.sectionID.ToInt();
            if (sectionId != 0)
            {
                machineIds = _machineRepository.GetNCLevelSectionMachineIds(sectionId, ProjectId).ToList();
            }
            var repository = new SliceSateRepository(CompanyId, ProjectId);
            var modeIds = new List<int>();
            var parentModes = new List<int>();
            var modeids = new List<int>();
            var sonWorkModes = new List<siger_project_machine_wordingmode>();
            if (request.parent_mode != "0" && !string.IsNullOrEmpty(request.parent_mode))
            {
                parentModes = request.parent_mode.Split(',').Select(t => t.ToInt()).ToList();
                if (parentModes.Any())
                {
                    sonWorkModes = _wordingModeRepository.GetList(t => parentModes.Contains(t.parentid) && t.projectid == ProjectId && t.status == (int)RowState.Valid).ToList();
                    modeids = sonWorkModes.Select(t => t.id).ToList();
                    var sonModes = request.working_mode.Split(',').Select(t => t.ToInt()).ToList();
                    modeIds = (sonModes.Any() && request.working_mode != "0" && !string.IsNullOrEmpty(request.working_mode)) ? modeids.Where(t => sonModes.Contains(t)).ToList() : modeids;
                }
            }
            if (string.IsNullOrEmpty(request.parent_mode) || request.parent_mode == "0")
            {
                parentModes = _wordingModeRepository.GetList(t => t.projectid == ProjectId && t.status == (int)RowState.Valid && t.parentid == 0).Select(t => t.id).ToList();
                modeIds = _wordingModeRepository.GetList(t => parentModes.Contains(t.parentid) && t.projectid == ProjectId && t.status == (int)RowState.Valid).Select(t => t.id).ToList();
            }
            else if (!modeIds.Any())
            {
                modeIds.Add(-1);
            }

            var result = new List<ResponseGetAlarmDataForAnalysis>();
            var responses = new List<ResponseGetAlarmDataForAnalysis>();
            var xid = request.xID.ToInt();
            var patchId = request.patchID.ToInt();
            double rate = 0;
            if (xid == 0)
            {
                var sates = await repository.GetCncSliceSatesForWorkingMode(machineIds, modeIds, dtStart.ToString(ParameterConstant.DateTimeFormat), dtEnd.ToString(ParameterConstant.DateTimeFormat));
                var cncSlices = sates.Where(q => (q.EndTime >= dtStart && q.EndTime <= dtEnd || q.StartTime >= dtStart && q.StartTime <= dtEnd) && q.WordingModeId > 0).ToList();
                //处理柏拉图数据
                var all = cncSlices.Sum(t => ((t.EndTime <= dtEnd ? t.EndTime : dtEnd) - (t.StartTime >= dtStart ? t.StartTime : dtStart)).TotalMinutes);
                var type = 0;
                if (patchId == 1)
                {
                    type = 11;
                }
                else if (patchId == 2)
                {
                    type = 12;
                }
                else
                {
                    type = patchId;
                }
                var interal = DateTimeHelper.GetInteral(patchId);
                var dates = DateTimeHelper.GetDateTimes(dtStart, dtEnd, type);
                var xData = DateTimeHelper.GetStrDateTimes(dtStart, dtEnd, type);
                var count = 0;
                foreach (var date in dates)
                {
                    var response = new ResponseGetAlarmDataForAnalysis();
                    DateTime start;
                    DateTime end;
                    if (patchId == 0)
                    {
                        start = date;
                        end = date.AddDays(interal).AddSeconds(-1);
                        response.Abscissa = end.ToString(ParameterConstant.DateFormat);
                    }
                    else if (patchId == 1)
                    {
                        response.Abscissa = xData[count];
                        var weekStart = DateTimeHelper.GetWeekRangeStart(response.Abscissa);
                        var weekEnd = DateTimeHelper.GetWeekRangeEnd(response.Abscissa);
                        start = dtStart > weekStart ? dtStart : weekStart;
                        end = dtEnd < weekEnd ? dtEnd : weekEnd.AddDays(1).AddSeconds(-1);
                    }
                    else
                    {
                        start = dates[count];
                        var dts = start.AddMonths(1);
                        dts = dts.AddDays(0 - dts.Day).AddDays(1).AddSeconds(-1);
                        end = dts > dtEnd ? dtEnd.AddDays(1).AddSeconds(-1) : dts; //到月底
                        response.Abscissa = end.ToString("yyyy-MM");
                    }

                    response.Ordinate = Math.Round(cncSlices.Where(q => q.EndTime >= start && q.EndTime <= end || q.StartTime >= start && q.StartTime <= end).Sum(t => ((t.EndTime <= end ? t.EndTime : end) - (t.StartTime >= start ? t.StartTime : start)).TotalMinutes), 0);

                    response.Rate = Math.Round(all > 0 ? Math.Round(response.Ordinate / all, 4) * 100 : 0, 2);
                    //rate = rate > 0 ? Math.Round(rate + response.Ordinate / all, 4) * 100 : 0;
                    responses.Add(response);
                    count++;
                }
            }

            if (xid == 4)
            {
                //patchId 为levelId
                //取sectionID下面的设备
                try
                {
                    var sates = await repository.GetCncSliceSatesForWorkingMode(machineIds, modeIds, dtStart.ToString(ParameterConstant.DateTimeFormat), dtEnd.ToString(ParameterConstant.DateTimeFormat));
                    var cncSlices = sates.Where(q => (q.EndTime >= dtStart && q.EndTime <= dtEnd || q.StartTime >= dtStart && q.StartTime <= dtEnd) && q.WordingModeId > 0).ToList();//await GroupedSates(sates);
                    //处理柏拉图数据
                    var all = Math.Round(cncSlices.Sum(t => ((t.EndTime <= dtEnd ? t.EndTime : dtEnd) - (t.StartTime >= dtStart ? t.StartTime : dtStart)).TotalMinutes), 2);
                    var sections = _machineRepository.GetNCLevelSections(sectionId, ProjectId);
                    var levels = sections.Where(q => q.levelid == patchId).ToList();
                    if (levels.Any())
                    {
                        foreach (var levelSection in levels)
                        {
                            machineIds = _machineRepository.GetNCLevelSectionMachineIds(levelSection.id, ProjectId).ToList();
                            var response = new ResponseGetAlarmDataForAnalysis
                            {
                                Abscissa = levelSection.title,
                                Ordinate = Math.Round(cncSlices.Where(q => machineIds.Contains(q.MachineID)).Sum(t => ((t.EndTime <= dtEnd ? t.EndTime : dtEnd) - (t.StartTime >= dtStart ? t.StartTime : dtStart)).TotalMinutes), 0)
                            };

                            result.Add(response);
                        }
                    }
                    else //最后一级
                    {
                        var machine = _machineRepository.GetNCMachineBySectionId(sectionId, ProjectId);
                        machineIds = _machineRepository.GetNCLevelSectionMachineIds(sectionId, ProjectId).ToList();
                        var response = new ResponseGetAlarmDataForAnalysis
                        {
                            Abscissa = machine.name,
                            Ordinate = Math.Round(cncSlices.Where(q => machineIds.Contains(q.MachineID)).Sum(t => ((t.EndTime <= dtEnd ? t.EndTime : dtEnd) - (t.StartTime >= dtStart ? t.StartTime : dtStart)).TotalMinutes), 0)
                        };
                        result.Add(response);
                    }

                    var i = 1;
                    foreach (var analysis in result.OrderByDescending(q => q.Ordinate).ToList())
                    {
                        rate += all > 0 ? Math.Round(analysis.Ordinate / all, 4) * 100 : 0;
                        var response = new ResponseGetAlarmDataForAnalysis
                        {
                            Abscissa = analysis.Abscissa,
                            Ordinate = analysis.Ordinate,
                            Rate = i == result.Count ? 100 : Math.Round(rate, 2)
                        };
                        responses.Add(response);
                        i++;
                    }
                }
                catch
                {
                    throw new BadRequestException(CommonEnum.RecordNotFound);
                }
            }
            if (xid == 5)
            {
                var sates = await repository.GetCncSliceSatesForWorkingMode(machineIds, modeIds, dtStart.ToString(ParameterConstant.DateTimeFormat), dtEnd.ToString(ParameterConstant.DateTimeFormat));
                var sateList = new List<CncSliceSate>();
                var all = 0.0;
                if (request.patchID == "1")
                {

                    sateList = sates.Where(t => t.WordingModeId > 0).ToList();
                    foreach (var item in sateList)
                    {
                        if (item.WordingModeId > 0)
                        {
                            var workMode = _wordingModeRepository.Get(t => t.id == item.WordingModeId);
                            if (workMode != null)
                            {
                                var mode = _wordingModeRepository.Get(t => t.id == workMode.parentid);
                                item.WordingName = mode != null ? mode.workingmodename : "";
                            }
                        }

                    }
                    var names = sateList.Select(s => s.WordingName).Distinct();
                    foreach (var item in names)
                    {
                        var ret = new ResponseGetAlarmDataForAnalysis { Abscissa = item, Ordinate = Math.Round(sateList.Where(q => q.WordingName == item).Sum(t => ((t.EndTime <= dtEnd ? t.EndTime : dtEnd) - (t.StartTime >= dtStart ? t.StartTime : dtStart)).TotalMinutes), 2) };
                        result.Add(ret);
                    }
                    var cncSlices = sateList.Where(q => (q.EndTime >= dtStart && q.EndTime <= dtEnd || q.StartTime >= dtStart && q.StartTime <= dtEnd));//await GroupedSates(sateList);
                                                                                                                                                        //处理柏拉图数据
                    all = Math.Round(cncSlices.Sum(t => ((t.EndTime <= dtEnd ? t.EndTime : dtEnd) - (t.StartTime >= dtStart ? t.StartTime : dtStart)).TotalMinutes), 2);
                }
                else
                {

                    sateList = sates.Where(t => t.WordingModeId > 0).ToList();
                    foreach (var item in sateList)
                    {
                        if (item.WordingModeId > 0)
                        {
                            var workMode = _wordingModeRepository.Get(t => t.id == item.WordingModeId);
                            if (workMode != null)
                            {
                                item.WordingName = workMode.workingmodename;
                            }
                        }

                    }
                    var cncSlices = sateList.Where(q => (q.EndTime >= dtStart && q.EndTime <= dtEnd || q.StartTime >= dtStart && q.StartTime <= dtEnd));//await GroupedSates(sateList);
                                                                                                                                                        //处理柏拉图数据
                    all = Math.Round(cncSlices.Sum(t => ((t.EndTime <= dtEnd ? t.EndTime : dtEnd) - (t.StartTime >= dtStart ? t.StartTime : dtStart)).TotalMinutes), 2);
                    var modes = cncSlices.Select(m => m.WordingModeId).Distinct().ToList();
                    foreach (var mode in modes)
                    {
                        var workMode = cncSlices.FirstOrDefault(t => t.WordingModeId == mode);
                        if (workMode == null)
                        {
                            continue;
                        }
                        var response = new ResponseGetAlarmDataForAnalysis
                        {
                            Abscissa = workMode.WordingName,
                            Ordinate = Math.Round(cncSlices.Where(q => q.WordingModeId == mode).Sum(t => ((t.EndTime <= dtEnd ? t.EndTime : dtEnd) - (t.StartTime >= dtStart ? t.StartTime : dtStart)).TotalMinutes), 2)
                        };
                        result.Add(response);
                    }
                }
                var i = 1;
                foreach (var analysis in result.OrderByDescending(q => q.Ordinate).ToList())
                {
                    rate += all > 0 ? Math.Round(analysis.Ordinate / all, 4) * 100 : 0;
                    var response = new ResponseGetAlarmDataForAnalysis
                    {
                        Abscissa = analysis.Abscissa,
                        Ordinate = analysis.Ordinate,
                        Rate = i == result.Count ? 100 : Math.Round(rate, 2)
                    };
                    responses.Add(response);
                    i++;
                }
            }
            if (request.toexcel == 0)
            {
                return new ObjectResult(responses);
            }
            var machines = _machineRepository.GetProjectLanguage(ProjectId);
            switch (xid)
            {
                case 0:
                    return ExportBarChart(responses, machines, (int)XTypes.DateStatus);
                case 4:
                    return ExportBarChart(responses, machines, (int)XTypes.SectionStatus);
                case 5:
                    return ExportBarChart(responses, machines, (int)XTypes.FaultCode);
                default:
                    return ExportBarChart(responses, machines, (int)XTypes.OtherType);
            }
        }

        [HttpPost]
        public IActionResult GetSonModesByParents([FromBody] RequestGetModesByParents req)
        {
            var ids = new List<int>();
            if (req.parentIds != null && req.parentIds.Any() && req.parentIds != "0")
            {
                ids = req.parentIds.Split(',').Select(t => t.ToInt()).ToList();
            }

            var query = _wordingModeRepository.GetList(q => q.projectid == ProjectId && q.status == (int)RowState.Valid && ids.Contains(q.parentid));
            var queryList = query.Select(m => new
            {
                m.id,
                m.workingmodename
            }).ToList();
            return new ObjectResult(queryList);
        }

        [HttpGet]
        public IActionResult GetParentModesByMachineId(int machineID)
        {
            var query = _wordingModeRepository.GetWorkModeList(ProjectId).ToList();
            return new ObjectResult(query.Where(t => t.parentid == 0).ToList());
        }

        [HttpPost]
        public async Task<IActionResult> WorkingModeAnalysisTwo([FromBody] RequestWorkingModeAnalysisTwo request)
        {
            //xID - 0:时间 1：层级 2：故障代码
            //yID - 只有时长
            //patchID - xID=0时 0:天 1：周 2：月；xID=4时 patchID为levelID；xID=5时，pactchid为errorCode；xID=5时，按照故障类型
            request.patchID = "1";
            request.xID = "5";

            if (!DateTime.TryParse(request.startTime, out var dtStart))
            {
                throw new ServerException(500146);
            }
            if (!DateTime.TryParse(dtStart.AddDays(1).AddSeconds(-1).ToString(), out var dtEnd))
            {
                throw new ServerException(500146);
            }

            if (request.frequency > 0)
            {
                var frequency = _sigerProjectShiftRepository.Get(q => q.id == request.frequency && q.status == (int)RowState.Valid && q.projectid == ProjectId);
                var starts = UnixTimeHelper.GetTimeByUnix(frequency.start_time);
                var ends = UnixTimeHelper.GetTimeByUnix(frequency.end_time);
                if (frequency.start_time < frequency.end_time)
                {
                    var s1 = dtStart.ToString(ParameterConstant.DateFormat) + " " + starts;
                    var s2 = dtEnd.ToString(ParameterConstant.DateFormat) + " " + ends;
                    DateTime.TryParse(s1, out dtStart);
                    DateTime.TryParse(s2, out dtEnd);
                }
                else
                {
                    var s1 = dtStart.ToString(ParameterConstant.DateFormat) + " " + starts;
                    var s2 = dtStart.AddDays(1).ToString(ParameterConstant.DateFormat) + " " + ends;
                    DateTime.TryParse(s1, out dtStart);
                    DateTime.TryParse(s2, out dtEnd);
                }
            }
            if (dtStart > dtEnd)
            {
                throw new ServerException(100158);
            }

            var machineIds = new List<int>();
            var sectionId = request.sectionID.ToInt();
            if (sectionId != 0)
            {
                machineIds = _machineRepository.GetNCLevelSectionMachineIds(sectionId, ProjectId).ToList();
            }
            var repository = new SliceSateRepository(CompanyId, ProjectId);
            var modeIds = new List<int>();
            var parentModes = new List<int>();
            var modeids = new List<int>();
            var sonWorkModes = new List<siger_project_machine_wordingmode>();
            if (request.parent_mode != "0" && !string.IsNullOrEmpty(request.parent_mode))
            {
                parentModes = request.parent_mode.Split(',').Select(t => t.ToInt()).ToList();
                if (parentModes.Any())
                {
                    sonWorkModes = _wordingModeRepository.GetList(t => parentModes.Contains(t.parentid) && t.projectid == ProjectId && t.status == (int)RowState.Valid).ToList();
                    modeids = sonWorkModes.Select(t => t.id).ToList();
                    var sonModes = request.working_mode.Split(',').Select(t => t.ToInt()).ToList();
                    modeIds = (sonModes.Any() && request.working_mode != "0" && !string.IsNullOrEmpty(request.working_mode)) ? modeids.Where(t => sonModes.Contains(t)).ToList() : modeids;
                }
            }
            if (string.IsNullOrEmpty(request.parent_mode) || request.parent_mode == "0")
            {
                parentModes = _wordingModeRepository.GetList(t => t.projectid == ProjectId && t.status == (int)RowState.Valid && t.parentid == 0).Select(t => t.id).ToList();
                modeIds = _wordingModeRepository.GetList(t => parentModes.Contains(t.parentid) && t.projectid == ProjectId && t.status == (int)RowState.Valid).Select(t => t.id).ToList();
            }
            else if (!modeIds.Any())
            {
                modeIds.Add(-1);
            }

            var result = new List<ResponseGetAlarmDataForAnalysis>();
            var responses = new List<ResponseGetAlarmDataForAnalysis>();
            var xid = request.xID.ToInt();
            var patchId = request.patchID.ToInt();
            double rate = 0;
            
            if (xid == 5)
            {
                var sates = await repository.GetCncSliceSatesForWorkingMode(machineIds, modeIds, dtStart.ToString(ParameterConstant.DateTimeFormat), dtEnd.ToString(ParameterConstant.DateTimeFormat));
                var sateList = new List<CncSliceSate>();
                var all = 0.0;
                if (request.patchID == "1")
                {

                    sateList = sates.Where(t => t.WordingModeId > 0).ToList();
                    foreach (var item in sateList)
                    {
                        if (item.WordingModeId > 0)
                        {
                            var workMode = _wordingModeRepository.Get(t => t.id == item.WordingModeId);
                            if (workMode != null)
                            {
                                var mode = _wordingModeRepository.Get(t => t.id == workMode.parentid);
                                item.WordingName = mode != null ? mode.workingmodename : "";
                            }
                        }

                    }
                    var names = sateList.Select(s => s.WordingName).Distinct();
                    foreach (var item in names)
                    {
                        var ret = new ResponseGetAlarmDataForAnalysis { Abscissa = item, Ordinate = Math.Round(sateList.Where(q => q.WordingName == item).Sum(t => ((t.EndTime <= dtEnd ? t.EndTime : dtEnd) - (t.StartTime >= dtStart ? t.StartTime : dtStart)).TotalMinutes), 2) };
                        result.Add(ret);
                    }
                    var cncSlices = sateList.Where(q => (q.EndTime >= dtStart && q.EndTime <= dtEnd || q.StartTime >= dtStart && q.StartTime <= dtEnd));//await GroupedSates(sateList);
                                                                                                                                                        //处理柏拉图数据
                    all = Math.Round(cncSlices.Sum(t => ((t.EndTime <= dtEnd ? t.EndTime : dtEnd) - (t.StartTime >= dtStart ? t.StartTime : dtStart)).TotalMinutes), 2);
                }
                else
                {

                    sateList = sates.Where(t => t.WordingModeId > 0).ToList();
                    foreach (var item in sateList)
                    {
                        if (item.WordingModeId > 0)
                        {
                            var workMode = _wordingModeRepository.Get(t => t.id == item.WordingModeId);
                            if (workMode != null)
                            {
                                item.WordingName = workMode.workingmodename;
                            }
                        }

                    }
                    var cncSlices = sateList.Where(q => (q.EndTime >= dtStart && q.EndTime <= dtEnd || q.StartTime >= dtStart && q.StartTime <= dtEnd));//await GroupedSates(sateList);
                                                                                                                                                        //处理柏拉图数据
                    all = Math.Round(cncSlices.Sum(t => ((t.EndTime <= dtEnd ? t.EndTime : dtEnd) - (t.StartTime >= dtStart ? t.StartTime : dtStart)).TotalMinutes), 2);
                    var modes = cncSlices.Select(m => m.WordingModeId).Distinct().ToList();
                    foreach (var mode in modes)
                    {
                        var workMode = cncSlices.FirstOrDefault(t => t.WordingModeId == mode);
                        if (workMode == null)
                        {
                            continue;
                        }
                        var response = new ResponseGetAlarmDataForAnalysis
                        {
                            Abscissa = workMode.WordingName,
                            Ordinate = Math.Round(cncSlices.Where(q => q.WordingModeId == mode).Sum(t => ((t.EndTime <= dtEnd ? t.EndTime : dtEnd) - (t.StartTime >= dtStart ? t.StartTime : dtStart)).TotalMinutes), 2)
                        };
                        result.Add(response);
                    }
                }
                var i = 1;
                foreach (var analysis in result.OrderByDescending(q => q.Ordinate).ToList())
                {
                    rate += all > 0 ? Math.Round(analysis.Ordinate / all, 4) * 100 : 0;
                    var response = new ResponseGetAlarmDataForAnalysis
                    {
                        Abscissa = analysis.Abscissa,
                        Ordinate = analysis.Ordinate,
                        Rate = i == result.Count ? 100 : Math.Round(rate, 2)
                    };
                    responses.Add(response);
                    i++;
                }
            }
            return new ObjectResult(responses);
        }
    }
}