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.Entities;
using Siger.Middlelayer.Repository.Extensions;
using Siger.Middlelayer.Repository.Paged;
using Siger.Middlelayer.Repository.Repositories.Interface;
using Siger.Middlelayer.Repository.Response;
using Siger.Middlelayer.Utility.ImportEntities;

namespace Siger.Middlelayer.Repository.Repositories
{
    internal class ProductRouteRepository : ApiConfigRepositoryBase<siger_project_product_route>, IProductRouteRepository
    {
        private readonly ApiConfigDbContext _context;
        public ProductRouteRepository(ApiConfigDbContext context) : base(context)
        {
            _context = context;
        }

        public IPagedCollectionResult<ResponseGetProductRoute> GetPagedRoutesList(int productId, int page, int pagesize, int projectId)
        {
            var queryList = from q in _context.siger_project_product_route
                            join p in _context.siger_project_product on q.productId equals p.id
                            join u in _context.siger_project_user on q.create_usermid equals u.mid
                            where q.projectId == projectId && q.status == (int)RowState.Valid && p.status == (int)RowState.Valid
                                  && q.projectId == projectId
                            select new ResponseGetProductRoute
                            {
                                id = q.id,
                                productid = q.productId,
                                productcode = p.code,
                                productname = p.name,
                                addtime = q.addTime,
                                sectionid = q.sectionId,
                                serialnumber = q.serialNumber,
                                name = q.name,
                                description = q.description,
                                route_code = q.route_code,
                                working_hours = q.working_hours,
                                prepare = q.prepare,
                                create_usermid = q.create_usermid,
                                create_username = u.name,
                                create_time = q.addTime.ToString(ParameterConstant.DateTimeFormat)
                            };
            Expression<Func<ResponseGetProductRoute, bool>> productnameExpression = q => true;
            if (productId != 0)
            {
                productnameExpression = q => q.productid == productId;
            }
            Expression<Func<ResponseGetProductRoute, bool>> stationExpression = q => true;

            var predicate = productnameExpression.And(stationExpression);

            var totalCount = queryList.Count(predicate);
            var entities = queryList.Where(predicate).OrderBy(q => q.serialnumber).Skip((page - 1) * pagesize).Take(pagesize).AsNoTracking().ToList();

            return new PagedCollectionResult<ResponseGetProductRoute>(entities, totalCount);
        }

        public CommonImportResult ImportRoutes(IEnumerable<RouteList> routes, int projectid, int userid)
        {
            var errors = new List<string>();
            var entities = new List<siger_project_product_route>();
            var rowIndex = 1;
            var productLists = routes.ToList();
            foreach (var route in productLists)
            {
                rowIndex++;
                var product = _context.siger_project_product.FirstOrDefault(q => q.drawingcode == route.ProductDrawCode && q.projectid == projectid
                                                                                                                    && q.status == (int)RowState.Valid);
                if (product == null)
                {
                    product = _context.siger_project_product.FirstOrDefault(q => q.code == route.ProductCode && q.projectid == projectid
                                                                                                                     && q.status == (int)RowState.Valid);
                    if (product == null)
                    {
                        errors.Add($"{rowIndex},{Convert.ToString((int)RequestEnum.ProductNotFound)}");
                    }
                }
                else
                {
                    var entity = _context.siger_project_product_route.FirstOrDefault(q => q.productId == product.id && q.projectId == projectid
                                                                                                                    && q.status == (int)RowState.Valid);
                    if (entity != null)
                    {
                        errors.Add($"{rowIndex},{Convert.ToString((int)CommonEnum.RecordExits)}");
                    }
                }

                //if (!string.IsNullOrWhiteSpace(route.MachineType))
                //{
                //    var machineType = _context.siger_project_machine_type.FirstOrDefault(q => q.title == route.MachineType && q.projectid == projectid
                //                                                                                                           && q.status == (int)RowState.Valid);
                //    if (machineType == null)
                //    {
                //        errors.Add($"{rowIndex},{Convert.ToString((int)RequestEnum.MachineChildTypeNotFound)}");
                //    }
                //}
            }

            if (errors.Any())
            {
                return new CommonImportResult(0, string.Join(";", errors));
            }

            foreach (var route in productLists)
            {
                var product = _context.siger_project_product.FirstOrDefault(q => q.code == route.ProductCode && q.projectid == projectid
                                                                                                                    && q.status == (int)RowState.Valid);
                if(product==null)
                {
                    product = _context.siger_project_product.FirstOrDefault(q => q.drawingcode == route.ProductDrawCode && q.projectid == projectid
                                                                                                                    && q.status == (int)RowState.Valid);
                }
                if (product == null)
                {
                    continue;
                }
                //var machineType = _context.siger_project_machine_type.FirstOrDefault(q => q.title == route.MachineType && q.projectid == projectid
                //                                                                                                       && q.status == (int)RowState.Valid);
                var entity = new siger_project_product_route
                {
                    name = route.RouteName,
                    serialNumber = route.RouteNumber.ToInt(),
                    addTime = DateTime.Now,
                    create_usermid = userid,
                    projectId = projectid,
                    description = route.Remark,
                    status = (int)RowState.Valid,
                    working_hours = route.Hours,
                    prepare = route.Prepare.ToDouble(),
                    machine_type = 0,
                    productId = product?.id ?? 0
                };
                entities.Add(entity);
            }
            try
            {
                _context.siger_project_product_route.AddRange(entities);
                _context.SaveChanges();
                return new CommonImportResult(1, "1");
            }
            catch
            {
                throw;
            }
        }

        public double GetLastProductRouteByName(int pid, string name)
        {
            var ret = 0d;
            var productId = _context.siger_project_product.FirstOrDefault(f => f.name == name && f.projectid == pid && f.status != 0)?.id ?? 0;
            if (productId != 0)
            {
                ret = _context.siger_project_product_route.Where(f => f.productId == productId && f.status != 0 && f.projectId == pid).OrderByDescending(o => o.serialNumber).FirstOrDefault()?.working_hours ?? 0;
            }
            return ret;
        }

        public siger_project_product_route InsertProductRouteModel(siger_project_product_route model)
        {
            Insert(model);
            _context.SaveChanges();
            return model;
        }
    }
}
