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

namespace Siger.ApiConfig.Controller
{
    public class ProjectProductStructureController : BaseController
    {
        private readonly IUnitOfWork _unitOfWork;
        private readonly ISigerProjectProductRepository _productRepository;
        private readonly ISigerTrMaterialsRepository _sigerTrMaterialsRepository;
        private readonly ISigerProjectProductStructure _sigerProjectProductStructure;
        public ProjectProductStructureController(IUnitOfWork unitOfWork, ISigerProjectProductRepository sigerProjectProductRepository, ISigerTrMaterialsRepository sigerTrMaterialsRepository, ISigerProjectProductStructure sigerProjectProduct)
        {
            _unitOfWork = unitOfWork;
            _productRepository = sigerProjectProductRepository;
            _sigerTrMaterialsRepository = sigerTrMaterialsRepository;
            _sigerProjectProductStructure = sigerProjectProduct;
        }
        /// <summary>
        ///  Bom 结构树
        /// </summary>
        /// <param name="productId"></param>
        /// <param name="materialId"></param>
        /// <param name="productName"></param>
        /// <returns></returns>
        [HttpGet]
        public IActionResult GetProductTree(int productId,int materialId,string productName)
        {
            // 产品信息
            //已配置COMBOX 产品 / 物料
            var ids = GetIds(productId, materialId);
            var lst = _sigerProjectProductStructure.GetList();
            var productStructureInfo = _sigerProjectProductStructure.GetTreeData(ProjectId, ids).ToList();

            var TreeData = BindTree(productStructureInfo, 0);
            return new ObjectResult(TreeData);
        }

        private List<ResponseProductStructureTree> BindTree(List<ProductstructureData>Data,int parentid)
        {
            var response = new List<ResponseProductStructureTree>();
            var model = Data.Where(f => f.ParentId==parentid);
            if (!model.Any())
                return response;
            foreach (var item in model)
            {
                var desc = string.Empty;
                if (item.ComboxItem == ComboxItem.Material)
                    desc = $"{item.MaterialName} [{item.Pn}] {item.ItemCount}";
                else
                    desc = item.ProductDesc;
                response.Add(new ResponseProductStructureTree
                {
                    Title = desc,
                    Id = item.Id,
                    Expand=true,
                    ParentId =item.ParentId,
                    ItemId=item.ItemId,
                    ItemType =item.ComboxItem,
                    material=item.MaterialName,
                    Pn=item.Pn,
                    Spec=item.MaterlSpec,
                    Count=item.ItemCount,
                    Children = BindTree(Data, item.Id)
                });
            }
            return response;
        }

        /// <summary>
        /// 添加
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [HttpPost]
        public IActionResult Add([FromBody]RequestAddProductstruct request)
        {
           
            if (_sigerProjectProductStructure.IsExist(f=>f.itemid==request.ItemId && f.parent_id==request.Id))
                throw new BadRequestException(CommonEnum.RecordExits);

            //存在
            _sigerProjectProductStructure.Insert(new siger_project_product_structure
            {
                parent_id = request.Id,
                projectid = ProjectId,
                itemid = request.ItemId,
                itemcount = request.ItemCount,
                itemtype = ComboxItem.Material,
                user = UserId,
                datetime = DateTime.Now,
                status = (int)RowState.Valid,
            });

            //物料
            if (_unitOfWork.Commit() > 0)
                return new ObjectResult(CommonEnum.Succefull);
            else
                return new ObjectResult(CommonEnum.Fail);

        }
        [HttpPost]
        public IActionResult Edit([FromBody]RequestEditProductstruct request)
        {
            var items = _sigerProjectProductStructure.Get(f => f.projectid == ProjectId && f.itemtype== ComboxItem.Material && f.parent_id == request.ParentId && f.itemid == request.ItemId);
            if (items==null)
                throw new BadRequestException(CommonEnum.RecordNotFound);

            if (_sigerProjectProductStructure.IsExist(f => f.itemid == request.ItemId && f.parent_id == request.Id))
                throw new BadRequestException(CommonEnum.RecordExits);
            items.itemid = request.ItemId;
            items.itemcount = request.ItemCount;
            _sigerProjectProductStructure.Update(items);
            if (_unitOfWork.Commit() > 0)
                return new ObjectResult(CommonEnum.Succefull);
            else
                return new ObjectResult(CommonEnum.Fail);
        }
        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpGet]
        public IActionResult Del(int id)
        {
            var obj = _sigerProjectProductStructure.Get(id);
            if (obj==null)
                throw new BadRequestException(CommonEnum.RecordNotFound);
            var lstParent = _sigerProjectProductStructure.GetList(f => f.projectid == ProjectId && f.parent_id == id);
          
            foreach(var p in lstParent)
            {
                _sigerProjectProductStructure.Delete(p);
            }
            _sigerProjectProductStructure.Delete(obj);
            if (_unitOfWork.Commit() > 0)
                return new ObjectResult(CommonEnum.Succefull);
            else
                return new ObjectResult(CommonEnum.Fail);
        }


        [HttpGet]
        public IActionResult ExportExcel(int productId, int materialId, string productName)
        {
            var rootDir = FileSystemHelper.GetPhysicalFolders(FileSystemHelper.CommonFileSetting.PhysicalFolder, FileSystemHelper.ExportFileName);
            var ids = GetIds(productId, materialId);
            //var data = _sigerProjectProductStructure.GetProductStructureDatas(ProjectId, ids).ToList();
            var data = _sigerProjectProductStructure.GetTreeData(ProjectId, ids).ToList();
            if (!data.Any())
            {
                throw new BadRequestException(CommonEnum.RecordNotFound);
            }
            var dataList = new List<ExportProductStructureBom>();
            foreach (var item in data)
            {
                var _productName = item.ProductDesc;
                if (item.ComboxItem == ComboxItem.Material)
                {
                    var pid = GetParent(data, item.ParentId);
                    var pobj = data.Find(f => f.Id == pid);
                    if (pobj.ComboxItem == ComboxItem.Product)
                        _productName = data.Find(f => f.Id == pid).ProductDesc;
                    else
                        _productName = data.Find(f => f.Id == pid).Pn;
                }
                dataList.Add(new ExportProductStructureBom
                {
                    Id = item.Id,
                    ProductName = _productName,
                    ParentType = (int)item.ComboxItem,
                   // ParentId = item.ParentId,
                    MaterialPn =item.ComboxItem==ComboxItem.Material? item.MaterialPn:"",
                    MaterialCount = item.Count
                });
            }
            if (dataList.Any())
            {
                EpPlusExcelHelper<ExportProductStructureBom> helper = null;
                try
                {
                    helper = new EpPlusExcelHelper<ExportProductStructureBom>();
                    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 Inspection Standard Info failed, error:" + e);
                    throw new BadRequestException(RequestEnum.ExportFailed);
                }
                finally
                {
                    helper?.Dispose();
                }
            }

            throw new BadRequestException(CommonEnum.Fail);
        }

        List<int>GetIds(int productId, int materialId)
        {
            var ids = new List<int>();
            if (productId != 0)
            {
                var strProduct = _sigerProjectProductStructure.Get(f => f.projectid == ProjectId && f.itemtype == ComboxItem.Product && f.itemid == productId);
                if (strProduct != null)
                {
                    ids.Add(strProduct.id);
                    var sonObj = _sigerProjectProductStructure.GetSon(strProduct.id, ProjectId);
                    ids.AddRange(sonObj.Select(s=>s.id));
                }
            }
            if (materialId != 0)
            {
                var strMaterial= _sigerProjectProductStructure.Get(f => f.projectid == ProjectId && f.itemtype == ComboxItem.Material && f.itemid == productId);
                if (strMaterial!=null)
                {
                    ids.Add(strMaterial.id);
                    var sonObj = _sigerProjectProductStructure.GetSon(strMaterial.id, ProjectId);
                    ids.AddRange(sonObj.Select(s => s.id));
                }
            }
            return ids;
        }
        int GetParent(IEnumerable<ProductstructureData> data,int parentId)
        {
            var parentLst = data.FirstOrDefault(f => f.Id == parentId);

            return parentLst.Id;
            //foreach(var p in parentLst)
            //{
            //    GetParent(parentLst, p.ParentId);
            //}
            //return data.FirstOrDefault().Id;
        }
    }
}
