using Siger.Middlelayer.Repository.Data;
using Siger.Middlelayer.Repository.Entities;
using Siger.Middlelayer.Repository.Repositories.Interface;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using Siger.Middlelayer.Common;
using Siger.Middlelayer.Common.ModuleEnum;
using Siger.Middlelayer.Repository.Extensions;
using Siger.Middlelayer.Utility.ImportEntities;

namespace Siger.Middlelayer.Repository.Repositories
{
    internal  class SigerProjectProductStructure : ApiConfigRepositoryBase<siger_project_product_structure>, ISigerProjectProductStructure
    {
        private readonly ApiConfigDbContext _context;
        public SigerProjectProductStructure(ApiConfigDbContext context) : base(context)
        {
            _context = context;
        }
        public IEnumerable<ProductInfoData>GetProductMaterial(int projectId,int productId,int material, string productname)
        {
            Expression<Func<ProductInfoData, bool>> FunProduct = f => true;
            Expression<Func<ProductInfoData, bool>> FunProductName = f => true;
            Expression<Func<ProductInfoData, bool>> FunMater = f => true;
            var query = from p in _context.siger_project_product
                        join ps in _context.siger_project_product_structure on p.id equals ps.itemid into temp
                        from psc in temp.DefaultIfEmpty()
                        where p.projectid == projectId && p.status == (int)RowState.Valid 
                        select new ProductInfoData
                        {
                            ProductId = p.id,
                            ProductName = p.name,
                            MaterialId = psc != null ? psc.itemid:0,
                            ComboxItem=psc!=null?(int)psc.itemtype:0
                        };
            if (productId != 0)
                FunProduct = f => f.ProductId == productId;
            if (material != 0)
                FunMater = f => f.MaterialId == material && f.ComboxItem==(int)ComboxItem.Material;
            if (!string.IsNullOrEmpty(productname))
                FunProductName = f => f.ProductName.Contains(productname);

            var predicate = FunProduct.And(FunMater).And(FunProductName);
            return query.Where(predicate).GroupBy(f=>f.ProductId).Select(g=>g.FirstOrDefault());
        }

        public IEnumerable<DownProductStructureData> GetProductStructureDatas(int projectId, List<int> ids)
        {
            Expression<Func<DownProductStructureData, bool>> FunKeys = f => true;
            Expression<Func<DownProductStructureData, bool>> FunProductName = f => true;
            Expression<Func<DownProductStructureData, bool>> FunMater = f => true;

            var query = from d in _context.siger_project_product_structure
                        join m in _context.siger_tr_materials on d.itemid equals m.id into mtemp
                        from mt in mtemp.DefaultIfEmpty()
                        join p in _context.siger_project_product on d.itemid equals p.id into ptemp
                        from pt in ptemp.DefaultIfEmpty()
                        where d.projectid == projectId && d.status == (int)RowState.Valid
                        select new DownProductStructureData
                        {
                            Id=d.id,
                            ParentId=d.parent_id,
                            Count=d.itemcount,
                            MaterialId = mt != null ? mt.id : d.itemid,
                            MaterialName = mt != null ? mt.name : "",
                            MaterialPn = mt != null ? mt.pn : "",
                            ProductName = pt != null ? pt.name : "",
                            ProductId = pt != null ? pt.id : d.itemid,
                            ComboxItem=d.itemtype
                            
                        };
            if (ids.Any())
                FunKeys = f =>ids.Contains(f.ProductId);
            return query.Where(FunKeys);
        }

        public IEnumerable<ProductstructureData> GetTreeData(int projectId, List<int> ids)
        {
            Expression<Func<ProductstructureData, bool>> FunId = f => true;
            var query = from d in _context.siger_project_product_structure
                        join m in _context.siger_tr_materials on d.itemid equals m.id into mtemp
                        from mt in mtemp.DefaultIfEmpty()
                        join p in _context.siger_project_product on d.itemid equals p.id into ptemp
                        from pt in ptemp.DefaultIfEmpty()
                        where d.projectid == projectId && d.status == (int)RowState.Valid
                        select new ProductstructureData
                        {
                            Id = d.id,
                            ParentId = d.parent_id,
                            ItemId = d.itemid,
                            Count = d.itemcount,
                            Pn = mt != null ? mt.pn : "",
                            MaterialId = mt != null ? mt.id : d.itemid,
                            MaterialName = mt != null ? mt.name : "",
                            MaterialPn = mt != null ? mt.pn : "",
                            MaterlSpec = mt != null ? mt.spec : "",
                            ProductId = pt != null ? pt.id : d.itemid,
                            ProductDesc = pt != null ? pt.name : "",
                            ComboxItem = d.itemtype,
                            ItemCount=d.itemcount
                        };
            
            if (ids.Any())
                FunId = f => ids.Contains(f.Id);
            return query.Where(FunId);
        }


        public IEnumerable<siger_project_product_structure>GetSon(int parentId,int projectid)
        {
            var query = from c in _context.siger_project_product_structure
                        where c.parent_id == parentId && c.projectid == projectid && c.status == (int)RowState.Valid
                        select c;

            return query.ToList().Concat(query.ToList().SelectMany(t => GetSon(t.id, projectid)));
        }
        public CommonImportResult ImportData(IEnumerable<ProductStructureBom> data, int projectId, int userId)
        {
            var errors = new List<string>();
            var entities = new List<siger_project_product_structure>();
            var rowIndex = 1;
            var dataList = data.ToList();
           // var structMaxId = 0;


            int MaxId = _context.siger_project_product_structure.Max(f => f.id);

            foreach (var item in dataList)
            {
                rowIndex++;
                if(item.ProductName==item.MaterialPn)
                    errors.Add($"{rowIndex},{Convert.ToString((int)CommonEnum.CheckFaild)}");
                if (item.ParentType == (int)ComboxItem.Product)
                {//产品 
                    var product = _context.siger_project_product.FirstOrDefault(q => q.projectid == projectId && q.code== item.ProductName && q.status == (int)RowState.Valid);
                    if (product == null)
                        errors.Add($"{rowIndex},{Convert.ToString((int)CommonEnum.RecordNotFound)}");
                }
                else
                {//物料
                    //是否存在
                    var materialParent = _context.siger_tr_materials.FirstOrDefault(q => q.pn == item.MaterialPn && q.projectId == projectId && q.status == (int)RowState.Valid);
                    if (materialParent == null)
                    {
                        errors.Add($"{rowIndex},{Convert.ToString((int)CommonEnum.RecordNotFound)}");
                    }
                    else
                    {
                        //物料是否有父级
                        var pdStructure = _context.siger_project_product_structure.FirstOrDefault(f => f.itemid == materialParent.id && f.parent_id != 0);
                        if (pdStructure == null)
                            errors.Add($"{rowIndex},{Convert.ToString((int)ConfigEnum.PnParentNotfound)}");
                    }

                }

                //子级（物料）
                //var material = _context.siger_tr_materials.FirstOrDefault(q => q.pn == item.MaterialPn && q.projectId == projectId && q.status == (int)RowState.Valid);
                //if (material == null)
                //    errors.Add($"{rowIndex},{Convert.ToString((int)CommonEnum.RecordNotFound)}");
            }

            if (errors.Any())
            {
                return new CommonImportResult(0, string.Join(";", errors));
            }
            try
            {
                foreach (var item in dataList)
                {
                    if (item.ParentType == 1)
                    {
                        var product = _context.siger_project_product.FirstOrDefault(q => q.projectid == projectId && q.code == item.ProductName && q.status == (int)RowState.Valid);
                        var material = _context.siger_tr_materials.FirstOrDefault(q => q.projectId == projectId && q.pn == item.MaterialPn && q.status == (int)RowState.Valid);
                        var structure = _context.siger_project_product_structure.FirstOrDefault(q => q.projectid == projectId && q.itemid == product.id && q.itemtype == ComboxItem.Product);
                        if (product != null || material != null || structure != null)
                        {
                            //插入子级
                            _context.siger_project_product_structure.Add(new siger_project_product_structure
                            {
                                projectid = projectId,
                                parent_id = structure.id,
                                itemid = material.id,
                                itemtype = ComboxItem.Material,
                                itemcount = item.MaterialCount,
                                datetime = DateTime.Now,
                                status = (int)RowState.Valid,
                                user = userId
                            });
                            _context.SaveChanges();
                        }
                    }
                    else
                    { //物料   
                        var materialParent = _context.siger_tr_materials.FirstOrDefault(q => q.projectId == projectId && q.pn == item.ProductName && q.status == (int)RowState.Valid);
                        var material = _context.siger_tr_materials.FirstOrDefault(q => q.projectId == projectId && q.pn == item.MaterialPn && q.status == (int)RowState.Valid);
                        var structure = _context.siger_project_product_structure.FirstOrDefault(q => q.projectid == projectId && q.itemid == materialParent.id && q.itemtype == ComboxItem.Product);
                        if (structure != null)
                        {
                            //存在父级
                            _context.siger_project_product_structure.Add(new siger_project_product_structure
                            {
                                projectid = projectId,
                                parent_id = structure.id,
                                itemid = materialParent.id,
                                itemtype = ComboxItem.Material,
                                itemcount = item.MaterialCount,
                                datetime = DateTime.Now,
                                status = (int)RowState.Valid,
                                user = userId
                            });
                            _context.SaveChanges();

                        }
                        else
                        {// 先插入父级
                            var newMaterialParent = new siger_project_product_structure
                            {
                                projectid = projectId,
                                parent_id = 0,
                                itemid = materialParent.id,
                                itemtype = ComboxItem.Material,
                                itemcount = item.MaterialCount,
                                datetime = DateTime.Now,
                                status = (int)RowState.Valid,
                                user = userId
                            };
                            _context.siger_project_product_structure.Add(newMaterialParent);
                            _context.SaveChanges();
                            // 插入子级
                            _context.siger_project_product_structure.Add(new siger_project_product_structure
                            {
                                projectid = projectId,
                                parent_id = newMaterialParent.id,
                                itemid = materialParent.id,
                                itemtype = ComboxItem.Material,
                                itemcount = item.MaterialCount,
                                datetime = DateTime.Now,
                                status = (int)RowState.Valid,
                                user = userId
                            });
                            _context.SaveChanges();
                        }
                    }
                }
                return new CommonImportResult(1, "1");
            }
            catch
            {
                throw;
            }
            throw new NotImplementedException();
        }
    }
}
