using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Runtime.InteropServices.ComTypes;
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.Response;
using Siger.Middlelayer.IMSRepository.Entities;
using Siger.Middlelayer.IMSRepository.Repositories.Interface;
using Siger.Middlelayer.IMSRepository.Response;

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

        public IPagedCollectionResult<ResponseGetWorkorderList> GetPagedList(int id, string workorder, int productId, string draw_code, int macineType, string route, int page, int pagesize,
            int projectId)
        {
            var querylist = from q in _context.siger_project_ims_workorder
                            join tech in _context.siger_project_ims_technology on q.technology_id equals tech.id
                            join p in _context.siger_project_product on tech.product_id equals p.id
                            join pr in _context.siger_project_product_route on tech.route_id equals pr.id
                            join mt in _context.siger_project_machine on tech.machine_type equals mt.id
                            join u in _context.siger_project_user on q.operator_id equals u.mid into temp
                            from uu in Enumerable.DefaultIfEmpty<siger_project_user>(temp)
                            where q.project_id == projectId && q.status == (int)RowState.Valid
                            select new ResponseGetWorkorderList
                            {
                                id = q.id,
                                product_id = tech.product_id,
                                product_name = p.name,
                                drawcode = tech.drawcode,
                                machine_type = tech.machine_type,
                                machineType_name = mt.title,
                                machineCode = mt.code,
                                date = q.need_time.ToString(ParameterConstant.DateFormat),
                                operator_name = uu != null ? uu.name : "",
                                order_number = q.workorder_code,
                                count = q.count,
                                order_status = (int)q.order_status,
                                route = pr.name ?? "",
                                technology_id = q.technology_id,
                                route_id = pr.id > 0 ? pr.id : 0,
                                create_name = uu.name ?? "",
                                tool_code = q.tool_code
                            };
            Expression<Func<ResponseGetWorkorderList, bool>> idExpression = q => true;
            if (id>0)
            {
                idExpression = q => q.id == id;
            }
            Expression<Func<ResponseGetWorkorderList, bool>> workorderExpression = q => true;
            if (!string.IsNullOrWhiteSpace(workorder))
            {
                workorderExpression = q => q.order_number.Contains(workorder);
            }
            Expression<Func<ResponseGetWorkorderList, bool>> productExpression = q => true;
            if (productId != 0)
            {
                productExpression = q => q.product_id == productId;
            }
            Expression<Func<ResponseGetWorkorderList, bool>> machineTypeExpression = q => true;
            if (macineType != 0)
            {
                machineTypeExpression = q => q.machine_type == macineType;
            }
            Expression<Func<ResponseGetWorkorderList, bool>> drawCodeExpression = q => true;
            if (!string.IsNullOrWhiteSpace(draw_code))
            {
                drawCodeExpression = q => q.drawcode.Contains(draw_code);
            }
            Expression<Func<ResponseGetWorkorderList, bool>> routeExpression = q => true;
            if (route.ToInt()>0)
            {
                routeExpression = q => q.route_id == route.ToInt();
            }

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

            var totalCount = querylist.Count(predicate);
            List<ResponseGetWorkorderList> entities;
            if (page == 0 || pagesize == 0)
            {
                entities = querylist.Where(predicate).OrderByDescending(t => t.id).AsNoTracking().ToList();
            }
            else
            {
                entities = querylist.Where(predicate).OrderByDescending(t => t.id).Skip((page - 1) * pagesize).Take(pagesize).AsNoTracking().ToList();
            }
            foreach (var item in entities)
            {
                var techData = _context.siger_project_ims_tech_tool.FirstOrDefault(f => f.project_id == projectId && f.status != 0 && f.technology_id == item.technology_id && f.tool_code == item.tool_code);
                if (techData != null)
                {
                    item.cutter_number = techData.cutter_number;
                    item.tool_code = techData.tool_code;
                    var toolIds = _context.ProjectIMSToolConfigEntities.Where(f => f.Projectid == projectId && f.Status != 0 && f.Code == item.tool_code).Select(s=>s.ToolId);
                    item.boom = _context.siger_project_ims_tool.Where(f => toolIds.Contains(f.id)).Select(s => new ResponseBoomData { categoryName = s.category_name, category = s.category_id.ToStr(), code = s.number, name = s.name }).AsNoTracking().ToList();
                }
            }
            return new PagedCollectionResult<ResponseGetWorkorderList>(entities, totalCount);
        }

        public List<ResponseGetWorkorderList> GetWorkorderData(int pid)
        {
            var querylist = from q in _context.siger_project_ims_workorder
                            join tech in _context.siger_project_ims_technology on q.technology_id equals tech.id
                            join p in _context.siger_project_product on tech.product_id equals p.id
                            join pr in _context.siger_project_product_route on tech.route_id equals pr.id
                            join mt in _context.siger_project_machine on tech.machine_type equals mt.id
                            join u in _context.siger_project_user on q.operator_id equals u.mid into temp
                            from uu in Enumerable.DefaultIfEmpty<siger_project_user>(temp)
                            where q.project_id == pid && q.status == (int)RowState.Valid && q.order_status!=Common.FieldEnum.OrderStatus.Completed
                            select new ResponseGetWorkorderList
                            {
                                id = q.id,
                                product_id = tech.product_id,
                                product_name = p.name,
                                drawcode = tech.drawcode,
                                machine_type = tech.machine_type,
                                machineType_name = mt.title,
                                date = q.need_time.ToString(ParameterConstant.DateFormat),
                                operator_name = uu != null ? uu.name : "",
                                order_number = q.workorder_code,
                                count = q.count,
                                order_status = (int)q.order_status,
                                route = pr.name ?? "",
                                technology_id = q.technology_id,
                                route_id = pr.id > 0 ? pr.id : 0,
                                create_name = uu.name ?? ""
                            };
            return querylist.OrderByDescending(o => o.id).AsNoTracking().ToList();
        }

        public IEnumerable<ResponseIdTitle> GetProductIdTitles(int workorder_id, int projectId)
        {
            var querylist = from q in _context.siger_project_ims_workorder
                join t in _context.siger_project_ims_technology on q.technology_id equals t.id
                join p in _context.siger_project_product on t.product_id equals p.id
                where q.status == (int) RowState.Valid && q.project_id == projectId && q.id == workorder_id
                select new ResponseIdTitle
                {
                    id = p.id,
                    title = p.name
                };
            return querylist.AsEnumerable();
        }
    }
}
