using System;
using System.Linq;
using log4net;
using Admin.Core.IService;
using Admin.Core.Model;
using Admin.Core.Common;


/// <summary>
/// 泡前库入库任务逻辑处理
/// </summary>
namespace Aucma.Core.Tasks
{
    public class Job_BoxFoamInStoreTaskTask
    {
        #region 事件
        /// <summary>
        /// 扫码信息刷新
        /// </summary>
        /// <param name="materialBarCode">条码</param>
        /// <param name="materialCode">编码</param>
        /// <param name="materialName">名称</param>
        /// <param name="spaceName">货到名称</param>
        public delegate Task RefreshDataGridDelegate();
        public static event RefreshDataGridDelegate RefreshDataGridDelegateEvent;
        /// <summary>
        /// 扫码信息刷新
        /// </summary>
        /// <param name="materialBarCode">条码</param>
        /// <param name="materialCode">编码</param>
        /// <param name="materialName">名称</param>
        /// <param name="spaceName">货到名称</param>
        public delegate void RefreshScanMateriaCode(string materialBarCode, string materialCode, string materialName, string spaceName,string msg);
        public static event RefreshScanMateriaCode RefreshScanMateriaCodeEvent;
        /// <summary>
        /// 初始化入库任务
        /// </summary>
        /// <param name="message"></param>
        public delegate void RefreshInStoreTask(RealTaskInfo taskInfos);
        public static event RefreshInStoreTask RefreshInStoreTaskEvent;
        /// <summary>
        /// 日志信息刷新
        /// </summary>
        /// <param name="message"></param>
        public delegate void RefreshLogMessage(string message);
        public static event RefreshLogMessage RefreshLogMessageEvent;
        /// <summary>
        /// 入库日志事件
        /// </summary>
        /// <param name="msg"></param>
        public delegate void LogDelegate(string msg);
        public static event LogDelegate LogDelegateEvent;
   
        #endregion

        private static readonly log4net.ILog logHelper = LogManager.GetLogger(typeof(Job_BoxFoamInStoreTaskTask));
        private readonly IBaseSpaceInfoServices _baseSpaceInfoServices;
        private readonly IRealTaskInfoServices _realTaskInfoService;
        private readonly IProductPlanInfoServices _productPlanInfoServices;
        private readonly IRecordInStoreServices _recordInstoreServices;
        private readonly IBaseStoreInfoServices _baseStoreInfoServices;
        private readonly IBaseSpaceDetailServices _baseSpaceDetailServices;

        public Job_BoxFoamInStoreTaskTask(IBaseSpaceInfoServices baseSpaceInfoServices, IRealTaskInfoServices realTaskInfoService,
            IProductPlanInfoServices productPlanInfoServices, IRecordInStoreServices recordInstoreServices, 
            IBaseStoreInfoServices baseStoreInfoServices, IBaseSpaceDetailServices IBaseSpaceDetailServices)
        {
            _realTaskInfoService=realTaskInfoService;
            _baseSpaceInfoServices = baseSpaceInfoServices;
            _productPlanInfoServices = productPlanInfoServices;
            _recordInstoreServices = recordInstoreServices;
            _baseStoreInfoServices = baseStoreInfoServices;
            _baseSpaceDetailServices = IBaseSpaceDetailServices;
        }

        public async Task InStoreRun()
        {
            string storeCode = Appsettings.app("StoreInfo", "BeforeStoreCode");//泡前库code
           // await InStore(storeCode, "B20231082080029650001");
        }
        public async Task OuteRun()
        {
            string storeCode = Appsettings.app("StoreInfo", "BeforeStoreCode");//泡前库code
            await MaterialEnterStore(storeCode);
        }

        //#region 入库
        ///// <summary>
        ///// 入库
        ///// </summary>
        ///// <param name="storeCode">仓库编号</param>
        ///// <param name="materialCode">物料条码</param>
        //private async Task InStore(string storeCode, string materialBarCode)
        //{
        //    try
        //    {
        //        if (string.IsNullOrEmpty(storeCode)) return;
        //        if (string.IsNullOrEmpty(materialBarCode)) return;

        //        logHelper.Info($"扫码成功,物料条码:{materialBarCode}");
        //        var taskList = await _realTaskInfoService.QueryAsync(d => d.MaterialCode.Equals(materialBarCode) && d.StoreCode == storeCode);
        //        if (taskList.Count() >0)
        //        {
        //            LogDelegateEvent?.Invoke($"物料条码[{materialBarCode}],任务创建失败,该物料入库任务已存在!");
        //            return;
        //        }
        //        string materialType = SubString(materialBarCode);//截取中间物料条码
        //        var spaceInfo =await _baseSpaceInfoServices.InStoreGetSpaceInfoByMaterialType(storeCode, materialType);
        //        if (spaceInfo != null)
        //        {
        //            //logHelper.Info($"匹配货道:{spaceInfo.ToJson()}");
        //            var list= await _productPlanInfoServices.QueryAsync(d => d.MaterialCode == materialType);
        //            if (list.Count()==0) return;
        //            var obj = list.FirstOrDefault();
        //            var repeatList = await _recordInstoreServices.QueryAsync(d => d.BarCodeCode.Equals(materialBarCode));
        //            if (repeatList.Count() > 0)
        //            {
        //                //logHelper.Error($"任务创建记录条码重复异常:{obj.ToJson()}");
        //                LogDelegateEvent?.Invoke($"物料条码[{materialBarCode}],任务创建失败,该条码任务记录中已存在,请检查!");
        //                return;
        //            }
        //            string message = $"物料[{obj.MaterialName}], 入{spaceInfo.SpaceName},入库中....";
        //            RefreshScanMateriaCodeEvent?.Invoke(materialBarCode, obj.MaterialCode, obj.MaterialName, spaceInfo.SpaceName, message); //刷新界面扫码信息
        //            CreateInStoreTask(spaceInfo, materialBarCode); //创建入库任务
        //        }
        //        else
        //        {
        //            //报警停线
        //        }
        //    }
        //    catch (Exception ex)
        //    {
        //        logHelper.Error($"入库业务异常:{ex}");
        //    }
        //}
        //#endregion

        #region 创建入库任务
        /// <summary>
        /// 创建入库任务
        /// </summary>
        /// <param name="spaceInfo"></param>
        private async void CreateInStoreTask(BaseSpaceInfo spaceInfo, string materialCode)
        {
            try
            {
                string storeCode = Appsettings.app("StoreInfo", "StoreCode");//泡前库code
                //生成入库任务依次下发至PLC
                RealTaskInfo realTaskInfo = new RealTaskInfo();
                realTaskInfo.TaskType = 1;
                realTaskInfo.TaskCode = System.Guid.NewGuid().ToString("N").Substring(0, 6);
                realTaskInfo.SpaceName = spaceInfo.SpaceName;
                realTaskInfo.StoreCode = spaceInfo.StoreCode;
                realTaskInfo.SpaceCode = spaceInfo.SpaceCode;
                realTaskInfo.MaterialType = spaceInfo.MaterialType;
                realTaskInfo.MaterialCode = materialCode;
                realTaskInfo.PlanAmount = 1;
                realTaskInfo.TaskStatus = 1; //任务状态:1 - 待执行;2 - 执行中;3 - 完成
                realTaskInfo.CreateTime = DateTime.Now;
                var taskList = await _realTaskInfoService.QueryAsync(d => d.MaterialCode.Equals(materialCode) && d.StoreCode == storeCode);
                if (taskList.Count() > 0) return;

                int result = await _realTaskInfoService.AddAsync(realTaskInfo);
                if (result > 0)
                {
                    logHelper.Info("入库任务创建成功");
                    RefreshInStoreTaskEvent?.Invoke(realTaskInfo);//刷新datagrid 列表
                }
                else
                {
                    logHelper.Info("入库任务创建失败");
                }
            }
            catch (Exception ex)
            {
                logHelper.Info($"入库任务创建异常:{ex.Message}");
            }
        }

        #endregion

        #region 截取物料编码
        public string SubString(string barCode)
        {
            try
            {
                string materialCode = barCode.Substring(7, 10);
                return materialCode;
            }
            catch (Exception ex)
            {
                logHelper.Info($"截取物料条码失败:{ex.Message}");
                return string.Empty;
            }
        }
        #endregion

        #region PLC 任务处理表
        /// <summary>
        ///  PLC 任务处理表
        /// </summary>
        /// <param name="storeCode">仓库编码</param>
        /// <param name="materialBarCode">物料编码</param>
        /// <returns></returns>
        public async Task MaterialEnterStore(string storeCode, string materialBarCode = "B20231082080029650001")
        {
            //扫描入库信号,入库完成
            try
            {
                var taskList = await _realTaskInfoService.QueryAsync(d => d.MaterialType.Equals(materialBarCode) && d.StoreCode == storeCode);
                if (taskList.Count() == 0) return;
                var obj = taskList.FirstOrDefault();
                var mCode= materialBarCode.Substring(7, 10);//物料条码
                //删除任务表、更新货道、添加入库明细、添加入库记录
                var planInfoList = await _productPlanInfoServices.QueryAsync(d => d.MaterialCode.Equals(mCode));//计划
                if (planInfoList.Count() == 0)
                {
                    logHelper.Error($"物料计划信息为空!");
                    return;
                }
                var baseStoreInfolist = await _baseStoreInfoServices.QueryAsync(d => d.StoreCode.Equals(obj.StoreCode));//仓库
                if (baseStoreInfolist.Count() == 0)
                {
                    logHelper.Error($"仓库信息为空!");
                    return;
                }
                var baseSpacelist = await _baseSpaceInfoServices.QueryAsync(d => d.SpaceCode.Equals(obj.SpaceCode));
                if (taskList.Count() == 0)
                {
                    LogDelegateEvent?.Invoke($"物料[{materialBarCode}],入库记录条码重复异常!");
                    logHelper.Error($"货道信息为空!");
                    return;
                }
                var baseSpaceDetailList = await _baseSpaceDetailServices.QueryAsync(d => d.MaterialCode.Equals(obj.MaterialCode));//货到详情
                if (baseSpaceDetailList.Count() != 0)
                {
                    logHelper.Error($"货到信息存在重复物料!");
                    return;
                }
                var baseSpace = baseSpacelist.FirstOrDefault();
                var planInfo = planInfoList.FirstOrDefault();
                var baseStoreInfo = baseStoreInfolist.FirstOrDefault();

                baseSpace.SpaceStock = baseSpace.SpaceStock + 1;
                baseSpace.OnRouteAmount = 0;
                //入库记录表
                RecordInStore recordInstore = new RecordInStore();
                recordInstore.StoreCode = storeCode;
                recordInstore.StoreArea = baseStoreInfo.StoreArea;
                recordInstore.SpaceCode = baseSpace.SpaceCode;
                recordInstore.MaterialType = baseSpace.MaterialType;
                recordInstore.MaterialCode = mCode;
                recordInstore.InStoreTime = DateTime.Now;
                recordInstore.BarCodeCode = materialBarCode;
                recordInstore.MaterialName = planInfo.MaterialName;
                recordInstore.EntryPattern = 0;
                recordInstore.IsFlag = 0;
                recordInstore.CreatedTime = DateTime.Now;
                //入库详情表
                BaseSpaceDetail baseDetail = new BaseSpaceDetail();
                baseDetail.StoreCode= storeCode;
                baseDetail.SpaceCode= baseSpace.SpaceCode;
                baseDetail.MaterialCode = materialBarCode;
                baseDetail.MaterialName = planInfo.MaterialName;
                baseDetail.MaterialAmount = 1;
                baseDetail.CreatedTime= DateTime.Now;

                bool result = await _recordInstoreServices.SaveRecordToDb(recordInstore, obj, baseSpace, baseDetail);
                if (result)
                {
                    string message = $"物料[{planInfo.MaterialName}], 入{baseSpace.SpaceName},入库成功!";
                    RefreshScanMateriaCodeEvent?.Invoke(obj.MaterialCode, materialBarCode, planInfo.MaterialName, baseSpace.SpaceName, message); //刷新界面扫码信息
                    LogDelegateEvent?.Invoke($"物料[{planInfo.MaterialName}], 入库[{baseSpace.SpaceName}]成功!");
                    RefreshDataGridDelegateEvent?.Invoke();
                }
                else
                {
                    LogDelegateEvent?.Invoke($"物料[{planInfo.MaterialName}], 入库[{baseSpace.SpaceName}]失败,任务回滚!");
                    logHelper.Error($"物料[{planInfo.MaterialName}], 入库[{baseSpace.SpaceName}]失败,任务回滚!");
                }
            }
            catch (Exception ex)
            {
                logHelper.Error($"入库数据处理异常:{ex.Message}");
            }
        }

        #endregion
    }
}