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

namespace Siger.ApiACC.Controllers
{
    public class RoutingController : BaseController
    {
        private readonly IUnitOfWork _unitOfWork;
        private readonly ISigerRoutingInStation _inStation;
        private readonly ISigerRoutingOutStation _outStation;
        private readonly ISigerProjectProcessRepository _process;
        private readonly ISigerProjectLevelSectionRepository _section;
        private readonly ISigerRoutingEventNo _routingEventNo;

        public RoutingController(IUnitOfWork unitOfWork, ISigerRoutingInStation inStation, ISigerRoutingOutStation outStation
            , ISigerProjectProcessRepository process, ISigerProjectLevelSectionRepository section, ISigerRoutingEventNo routingEventNo)
        {
            _unitOfWork = unitOfWork;
            _inStation = inStation;
            _outStation = outStation;
            _process = process;
            _section = section;
            _routingEventNo = routingEventNo;
        }

        /// <summary>
        /// 获取工艺路由配置数据
        /// </summary>
        /// <param name="req"></param>
        /// <returns></returns>
        [HttpPost]
        public IActionResult GetData([FromBody]RequestRoutingConfig req)
        {
            var result = GetRoutingData(req);
            var data = result.Data.ToList();
            foreach (var d in data)
            {
                var toline = _section.Get(f => f.id.Equals(d.StationId));
                d.FromLineId = toline.parentid;
            }
          
            return new PagedObjectResult(data, result.Total);
        }

        /// <summary>
        /// 修改工艺路由配置数据（只能改上一站和结果）
        /// </summary>
        /// <param name="req"></param>
        /// <returns></returns>
        [HttpPost]
        public IActionResult ModifyData([FromBody]RequestRoutingConfig req)
        {
            var indata = _inStation.Get(f => f.id==req.Id);
            if (indata==null)
                throw new BadRequestException(CommonEnum.RecordNotFound);

            var outModel = _outStation.Get(f => f.projectId == ProjectId && f.ResultStatus == indata.ResultStatus);
            if (outModel == null)
                throw new BadRequestException(AccEnum.Busi_EventNo_Null);
            //indata.Line = req.Line;
            indata.Station = req.ToStation;
            indata.ProductId = req.ProductCode;
            indata.ProcessId = req.ProcessId;
            _inStation.Update(indata);

            outModel.EventNo = req.EventNo;
            outModel.Station = req.FromStation;
            
            if (_unitOfWork.Commit() == 0)
                throw new BadRequestException(CommonEnum.Fail);
            return new ObjectResult(CommonEnum.Succefull);
        }

        /// <summary>
        /// 删除工艺路由配置数据
        /// </summary>
        /// <param name="req"></param>
        /// <returns></returns>
        [HttpPost]
        public IActionResult DeleteData([FromBody]RequestRoutingConfig req)
        {
            var indata = _inStation.Get(f => f.id == req.Id);
            if (indata==null)
                throw new BadRequestException(CommonEnum.RecordNotFound);
            var outData = _outStation.GetList(f => f.ResultStatus.Equals(indata.ResultStatus));
            foreach(var obj in outData)
            {
                _outStation.Delete(obj);
            }

            _inStation.Delete(indata);
            if (_unitOfWork.Commit() == 0)
            {
                throw new BadRequestException(CommonEnum.Fail);
            }
            return new ObjectResult(CommonEnum.Succefull);
        }

        /// <summary>
        /// 添加工艺路由配置数据
        /// </summary>
        /// <param name="req"></param>
        /// <returns></returns>
        [HttpPost]
        public IActionResult AddData([FromBody]RequestRoutingConfig req)
        {
            var eveno = _routingEventNo.Get(f => f.projectId == ProjectId && f.EventNo == req.EventNo);
            if (eveno==null)
                throw new BadRequestException(AccEnum.Busi_EventNo_Null);
            var outdata = _outStation.Get(f => f.projectId.Equals(ProjectId) && f.status == (int)RowState.Valid && req.FromStation.Equals(f.Station) && f.EventNo.Equals(req.EventNo));
            string resultStatus = GetStatus(req.FromStation,eveno.Descr);
            if (outdata != null)
            {
                resultStatus = outdata.ResultStatus;
            }
            else
            {
                var outStationData = new SigerTrRoutingOutStation
                {
                    Line = req.Line,
                    EventNo = req.EventNo,
                    Station = req.FromStation,
                    projectId = ProjectId,
                    status = (int)RowState.Valid,
                    ResultStatus = resultStatus,
                };
                _outStation.Insert(outStationData);
            }
            var indata = _inStation.Get(f => f.projectId.Equals(ProjectId) && f.status == (int)RowState.Valid && f.ProductId.Equals(req.ProductCode) && f.Station.Equals(req.ToStation) && f.ResultStatus.Equals(resultStatus));
            if (indata != null)
            {
                throw new BadRequestException(CommonEnum.RecordExits);
            }
            //init _inStation
            var toline = _section.Get(f => f.id.Equals(req.ToStation));
            var instationData = new SigerTrRoutingInStation
            {
                Station = req.ToStation,
                projectId = ProjectId,
                status = (int)RowState.Valid,
                ResultStatus = resultStatus,
                Line = toline.parentid,
                ProcessId = req.ProcessId,
                ProductId = req.ProductCode
            };
            _inStation.Insert(instationData);

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

        /// <summary>
        /// 导出工艺路由配置数据
        /// </summary>
        /// <param name="req"></param>
        /// <returns></returns>
        [HttpPost]
        public IActionResult ExportData([FromBody]RequestRoutingConfig req)
        {
            req.pagesize = 10000;
            req.page = 1;
            var data = GetRoutingData(req).Data.ToList();
            var dataList = new List<RoutingData>();
            data.ForEach(da => dataList.Add(Mapper<ResponseRoutingData, RoutingData>.Map(da)));
            
            var rootDir = FileSystemHelper.GetPhysicalFolders(FileSystemHelper.CommonFileSetting.PhysicalFolder, FileSystemHelper.ExportFileName);
            if (dataList.Any())
            {
                EpPlusExcelHelper<RoutingData> helper = null;
                try
                {
                    helper = new EpPlusExcelHelper<RoutingData>();
                    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("Export failed, error:" + e);
                    throw new BadRequestException(RequestEnum.ExportFailed);
                }
                finally
                {
                    helper?.Dispose();
                }
            }
            throw new BadRequestException(CommonEnum.RecordNotFound);
        }
       
        /// <summary>
        /// 获取工艺信息
        /// </summary>
        /// <param name="type"></param>
        /// <param name="code"></param>
        /// <returns></returns>
        [HttpGet]
        public IActionResult GetProcessData(string type, string code)
        {
            var resp = _process.GetList(f => f.status == (int)RowState.Valid && f.ProjectId.Equals(ProjectId) && f.Process_Type.Equals(type) && f.Product_code.Equals(code)).ToList();
            var data = new List<siger_project_process>();

            foreach (var item in resp)
            {
                data.Add(new siger_project_process
                {
                    id = item.id,
                    status = item.status,
                    Process_Seq = item.Process_Seq,
                    Process_name = item.Process_name,
                    Product_code = item.Product_code,
                    ProjectId = item.ProjectId
                });
            }
            return new ObjectResult(data);
        }

        /// <summary>
        /// 工艺类别
        /// </summary>
        /// <param name="code"></param>
        /// <returns></returns>
        [HttpGet]
        public IActionResult GetProcessType(string code)
        {
            var resp = _process.GetList(f => f.status == (int)RowState.Valid && f.ProjectId.Equals(ProjectId) && f.Product_code.Equals(code)).Select(s => s.Process_Type).Distinct().ToList();
            return new ObjectResult(resp);
        }

        /// <summary>
        /// 工位结果
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public IActionResult GetResultData()
        {
            var resp = _routingEventNo.GetList(f => f.status == (int)RowState.Valid && f.projectId.Equals(ProjectId)).ToList();
            return new ObjectResult(resp);
        }

        /// <summary>
        /// 获取路由信息
        /// </summary>
        /// <param name="req"></param>
        /// <returns></returns>
        private IPagedCollectionResult<ResponseRoutingData> GetRoutingData(RequestRoutingConfig req)
        {
            var data = _inStation.GetRoutingData(req, ProjectId);
           
            return data;
        }

        /// <summary>
        /// 出站状态
        /// </summary>
        /// <param name="sectionId"></param>
        /// <param name="even"></param>
        /// <returns></returns>
        private string GetStatus(int sectionId,string even)
        {
            var section = _section.Get(f => f.id == sectionId);
            if (section == null)
                throw new BadRequestException(RequestEnum.StationIsEmpty);
            var str = $"{section.id}-{section.title}->{even}";
            int i = 0;
            while (i < 100)
            {
                i++;
                if (!_outStation.IsExist(f => f.Station == sectionId && f.ResultStatus == str))
                    break;
                str += $"-{i}";
            }

            return str;
        }
    }
}