using System;
using System.Linq;
using System.Linq.Expressions;
using Microsoft.EntityFrameworkCore;
using Siger.Middlelayer.AccRepository.Entities;
using Siger.Middlelayer.AccRepository.Repositories.Interface;
using Siger.Middlelayer.Common;
using Siger.Middlelayer.Common.Helpers;
using Siger.Middlelayer.Repository.Data;
using Siger.Middlelayer.Repository.Extensions;
using Siger.Middlelayer.Repository.Paged;

namespace Siger.Middlelayer.AccRepository.Repositories
{
    internal class SigerTrWorkingOrderRepository : AccRepositoryBase<SigerTrWorkingOrder>, ISigerTrWorkingOrderRepository
    {
        private readonly ApiAccDbContext accDbContext;
        public SigerTrWorkingOrderRepository(ApiAccDbContext context) : base(context)
        {
            accDbContext = context;
        }

        public IPagedCollectionResult<WorkingOrder> GetPagedList(int lineid, string product_serial, string materials_id
            , string name, int projectid, int page, int pagesize)
        {
            var translateHelper = new TranslateHelper(GetProjectLanguage(projectid) == (int) LanguageType.EN);
            var yes = translateHelper.GetTranslateText(TranslateEnEnum.Yes);
            var no = translateHelper.GetTranslateText(TranslateEnEnum.No);
            int rowstate = (int)RowState.Valid;
            var workingOrders =
                accDbContext.siger_tr_working_order.Where(q => q.status == (int)RowState.Valid && q.projectId == projectid);
            var query = from p in workingOrders
                        join pro in accDbContext.siger_project_product
                        on p.product_serial equals pro.code
                        into protemp from pro in protemp.DefaultIfEmpty()
                        join q in accDbContext.siger_tr_materials
                        on new { materialsid = p.materials_pn, projectids = projectid, rowstatus = rowstate }
                        equals new { materialsid = q.pn, projectids = q.projectId, rowstatus = q.status }
                        into temp
                        from q in temp.DefaultIfEmpty()
                        join m in accDbContext.siger_project_level_section
                        on new { lineid = p.line, projectids = projectid, rowstatus = rowstate }
                        equals new { lineid = m.id, projectids = m.projectid, rowstatus = m.status }
                        into linetemp
                        from m in linetemp.DefaultIfEmpty()
                        join d in accDbContext.siger_tr_dict
                        on new { cate = p.category, rowstatus = rowstate, cats = AccDictCostNoProjectId.workordercategory }
                        equals new { cate = d.dkey, rowstatus = d.status, cats = d.cat }
                        into catetemp
                        from d in catetemp.DefaultIfEmpty()
                        select new WorkingOrder
                        {
                            id = p.id,
                            name = p.name,
                            line = p.line,
                            line_value = m.title,
                            product_serial = p.product_serial,
                            product_serial_value = pro.code,
                            materials_id = p.materials_id,
                            materials_id_value = q.name,
                            materials_pn = q.pn,
                            quantity = p.quantity,
                            order_no = p.order_no,
                            category = p.category,
                            category_value = d.dval,
                            is_autoserial = p.is_autoserial,
                            is_autoserial_value = p.is_autoserial == 1 ? yes : no,
                            transdatetime = UnixTimeHelper.ConvertIntDateTime(p.TransDateTime)
                        };
            Expression<Func<WorkingOrder, bool>> Funline = f => true;
            Expression<Func<WorkingOrder, bool>> Funcproductserial = f => true;
            Expression<Func<WorkingOrder, bool>> Funcmaterialsid = f => true;
            Expression<Func<WorkingOrder, bool>> Funcname = f => true;
            if (lineid > 0)
                Funline = f => f.line== lineid;
            if (!string.IsNullOrEmpty(product_serial)&&product_serial!="0")
                Funcproductserial = f => f.product_serial == product_serial;
            if (!string.IsNullOrEmpty(materials_id))
                Funcmaterialsid = f => f.materials_pn == materials_id;
            if (!string.IsNullOrEmpty(name) && name != "0")
                Funcname = f => f.name == name;
            var predicate = Funline.And(Funcproductserial).And(Funcmaterialsid).And(Funcname);

            var totalCount = query.Count(predicate);
            var entities = query.Where(predicate).OrderByDescending(q => q.id).Skip((page - 1) * pagesize).Take(pagesize).AsNoTracking().ToList();
            return new PagedCollectionResult<WorkingOrder>(entities, totalCount);
        }

        public int GetMax()
        {
            if (accDbContext.siger_tr_working_order.Count(t => t.id > 0) > 0)
            {
                return accDbContext.siger_tr_working_order.Max(t => t.id);
            }

            return 0;
        }
    }
}
