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

namespace Siger.ApiACC.Controllers.Report
{
    public class GeneralController : BaseController
    {
        private readonly ISigerTrSnTraceRepository _traceRepository;
        private readonly ISigerTrSnTraceDetailsRepository _traceDetailRepository;
        private readonly ISigerRoutingStationRpt _sigerRoutingStationRpt;
        private readonly ISigerProjectLevelSectionRepository _sigerProjectLevelSection;
        private readonly ISigerRoutingStationRptItem _sigerRoutingStationRptItem ;
        private readonly ISigerProjectUserRepository _sigerProjectUser;
        private readonly ISigerTrPackage _trPackage;
        private readonly ISigerTrPackageDetials _trPackageDetials;
        private readonly ISigerTrAssembRepository _sigerTrAssemb;
        private readonly ITrParameterConfigRepository _trParameterConfig;

        public GeneralController(ISigerTrSnTraceRepository sigerTrSnTrace, ISigerTrSnTraceDetailsRepository sigerTrSnTraceDetails, ISigerRoutingStationRpt sigerRoutingStationRpt,ISigerProjectLevelSectionRepository sigerProjectLevelSection
            , ISigerRoutingStationRptItem sigerRoutingStationRptItem, ISigerProjectUserRepository sigerProjectUser,ISigerTrPackage trPackage,ISigerTrPackageDetials trPackageDetials,ISigerTrAssembRepository sigerTrAssemb, ITrParameterConfigRepository trParameterConfig)
        {
            _traceRepository = sigerTrSnTrace;
            _traceDetailRepository = sigerTrSnTraceDetails;
            _sigerRoutingStationRpt = sigerRoutingStationRpt;
            _sigerProjectLevelSection = sigerProjectLevelSection;
            _sigerRoutingStationRptItem = sigerRoutingStationRptItem;
            _sigerProjectUser = sigerProjectUser;
            _trPackage = trPackage;
            _trPackageDetials = trPackageDetials;
            _sigerTrAssemb = sigerTrAssemb;
            _trParameterConfig = trParameterConfig;
        }
        /// <summary>
        /// 总体查询                
        /// </summary>
        /// <param name="rpt"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<IActionResult> TrackingDetail([FromBody]RequestGeneralReport rpt)
        {
            var headerRoute = _sigerRoutingStationRpt.GetReportRouteHeader(rpt.section, rpt.productCode, ProjectId);
            if (!headerRoute.Any())
                throw new BadRequestException(AccEnum.RouteRptIsEmpty);

            var stations = _sigerProjectLevelSection.GetLevelSectionIds(rpt.section, ProjectId).ToList();
            var HeaderItems = await _sigerRoutingStationRptItem.GetListAsync(f => f.projectId == ProjectId && f.Line == rpt.section  && f.status == (int)RowState.Valid);
           
            if (rpt.export == 0)
            {
                var packageList = _trPackageDetials.GetBoxDetailsPagedList(rpt.qrcode, rpt.productCode, stations, rpt.start.ToDateTime(), rpt.end.ToDateTime(), ProjectId, rpt.page, rpt.pageSize);
                if (!packageList.Data.Any())
                    throw new BadRequestException(CommonEnum.RecordNotFound);
                var tracking = await GetNormal(packageList.Data, headerRoute, HeaderItems.ToList());

          
                var outPut = new List<TrackingSnStationUI>();
                var groupData = tracking.Bodys.GroupBy(g => g.Row);
                foreach (var g in groupData)
                {
                    outPut.Add(new TrackingSnStationUI
                    {
                        RowNo = g.Key,
                        RowsCols=g.ToList()
                    });
                }
                var result = new GeneralTrackingSnResult
                {
                    Heads = tracking.Heads,
                    Bodys = outPut
                };
                return new PagedObjectResult(result, packageList.Total, rpt.page, rpt.pageSize);
            }else
            {
                //导出
                
                var rootDir = FileSystemHelper.GetPhysicalFolders(FileSystemHelper.CommonFileSetting.PhysicalFolder, FileSystemHelper.ExportFileName);
                var packageList = _trPackageDetials.GetBoxDetailsPagedList(rpt.qrcode, rpt.productCode, stations, rpt.start.ToDateTime(), rpt.end.ToDateTime(), ProjectId, 1, 9999999);
                if (!packageList.Data.Any())
                    throw new BadRequestException(CommonEnum.RecordNotFound);
                var tracking = await GetNormal(packageList.Data, headerRoute, HeaderItems.ToList());

                var importGeneralData = new List<ImportGeneralObj>();
                var groupData = tracking.Bodys.GroupBy(g => g.Row);
                foreach (var g in groupData)
                {
                    var obj = g.FirstOrDefault();
                    var objlist = g.ToList();
                    var head = new List<string>() { "SN"};
                    var items = new List<string>() { "SN" };
                    var values = new List<string> { obj != null ? obj.Sn : ""};
                    foreach(var o in objlist)
                    {
                        foreach(var dts in o.Items)
                        {
                            head.Add(o.Station);
                            items.Add(dts.Item);
                            values.Add(dts.Values);
                        }
                    }
                    importGeneralData.Add(new ImportGeneralObj
                    {
                        Head = head,
                        Items = items,
                        Values = values
                    });
                }

                EpPlusExcelTemplateHelper helper = null;
                try
                {
                    helper = new EpPlusExcelTemplateHelper();
                    var temporaryFileName = $"总体信息-{DateTime.Now:yyyyMMddHHmmss}.xlsx";

                    helper.GenerateAutoCol(importGeneralData, Path.Combine(rootDir, temporaryFileName));
                    return new ObjectResult($"{FileSystemHelper.CommonFileSetting.RequestPath}/{FileSystemHelper.ExportFileName}/{temporaryFileName}");
                }
                catch
                {
                    throw new BadRequestException(RequestEnum.ExportFailed);
                }
                finally
                {
                    helper?.Dispose();
                }
            }

        }
        private async Task<GeneralTrackingSn> GetNormal(IEnumerable<PackageDetailsObj> packageList, IEnumerable<HeaderStation> headerRoute, IEnumerable<SigerTrRoutingStaionRptItem> HeaderItems)
        {
            var tracking = new GeneralTrackingSn { Heads = new List<TrackingSnStation>(), Bodys = new List<TrackingSnStation>() };
            int row = 0;
            foreach (var box in packageList)
            {
                row += 1;
                var tracelst = await _traceRepository.GetListAsync(f => f.projectId == ProjectId && f.SN == box.Sn, "TransDateTime");
                //RPT 标题
                int col = 0;
                foreach (var h in headerRoute)
                {
                    col += 1;
                    var head = new TrackingSnStation
                    {
                        Sn = box.Sn,
                        Section = h.Station,
                        Station = h.Title,
                        Items = new List<ItemDts>()
                    };
                    var body = new TrackingSnStation
                    {
                        Row = row,
                        Sn = box.Sn,
                        Section = h.Station,
                        Station = h.Title,
                        Items = new List<ItemDts>()
                    };
                    //包装
                    if (col == 1)
                    {
                        head.Items.Add(new ItemDts { Item = "包装", Values = "" });
                        body.Items.Add(new ItemDts { Item = "包装", Values = box.BoxId });
                    }
                    
                    var stationItem = HeaderItems.Where(f => f.Station == h.Station);
                    var stationTracelst = tracelst.Where(f => f.Station == h.Station);
                    if (!stationTracelst.Any())
                    {
                     
                        foreach (var hItem in stationItem)
                        {
                            //占位
                            head.Items.Add(new ItemDts { Item = hItem.Item });
                            body.Items.Add(new ItemDts { Item = hItem.Item, Values = "" });
                        }
                        head.Items.Add(new ItemDts { Item = "结果", Values = "" });
                        head.Items.Add(new ItemDts { Item = "人员", Values = "" });
                        head.Items.Add(new ItemDts { Item = "时间", Values = "" });

                        body.Items.Add(new ItemDts { Item = "结果", Values = "" });
                        body.Items.Add(new ItemDts { Item = "人员", Values = "" });
                        body.Items.Add(new ItemDts { Item = "时间", Values = "" });
                    }
                    else
                    {
                        var trace = stationTracelst.FirstOrDefault();
                        if (trace != null)
                        {
                            var user = _sigerProjectUser.Get(f => f.mid == trace.UID);
                            var userName = user != null ? user.name : trace.UID.ToStr();

                            //取最新一条明细
                            var traceDtls = _traceDetailRepository.GetList(f => f.projectId == ProjectId && f.SeqID == trace.SeqID).ToList();
                            //整理检查项
                            foreach (var hItem in stationItem)
                            {
                                head.Items.Add(new ItemDts { Item = hItem.Item });
                                var curItemDtls = traceDtls.Where(f => f.Item == hItem.Item).ToList();
                                if (!curItemDtls.Any())
                                {
                                    body.Items.Add(new ItemDts { Item = hItem.Item, Values = " " });
                                    continue;
                                }
                                foreach (var d in curItemDtls)
                                {
                                    if (body.Items.Exists(f => f.Item.Contains(hItem.Item)))
                                        continue;
                                    body.Items.Add(new ItemDts { Item = hItem.Item, Values = d.Value });
                                }
                            }
                            head.Items.Add(new ItemDts { Item = "结果", Values = trace.Station != h.Station ? "" : trace.Result });
                            head.Items.Add(new ItemDts { Item = "人员", Values = trace.Station != h.Station ? "" : userName });
                            head.Items.Add(new ItemDts { Item = "时间", Values = trace.Station != h.Station ? "" : trace.TransDateTime.ToStr() });

                            if (traceDtls.Any())
                            {
                                body.Items.Add(new ItemDts { Item = "结果", Values = trace.Station != h.Station ? "" : trace.Result });
                                body.Items.Add(new ItemDts { Item = "人员", Values = trace.Station != h.Station ? "" : userName });
                                body.Items.Add(new ItemDts { Item = "时间", Values = trace.Station != h.Station ? "" : trace.TransDateTime.ToStr() });
                            }
                            else
                            {
                                body.Items.Add(new ItemDts { Item = "结果", Values = "" });
                                body.Items.Add(new ItemDts { Item = "人员", Values = "" });
                                body.Items.Add(new ItemDts { Item = "时间", Values = "" });
                            }
                        }
                    }
                    tracking.Bodys.Add(body);
                    if (!tracking.Heads.Exists(f => f.Section == head.Section))
                        tracking.Heads.Add(head);
                }
            }
            return tracking;
        }

        /// <summary>
        /// SKF 报表- 打包信息 
        /// </summary>
        /// <param name="report"></param>
        /// <returns></returns>
        [HttpPost]
        public IActionResult GetPackage([FromBody] RequestGeneralReport report)
        {
            var stations = _sigerProjectLevelSection.GetLevelSectionIds(report.section, ProjectId).ToList();

            var boxId = string.Empty;
            var packageObj = _trPackage.Get(f => f.projectId == ProjectId && f.boxid == report.qrcode);
            if (packageObj != null)
            {
                boxId = packageObj.boxid;
            }
            else
            {
                var packageDts = _trPackageDetials.Get(f => f.projectId == ProjectId && f.sn == report.qrcode);
                if (packageDts != null)
                {
                    boxId = packageDts.boxid;
                }
            }

            if (report.export == 0)
            {
                var data = _trPackage.GetPackagePagedList(report.productCode, stations, boxId,
                    report.start.ToDateTime(), report.end.ToDateTime(), ProjectId, report.page, report.pageSize);
                return new PagedObjectResult(data.Data, data.Total, report.page, report.pageSize);
            }
            else
            {
                //导出
              
                var rootDir = FileSystemHelper.GetPhysicalFolders(FileSystemHelper.CommonFileSetting.PhysicalFolder, FileSystemHelper.ExportFileName);
                var data = _trPackage.GetPackagePagedList(report.productCode, stations, boxId,
                    report.start.ToDateTime(), report.end.ToDateTime(), ProjectId, 1, 9999999);
                var packageList = new List<ImportPackage>();
                var packageDtslist = new List<ImportPackageDetails>();
                var step = 0;
                foreach (var item in data.Data)
                {
                    step += 1;
                    packageList.Add(new ImportPackage
                    {
                        No = step,
                        BoxId = item.BoxId,
                        ProductCode = item.ProductCode,
                        Pn = item.PartNo,
                        Count = item.Count,
                        Weight = item.Weight,
                        Suppler = item.Suppler,
                        Busidate = item.Busidate.ToStr(),
                        Batch = item.Batch,
                        SendCh = item.SendCh,
                        SendEn = item.SendEn,
                        ReciveCh = item.ReciveCh,
                        ReciveEn = item.ReciveEn,
                        IsOpen = item.IsOpen
                    });
                }

                var boxIds = data.Data.Select(s => s.BoxId).ToList();
                var dataDts = _trPackageDetials.GetList(f => f.projectId == ProjectId && boxIds.Contains(f.boxid));
                step = 0;
                foreach (var dts in dataDts)
                {
                    packageDtslist.Add(new ImportPackageDetails
                    {
                        No = step,
                        BoxId = dts.boxid,
                        SN = dts.sn
                    });
                }

                EpPlusExcelHelper<ImportPackage> helper = null;
                try
                {
                    helper = new EpPlusExcelHelper<ImportPackage>();
                    var temporaryFileName = $"包装信息-{DateTime.Now:yyyyMMddHHmmss}.xlsx";

                    helper.GenerateExcel(packageList, packageDtslist, Path.Combine(rootDir, temporaryFileName));
                    return new ObjectResult($"{FileSystemHelper.CommonFileSetting.RequestPath}/{FileSystemHelper.ExportFileName}/{temporaryFileName}");
                }
                catch
                {
                    throw new BadRequestException(RequestEnum.ExportFailed);
                }
                finally
                {
                    helper?.Dispose();
                }
            }
        }

        /// <summary>
        /// SKF 报表- 装配信息 
        /// </summary>
        /// <param name="report"></param>
        /// <returns></returns>
        [HttpPost]
        public IActionResult GetAssmbData([FromBody] RequestGeneralReport report)
        {
            var stations = _sigerProjectLevelSection.GetLevelSectionIds(report.section, ProjectId).ToList();
            if (report.export == 0)
            {
                var data = _sigerTrAssemb.GetAssembPagedList(report.qrcode, stations, report.start.ToDateTime(),
                    report.end.ToDateTime(), ProjectId, report.page, report.pageSize);
                var result = data.Data.ToList();
                foreach (var r in result)
                {
                    r.SectionDesc = GetAllTitle(r.Section);
                }

                return new PagedObjectResult(result, data.Total, report.page, report.pageSize);
            }
            else
            {
                //导出
                
                var rootDir = FileSystemHelper.GetPhysicalFolders(FileSystemHelper.CommonFileSetting.PhysicalFolder, FileSystemHelper.ExportFileName);

                var data = _sigerTrAssemb.GetAssembPagedList(report.qrcode, stations, report.start.ToDateTime(),
                    report.end.ToDateTime(), ProjectId, 1, 9999999);
                var result = data.Data.ToList();
                foreach (var r in result)
                {
                    r.SectionDesc = GetAllTitle(r.Section);
                }

                var packageList = new List<ImportAssemb>();
                var step = 0;
                foreach (var it in data.Data)
                {
                    step += 1;
                    packageList.Add(new ImportAssemb
                    {
                        No = step,
                        SN = it.Sn,
                        SN2 = it.Sn2,
                        Name = it.Name,
                        Section = it.SectionDesc,
                        User = it.User,
                        Date = it.DateTime.ToStr()
                    });
                }

                EpPlusExcelHelper<ImportAssemb> helper = null;
                try
                {
                    helper = new EpPlusExcelHelper<ImportAssemb>();
                    var temporaryFileName = $"装配信息-{DateTime.Now:yyyyMMddHHmmss}.xlsx";

                    helper.GenerateExcel(packageList, Path.Combine(rootDir, temporaryFileName));
                    return new ObjectResult($"{FileSystemHelper.CommonFileSetting.RequestPath}/{FileSystemHelper.ExportFileName}/{temporaryFileName}");
                }
                catch
                {
                    throw new BadRequestException(RequestEnum.ExportFailed);
                }
                finally
                {
                    helper?.Dispose();
                }
            }
        }

        private string GetAllTitle(int sectionId)
        {
            var titles = _sigerProjectLevelSection.GetLevelSectionTitles(sectionId, ProjectId);
            var list = titles.ToList();
            return list.Any() ? string.Join('-', list) : string.Empty;
        }

        /// <summary>
        /// SKF 报表 - 过站信息
        /// </summary>
        /// <param name="report"></param>
        /// <returns></returns>
        [HttpPost]
        public IActionResult GetTrace([FromBody] RequestGeneralReport report)
        {
            var stations = _sigerProjectLevelSection.GetLevelSectionIds(report.section, ProjectId).ToList();
            if (report.export == 0)
            {
                var data = _traceRepository.GetTrTracePagedList(report.qrcode, stations, report.type1, ProjectId,
                    report.start.ToDateTime(), report.end.ToDateTime(), report.page, report.pageSize);
                var result = data.Data.ToList();
                foreach (var r in result)
                {
                    r.SectionDesc = GetAllTitle(r.Section);
                }

                return new PagedObjectResult(data.Data, data.Total, report.page, report.pageSize);
            }
            else
            {
                //导出
                var rootDir = FileSystemHelper.GetPhysicalFolders(FileSystemHelper.CommonFileSetting.PhysicalFolder, FileSystemHelper.ExportFileName);

                var data = _traceRepository.GetTrTracePagedList(report.qrcode, stations, report.type1, ProjectId,
                    report.start.ToDateTime(), report.end.ToDateTime(), 1, 9999999);
                var packageList = new List<ImportTrace>();
                var packageDtslist = new List<ImportTraceDetails>();
                var step = 0;
                foreach (var item in data.Data)
                {
                    step += 1;
                    packageList.Add(new ImportTrace
                    {
                        No = step,
                        ProductCode = item.ProductCode,
                        SectionDesc = item.SectionDesc,
                        Sn = item.Sn,
                        Result = item.Result,
                        User = item.User,
                        Date = item.Busidate.ToStr()
                    });
                }

                var seqIds = data.Data.Select(s => s.SeqID).ToList();
                var dataDts = _traceDetailRepository.GetList(f => f.projectId == ProjectId && seqIds.Contains(f.SeqID))
                    .ToList();
                step = 0;
                foreach (var dts in dataDts)
                {
                    var param = _trParameterConfig.Get(f => f.projectId == ProjectId && f.name.Contains(dts.Item));
                    packageDtslist.Add(new ImportTraceDetails
                    {
                        No = step,
                        Sn = dts.SN,
                        Item = dts.Item,
                        Value = dts.Value,
                        Type = param != null ? param.attribute : ""
                    });
                }

                EpPlusExcelHelper<ImportTrace> helper = null;
                try
                {
                    helper = new EpPlusExcelHelper<ImportTrace>();
                    var temporaryFileName = $"过站信息-{DateTime.Now:yyyyMMddHHmmss}.xlsx";

                    helper.GenerateExcel(packageList, packageDtslist, Path.Combine(rootDir, temporaryFileName));
                    return new ObjectResult($"{FileSystemHelper.CommonFileSetting.RequestPath}/{FileSystemHelper.ExportFileName}/{temporaryFileName}");
                }
                catch
                {
                    throw new BadRequestException(RequestEnum.ExportFailed);
                }
                finally
                {
                    helper?.Dispose();
                }
            }
        }
    }
}
