using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Siger.ApiCNC.Result;
using Siger.ApiCommon.Result;
using Siger.ApiCommon.Utilities;
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.AppSettings;
using Siger.Middlelayer.Common.Extensions;
using Siger.Middlelayer.Common.Helpers;
using Siger.Middlelayer.Common.ModuleEnum;
using Siger.Middlelayer.Dapper;
using Siger.Middlelayer.Log;
using Siger.Middlelayer.Repository;
using Siger.Middlelayer.Repository.Entities;
using Siger.Middlelayer.Repository.Repositories.Interface;
using Siger.Middlelayer.Repository.Response;
using Siger.Middlelayer.Utility.Helpers;
using Siger.Middlelayer.Utility.ImportEntities;

namespace Siger.ApiCNC.Controllers
{
    public class ProductReportController : BaseController
    {
        private readonly ISigerProjectProductReport _productionReportRepository;
        private readonly ISigerProjectUserRepository _userRepository;
        private readonly IProductPlanRepository _planRepository;
        private readonly IUnitOfWork _unitOfWork;
        private readonly ISigerProjectMachineRepository _machineRepository;
        private readonly IProductPlanDetailRepository _planDetailRepository;
        private readonly IProductionBeatSetRepository _beatSetRepository;
        private readonly IProductRouteRepository _routeRepository;
        private readonly ISigerProjectProductRepository _productRepository;

        public ProductReportController(IUnitOfWork unitOfWork, ISigerProjectProductReport productionReportRepository,
            ISigerProjectUserRepository userRepository, IProductPlanRepository planRepository, ISigerProjectMachineRepository machineRepository,
            IProductPlanDetailRepository planDetailRepository, IProductionBeatSetRepository beatSetRepository,
            IProductRouteRepository routeRepository, ISigerProjectProductRepository productRepository)
        {
            _productionReportRepository = productionReportRepository;
            _userRepository = userRepository;
            _planRepository = planRepository;
            _unitOfWork = unitOfWork;
            _machineRepository = machineRepository;
            _planDetailRepository = planDetailRepository;
            _beatSetRepository = beatSetRepository;
            _routeRepository = routeRepository;
            _productRepository = productRepository;
        }

        //取出全部的生产部门的人员
        [HttpGet]
        public IActionResult GetWorkCode(string keyword)
        {
            var users = _machineRepository.GetUserCodes(keyword, ProjectId);
            return new ObjectResult(users);
        }

        [HttpGet]
        public IActionResult GetReportlist(int sectionid, string product_name, string draw_number, string code, string starttime, string endtime,
            string order_number, string worker_name, string state, int page = 1, int pagesize = 10,int toexel=0)
        {
            var machineIds = _machineRepository.GetMachinIdsBySectionId(sectionid, 0, ProjectId);
            var dtStart = UnixTimeHelper.GetUnixByDate(starttime);
            var dtEnd = UnixTimeHelper.GetUnixByDate(endtime) + 86400 - 1;
            if (toexel == 0)
            {
                var data = _planRepository.GetPagedProductReport(product_name, draw_number, code, machineIds, ProjectId, dtStart, dtEnd, order_number, worker_name, state, page, pagesize);
                return new PagedObjectResult(data.Data, data.Total, page, pagesize);
            }else
            {
                var data = _planRepository.GetPagedProductReport(product_name, draw_number, code, machineIds, ProjectId, dtStart, dtEnd, order_number, worker_name, state, page, pagesize);
                if (!data.Data.Any())
                {
                    throw new BadRequestException(CommonEnum.RecordNotFound);
                }
                var rootDir = FileSystemHelper.GetPhysicalFolders(FileSystemHelper.CommonFileSetting.PhysicalFolder, FileSystemHelper.ExportFileName);

                var dataList = new List<ImportProductReport>();
                foreach(var d in data.Data.ToList())
                {
                    var plantype = string.Empty;
                    var approvaldesc ="待审核";
                    if(d.approval_status!=0)
                    {
                        approvaldesc = d.approval_status == 1 ? "审核通过" : "审核未通过";
                    }
                    dataList.Add(new ImportProductReport
                    {
                        product_name=d.product_name,
                        route=d.route_name,
                        location=d.machineLocation,
                        worker_name=d.worker_name,
                        orderno=d.orderNumber,
                        code=d.code,
                        output=d.output,
                        okCnt=d.actual_output,
                        ngCnt=d.nok_number,
                        time=UnixTimeHelper.ConvertStringDateTime(d.time.ToStr()),
                        approuser=d.approval_username,
                        approtime= UnixTimeHelper.ConvertStringDateTime(d.approval_time.ToStr()),
                        approstatus= approvaldesc,
                        type =d.plan_type==1?"计划内":"计划外"
                    });
                }
                if (dataList.Any())
                {
                    EpPlusExcelHelper<ImportProductReport> helper = null;
                    try
                    {
                        helper = new EpPlusExcelHelper<ImportProductReport>();
                        var temporaryFileName = $"报工记录_{DateTime.Now:yyyyMMddHHmmss}.xlsx";
                        helper.GenerateExcel(dataList, Path.Combine(rootDir, temporaryFileName));
                        return new ObjectResult($"{FileSystemHelper.CommonFileSetting.RequestPath}/{FileSystemHelper.ExportFileName}/{temporaryFileName}");
                    }
                    catch (Exception e)
                    {
                        Logger.WriteLineError("ExportDict failed, error:" + e);
                       
                    }
                    finally
                    {
                        helper?.Dispose();
                    }
                }
                throw new BadRequestException(RequestEnum.ExportFailed);
            }

           
        }

        [HttpPost]
        public async Task<IActionResult> AddProduceReport([FromBody] RequestAddProduceReport request)
        {
            var times = request.time.Split(" - ");
            if (times.Length != 2)
            {
                throw new BadRequestException(RequestEnum.TimeSpanNotNull);
            }
            if (string.IsNullOrWhiteSpace(request.code))
            {
                throw new BadRequestException(CncEnum.WorkOrderNotExist);
            }
            //工令单存在
            var planDetail =
                _planDetailRepository.Get(m => m.orderNumber == request.code && m.status != (int)RowState.Invalid && m.projectId == ProjectId);
            if (planDetail == null)
            {
                return new ObjectResult(CncEnum.WorkOrderNotExist);
            }

            var machineid = request.machineId.ToInt();
            var machinelevel = _machineRepository.GetMachineAttributionByMachineId(machineid);
            if (machinelevel==null)
            {
                return new ObjectResult(CncEnum.MachineIdNotExist);
            }
            //报工时间是否冲突
            var startTime = UnixTimeHelper.GetUnixByDate(times[0]);
            var endTime = UnixTimeHelper.GetUnixByDate(times[1]);

            var query = await _productionReportRepository.GetListAsync(q =>
                q.projectid == ProjectId && q.machineid == machineid
                                         && ((q.start_time > startTime && q.start_time < endTime)
                || (q.end_time > startTime && q.end_time < endTime)));
            if (query.Any())
            {
                throw new ServerException(500159);
            }

            var user = await _userRepository.GetAsync(q =>
                q.mid == request.workercode.ToInt() && q.projectid == ProjectId && q.status == (int)RowState.Valid);

            //计划存在
            var plan = _planRepository.Get(q => q.id == planDetail.planId && q.projectid == ProjectId);
            if (plan != null)
            {
                var entity = new siger_project_product_report
                {
                    draw_number = plan.draw_number,
                    plan_id = plan.id,
                    product_name = plan.product_name,
                    product_code = plan.product_code,
                    code = request.code,
                    actual_output = request.actualoutput.ToInt(),
                    end_time = endTime,
                    machineid = machineid,
                    station= machinelevel.station,
                    nok_number = request.noknumber.ToInt(),
                    produced_program_number = request.programnumber.ToStr(),
                    start_time = startTime,
                    worker_code = user != null ? user.work_code : "",
                    worker_name = user != null ? user.name : "",
                    projectid = ProjectId,
                    time = UnixTimeHelper.GetNow(),
                    route_name = request.route_name, //route id
                    rest_minutes = request.rest_minutes.ToStr().ToDouble()
                };
                _productionReportRepository.InsertProductReportData(entity);

                return UpdatePlanDetailProduceNumber(plan, request.route_id, planDetail,
                    request.actualoutput.ToInt(),
                    request.noknumber.ToInt());

                //修改工单状态
                //if (await UpdateProduceStatus(plan.id) == CommonEnum.Succefull)
                //{
                //    return new ObjectResult(CommonEnum.Succefull);
                //}
            }
            else
            {
                var product = _productRepository.Get(q =>
                    q.id == planDetail.levelId && q.projectid == ProjectId);
                var entity = new siger_project_product_report
                {
                    draw_number = product.drawingcode,
                    plan_id = 0,
                    product_name = product.name,
                    product_code = product.code,
                    code = request.code,
                    actual_output = request.actualoutput.ToInt(),
                    end_time = endTime,
                    machineid = machineid,
                    nok_number = request.noknumber.ToInt(),
                    produced_program_number = request.programnumber.ToStr(),
                    start_time = startTime,
                    worker_code = user != null ? user.work_code : "",
                    worker_name = user != null ? user.name : "",
                    projectid = ProjectId,
                    time = UnixTimeHelper.GetNow(),
                    route_name = request.route_name, //route id
                    rest_minutes = request.rest_minutes.ToStr().ToDouble()
                };
                _productionReportRepository.InsertProductReportData(entity);

               return UpdatePlanDetailProduceNumber(plan, request.route_id, planDetail,
                    request.actualoutput.ToInt(),
                    request.noknumber.ToInt());
            }
        }

        /// <summary>
        /// 修改工令单生产数量，只有最后一道工序报工后，才累计数量
        /// </summary>
        private ActionResult UpdatePlanDetailProduceNumber(siger_project_product_plan plan, int routeid, siger_project_product_plan_detail planDetail,
            int actualoutput, int noknumber)
        {
            //查询是否是最后一道工序
            var route = _routeRepository.GetList(q => q.id == routeid && q.projectId == ProjectId && q.status == (int)RowState.Valid).OrderByDescending(m => m.serialNumber).FirstOrDefault();
            if (route == null)
            {
                throw new BadRequestException(RequestEnum.RouteNotFound);
            }
            if (route.id == routeid)
            {
                //修改工令单数量
                planDetail.ok_number += actualoutput;
                planDetail.nok_number += noknumber; ;
                planDetail.producted_number += (actualoutput + noknumber);
                if (planDetail.producted_number >= planDetail.quantity)
                {
                    planDetail.status = (int)PlanDispatch.Finished;
                }
                //更新plan
                plan.producted_number += actualoutput + noknumber;
                plan.nok_number += noknumber;
                if (plan.producted_number >= plan.quantity)
                {
                    plan.status = (int)PlanDispatch.Finished;
                    plan.finish_time = UnixTimeHelper.GetNow();
                }
            }
            else
            {
                planDetail.status = (int)PlanDispatch.Producing;
                plan.status = (int)PlanDispatch.Producing;
            }
            _planDetailRepository.Update(planDetail);
            _planRepository.Update(plan);
            if (_unitOfWork.Commit() > 0)
            {
                return new ObjectResult(CommonEnum.Succefull);
            }
            throw new BadRequestException(CommonEnum.Fail);
        }

        private async Task<CommonEnum> UpdateProduceStatus(int planId)
        {
            var reports = await _planDetailRepository.GetListAsync(q => q.planId == planId && q.projectId == ProjectId);

            var plan = await _planRepository.GetAsync(planId);

            var status = PlanProcess.HasPlan; //待生产
            var finishTime = 0;
            var totalOutput = reports.Sum(m => m.ok_number);
            if (totalOutput >= plan.quantity)
            {
                status = PlanProcess.Finished; //已完成
                finishTime = UnixTimeHelper.GetNow();
            }
            else
            {
                status = PlanProcess.Producing; //生产中
            }
            plan.status = (int)status;
            plan.finish_time = finishTime;
            plan.producted_number = totalOutput;
            plan.nok_number = reports.Sum(m => m.nok_number);
            await _planRepository.UpdateAsync(plan);
            if (await _unitOfWork.CommitAsync() > 0)
            {
                return CommonEnum.Succefull;
            }

            return CommonEnum.Fail;
        }

        [HttpGet]
        public IActionResult GetProduceReport(int id)
        {
            var report = _productionReportRepository.Get(id);
            if (report == null)
            {
                throw new BadRequestException(CommonEnum.Fail);
            }

            var response = Mapper<siger_project_product_report, ResponseGetProduceReport>.Map(report);
            response.daytime = UnixTimeHelper.ConvertIntDate(report.start_time);
            response.start_time = UnixTimeHelper.ConvertStringDateTime(report.start_time.ToString()).ToString(ParameterConstant.TimeFormat);
            response.end_time = UnixTimeHelper.ConvertStringDateTime(report.end_time.ToString()).ToString(ParameterConstant.TimeFormat);
            response.start_end_time = response.start_time + " - " + response.end_time;

            var users = _machineRepository.GetUserCodes(string.Empty, ProjectId);
            foreach (var user in users)
            {
                response.users.Add(new ResponseIdName { id = user.id, name = user.text });
            }

            var section = _machineRepository.GetSectionByMachineId(report.machineid, ProjectId);
            if (section != null)
            {
                response.section_id = section.id;
                response.title = section.name;
            }

            return new ObjectResult(response);
        }

        [HttpPost]
        public async Task<IActionResult> EditProduceReport([FromBody] RequestEditProduceReport request)
        {
            var entity = _productionReportRepository.Get(request.id);
            if (entity == null || entity.status != (int)RowState.Valid)
            {
                throw new BadRequestException(CommonEnum.RecordNotFound);
            }
            if (entity.approval_status== OrderReportApprovalStatus.Pass)
            {
                throw new BadRequestException(CncEnum.DataAlreadyExists);
            }
            //工令单存在
            var planDetail = _planDetailRepository.Get(m => m.orderNumber == entity.code && m.projectId == ProjectId);
            if (planDetail == null)
            {
                throw new BadRequestException(CncEnum.WorkOrderNotExist);
            }
            //计划存在
            var plan = _planRepository.Get(q => q.id == planDetail.planId && q.projectid == ProjectId);
            if (plan == null)
            {
                throw new ServerException(500160);
            }
            //验证机器上一条的报工时间
            var startTime = UnixTimeHelper.GetUnixByDate(request.starttime);
            var endTime = UnixTimeHelper.GetUnixByDate(request.endtime);

            var diffOk =  request.oknumber.ToInt() - entity.actual_output;
            var diffNg =  request.noknumber.ToInt()- entity.nok_number;

            entity.actual_output = request.oknumber.ToInt();
            entity.end_time = endTime;
            entity.nok_number = request.noknumber.ToInt();
            entity.output= request.oknumber.ToInt() + request.noknumber.ToInt();
            entity.start_time = startTime;
            if (_productionReportRepository.UpdateProductReportData(entity) > 0)
            {
                var productRoutes = _routeRepository.GetList(q => q.productId == plan.product_id && q.projectId == ProjectId && q.status == (int)RowState.Valid);
                if (!productRoutes.Any())
                {
                    throw new BadRequestException(RequestEnum.RouteNotFound);
                }

                var route = productRoutes.OrderByDescending(m => m.serialNumber).FirstOrDefault();
                //最后一道工序
                if (route.id != entity.route_id)
                {
                    return new ObjectResult(CommonEnum.Succefull);
                }
                ////更新工令单
                planDetail.ok_number += diffOk;
                planDetail.nok_number += diffNg;
                planDetail.producted_number += (diffOk + diffNg);
                if (planDetail.producted_number >= planDetail.quantity)
                {
                    planDetail.status = (int)PlanDispatch.Finished;
                }
                else
                {
                    planDetail.status = (int)PlanDispatch.Producing;
                }
                ////更新工单
                plan.producted_number += (diffOk + diffNg);
                plan.nok_number += diffNg;
                if (plan.producted_number >= plan.quantity)
                {
                    plan.status = (int)PlanDispatch.Finished;
                    plan.finish_time = UnixTimeHelper.GetNow();
                }
                else
                {
                    plan.status = (int)PlanDispatch.Producing;
                }
                _planDetailRepository.Update(planDetail);
                _planRepository.Update(plan);
                if (_unitOfWork.Commit() > 0)
                {
                    return new ObjectResult(CommonEnum.Succefull);
                }
                throw new BadRequestException(CommonEnum.Fail);
                //修改工令单数量
                // return UpdatePlanDetailProduceNumber(plan, entity.route_id, planDetail, request.oknumber.ToInt()-planDetail.ok_number, request.noknumber.ToInt()-planDetail.nok_number);
            }

            throw new BadRequestException(CommonEnum.Fail);
        }

        /// <summary>
        /// 此功能已弃用
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<IActionResult> DeleteProduceReport(int id)
        {
            var entity = await _productionReportRepository.GetAsync(id);
            if (entity == null)
            {
                throw new BadRequestException(CommonEnum.RecordNotFound);
            }
            //工令单存在
            var planDetail =
                _planDetailRepository.Get(m => m.orderNumber == entity.code && m.status == (int)RowState.Valid && m.projectId == ProjectId);
            if (planDetail == null)
            {
                return new ObjectResult(CncEnum.WorkOrderNotExist);
            }
            _productionReportRepository.Delete(entity.id);
            if (_unitOfWork.Commit() > 0)
            {
                //修改工令单数量
                //UpdatePlanDetailProduceNumber(entity.machineid, entity.draw_number, planDetail,
                //    -entity.actual_output,
                //    -entity.nok_number);
                //if (await UpdateProduceStatus(entity.plan_id) == CommonEnum.Succefull)
                //{
                //    return new ObjectResult(CommonEnum.Succefull);
                //}
            }
            throw new BadRequestException(CommonEnum.Fail);
        }

        [HttpPost]
        public IActionResult GetProgramList([FromBody] RequestGetProgramList request)
        {
            string dtStart;
            string dtEnd;
            if (string.IsNullOrWhiteSpace(request.datetime))
            {
                dtStart = UnixTimeHelper.ConvertIntDateTime(request.startTime.ToInt());
                dtEnd = UnixTimeHelper.ConvertIntDateTime(request.endTime.ToInt());
            }
            else
            {
                dtStart = request.datetime + " " + request.startTime;
                dtEnd = request.datetime + " " + request.endTime;
            }
            var result = new GetProgramListResult();

            var beates = _beatSetRepository.GetList(q => q.machineID == request.machineid && q.projectID == ProjectId && q.status == (int)RowState.Valid
                                                         && q.start_time <= DateTime.Now && q.end_time >= DateTime.Now).ToList();
            var productRep = new ProductRepository(CompanyId, ProjectId);
            var programs = productRep.GetYieldByMachine(request.machineid, dtStart, dtEnd);
            foreach (var productYield in programs)
            {
                var beat = beates.FirstOrDefault(q => q.machineID == request.machineid && q.process_number == productYield.programCode);
                var actYield = beat == null ? productYield.yield : productYield.yield * beat.yieldrate;
                result.program_number.Add(new ProgramList
                {
                    output = actYield,
                    program_number = productYield.programCode
                });
            }

            var users = _userRepository.GetList(q => q.status == (int)RowState.Valid && q.projectid == ProjectId)
                .Select(m => new
                {
                    m.id,
                    m.name
                });
            foreach (var user in users)
            {
                result.users.Add(new ResponseIdName
                {
                    id = user.id,
                    name = user.name
                });
            }

            return new ObjectResult(result);
        }

        /// <summary>
        /// 生产统计报表
        /// </summary>
        /// <param name="sectionId"></param>
        /// <param name="dateTime"></param>
        /// <param name="type"></param>
        /// <param name="typeValue"></param>
        /// <param name="toexcel"></param>
        /// <returns></returns>
        [HttpGet]
        public IActionResult GetProduceSummary(int sectionId, string dateTime, int type, int typeValue, int toexcel = 0)
        {
            //type:  1时间范围 2产线区域 3报工人员 4产品名称
            //typeValue :1日 2周 3月 4年
            var dateTimes = dateTime.Split(" - ");
            if (dateTimes.Length != 2)
            {
                throw new BadRequestException(CncEnum.DateTimeFormatError);
            }

            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 start = (int)UnixTimeHelper.ConvertDataTimeLong(dtStart);
            var end = (int)UnixTimeHelper.ConvertDataTimeLong(dtEnd.AddDays(1).AddSeconds(-1));
            var machineIds = _machineRepository.GetMachinIdsBySectionId(sectionId, 0, ProjectId);

            var responses = new List<ResponseProduceNumber>();
            var reports = _productionReportRepository.GetList(q =>
                q.projectid == ProjectId && machineIds.Contains(q.machineid)
                                         && q.status == (int)RowState.Valid && q.start_time >= start && q.end_time <= end);

            if (type == 1) //时间
            {
                if (typeValue == 1) //日
                {
                    responses.AddRange(GetReportProduces(start, end, 1, reports.ToList()));
                }
                if (typeValue == 2)//周
                {
                    responses.AddRange(GetReportProduces(start, end, 7, reports.ToList()));
                }
                if (typeValue == 3)//月
                {
                    responses.AddRange(GetReportProduces(start, end, 30, reports.ToList()));
                }
                if (typeValue == 4)//年
                {
                    responses.AddRange(GetReportProduces(start, end, 365, reports.ToList()));
                }
            }
            else if (type == 2) //工位
            {
                if (typeValue == 0)
                {
                    throw new ServerException(1037);
                }
                var sections = _machineRepository.GetLevelSections(sectionId, ProjectId);
                var levels = sections.Where(q => q.levelid == typeValue).ToList();
                foreach (var levelSection in levels)
                {
                    var machines = _machineRepository.GetMachinIdsBySectionId(levelSection.id, 0, ProjectId);

                    var query = reports.Where(q => machines.Contains(q.machineid) && machineIds.Contains(q.machineid));
                    responses.Add(new ResponseProduceNumber
                    {
                        title = levelSection.title,
                        number = query.Sum(q => q.actual_output)
                    });
                }
            }
            else if (type == 3) //报工人
            {
                var report = from m in reports
                             group m by new
                             {
                                 m.worker_name
                             }
                    into temp
                             select new ResponseProduceNumber
                             {
                                 title = temp.Key.worker_name,
                                 number = temp.Sum(m => m.actual_output),
                             };

                foreach (var hasProduce in report.ToList())
                {
                    responses.Add(new ResponseProduceNumber
                    {
                        number = hasProduce.number,
                        title = hasProduce.title
                    });
                }
            }
            else if (type == 4) //产品名称
            {
                var report = from m in reports
                             group m by new
                             {
                                 m.product_name
                             }
                    into temp
                             select new ResponseProduceNumber
                             {
                                 title = temp.Key.product_name,
                                 number = temp.Sum(m => m.actual_output),
                             };

                foreach (var hasProduce in report.ToList())
                {
                    responses.Add(new ResponseProduceNumber
                    {
                        number = hasProduce.number,
                        title = hasProduce.title
                    });
                }
            }

            if (toexcel == 0)
            {
                return new ObjectResult(responses);
            }
            var records = new List<ResponseGetAlarmDataForAnalysis>();
            foreach (var response in responses)
            {
                records.Add(new ResponseGetAlarmDataForAnalysis
                {
                    Abscissa = response.title,
                    Ordinate = response.number
                });
            }

            return ExportBarChart(records, _machineRepository.GetProjectLanguage(ProjectId), (int)XTypes.OtherType);
        }

        private IEnumerable<ResponseProduceNumber> GetReportProduces(int startTime, int endTime, int num, IEnumerable<siger_project_product_report> reports)
        {
            var list = new List<ResponseProduceNumber>();
            if (num == 365) //按年统计
            {
                var dtStart = DateTime.Parse(UnixTimeHelper.ConvertIntDateTime(startTime));
                var dtEnd = DateTime.Parse(UnixTimeHelper.ConvertIntDateTime(endTime));
                var dateTimes = DateTimeHelper.GetStrDateTimes(dtStart, dtEnd, 3);
                foreach (var dateTime in dateTimes)
                {
                    var dtCompareStart = DateTime.Parse(dateTime + "-01-01");
                    var dtCompareEnd = dtCompareStart.AddYears(1).AddSeconds(-1);

                    var unixStart = UnixTimeHelper.ConvertDataTimeLong(dtCompareStart);
                    var unixEnd = UnixTimeHelper.ConvertDataTimeLong(dtCompareEnd);

                    var query = reports.Where(q => q.projectid == ProjectId && q.time >= unixStart && q.time <= unixEnd);
                    list.Add(new ResponseProduceNumber
                    {
                        title = dateTime,
                        number = query.Sum(q => q.actual_output)
                    });
                }
            }
            if (num == 30) //按月统计
            {
                var dtStart = DateTime.Parse(UnixTimeHelper.ConvertIntDateTime(startTime));
                var dtEnd = DateTime.Parse(UnixTimeHelper.ConvertIntDateTime(endTime));
                var dateTimes = DateTimeHelper.GetStrDateTimes(dtStart, dtEnd, 2);
                foreach (var dateTime in dateTimes)
                {
                    var dtCompareStart = DateTime.Parse(dateTime + "-01");
                    var dtCompareEnd = dtCompareStart.AddMonths(1).AddSeconds(-1);

                    var unixStart = UnixTimeHelper.ConvertDataTimeLong(dtCompareStart);
                    var unixEnd = UnixTimeHelper.ConvertDataTimeLong(dtCompareEnd);

                    var query = reports.Where(q => q.projectid == ProjectId && q.time >= unixStart && q.time <= unixEnd);
                    list.Add(new ResponseProduceNumber
                    {
                        title = dateTime,
                        number = query.Sum(q => q.actual_output)
                    });
                }
            }
            else if (num == 7) //按月统计
            {
                var dtStart = DateTime.Parse(UnixTimeHelper.ConvertIntDateTime(startTime));
                var dtEnd = DateTime.Parse(UnixTimeHelper.ConvertIntDateTime(endTime));
                var xData2 = new List<string>();
                var xData = DateTimeHelper.GetStrDateTimes(dtStart, dtEnd, 1);
                DateTimeHelper.GetDateTimes(dtStart, dtEnd, 1).ForEach(q =>
                {
                    xData2.Add(q.ToString(UnixTimeHelper.DateFormat));
                });
                var interal = DateTimeHelper.GetInteral(1);
                for (int i = 1; i <= xData2.Count; i++)
                {
                    var stime = UnixTimeHelper.ConvertDataTimeLong(DateTime.Parse(xData2[i - 1]));
                    var end = UnixTimeHelper.ConvertDataTimeLong(DateTime.Parse(xData2[i - 1]).AddDays(interal).AddSeconds(-1));
                    var query = reports.Where(q => (q.time >= stime && q.time <= end)
                                                      || (q.time < end && q.time > end)
                                                      || (q.time < stime && q.time > stime)
                                                      || (q.time < stime && q.time > end));

                    list.Add(new ResponseProduceNumber
                    {
                        title = xData[i - 1].ToStr(),
                        number = query.Sum(q => q.actual_output)
                    });
                }
            }
            else
            {
                for (var stime = startTime; stime < endTime; stime += 86400 * num)
                {
                    var etime = stime + 86400 * num;
                    var query = reports.Where(q => q.projectid == ProjectId && q.time >= stime && q.time < etime);
                    list.Add(new ResponseProduceNumber
                    {
                        title = UnixTimeHelper.ConvertIntDate(stime),
                        number = query.Sum(q => q.actual_output)
                    });
                }
            }

            return list;
        }

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

            var ids = request.ids.Split(',').ToList();
            var entities = _productionReportRepository.GetList(q => ids.Contains(q.id.ToString()) && q.status == (int)RowState.Valid && q.projectid == ProjectId);
            if (!entities.Any())
            {
                throw new BadRequestException(CommonEnum.RecordNotFound);
            }
            foreach (var item in entities)
            {
                if (item.approval_status != OrderReportApprovalStatus.WaitingForApproval)
                {
                    throw new BadRequestException(CncEnum.DataAlreadyExists);
                }
            }
            
            if (!Enum.TryParse(request.state.ToString(), out OrderReportApprovalStatus status))
            {
                throw new BadRequestException(RequestEnum.ParameterError);
            }

            foreach (var report in entities.ToList())
            {
                report.approval_usermid = UserId;
                report.approval_status = status;
                report.approval_time = UnixTimeHelper.GetNow();
                _productionReportRepository.UpdateProductReportData(report);
            }

            return new ObjectResult(CommonEnum.Succefull);
        }


        /// <summary>
        /// 长龄首页 合格率
        /// </summary>
        /// <param name="section"></param>
        /// <param name="begin"></param>
        /// <param name="end"></param>
        /// <returns></returns>
        [HttpGet]
        public IActionResult GetPassRate(int section,string begin,string end)
        {
            var mids = _machineRepository.GetMachineIdsBySectionIds(new List<int> { section }, ProjectId).ToList();
            var stime = UnixTimeHelper.ConvertDataTimeLong(begin.ToDateTime());
            var etime = UnixTimeHelper.ConvertDataTimeLong(end.ToDateTime());

            var reportData = _productionReportRepository.GetList(f => f.projectid == ProjectId && mids.Contains(f.machineid) && f.time>=stime && f.time<=etime);
            if (reportData.Any())
                return new ObjectResult(0d);

            double inputOk = reportData.Sum(s => s.actual_output);
            double inputNg = reportData.Sum(s => s.nok_number);
            if (inputOk +inputNg ==0)
                return new ObjectResult(0d);

            double actReport = inputOk / (inputOk + inputNg);
            var rate = Math.Round(actReport, 2);

            return new ObjectResult(rate * 100);
        }
    }
}