using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using Microsoft.EntityFrameworkCore;
using Siger.Middlelayer.Common;
using Siger.Middlelayer.Common.FieldEnum;
using Siger.Middlelayer.Common.Helpers;
using Siger.Middlelayer.Common.ModuleEnum;
using Siger.Middlelayer.TlmRepository.Entities;
using Siger.Middlelayer.TlmRepository.Repositories.Interface;
using Siger.Middlelayer.TlmRepository.Response;

namespace Siger.Middlelayer.TlmRepository.Repositories
{
    internal class ToolLifeToolChoiceSummaryRepository : TlmRepositoryBase<siger_project_toollife_tool_choice_summary>,
        IToolLifeToolChoiceSummaryRepository
    {
        private readonly object _lockObj = new object();
        private readonly ApiTlmDbContext _context;

        public ToolLifeToolChoiceSummaryRepository(ApiTlmDbContext context) : base(context)
        {
            _context = context;
        }

        public IEnumerable<ResponseGetToolChoiceSummary> GetSummaryPagedList(int technologyId, int workorder_id, int projectId)
        {
            var querylist = from q in _context.siger_project_toollife_tool_choice_summary
                            join tt in _context.siger_project_toollife_tool on q.material_id equals tt.material_id
                            join m in _context.siger_tr_materials on tt.material_id equals m.id
                            join s in _context.siger_wms_stock on q.material_id equals s.material_id
                            join sl in _context.siger_wms_storage_location on s.storage_location_id equals sl.id
                            where q.technology_id == technologyId && q.workorder_id == workorder_id
                            && q.status == (int)RowState.Valid && q.project_id == projectId
                            select new ResponseGetToolChoiceSummary
                            {
                                //id = q.id,
                                part_no = tt.part_no,
                                category_id = tt.category_id,
                                material_name = m.name ?? "",
                                supplier = "",
                                quantity = q.quantity,
                                position = sl.name ?? "",
                                positionId = sl.id,
                                stock = q.quantity,
                                number = string.IsNullOrEmpty(s.serial_number) ? s.batch_number : s.serial_number,
                                material_id=m.id
                            };

            var entities = querylist.OrderBy(o => o.category_id).OrderByDescending(o => o.id).AsNoTracking().ToList();
            return entities.Distinct();
        }

        public IEnumerable<ResponseGetToolChoiceSummary> GetDataListFromTechTool(int technologyId, string cutterNumber, int projectId)
        {
            var querylist =
                from q in _context.siger_project_toollife_tech_tool
                join tech in _context.siger_project_toollife_technology on q.technology_id equals tech.id
                join m in _context.siger_tr_materials on q.material_id equals m.id
                join t in _context.siger_project_toollife_tool on q.material_id equals t.material_id
                //join c in _context.siger_project_toollife_category on t.category_id equals c.id
                //join s in _context.siger_wms_stock on q.material_id equals s.material_id into ss
                //from s in ss.DefaultIfEmpty()
                //join sl in _context.siger_wms_storage_location on s.storage_location_id equals sl.id into slsl
                //from sl in slsl.DefaultIfEmpty()
                where q.status == (int)RowState.Valid && q.project_id == projectId && q.technology_id == technologyId
                select new ResponseGetToolChoiceSummary
                {
                    tech_tool_id = q.id,
                    part_no = t.part_no,
                    material_name = m.name ?? "",
                    supplier = "",
                    quantity = q.quantity,
                    //position = sl.name ?? "",
                    material_id = m.id,
                    stock = q.quantity,
                    cutter_number = q.cutter_number
                };

            Expression<Func<ResponseGetToolChoiceSummary, bool>> cutterNumberExpression = q => true;
            if (!string.IsNullOrWhiteSpace(cutterNumber))
            {
                cutterNumberExpression = q => q.cutter_number == cutterNumber;
            }
            var entities = querylist.Where(cutterNumberExpression).GroupBy(t=>t.tech_tool_id).Select(t=>t.FirstOrDefault()).AsNoTracking().ToList();
            var ret = new List<ResponseGetToolChoiceSummary>();
            foreach (var entity in entities)
            {
                var stock = _context.siger_wms_stock.Where(f => f.projectid == projectId && f.status != 0 && f.stock_state == 0 && f.material_id == entity.material_id);
                var stockquery = from s in stock
                                 join sl in _context.siger_wms_storage_location on s.storage_location_id equals sl.id into slsl
                                 from sl in slsl.DefaultIfEmpty()
                                 select new { s.material_id, sl.name, s.quantity,sl.id,s.serial_number,s.batch_number };
                var stockList = stockquery.ToList();
                if (ret.Any(f => f.material_id == entity.material_id))
                {
                    continue;
                }
                if (stockquery.Any())
                {
                    foreach (var item in stockquery.ToList())
                    {
                        var model = Mapper<ResponseGetToolChoiceSummary, ResponseGetToolChoiceSummary>.Map(entity);
                        model.stock = item.quantity;
                        model.position = item.name;
                        model.positionId = item.id;
                        model.number = string.IsNullOrEmpty(item.serial_number) ? item.batch_number : item.serial_number;
                        ret.Add(model);
                    }
                }
                else
                {
                    var model = Mapper<ResponseGetToolChoiceSummary, ResponseGetToolChoiceSummary>.Map(entity);
                    ret.Add(model);
                }
            }
            return ret;
        }

        public int CountStockQuantity(int material_id, string part_no, int projectid, int location = 0, string no = "")
        {
            var toolData = _context.siger_project_toollife_tool.FirstOrDefault(f => f.material_id == material_id && f.project_id == projectid && f.status != 0);
            if (toolData == null)
            {
                return 0;
            }
            List<string> expect=new List<string>();
            if (toolData.need_detection == 1)
            {
                expect = _context.ProjectToollifeDetectionRecordEntities.Where(f => f.Projectid == projectid && f.Status != 0 && f.State != TlmDetectionState.InStock)
                .Select(s => s.serial_number).ToList();
            }
            var query = _context.siger_wms_stock.Where(t => (t.material_id == material_id && material_id > 0 || t.material_pn == part_no)
                && t.status == (int)RowState.Valid && t.projectid == projectid && t.stock_state == (int)StockEnum.InWavehouse
                && !expect.Contains(t.serial_number) && !expect.Contains(t.batch_number));
            if (location != 0)
            {
                query = query.Where(f => f.storage_location_id == location);
            }
            if (!string.IsNullOrEmpty(no))
            {
                query = query.Where(f => f.serial_number == no || f.batch_number == no);
            }
            return query.Sum(t => t.quantity);
        }
    }
}
