using Admin.Core.IService;
using Admin.Core.Model;
using Aucma.Scada.UI.Common;
using Aucma.Scada.UI.ViewModel;
using log4net;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Aucma.Scada.UI
{
    /// <summary>
    /// 组装计划业务逻辑
    /// </summary>
    public  class AssemblyPlanBusiness
    {
        #region 单例实现
        //private static readonly AssemblyPlanBusiness lazy = new AssemblyPlanBusiness();
        //public static AssemblyPlanBusiness Instance
        //{
        //    get
        //    {
        //        return lazy;
        //    }
        //}
        #endregion

        #region 对象引用

        private static readonly log4net.ILog logHelper = LogManager.GetLogger(typeof(AssemblyPlanBusiness));
        private AppConfig appConfig = new  AppConfig();//AppConfig.Instance;

        #endregion

        #region 接口引用
        /// <summary>
        /// 生产计划
        /// </summary>
        private IProductPlanInfoServices? _productPlanInfoService;

        /// <summary>
        /// 执行计划
        /// </summary>
        private IExecutePlanInfoServices? _executePlanInfoService;

        /// <summary>
        /// BOM信息
        /// </summary>
        private IBaseBomInfoServices? _bomInfoService;

        /// <summary>
        /// 货道明细
        /// </summary>
        private IBaseSpaceDetailServices? _spaceDetailService;
        #endregion

        #region 委托事件
        /// <summary>
        /// 刷新执行计划
        /// </summary>
        /// <param name="taskInfos"></param>
        public delegate void RefreshExecutePlanInfo(List<ExecutePlanInfo> executePlanInfos);
        public event RefreshExecutePlanInfo RefreshExecutePlanInfoEvent;

        /// <summary>
        /// 下传执行计划
        /// </summary>
        /// <param name="planInfo"></param>
        public delegate void NextPassExecutePlanInfo(ExecutePlanInfo planInfo);
        public event NextPassExecutePlanInfo NextPassExecutePlanInfoEvent;
        #endregion

        public  AssemblyPlanBusiness()
        {
            _productPlanInfoService = App.ServiceProvider.GetService<IProductPlanInfoServices>();
            _executePlanInfoService = App.ServiceProvider.GetService<IExecutePlanInfoServices>();
            _bomInfoService = App.ServiceProvider.GetService<IBaseBomInfoServices>();
            _spaceDetailService = App.ServiceProvider.GetService<IBaseSpaceDetailServices>();
        }


        /// <summary>
        /// 根据产线工位编号获取生产计划
        /// </summary>
        /// <param name="productLineCode"></param>
        /// <returns></returns>
        public async Task<List<ProductPlanInfo>> GetProductPlanInfosByProductLineCode(string orderCode)
        {
            List<ProductPlanInfo> productPlanInfos = null;
            try
            {
                productPlanInfos =await _productPlanInfoService.GetProductPlanInfosByProductLineCode(appConfig.stationCode);

                if(productPlanInfos.Count>0 )
                {
                    if(!string.IsNullOrEmpty(orderCode))
                    {
                        productPlanInfos = productPlanInfos.Where(x=>x.OrderCode.Contains(orderCode)).ToList();
                    }
                }
            }
            catch (Exception ex)
            {
                logHelper.Error("根据产线工位编号获取生产计划异常", ex);
            }
            return productPlanInfos;
        }

        /// <summary>
        /// 根据产线工位编号获取执行计划
        /// </summary>
        /// <returns></returns>
        public async Task<List<ExecutePlanInfo>> GetEexecutePlanInfosByProductLineCode()
        {
            List<ExecutePlanInfo> planInfos = null;
            try
            {
                planInfos =(await _executePlanInfoService.GetExecutePlanInfosByProductLineCode(appConfig.stationCode)).OrderBy(x => x.ExecuteOrder).ToList();
                if (planInfos != null)
                {
                    planInfos = planInfos.Where(x => x.ExecuteStatus != 3).ToList();
                    RefreshExecutePlanInfoEvent?.Invoke(planInfos);
                }
            }
            catch (Exception ex)
            {
                logHelper.Error("根据产线工位编号获取执行计划异常", ex);
            }
            return planInfos;
        }

        /// <summary>
        /// 判断库存
        /// </summary>
        /// <param name="planInfo">生产计划</param>
        /// <param name="transmitAmount">下达数量</param>
        /// <param name="materialType">BOM类型</param>
        /// <param name="storeCode"></param>
        /// <returns></returns>
        public async Task<bool> JudgmentStock(ProductPlanInfo planInfo,int transmitAmount, string materialType,string storeCode)
        {
            bool result = false;
            try
            {
                var shellBomInfo =await _bomInfoService.GetChildenBomInfoByMaterialCode(planInfo.MaterialCode, materialType);
                if(shellBomInfo != null)
                {
                    materialType = shellBomInfo.MaterialCode;

                    List<BaseSpaceDetail> spaceDetails =await _spaceDetailService.GetSpaceDetailsByMaterialTypeAsync(storeCode, materialType);

                    if (spaceDetails.Count > transmitAmount)
                    {
                        result = true;
                    }
                }
            }
            catch (Exception ex)
            {
                logHelper.Error("计划下达判断库存异常", ex);
            }
            return result;
        }

        /// <summary>
        /// 根据生产计划下达执行计划
        /// </summary>
        /// <param name="productPlanCode"></param>
        /// <param name="transmitAmount"></param>
        public async Task<bool> PlanTransmitByProductPlan(string productPlanCode, int transmitAmount)
        {
            bool result = false;
            try
            {
                var productPlanInfo =await _productPlanInfoService.GetProductPlanByPlanCode(productPlanCode);
                if (productPlanInfo != null)
                {
                    ExecutePlanInfo executePlanInfo = new ExecutePlanInfo();
                    executePlanInfo.ExecutePlanCode = System.Guid.NewGuid().ToString("N");
                    executePlanInfo.ProductPlanCode = productPlanInfo.PlanCode;
                    executePlanInfo.ProductLineCode = productPlanInfo.ProductLineCode;
                    executePlanInfo.OrderCode = productPlanInfo.OrderCode;
                    executePlanInfo.MaterialCode = productPlanInfo.MaterialCode;
                    executePlanInfo.MaterialName = productPlanInfo.MaterialName;
                    int lineCode=await _executePlanInfoService.GetExecuteOrderByProductLineCode(appConfig.stationCode);
                    executePlanInfo.ExecuteOrder = lineCode;
                    executePlanInfo.ExecuteStatus = 1;
                    executePlanInfo.PlanAmount = transmitAmount;
                    executePlanInfo.CreatedTime = DateTime.Now;
                    result =await _executePlanInfoService.InsertExecutePlanInfo(executePlanInfo);

                    if (result)
                    {
                      await  GetEexecutePlanInfosByProductLineCode();
                    }
                }
            }
            catch (Exception ex)
            {
                logHelper.Error("根据生产计划下达执行计划异常", ex);
            }
            return result;
        }

        /// <summary>
        /// 执行计划上移
        /// </summary>
        /// <param name="executePlanCode"></param>
        public async void ExecutePlanInfo_MoveUp(List<ExecutePlanInfo> executePlanInfos, string executePlanCode)
        {
            List<ExecutePlanInfo> executePlans = new List<ExecutePlanInfo>();
            if (executePlanInfos != null)
            {
                ExecutePlanInfo planInfo = executePlanInfos.Where(x => x.ExecutePlanCode == executePlanCode).First();
                int executeOrder = planInfo.ExecuteOrder;
                int planIndex = executePlanInfos.IndexOf(planInfo);
                if (planIndex != -1 && planIndex != 0)
                {
                    var lastPlanInfo = executePlanInfos[planIndex - 1];
                    planInfo.ExecuteOrder = lastPlanInfo.ExecuteOrder;
                    lastPlanInfo.ExecuteOrder = executeOrder;
                    executePlans.Add(planInfo);
                    executePlans.Add(lastPlanInfo);
                    var result =await _executePlanInfoService.UpdateRangeExecutePlanInfo(executePlans);
                    if (result)
                    {
                        GetEexecutePlanInfosByProductLineCode();
                    }
                }
            }
        }

        /// <summary>
        /// 执行计划下移
        /// </summary>
        /// <param name="executePlanCode"></param>
        public async void ExecutePlanInfo_MoveDown(List<ExecutePlanInfo> executePlanInfos, string executePlanCode)
        {
            List<ExecutePlanInfo> executePlans = new List<ExecutePlanInfo>();
            if (executePlanInfos != null)
            {
                ExecutePlanInfo planInfo = executePlanInfos.Where(x => x.ExecutePlanCode == executePlanCode).First();
                int executeOrder = planInfo.ExecuteOrder;
                int planIndex = executePlanInfos.IndexOf(planInfo);
                if (planIndex != executePlanInfos.Count - 1)
                {
                    var lastPlanInfo = executePlanInfos[planIndex + 1];
                    planInfo.ExecuteOrder = lastPlanInfo.ExecuteOrder;
                    lastPlanInfo.ExecuteOrder = executeOrder;
                    executePlans.Add(planInfo);
                    executePlans.Add(lastPlanInfo);
                    var result =await _executePlanInfoService.UpdateRangeExecutePlanInfo(executePlans);
                    if (result)
                    {
                        GetEexecutePlanInfosByProductLineCode();
                    }
                }
            }
        }

        /// <summary>
        /// 根据执行计划编号删除执行计划
        /// </summary>
        /// <param name="planCode"></param>
        /// <returns></returns>
        public async Task<bool> ExecutePlanInfo_Delete(string planCode)
        {
            bool result =await _executePlanInfoService.DeleteExecutePlanInfoByPlanCode(planCode);
            if (result)
            {
               await GetEexecutePlanInfosByProductLineCode();
            }
            return result;
        }

        /// <summary>
        /// 下传计划
        /// </summary>
        /// <param name="planCode"></param>
        public async Task<ExecutePlanInfo> ExecutePlanInfo_NextPass(string planCode, string nowPlanCode)
        {
            ExecutePlanInfo planInfo = null;
            try
            {
                List<ExecutePlanInfo> planInfos = new List<ExecutePlanInfo>();
                if (!string.IsNullOrEmpty(nowPlanCode))
                {
                    ExecutePlanInfo nowPlanInfo =await _executePlanInfoService.GetExecutePlanInfoByPlanCode(nowPlanCode);
                    if (nowPlanInfo != null)
                    {
                        nowPlanInfo.ExecuteStatus = 1;
                        planInfos.Add(nowPlanInfo);
                    }
                }

                //获取执行计划
                planInfo =await _executePlanInfoService.GetExecutePlanInfoByPlanCode(planCode);
                if (planInfo != null)
                {
                    //传给出库
                    NextPassExecutePlanInfoEvent?.Invoke(planInfo);

                    planInfo.ExecuteStatus = 2;
                    planInfo.BeginTime = DateTime.Now;
                    planInfos.Add(planInfo);
                }
                else
                {
                    logHelper.Info($"执行计划下传失败,执行计划编号:{planCode}未获取到执行计划");
                    return planInfo;
                }

                if (planInfos.Count > 0)
                {
                    var result =await _executePlanInfoService.UpdateRangeExecutePlanInfo(planInfos);
                    if (result)
                    {
                        GetEexecutePlanInfosByProductLineCode();
                    }
                }

            }
            catch (Exception ex)
            {
                logHelper.Error("计划下传异常", ex);
            }
            return planInfo;
        }

        /// <summary>
        /// 获取小时产量
        /// </summary>
        /// <returns></returns>
        public async Task<List<dynamic>> GetHourAmount()
        {
            return await _executePlanInfoService.GetStationHourAmount(appConfig.stationCode);
        }

        /// <summary>
        /// 获取物料型号统计
        /// </summary>
        /// <returns></returns>
        public async Task<List<dynamic>> GetMaterialStats()
        {
            return await _executePlanInfoService.GetStationMaterialStats(appConfig.stationCode);
        }
    }
}