using Microsoft.AspNetCore.Mvc;
using Siger.Middlelayer.Repository;
using Siger.ApiCommon.Result;
using Siger.Middlelayer.AccRepository.Repositories.Interface;
using Siger.Middlelayer.AccRepository.Request;
using Siger.Middlelayer.Repository.Repositories.Interface;
using Siger.Middlelayer.Common;
using Siger.Middlelayer.Common.Helpers;
using Siger.Middlelayer.Common.ModuleEnum;
using Siger.Middlelayer.Common.Log;
using System.Linq;
using Siger.Middlelayer.Repository.Entities;
using System.Collections.Generic;
using Siger.Middlelayer.Repository.Response;
using Siger.ApiCommon.Utilities;
using Siger.Middlelayer.Common.AppSettings;
using System.IO;
using System;
using Siger.Middlelayer.Utility.Helpers;
using Siger.Middlelayer.Utility.ImportEntities;

namespace Siger.ApiACC.Controllers
{
    public class ReportWorkingController : BaseController
    {
        private readonly IUnitOfWork _unitOfWork;
        private readonly IProductPlanDetails _productPlanDetails;
        private readonly IProductPlanRepository _productPlanRepository;
        private readonly ISigerProjectProductReport _projectProductReport;
        private readonly ISigerAccTraceRepository _sigerAccTrace;
        private readonly ISigerProjectUserRepository _user;
        private readonly ISigerRoutingInStation _inStation;

        public ReportWorkingController(IUnitOfWork unitOfWork, IProductPlanDetails productPlanDetails, IProductPlanRepository productPlanRepository, ISigerProjectProductReport projectProductReport
            , ISigerAccTraceRepository sigerAccTrace, ISigerProjectUserRepository user, ISigerRoutingInStation inStation)
        {
            _unitOfWork = unitOfWork;
            _productPlanDetails = productPlanDetails;
            _productPlanRepository = productPlanRepository;
            _projectProductReport = projectProductReport;
            _sigerAccTrace = sigerAccTrace;
            _user = user;
            _inStation = inStation;
        }

        [HttpGet]
        public IActionResult GetWorkOrderData(string ordernumber, int count)
        {
            if (count == 0)
            {
                count = 50;
            }
            var data = _productPlanDetails.GetProductPlanData(ProjectId, 1, count, "", "", ordernumber);
            var resp = data.Data;
            foreach (var item in resp)
            {
                item.ReportCount = _projectProductReport.GetList(f => f.code.Equals(item.OrderNumber)).Sum(s => s.output);
            }
            return new ObjectResult(data.Data);
        }
        /// <summary>
        /// 查询可报工信息
        /// </summary>
        /// <param name="req"></param>
        /// <returns></returns>
        [HttpPost]
        public IActionResult GetProductReportData([FromBody] RequestReportWorking req)
        {
            var data = _projectProductReport.ProductReportDataByCode(ProjectId, req.OrderNumber, req.StartTime, req.EndTime, req.page, req.pagesize);
            var resp = data.Data.ToList();
            resp.ForEach(da =>
            {
                da.station_value = _sigerAccTrace.GetLineStationData(da.station, ProjectId);
            });
            #region 汇总版
            //var resp = new List<ResponseProductReport>();
            //for (int i = 0; i < data.Count(); i++)
            //{
            //    var query = resp.Where(f => f.processId.Equals(data[i].processId)).FirstOrDefault();
            //    if (query != null)
            //    {

            //        query.end_time = data[i].end_time;
            //        query.okcount += data[i].okcount;
            //        query.industrial_waste += data[i].industrial_waste;
            //        query.material_waste += data[i].material_waste;
            //        query.output += data[i].output;
            //        var planDetail = _productPlanDetails.Get(m => m.OrderNumber == data[i].code && m.status == (int)RowState.Valid && m.projectId == ProjectId);
            //        //改状态
            //        if (planDetail.Quantity == query.output)
            //        {
            //            query.status = 2;
            //        }
            //        continue;
            //    }
            //    data[i].station_value = _sigerAccTrace.GetLineStationData(data[i].station, ProjectId);
            //    resp.Add(data[i]);
            //}
            #endregion
            return new PagedObjectResult(resp, data.Total);
        }
        /// <summary>
        /// 报工
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [HttpPost]
        public IActionResult AddProduceReport([FromBody] RequestReportWorkingData request)
        {
            var times = request.time.Split(" - ");
            if (times.Length != 2)
            {
                throw new BadRequestException(RequestEnum.TimeSpanNotNull);
            }
            if (string.IsNullOrWhiteSpace(request.code))
            {
                throw new BadRequestException(CommonEnum.Fail);
            }
            //工令单存在
            var planDetail =
                _productPlanDetails.Get(m => m.OrderNumber == request.code && m.status != (int)RowState.Invalid && m.projectId == ProjectId);
            if (planDetail == null)
            {
                Logger.WriteLineInfo($"工令单{request.code}不存在");
                throw new BadRequestException(AccEnum.Data_Null);
            }
            var plan = _productPlanRepository.Get(q => q.id == planDetail.PlanId && q.projectId == ProjectId);
            if (plan == null)
            {
                Logger.WriteLineInfo($"工单{planDetail.PlanId}不存在");
                throw new BadRequestException(AccEnum.Data_Null);
            }
            //是否超出工单数量
            var nowcount = 0;
            var model = _projectProductReport.GetList(f => f.station.Equals(request.section) && f.status != (int)RowState.Invalid && f.code.Equals(request.code));
            model.ToList().ForEach(f =>
            {
                nowcount += f.output;
            });
            if (nowcount + request.okcount + request.material_waste + request.industrial_waste > planDetail.Quantity)
            {
                throw new BadRequestException(AccEnum.MoreThanWorkQty);
            }
            var startTime = UnixTimeHelper.GetUnixByDate(times[0]);
            var endTime = UnixTimeHelper.GetUnixByDate(times[1]);

            var user = _user.Get(q =>
               q.mid == request.uid && q.projectid == ProjectId && q.status == (int)RowState.Valid);
            //工艺获取
            //var instationModel = _inStation.Get(f => f.Station.Equals(request.section));
            var entity = new siger_project_product_report
            {
                draw_number = plan.draw_number,
                plan_id = planDetail.id,
                product_name = plan.product_name,
                code = planDetail.OrderNumber,
                end_time = endTime,
                station = request.section,
                industrial_waste = request.industrial_waste,
                material_waste = request.material_waste,
                start_time = startTime,
                worker_code = user != null ? user.work_code : "",
                worker_name = user != null ? user.name : "",
                uid = user != null ? user.mid : 0,
                projectid = ProjectId,
                time = UnixTimeHelper.GetNow(),
                processid = request.processid,
                nok_number = request.material_waste + request.industrial_waste,
                output = request.okcount + request.material_waste + request.industrial_waste,
                actual_output = request.okcount,
                product_code = plan.product_code
            };
            if (_projectProductReport.InsertProductReportData(entity) > 0)
                return new ObjectResult(CommonEnum.Succefull);
            throw new BadRequestException(CommonEnum.Fail);
        }
        /// <summary>
        /// 修改报工
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [HttpPost]
        public IActionResult ModifyProduceReport([FromBody] RequestReportWorkingData request)
        {
            var times = request.time.Split(" - ");
            if (times.Length != 2)
            {
                throw new BadRequestException(RequestEnum.TimeSpanNotNull);
            }
            if (request.id == 0)
            {
                throw new BadRequestException(CommonEnum.Fail);
            }
            //是否存在
            var model = _projectProductReport.Get(f => f.id == request.id && f.status != (int)RowState.Invalid);
            if (model == null)
            {
                throw new BadRequestException(AccEnum.Data_Null);
            }
            //工令单存在
            var planDetail =
                _productPlanDetails.Get(m => m.OrderNumber == model.code && m.status != (int)RowState.Invalid && m.projectId == ProjectId);
            if (planDetail == null)
            {
                Logger.WriteLineInfo($"工令单{model.code}不存在");
                throw new BadRequestException(AccEnum.Data_Null);
            }
            var plan = _productPlanRepository.Get(q => q.id == planDetail.PlanId && q.projectId == ProjectId);
            if (plan == null)
            {
                Logger.WriteLineInfo($"工单{planDetail.PlanId}不存在");
                throw new BadRequestException(AccEnum.Data_Null);
            }

            //是否超出工单数量
            var nowcount = 0;
            var reports = _projectProductReport.GetList(f => f.station.Equals(request.section) && f.status != (int)RowState.Invalid && f.code.Equals(request.code));
            reports.ToList().ForEach(f =>
            {
                nowcount += f.output;
            });
            if (nowcount + request.okcount + request.material_waste + request.industrial_waste > planDetail.Quantity)
            {
                throw new BadRequestException(AccEnum.MoreThanWorkQty);
            }
            var startTime = UnixTimeHelper.GetUnixByDate(times[0]);
            var endTime = UnixTimeHelper.GetUnixByDate(times[1]);
            var user = _user.Get(q =>
               q.mid == request.uid && q.projectid == ProjectId && q.status == (int)RowState.Valid);
            model.uid = request.uid;
            model.actual_output = request.okcount;
            model.material_waste = request.material_waste;
            model.industrial_waste = request.industrial_waste;
            model.start_time = startTime;
            model.end_time = endTime;
            if (_projectProductReport.UpdateProductReportData(model) > 0)
                return new ObjectResult(CommonEnum.Succefull);
            throw new BadRequestException(CommonEnum.Fail);
        }
        /// <summary>
        /// 删除报工
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [HttpPost]
        public IActionResult DeleteProduceReport([FromBody] RequestReportWorkingData request)
        {
            //是否存在
            var model = _projectProductReport.Get(f => f.id == request.id && f.status != (int)RowState.Invalid);
            if (model == null)
            {
                return new ObjectResult(CommonEnum.Succefull);
            }
            model.status = (int)RowState.Invalid;
            if (_projectProductReport.UpdateProductReportData(model) > 0)
                return new ObjectResult(CommonEnum.Succefull);
            throw new BadRequestException(CommonEnum.Fail);
        }

        /// <summary>
        /// 导出信息
        /// </summary>
        /// <param name="req"></param>
        /// <returns></returns>
        [HttpPost]
        public IActionResult ExportData([FromBody] RequestReportWorking req)
        {
            var rootDir = FileSystemHelper.GetPhysicalFolders(FileSystemHelper.CommonFileSetting.PhysicalFolder, FileSystemHelper.ExportFileName);

            int page = 1;
            int pagesize = 10000;
            var result = _projectProductReport.ProductReportDataByCode(ProjectId, req.OrderNumber, req.StartTime, req.EndTime, page, pagesize);
            var records = result.Data.ToList();
            if (!records.Any())
                throw new BadRequestException(CommonEnum.RecordNotFound);


            var resList = new List<ImportProductReport>();
            foreach (var d in records)
            {
                d.station_value = _sigerAccTrace.GetLineStationData(d.station, ProjectId);
                resList.Add(Mapper<ResponseProductReport, ImportProductReport>.Map(d));
            }
            EpPlusExcelHelper<ImportProductReport> helper = null;
            try
            {
                helper = new EpPlusExcelHelper<ImportProductReport>();
                var temporaryFileName = $"报工记录_{DateTime.Now:yyyyMMddHHmmss}.xlsx";
                helper.GenerateExcel(resList, Path.Combine(rootDir, temporaryFileName));
                return new ObjectResult($"{FileSystemHelper.CommonFileSetting.RequestPath}/{FileSystemHelper.ExportFileName}/{temporaryFileName}");
            }
            catch (Exception e)
            {
                Logger.WriteLineError("ExportSn failed, error:" + e);
                throw new BadRequestException(RequestEnum.ExportFailed);
            }
            finally
            {
                helper?.Dispose();
            }
        }
    }
}
