using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using Siger.Middlelayer.Common;
using Siger.Middlelayer.Common.Helpers;
using Siger.Middlelayer.Common.ModuleEnum;
using Siger.Middlelayer.Repository.Extensions;
using Siger.Middlelayer.WmsRepository.Entities;
using Siger.Middlelayer.WmsRepository.Repositories.Interface;
using Siger.Middlelayer.WmsRepository.Response;

namespace Siger.Middlelayer.WmsRepository.Repositories
{
    internal class siger_wms_stock_detailRepository : WMSRepositoryBase<siger_wms_stock_detail>, Isiger_wms_stock_detailRepository
    {
       private readonly ApiWmsDbContext dbContext;
        public siger_wms_stock_detailRepository(ApiWmsDbContext context) : base(context)
        {
            dbContext = context;
        }

        public IEnumerable<ResponseOrderDetail> GetDetails(int businessID,WaveHouseType type, int dataFilter, int wavehouseid, string billCode, int inventoryid, string originOrderNumber, DateTime start, DateTime end, int projectId, int userId, out int count, int page, int pageSize)
        {
            switch (type)
            {
                case WaveHouseType.In:
                    break;
                case WaveHouseType.Out:
                    break;
                default:
                    throw new BadRequestException(RequestEnum.ErrorWaveHouseType);
            }
            var data = dbContext.siger_wms_stock_access_order.Where(f => f.access_type == (int)type && f.status == (int)RowState.Valid && f.projectid == projectId);

            //过滤审核的数据
            if (dataFilter == 1)
            {
                data = data.Where(f => f.order_status == (int)WaveHousingState.Checked ||
                                    f.order_status == (int)WaveHousingState.WaveHousingOut ||
                                    f.order_status == (int)WaveHousingState.WaveHousing);
            }
            if (wavehouseid != 0)
                data = data.Where(f => f.storageid == wavehouseid);
            if (!string.IsNullOrEmpty(billCode))
                data = data.Where(f => f.order_number.Contains(billCode));
            if (!string.IsNullOrEmpty(originOrderNumber))
                data = data.Where(f => f.origin_order_number.Equals(originOrderNumber));
            if (start != null && start != DateTime.MinValue)
            {
                data = data.Where(f => f.update_time >= start);
            }
            if (end != null && end != DateTime.MinValue)
            {
                data = data.Where(f => f.update_time <= end);
            }

            var billid = data.Select(f => f.id).ToList();

            //料号过滤
            var details = dbContext.siger_wms_stock_access_order_detail.Where(f => f.status == (int)RowState.Valid && billid.Contains(f.orderid) && f.projectid == projectId);
            if (inventoryid != 0)
            {
                details = details.Where(f => f.material_id == inventoryid);
            }
            //供应商过滤
            if(businessID!=0)
            {
                details = details.Where(f => f.businessid == businessID);
            }

            count = details.Count();
            var tmp = details.Skip((page - 1) * pageSize).Take(pageSize).ToList();

            billid = tmp.Select(f => f.orderid).ToList();
            data = data.Where(f => billid.Contains(f.id));
            var dict = data.ToDictionary(f => f.id, f => f.order_number);
            var storageidDic = data.ToDictionary(f => f.id, f => f.storageid);

            var businessIDs = tmp.Select(f => f.businessid);
            var businessDic = dbContext.siger_wms_bussinese_contacts.Where(f => f.status == (int)RowState.Valid && f.projectid == projectId && businessIDs.Contains(f.id)).ToDictionary(f => f.id, f => f.name);
            List<ResponseOrderDetail> result = new List<ResponseOrderDetail>();
            foreach (var item in tmp)
            {
                try
                {
                    var mapData = Mapper<siger_wms_stock_access_order_detail, ResponseOrderDetail>.Map(item);
                    if (int.TryParse(mapData.manage_mode, out int mode))
                    {
                        mapData.manage_modeName = EnumHelper.GetEnumDesc((managemodel)mode);
                    }
                    try
                    {
                        mapData.billCode = dict[item.orderid];
                    }
                    catch (Exception)
                    {
                    }
                    try
                    {
                        mapData.storageid = storageidDic[item.orderid];
                    }
                    catch (Exception)
                    {
                    }
                    //返回供应商信息
                    if(mapData.businessid!=0)
                    {
                        if(businessDic.TryGetValue(mapData.businessid,out string v))
                        {
                            mapData.businessName=v;
                        }
                        else
                        {
                            mapData.businessName = "NA";
                        }
                    }
                    var billModel = dbContext.siger_wms_stock_access_order.FirstOrDefault(t => t.id == item.orderid);
                    mapData.picker = billModel?.picker ?? 0;
                    mapData.picker_name = billModel != null ? GetUserName(billModel.picker) : "";
                    result.Add(mapData);
                }
                catch
                {

                }
            }
            return result;
        }

        public IEnumerable<ResponseStockDetail> GetStockDetails(int ProjectId, string filter, SearchType type, DateTime start, DateTime end, int page, int pageSize, out int totalCount,bool paging=true)
        {
            Expression<Func<siger_wms_stock_detail, bool>> expression = f => f.state == (int)RowState.Valid && f.projectid == ProjectId;
            Expression<Func<siger_wms_stock_detail, bool>> searchExpx = f => true;
            Expression<Func<siger_wms_stock_detail, bool>> startExp = f => true;
            Expression<Func<siger_wms_stock_detail, bool>> endExp = f => true;
            if(start!=null&&start!=DateTime.MinValue)
            {
                startExp = f => f.updatetime >= start;
            }
            if (end != null && end != DateTime.MinValue)
            {
                endExp = f => f.updatetime <= end;
            }

            if (!string.IsNullOrEmpty(filter))
            {
                switch (type)
                {
                    case SearchType.BILLNUMBER:
                        searchExpx = f => f.billID == filter.Trim();
                        break;
                    case SearchType.BATCH:
                        searchExpx = f => f.batch == filter.Trim();
                        break;
                    case SearchType.INVENTORYPN:
                        searchExpx = f => f.inventorySN == filter.Trim();
                        break;
                    case SearchType.SN:
                        searchExpx = f => f.no == filter.Trim();
                        break;
                    default:
                        break;
                }
            }

            var finalExpression = expression.And(searchExpx).And(startExp).And(endExp);
            var data = GetList(finalExpression);

            totalCount = data.Count();

            if (paging)
            {
                data = data.Skip((page - 1) * pageSize).Take(pageSize);
            }
            var result = new List<ResponseStockDetail>();
            foreach (var item in data)
            {
                var tmp = Mapper<siger_wms_stock_detail, ResponseStockDetail>.Map(item);
                tmp.batch = tmp.batch?? "";
                tmp.no = tmp.no ?? "";
                tmp.locationname = tmp.locationname ?? "";
                tmp.updatetimeStr = tmp.updatetime == null || tmp.updatetime == DateTime.MinValue ? "" : tmp.updatetime.ToString(UnixTimeHelper.DateTimeFormat);
                try
                {
                    tmp.action = EnumHelper.GetEnumDesc((traceType)item.type);
                }
                catch (Exception)
                {
                    
                }
                result.Add(tmp);
                if(tmp.billID==null||string.IsNullOrEmpty(tmp.billID))
                {
                    tmp.billID = "";
                }
            }
            return result;
        }
    }
}

