using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using Microsoft.EntityFrameworkCore;
using Siger.Middlelayer.Common;
using Siger.Middlelayer.Common.Extensions;
using Siger.Middlelayer.Repository.Data;
using Siger.Middlelayer.Repository.Extensions;
using Siger.Middlelayer.Repository.Paged;
using Siger.Middlelayer.IMSRepository.Entities;
using Siger.Middlelayer.IMSRepository.Repositories.Interface;
using Siger.Middlelayer.IMSRepository.Response;
using Siger.Middlelayer.Utility.ImportEntities;

namespace Siger.Middlelayer.IMSRepository.Repositories
{
    internal class ToolLifeTechnologyRepository : IMSRepositoryBase<siger_project_ims_technology>, IToolLifeTechnologyRepository
    {
        private readonly ApiIMSDbContext _context;
        public ToolLifeTechnologyRepository(ApiIMSDbContext context) : base(context)
        {
            _context = context;
        }

        public IPagedCollectionResult<ResponseGetTechnologys> GetPagedList(int productId, string draw_code, int macineType, int page, int pagesize,
            int toexcel, string route, int projectId)
        {
            var querylist = from q in _context.siger_project_ims_technology
                join p in _context.siger_project_product on q.product_id equals p.id
                join mt in _context.siger_project_machine on q.machine_type equals mt.id
                join u in _context.siger_project_user on q.create_id equals u.mid
                join pr in _context.siger_project_product_route on q.route_id equals pr.id
                where q.status == (int) RowState.Valid && q.project_id == projectId
                select new ResponseGetTechnologys
                {
                    program = q.program,
                    create_time = q.create_time.ToString(),
                    create_name = u.name,
                    drawcode = q.drawcode,
                    id = q.id,
                    machineType_name = mt.title,
                    product_name = p.name,
                    remark = q.remark,
                    route = pr.name ?? "",
                    product_id = q.product_id,
                    machine_type = q.machine_type,
                    create_id = q.create_id,
                    route_id = q.route_id
                };
            Expression<Func<ResponseGetTechnologys, bool>> productExpression = q => true;
            if (productId != 0)
            {
                productExpression = q => q.product_id == productId;
            }
            Expression<Func<ResponseGetTechnologys, bool>> machineTypeExpression = q => true;
            if (macineType != 0)
            {
                machineTypeExpression = q => q.machine_type == macineType;
            }
            Expression<Func<ResponseGetTechnologys, bool>> drawCodeExpression = q => true;
            if (!string.IsNullOrWhiteSpace(draw_code))
            {
                drawCodeExpression = q => q.drawcode.Contains(draw_code);
            }
            Expression<Func<ResponseGetTechnologys, bool>> routeExpression = q => true;
            if (!string.IsNullOrWhiteSpace(route))
            {
                routeExpression = q => q.route_id == route.ToInt();
            }

            var predicate = productExpression.And(machineTypeExpression).And(drawCodeExpression).And(routeExpression);

            if (toexcel == 0)
            {
                var totalCount = Queryable.Count(querylist, predicate);
                var entities = Queryable.Where(querylist, predicate).Skip((page - 1) * pagesize).Take(pagesize).AsNoTracking().ToList();
                return new PagedCollectionResult<ResponseGetTechnologys>(entities, totalCount);
            }
            else
            {
                var entities = Queryable.Where(querylist, predicate).AsNoTracking().ToList();
                return new PagedCollectionResult<ResponseGetTechnologys>(entities, 0);
            }
        }

        public IEnumerable<ResponseGetTechCondition> GetTechConditions(int productId, string draw_code, int macineType, int projectId)
        {
            var querylist = from q in _context.siger_project_ims_technology
                            join p in _context.siger_project_product on q.product_id equals p.id
                            join mt in _context.siger_project_machine on q.machine_type equals mt.id
                            where q.status == (int)RowState.Valid && q.project_id == projectId
                            select new ResponseGetTechCondition
                            {
                                drawcode = q.drawcode,
                                machineType_name = mt.title,
                                product_name = p.name,
                                product_id = q.product_id,
                                machine_type = q.machine_type,
                            };
            Expression<Func<ResponseGetTechCondition, bool>> productExpression = q => true;
            if (productId != 0)
            {
                productExpression = q => q.product_id == productId;
            }
            Expression<Func<ResponseGetTechCondition, bool>> machineTypeExpression = q => true;
            if (macineType != 0)
            {
                machineTypeExpression = q => q.machine_type == macineType;
            }
            Expression<Func<ResponseGetTechCondition, bool>> drawCodeExpression = q => true;
            if (!string.IsNullOrWhiteSpace(draw_code))
            {
                drawCodeExpression = q => q.drawcode.Contains(draw_code);
            }

            var predicate = productExpression.And(machineTypeExpression).And(drawCodeExpression);
            return Queryable.Where(querylist, predicate).AsNoTracking().ToList();
        }

        public CommonImportResult ImportTechnology(IEnumerable<TechnologyList> techs, int projectid, int userId)
        {
            var errors = new List<string>();
            var entities = new List<siger_project_ims_technology>();
            var rowIndex = 1;
            foreach (var tech in techs)
            {
                rowIndex++;
                //查询产品
                var product = _context.siger_project_product.FirstOrDefault(q =>
                    q.name == tech.ProductName && q.status == (int) RowState.Valid &&
                    q.projectid == projectid);
                if (product == null)
                {
                    errors.Add($"{rowIndex},{Convert.ToString((int)RequestEnum.ProductNotFound)}");
                }

                var route = _context.siger_project_product_route.FirstOrDefault(q =>
                    q.name == tech.Route && q.status == (int)RowState.Valid && q.projectId == projectid);
                if (route == null)
                {
                    errors.Add($"{rowIndex},{Convert.ToString((int)RequestEnum.RouteNotFound)}");
                }

                var machineType = _context.siger_project_machine.FirstOrDefault(q =>
                    q.title == tech.MachineType && q.status == (int)RowState.Valid &&
                    q.projectid == projectid);
                if (machineType == null)
                {
                    errors.Add($"{rowIndex},{Convert.ToString((int)RequestEnum.MachineNotFound)}");
                }

                var technology = Queryable.FirstOrDefault<siger_project_ims_technology>(_context.siger_project_ims_technology, q =>
                    q.product_id == product.id && q.route_id == route.id && q.status == (int)RowState.Valid
                                                && q.project_id == projectid);
                if (technology != null)
                {
                    errors.Add($"{rowIndex},{Convert.ToString((int)RequestEnum.TechnologyIsExist)}");
                }
                
                if (errors.Any())
                {
                    return new CommonImportResult(0, string.Join(";", errors));
                }
                var entity = new siger_project_ims_technology
                {
                    create_time = DateTime.Now,
                    create_id = userId,
                    drawcode = tech.DrawCode,
                    machine_type = machineType.id,
                    product_id = product.id,
                    program = tech.Program.ToStr(),
                    remark = tech.Remark.ToStr(),
                    route_id = route.id,
                    project_id = projectid
                };
                entities.Add(entity);
            }

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

        public IEnumerable<ResponseGetTechnologys> GetDataList(int productId, string route, string machineid, int projectId)
        {
            var querylist = from q in _context.siger_project_ims_technology
                            join p in _context.siger_project_product on q.product_id equals p.id
                            join mt in _context.siger_project_machine on q.machine_type equals mt.id
                            join u in _context.siger_project_user on q.create_id equals u.mid
                            join pr in _context.siger_project_product_route on q.route_id equals pr.id
                            where q.status == (int)RowState.Valid && q.project_id == projectId                               
                            select new ResponseGetTechnologys
                            {
                                program = q.program,
                                create_time = q.create_time.ToString(),
                                create_name = u.name,
                                drawcode = q.drawcode,
                                id = q.id,
                                machineType_name = mt.title,
                                product_name = p.name,
                                remark = q.remark,
                                route = pr.name ?? "",
                                product_id = q.product_id,
                                machine_type = q.machine_type,
                                create_id = q.create_id,
                                route_id = q.route_id
                            };
            Expression<Func<ResponseGetTechnologys, bool>> productExpression = q => true;
            if (productId != 0)
            {
                productExpression = q => q.product_id == productId;
            }
            Expression<Func<ResponseGetTechnologys, bool>> routeExpression = q => true;
            if (!string.IsNullOrWhiteSpace(route))
            {
                routeExpression = q => q.route_id == route.ToInt();
            }
            Expression<Func<ResponseGetTechnologys, bool>> machineExpression = q => true;
            if (!string.IsNullOrWhiteSpace(machineid))
            {
                machineExpression = q => q.machine_type == machineid.ToInt();
            }
            var predicate = productExpression.And(routeExpression).And(machineExpression);
            var entities = Queryable.Where(querylist, predicate).AsNoTracking().ToList();
            return entities;
        }
    }
}
