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

namespace Siger.ApiACC.Controllers.Report
{
    public class UnhealthyController : BaseController
    {
        private readonly IUnitOfWork _unitOfWork;
        private readonly ISigerTrBatchTraceDetailRepository _sigerTrBatchTraceDetail;
        private readonly ISigerTrCategoryItemRepository _sigerTrCategoryItem;
        public UnhealthyController(IUnitOfWork unitOfWork, ISigerTrBatchTraceDetailRepository sigerTrBatchTraceDetail
            , ISigerTrCategoryItemRepository sigerTrCategoryItem)
        {
            _unitOfWork = unitOfWork;
            _sigerTrBatchTraceDetail = sigerTrBatchTraceDetail;
            _sigerTrCategoryItem = sigerTrCategoryItem;
        }

        [HttpGet]
        public IActionResult GetList(int line, string starttime, string endtime, int page = 1, int pagesize = 10)
        {
            var data = _sigerTrBatchTraceDetail.GetPagedList(line, starttime, endtime, ProjectId, page, pagesize);

            return new PagedObjectResult(data.Data, data.Total, page, pagesize);
        }

        [HttpGet]
        public IActionResult ExportAll(int line, string starttime, string endtime)
        {
            var rootDir = FileSystemHelper.GetPhysicalFolders(FileSystemHelper.CommonFileSetting.PhysicalFolder, FileSystemHelper.ExportFileName);

            var query = _sigerTrBatchTraceDetail.GetDataList(line, starttime, endtime, ProjectId);
            var dataList = new List<UnhealthyList>();
            int k = 0;
            foreach (var item in query)
            {
                k++;
                dataList.Add(new UnhealthyList
                {
                    No = k,
                    line = item.line_value??"",
                    station = item.station_value??"",
                    item = item.item??"",
                    qty = item.qty,
                    BeginDateTime = item.begindatetime??"",
                    EndDateTime = item.enddatetime??"",
                    username=item.uid_value??"",
                    TransDateTime=item.transdatetime??"",
                });
            }
            if (dataList.Any())
            {
                EpPlusExcelHelper<UnhealthyList> helper = null;
                try
                {
                    helper = new EpPlusExcelHelper<UnhealthyList>();
                    var temporaryFileName = $"不良录入_Unhealthy_{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("ExportUnhealthy failed, error:" + e);
                    throw new BadRequestException(RequestEnum.ExportFailed);
                }
                finally
                {
                    helper?.Dispose();
                }
            }
            else
            {
                throw new BadRequestException(CommonEnum.RecordNotFound);
            }
        }

        private int getUnhealthyNumbers(int line,int station,int itemid, string starttime,string endtime)
        {
            Expression<Func<SigerTrBatchTraceDetail, bool>> Func = f => (f.status == (int)RowState.Valid && f.projectId == ProjectId);
            Expression<Func<SigerTrBatchTraceDetail, bool>> FunLine = f => true;
            Expression<Func<SigerTrBatchTraceDetail, bool>> FunStation = f => true;
            Expression<Func<SigerTrBatchTraceDetail, bool>> FunItem = f => true;
            Expression<Func<SigerTrBatchTraceDetail, bool>> FunTime = f => true;
            if (station > 0)
                FunStation = f => f.Station == station.ToStr();
            if (line > 0)
                FunLine = f => f.Line == line.ToStr();
            if (itemid > 0)
                FunItem = f => f.Item == itemid.ToStr();
            if (DateTime.TryParse(starttime, out DateTime stime) && DateTime.TryParse(endtime, out DateTime etime))
                FunTime = f => (f.BeginDateTime >= stime && f.EndDateTime <= etime);
            var predicate = Func.And(FunLine).And(FunStation).And(FunLine).And(FunItem).And(FunTime);

            var query = _sigerTrBatchTraceDetail.GetList(predicate);

            if (query != null && query.Any())
            {
                return query.Sum(t => t.QTY);
            }
            return 0;
        }

        [HttpGet]
        public IActionResult GetEchartsdata(int line, string starttime, string endtime)
        {
            var errorData = _sigerTrCategoryItem.Get(t => t.Line == line.ToString() && t.projectId == ProjectId && t.status == (int)RowState.Valid
                                    && (t.UpItem == "0" || t.UpItem == "" || t.UpItem == null));

            var mistakeinput = errorData != null ? errorData.Item : "";
            if (!string.IsNullOrEmpty(mistakeinput))
            {
                var reslist = new List<ResponseCategoryItem>();

                var query = _sigerTrCategoryItem.GetList(t => t.Line == line.ToString() && t.projectId == ProjectId && t.status == (int)RowState.Valid
                                    && t.UpItem == mistakeinput).ToList();
                if (query.Any())
                {
                    foreach(var item in query)
                    { 
                        var datalist = _sigerTrCategoryItem.GetList(t => t.Line == line.ToStr() && t.projectId == ProjectId && t.status == (int)RowState.Valid
                                    && t.UpItem == item.Item).ToList();
                        var itemlist = new List<CategoryItemModel>();
                        if (datalist.Any())
                        {
                            foreach(var data in datalist)
                            {
                                itemlist.Add(new CategoryItemModel
                                {
                                    Item = data.Item,
                                    UpItem = data.UpItem,
                                    Line = data.Line,
                                    num = getUnhealthyNumbers(line, item.id, data.id, starttime, endtime)
                                });
                            }
                        }
                        reslist.Add(new ResponseCategoryItem
                        {
                            Item = item.Item,
                            UpItem = item.UpItem,
                            Line = item.Line,
                            count = getUnhealthyNumbers(line, item.id, 0, starttime, endtime),
                            childs = itemlist
                        });
                    }
                }

                var response = new List<ResCategoryItem>();
                foreach (var item in reslist)
                {
                    var itemlist = new List<CateItemModel>();
                    var namevalueList = new NameValueModel[item.childs.Count()];
                    string[] namelist = new string[item.childs.Count()];
                    foreach (var data in item.childs)
                    {
                        namelist.Append(data.Item);
                        namevalueList.Append(new NameValueModel
                        {
                            name = data.Item,
                            value = data.num.ToStr()
                        });
                    }
                    itemlist.Add(new CateItemModel
                    {
                        name = namelist,
                        data = namevalueList
                    });
                    response.Add(new ResCategoryItem
                    {
                        name = item.Item,
                        child = itemlist
                    });
                }
                return new ObjectResult(response);
            }

            throw new BadRequestException(CommonEnum.RecordNotFound);
        }

        [HttpPost]
        public IActionResult AddUnhealthy([FromBody]List<RequestUnhealthy> data)
        {
            var adddatas = new List<SigerTrBatchTraceDetail>();
            foreach(var res in data)
            {
                adddatas.Add(new SigerTrBatchTraceDetail
                {
                    projectId = ProjectId,
                    Line = res.Line,
                    Item = res.Item,
                    Station = res.Station,
                    QTY = res.QTY,
                    UID = UserId.ToStr(),
                    BeginDateTime = res.BeginDateTime.ToDateTime(),
                    EndDateTime = res.EndDateTime.ToDateTime(),
                    TransDateTime = DateTime.Now
                });
            }
            _sigerTrBatchTraceDetail.Insert(adddatas);
            if (_unitOfWork.Commit() > 0)
                return new ObjectResult(CommonEnum.Succefull);
            throw new BadRequestException(CommonEnum.Fail);
        }

        [HttpGet]
        public IActionResult GetCategroyItems(int line)
        {
            var errorData = _sigerTrCategoryItem.Get(t => t.Line == line.ToString() && t.projectId == ProjectId && t.status == (int)RowState.Valid
                                    && (t.UpItem == "0" || t.UpItem == "" || t.UpItem == null));
            var mistakeinput = errorData != null ? errorData.Item : "";
            if (!string.IsNullOrEmpty(mistakeinput))
            {
                var reslist = new List<ResponseCategoryItem>();

                var query = _sigerTrCategoryItem.GetList(t => t.Line == line.ToStr() && t.projectId == ProjectId && t.status == (int)RowState.Valid
                                    && t.UpItem == mistakeinput).ToList();
                if (query.Any())
                {
                    foreach (var item in query)
                    {
                        var datalist = _sigerTrCategoryItem.GetList(t => t.Line == line.ToStr() && t.projectId == ProjectId && t.status == (int)RowState.Valid
                                    && t.UpItem == item.Item).ToList();
                        var itemlist = new List<CategoryItemModel>();
                        if (datalist.Any())
                        {
                            foreach (var data in datalist)
                            {
                                itemlist.Add(new CategoryItemModel
                                {
                                    Item = data.Item,
                                    UpItem = data.UpItem,
                                    Line = data.Line
                                });
                            }
                        }
                        reslist.Add(new ResponseCategoryItem
                        {
                            Item = item.Item,
                            UpItem = item.UpItem,
                            Line = item.Line,
                            childs = itemlist
                        });
                    }
                }
                return new ObjectResult(reslist);
            }

            throw new BadRequestException(CommonEnum.RecordNotFound);
        }
    }
}