using System;
using System.Linq;
using System.Linq.Expressions;
using Microsoft.AspNetCore.Mvc;
using Siger.Middlelayer.Repository;
using Siger.Middlelayer.Repository.Extensions;
using Siger.Middlelayer.Common;
using System.Collections.Generic;
using Siger.Middlelayer.Common.Extensions;
using Siger.ApiCommon.Utilities;
using Siger.Middlelayer.Common.AppSettings;
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.Log;
using Siger.Middlelayer.Repository.Repositories.Interface;
using Siger.Middlelayer.Utility.Helpers;
using Siger.Middlelayer.Utility.ImportEntities;
using Siger.Middlelayer.Common.Helpers;

namespace Siger.ApiACC.Controllers
{
    public class PackingFullQtyController : BaseController
    {
        private readonly IUnitOfWork _unitOfWork;
        private readonly ISigerPackingFullQty _sigerPackingFull;
        private readonly ISigerDict _sigerDict;
        private readonly ISigerProjectProductRepository _sigerTrProduct;
        public PackingFullQtyController(IUnitOfWork unitOfWork, ISigerPackingFullQty sigerPackingFull, ISigerProjectProductRepository sigerTrProduct
            , ISigerDict sigerDict)
        {
            _unitOfWork = unitOfWork;
            _sigerPackingFull = sigerPackingFull;
            _sigerDict = sigerDict;
            _sigerTrProduct = sigerTrProduct;
        }
        [HttpGet]
        public IActionResult Getlist(string productId, string pn, int page = 1, int pagesize = 10)
        {
            Expression<Func<SigerTrPackingFullQty, bool>> Funcat = f => f.projectId == ProjectId && f.status == RowState.Valid.GetHashCode();
            Expression<Func<SigerTrPackingFullQty, bool>> Funkey = f => true;
            Expression<Func<SigerTrPackingFullQty, bool>> FunproductId = f => true;
            if (!string.IsNullOrEmpty(productId) && productId != "0")
                FunproductId = f => f.ProductID == productId;
            if (!string.IsNullOrEmpty(pn) && pn != "0")
                Funkey = f => f.PN.Contains(pn);
            var predicate = Funcat.And(Funkey).And(FunproductId);
            var data = _sigerPackingFull.GetPagedList(page, pagesize, predicate);

            var response = new List<ResponsePackingFullQty>();
            foreach (var item in data.Data)
            {
                var products = _sigerTrProduct.Get(t => t.projectid == ProjectId && t.code == item.ProductID && t.status == (int)RowState.Valid);
                var users = _sigerPackingFull.GetUserInfo(item.UID.ToInt(), ProjectId);
                response.Add(new ResponsePackingFullQty
                {
                    id = item.id,
                    productid = item.ProductID,
                    pn = item.PN,
                    pn_value = item.PN,
                    productid_value = products != null ? products.code : "",
                    region = item.Region,
                    region_value = _sigerDict.GetDictValue(ProjectId, AccDictCost.region, item.Region),
                    qty = item.QTY,
                    uid = item.UID,
                    uid_value = users != null ? users.name : "",
                    transdatetime = item.TransDateTime.ToString(ParameterConstant.DateTimeFormat)
                });
            }

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

        [HttpPost]
        public IActionResult Add([FromBody] RequestPackingFullQty fullQty)
        {
            if (!(fullQty.Qty > 0))
            {
                throw new BadRequestException(RequestEnum.FullQtyMustMoreThanZero);
            }
            var model = _sigerPackingFull.Get(t => t.PN == fullQty.Pn && t.Region == fullQty.Region && t.ProductID == fullQty.ProductID && t.status == (int)RowState.Valid && t.projectId == ProjectId);
            if (model != null)
                throw new BadRequestException(RequestEnum.ProductNoPnRegionExsit);

            _sigerPackingFull.Insert(new SigerTrPackingFullQty
            {
                projectId = ProjectId,
                ProductID = fullQty.ProductID,
                PN = fullQty.Pn,
                QTY = fullQty.Qty,
                Region = fullQty.Region,
                UID = UserId.ToString(),
                TransDateTime = DateTime.Now
            });
            if (_unitOfWork.Commit() > 0)
                return new ObjectResult(CommonEnum.Succefull);
            throw new BadRequestException(CommonEnum.Fail);
        }
        [HttpPost]
        public IActionResult Modify([FromBody] RequestModifyPackingFullQty fullQty)
        {
            if (!(fullQty.Qty > 0))
            {
                throw new BadRequestException(RequestEnum.FullQtyMustMoreThanZero);
            }
            var NewObj = _sigerPackingFull.Get(fullQty.Id);
            if (NewObj == null)
                throw new BadRequestException(CommonEnum.RecordNotFound);

            var model = _sigerPackingFull.Get(t => t.PN == fullQty.Pn && t.Region == fullQty.Region && t.ProductID == fullQty.ProductID && t.id != fullQty.Id
                && t.status == (int)RowState.Valid && t.projectId == ProjectId);
            if (model != null)
                throw new BadRequestException(RequestEnum.ProductNoPnRegionExsit);

            NewObj.ProductID = fullQty.ProductID;
            NewObj.PN = fullQty.Pn;
            NewObj.QTY = fullQty.Qty;
            NewObj.Region = fullQty.Region;
            NewObj.UID = UserId.ToString();
            NewObj.TransDateTime = DateTime.Now;
            _sigerPackingFull.Update(NewObj);
            if (_unitOfWork.Commit() > 0)
                return new ObjectResult(CommonEnum.Succefull);
            throw new BadRequestException(CommonEnum.Fail);
        }
        [HttpGet]
        public IActionResult Delete(string id)
        {
            foreach (var item in id.Split(','))
            {
                var NewObj = _sigerPackingFull.Get(item.ToInt());
                if (NewObj == null)
                    throw new BadRequestException(CommonEnum.RecordNotFound);
                NewObj.status = (int)RowState.Invalid;
                _sigerPackingFull.Update(NewObj);
            }
            if (_unitOfWork.Commit() > 0)
                return new ObjectResult(CommonEnum.Succefull);
            throw new BadRequestException(CommonEnum.Fail);
        }

        [HttpGet]
        public IActionResult exportAll(string productid, string pn)
        {            
            var rootDir = FileSystemHelper.GetPhysicalFolders( FileSystemHelper.CommonFileSetting.PhysicalFolder, FileSystemHelper.ExportFileName);
            if (!Directory.Exists(rootDir))
            {
                Directory.CreateDirectory(rootDir);
            }

            Expression<Func<SigerTrPackingFullQty, bool>> Funcat = f => f.projectId == ProjectId && f.status == (int)RowState.Valid;
            Expression<Func<SigerTrPackingFullQty, bool>> Funkey = f => true;
            Expression<Func<SigerTrPackingFullQty, bool>> Funproductid = f => true;
            if (!string.IsNullOrEmpty(productid) && productid != "0")
                Funproductid = f => f.ProductID.Contains(productid);
            if (!string.IsNullOrEmpty(pn) && pn != "0")
                Funkey = f => f.PN.Contains(pn);
            var predicate = Funcat.And(Funkey).And(Funproductid);
            var data = _sigerPackingFull.GetList(predicate).ToList();
            if (!data.Any())
            {
                throw new BadRequestException(CommonEnum.RecordNotFound);
            }
            var dataList = new List<PackingFullQtyTemplate>();
            foreach (var item in data)
            {
                var products = _sigerTrProduct.Get(t => t.projectid == ProjectId && t.code == item.ProductID && t.status == (int)RowState.Valid);
                var users = _sigerPackingFull.GetUserInfo(item.UID.ToInt(), ProjectId);
                dataList.Add(new PackingFullQtyTemplate
                {
                    productid = products != null ? products.code : "",
                    pn = item.PN,
                    region = _sigerDict.GetDictValue(ProjectId, AccDictCost.region, item.Region),
                    qty = item.QTY.ToString(),
                    uid = users != null ? users.name : "",
                    transdatetime = item.TransDateTime.ToString(ParameterConstant.DateTimeFormat)
                });
            }
            if (dataList.Any())
            {
                EpPlusExcelHelper<PackingFullQtyTemplate> helper = null;
                try
                {
                    helper = new EpPlusExcelHelper<PackingFullQtyTemplate>();
                    var temporaryFileName = $"打包设置信息_PackingFullQtyInfo_{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("ExportPackingFullQty failed, error:" + e);
                    throw new BadRequestException(RequestEnum.ExportFailed);
                }
                finally
                {
                    helper?.Dispose();
                }
            }

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