using Siger.Middlelayer.Common;
using Siger.Middlelayer.QmsRepository.Entities;
using Siger.Middlelayer.QmsRepository.Repositories.Interface;
using Siger.Middlelayer.QmsRepository.Response;
using Siger.Middlelayer.Repository.Extensions;
using Siger.Middlelayer.Repository.Paged;
using Siger.Middlelayer.Utility.ImportEntities;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;

namespace Siger.Middlelayer.QmsRepository.Repositories
{
    internal class QmsReworkSettingRepository : QMSRepositoryBase<siger_qms_rework_setting>, IQmsReworkSettingRepository
    {
        private readonly ApiQmsDbContext _context;
        public QmsReworkSettingRepository(ApiQmsDbContext context) : base(context)
        {
            _context = context;
        }

        public IEnumerable<ResponseReworkSettingData> GetAllData(int productId, int materailId, int preRoute, int route, int projectId)
        {
            Expression<Func<ResponseReworkSettingData, bool>> funproductId = f => true;
            Expression<Func<ResponseReworkSettingData, bool>> funmaterId = f => true;
            Expression<Func<ResponseReworkSettingData, bool>> funpreRoute = f => true;
            Expression<Func<ResponseReworkSettingData, bool>> funroute = f => true;


            if (productId != 0)
                funproductId = f => f.ProductId == productId;
            if (materailId != 0)
                funmaterId = f => f.MaterialId == materailId;
            if (preRoute != 0)
                funpreRoute = f => f.PreRoute == preRoute;
            if (route != 0)
                funroute = f => f.Route == route;

            var predicates = funproductId.And(funmaterId).And(funpreRoute).And(funroute);
            var query = from st in _context.siger_qms_rework_setting
                        join r in _context.siger_project_product_route on st.Route_Id equals r.id
                        join pr in _context.siger_project_product_route on st.Preroute_Id equals pr.id
                        join m in _context.siger_tr_materials on st.Material_Id equals m.id
                        join p in _context.siger_project_product on st.Product_Id equals p.id
                        where st.projectid == projectId
                        select new ResponseReworkSettingData
                        {
                            Id = st.id,
                            ProductId = st.Product_Id,
                            ProductCode = p.code,
                            ProductName = p.name,
                            MaterialId = st.Material_Id,
                            Pn = m.pn,
                            MaterialName = m.name,
                            MaterialSpec = m.spec,
                            PreRoute = st.Preroute_Id,
                            PreRouteDesc = pr.name,
                            Route = st.Route_Id,
                            RouteDesc = r.name,
                            DateTime = st.DateTime
                        };
            return query.Where(predicates).ToList();
        }

        public IEnumerable<ResponseProductRoute> GetReworkRoute(int productId, int route, int projectId)
        {
            Expression<Func<ResponseProductRoute, bool>> funproductId = f => true;
            Expression<Func<ResponseProductRoute, bool>> funpreRoute = f => true;

            var query = from s in _context.siger_qms_rework_setting
                        join r in _context.siger_project_product_route on s.Route_Id equals r.id
                        where  s.Product_Id == productId && s.projectid == projectId
                        select new ResponseProductRoute
                        {
                            Id=r.id,
                            Name=r.name,
                            ProductId=s.Product_Id,
                            PreRoute=s.Preroute_Id

                        };
            if (route!=0)
            {
                funpreRoute = f => f.PreRoute == route;
            }
            var predicates = funproductId.And(funpreRoute);
            return query.Where(predicates).ToList();
        }

        public IPagedCollectionResult<ResponseReworkSettingData> GetSettingPagedList(int productId, int materialId, int preRoute, int route, int projectId, int page, int pagesize)
        {
            Expression<Func<ResponseReworkSettingData, bool>> funproductId = f => true;
            Expression<Func<ResponseReworkSettingData, bool>> funmaterId = f => true;
            Expression<Func<ResponseReworkSettingData, bool>> funpreRoute = f => true;
            Expression<Func<ResponseReworkSettingData, bool>> funroute = f => true;
            if (productId!=0)
                funproductId = f => f.ProductId==productId;
            if (materialId != 0)
                funmaterId = f => f.MaterialId == materialId;
            if (preRoute != 0)
                funpreRoute = f => f.PreRoute == preRoute;
            if (route != 0)
                funroute = f => f.Route == route;

            var predicates = funproductId.And(funmaterId).And(funpreRoute).And(funroute);
            var query = from st in _context.siger_qms_rework_setting
                        join r in _context.siger_project_product_route on st.Route_Id equals r.id
                        join pr in _context.siger_project_product_route on st.Preroute_Id equals pr.id
                        join m in _context.siger_tr_materials on st.Material_Id equals m.id
                        join p in _context.siger_project_product on st.Product_Id equals p.id
                        where st.projectid == projectId
                        select new ResponseReworkSettingData
                        {
                            Id = st.id,
                            ProductId=st.Product_Id,
                            ProductCode = p.code,
                            ProductName = p.name,
                            MaterialId=st.Material_Id,
                            Pn = m.pn,                   
                            MaterialName = m.name,
                            MaterialSpec = m.spec, 
                            PreRoute = st.Preroute_Id,
                            PreRouteDesc = pr.name,
                            Route = st.Route_Id,
                            RouteDesc = r.name,
                            DateTime = st.DateTime
                        };
            var total = query.Count(predicates);
            var entities = query.Where(predicates).Skip((page - 1) * pagesize).Take(pagesize).ToList();

            return new PagedCollectionResult<ResponseReworkSettingData>(entities, total);
   
        }

        public CommonImportResult ImportReworkSetting(IEnumerable<ReworkSetting> standards, int projectid)
        {
            var errors = new List<string>();
            var rowIndex = 1;
       
            var reworkEntity = new List<siger_qms_rework_setting>();
            foreach (var p in standards)
            {
                rowIndex++;
                var product = _context.siger_project_product.FirstOrDefault(t => t.code == p.ProductCode && t.name==p.ProductName && t.projectid == projectid && t.status == (int)RowState.Valid);
                if (product == null)
                    errors.Add($"{rowIndex},{(int)RequestEnum.ProductCodeIsNull}");
                var material = _context.siger_tr_materials.FirstOrDefault(t => t.pn == p.Pn && t.name == p.Material && t.spec == p.MaterialSpec && t.projectId == projectid && t.status == (int)RowState.Valid);
                if (material==null)
                    errors.Add($"{rowIndex},{(int)RequestEnum.MaterialNotExist}");
                var preRouteName = _context.siger_project_product_route.FirstOrDefault(t => t.name == p.PreRoute && t.status == (int)RowState.Valid);
                if (preRouteName == null)
                    errors.Add($"{rowIndex},{(int)RequestEnum.RouteNotFound}");
                var RouteName = _context.siger_project_product_route.FirstOrDefault(t => t.name == p.Route && t.status == (int)RowState.Valid);
                if (RouteName == null)
                    errors.Add($"{rowIndex},{(int)RequestEnum.RouteNotFound}");
               
                if (!errors.Any())
                {
                    reworkEntity.Add(new siger_qms_rework_setting
                    {
                         Product_Id=product.id,
                         Material_Id=material.id,
                         Preroute_Id=preRouteName.id,
                         Route_Id=RouteName.id,
                         projectid=projectid,
                         DateTime=DateTime.Now,
                         status=(int)RowState.Valid
                    });
                }
            }
            if (errors.Any())
                return new CommonImportResult(0, string.Join(";", errors));

            try
            {
                _context.siger_qms_rework_setting.AddRange(reworkEntity);
                _context.SaveChanges();
                return new CommonImportResult(1, "1");
            }
            catch
            {
                throw;
            }
        }
    }
}
