using System;
using System.Linq;
using Microsoft.EntityFrameworkCore;
using Siger.Middlelayer.Common;
using Siger.Middlelayer.Common.ModuleEnum;
using Siger.Middlelayer.Repository;
using Siger.Middlelayer.Repository.Entities;
using Siger.Middlelayer.WmsRepository.Entities;

namespace Siger.Middlelayer.WmsRepository.Repositories
{
    internal abstract class WMSRepositoryBase<TEntity> : RepositoryBase<TEntity> where TEntity : WmsEntityBase
    {
        private readonly object lockObj = new object();
        private readonly ApiWmsDbContext dbContext;
        protected WMSRepositoryBase(ApiWmsDbContext context) : base(context)
        {
            dbContext = context;
        }
        
        public IQueryable<t> Paging<t>(IQueryable<t> list, int page, int pageSize)
        {
            list = list.Skip((page - 1) * pageSize).Take(pageSize);
            return list;
        }

        public string GetUserName(int userId)
        {
            var user = dbContext.siger_user.FirstOrDefault(f => f.status == (int)RowState.Valid && f.id == userId);
            return user == null ? "" : user.nickname;
        }

        public string GetBillIDs(Settings data, int projectid)
        {
            var tmp = dbContext.siger_wms_settings.FirstOrDefault(f => f.key == data.ToString() && f.projectid == projectid);
            string value = "";
            if (tmp == null)
            {
                switch (data)
                {
                    case Settings.WaveHousingPre:
                        value = "SH";
                        break;
                    case Settings.WaveHouseOutPre:
                        value = "SC";
                        break;
                    case Settings.AllocationPre:
                        value = "SC";
                        break;
                    case Settings.SystemBatchPre:
                        value = "PC";
                        break;
                    case Settings.CheckPre:
                        value = "PD";
                        break;
                    default:
                        break;
                }
            }
            else
            {
                value = tmp.value;
            }
            siger_wms_id t;
            lock (lockObj)
            {
                t = new siger_wms_id
                {
                    day = DateTime.Now,
                    type = (int)data
                };
                dbContext.siger_wms_id.Add(t);
                dbContext.SaveChanges();

                var count = dbContext.siger_wms_id.Count(f => f.day > t.day.Date && f.day <= t.day.AddDays(1).Date && f.type == Convert.ToInt32(data));
                t.code = $"{count:D6}";
                //add new
                //calc count in this day
                //gen sn by count
                dbContext.siger_wms_id.Update(t);
                dbContext.SaveChanges();
            }
            if (t != null)
            {
                var result = $"{value}{DateTime.Now.ToString("yyyyMMdd")}{t.code}";
                return result;
            }

            return string.Empty;
        }

        /// <summary>
        /// 库存汇总-增加数量
        /// </summary>
        /// <param name="storage"></param>
        /// <param name="inventoryid"></param>
        /// <param name="count"></param>
        /// <param name="projectid"></param>
        public void AddStockChange(int storage, int inventoryid, int count, int projectid)
        {
            var start = DateTime.Now.Date;
            var entity = dbContext.siger_wms_stock_change.FirstOrDefault(f => f.time >= start && f.state == (int)RowState.Valid && f.projectid == projectid && f.storageid == storage && f.inventoryid == inventoryid);
            if (entity == null)
            {
                entity = dbContext.siger_wms_stock_change.Where(f => f.state == (int)RowState.Valid && f.projectid == projectid && f.storageid == storage && f.inventoryid == inventoryid).OrderByDescending(f => f.time).FirstOrDefault();
                if (entity != null)
                {
                    var newData = new siger_wms_stock_change
                    {
                        storageid = storage,
                        inventoryid = inventoryid,
                        count = entity.count + count,
                        time = DateTime.Now,
                        projectid = projectid,
                        state = (int)RowState.Valid
                    };
                    dbContext.siger_wms_stock_change.Add(newData);
                }
                else
                {
                    entity = new siger_wms_stock_change
                    {
                        storageid = storage,
                        inventoryid = inventoryid,
                        count = count,
                        time = DateTime.Now,
                        projectid = projectid,
                        state = (int)RowState.Valid
                    };
                    dbContext.siger_wms_stock_change.Add(entity);
                }
            }
            else
            {
                entity.count += count;
                dbContext.siger_wms_stock_change.Update(entity);
            }
        }

        /// <summary>
        /// 库存汇总-减少数量
        /// </summary>
        /// <param name="storage"></param>
        /// <param name="inventoryid"></param>
        /// <param name="count"></param>
        /// <param name="projectid"></param>
        public void SubtractStockChange(int storage, int inventoryid, int count, int projectid)
        {
            var start = DateTime.Now.Date;
            var entity = dbContext.siger_wms_stock_change.FirstOrDefault(f => f.time >= start && f.state == (int)RowState.Valid && f.projectid == projectid && f.storageid == storage && f.inventoryid == inventoryid);
            if (entity == null)
            {
                int tmpCount = 0;
                entity = dbContext.siger_wms_stock_change.Where(f => f.state == (int)RowState.Valid && f.projectid == projectid && f.storageid == storage && 
                f.inventoryid == inventoryid).OrderByDescending(f=>f.time).FirstOrDefault();
                if (entity == null)
                {
                    return;
                }

                tmpCount = entity.count - count;
                if (tmpCount < 0)
                {
                    return;
                }
                entity = new siger_wms_stock_change
                {
                    storageid = storage,
                    inventoryid = inventoryid,
                    count = tmpCount,
                    time = DateTime.Now,
                    projectid = projectid,
                    state = (int)RowState.Valid
                };
                dbContext.siger_wms_stock_change.Add(entity);
            }
            else
            {
                entity.count -= count;
                if (entity.count < 0)
                {
                    return;
                }
                dbContext.siger_wms_stock_change.Update(entity);
            }
        }

        public string GetBusinessName(int businessID, int projectId)
        {
            var data = dbContext.siger_wms_bussinese_contacts.AsNoTracking().FirstOrDefault(f => f.status == (int)RowState.Valid && f.projectid == projectId && f.id == businessID);
            if (businessID == 0)
            {
                return "";
            }
            if (data == null)
            {
                return "";
            }
            return data.name;
        }

        public siger_tr_materials GetMaterial(int id, int projectid)
        {
            return dbContext.siger_tr_materials.FirstOrDefault(t => t.id == id && t.projectId == projectid && t.status == (int)RowState.Valid);
        }
    }
}
