using Admin.Core.IRepository;
using Admin.Core.IService;
using Admin.Core.Model;
using Admin.Core.Model.Model_New;
using Microsoft.IdentityModel.Logging;
using System.Collections.Generic;
using System.Linq.Expressions;
using System;
using System.Threading.Tasks;
using Admin.Core.Common;
using Microsoft.AspNetCore.Razor.TagHelpers;
using System.Linq;
using log4net;
using StackExchange.Profiling.Internal;
using Admin.Core.Model.Sys;

namespace Admin.Core.Service
{
    public class BaseSpaceInfoServices : BaseServices<BaseSpaceInfo>, IBaseSpaceInfoServices
    {
        private static readonly log4net.ILog logHelper = LogManager.GetLogger(typeof(BaseSpaceInfoServices));
        private readonly IBaseRepository<BaseSpaceInfo> _dal;
        private readonly IBaseSpaceInfoRepository _baseSpaceInfoRepository;
        public BaseSpaceInfoServices(IBaseRepository<BaseSpaceInfo> dal, IBaseSpaceInfoRepository baseSpaceInfoRepository)
        {
            this._dal = dal;
            base.BaseDal = dal;
            _baseSpaceInfoRepository = baseSpaceInfoRepository;
        }

        #region 入库通过物料类型获取指定货道,如果没有对应类型的货道返回空白类型的货道
        /// <summary>
        /// 入库通过物料类型获取指定货道,如果没有对应类型的货道返回空白类型的货道
        /// </summary>
        /// <param name="store">物料条码</param>
        /// <param name="materialType">货道类型</param>
        /// <returns>获取合适货道</returns>
        public async Task<BaseSpaceInfo> InStoreGetSpaceInfoByMaterialType(string store, string materialType)
        {
            BaseSpaceInfo spaceInfo = null;
            List<BaseSpaceInfo> spaceInfos;
            try
            {
                //Expression<Func<BaseSpaceInfo, bool>> exp = s1 => true;
                //exp = exp.And(x => x.StoreCode == store && x.MaterialType == materialType && x.SpaceStatus == 1 && x.SpaceCapacity != (x.SpaceStock + x.OnRouteAmount)); //相同型号、启用状态、库存未满的货道信息
              
                spaceInfos = await _baseSpaceInfoRepository.QueryAsync(x => x.StoreCode == store && x.MaterialType == materialType && x.SpaceStatus == 1 && x.SpaceCapacity != (x.SpaceStock + x.OnRouteAmount));
                if (spaceInfos.Count == 0) //没有指定该类型物料的货道信息,需获取空白货道信息进行分配
                    spaceInfos = await GetEmptySpaceInfo(store);

                logHelper.Info($"根据仓库{store};物料:{materialType};获取到的货道信息:{spaceInfos.ToJson()}");
                spaceInfo = InStoreFilter(spaceInfos);
                logHelper.Info($"仓库{store};物料:{materialType};匹配的入库货道信息:{spaceInfo.ToJson()}");

                spaceInfo.MaterialType = materialType; 
            }
            catch (Exception ex)
            {
                logHelper.Error("入库通过物料类型获取货道信息异常", ex);
            }
            return spaceInfo;
        } 
        #endregion

        #region 获取空货道:未分配物料型号的空白货道

        /// <summary>
        /// 获取空货道:未分配物料型号的空白货道
        /// </summary>
        /// <returns></returns>
        private async Task<List<BaseSpaceInfo>> GetEmptySpaceInfo(string storeCode)
        {
            List<BaseSpaceInfo> spaceInfos = null;
            try
            {
            //    Expression<Func<BaseSpaceInfo, bool>> exp = s1 => true;
            //    exp = exp.And(x => x.MaterialType == null && x.SpaceCapacity != x.SpaceStock);
                spaceInfos = await _dal.QueryAsync(x =>x.StoreCode== storeCode&& x.MaterialType == null && x.SpaceCapacity != x.SpaceStock);
            }
            catch (Exception ex)
            {
                logHelper.Error($"获取空货道异常:{ex}");
            }
            return spaceInfos;
        }
        #endregion

        #region 入库过滤逻辑
        /// <summary>
        /// 入库过滤逻辑
        /// </summary>
        /// <param name="spaceInfos"></param>
        private BaseSpaceInfo InStoreFilter(List<BaseSpaceInfo> spaceInfos)
        {
            BaseSpaceInfo spaceInfo = null;
            if (spaceInfos.Count > 0)
            {
                //获取库存未满库存最多的货道
                var spaceInfosList = spaceInfos.Where(x => x.SpaceCapacity != x.SpaceStock);
                spaceInfosList.OrderByDescending(x => x.SpaceStock);
                spaceInfo = spaceInfosList.FirstOrDefault();
            }
            else
            {
                logHelper.Info("入库过滤未获取到匹配的货道信息");
            }
            return spaceInfo;
        } 
        #endregion
    }
}