using ICSharpCode.Core;
using Mesnac.Action.Base;
using Mesnac.Action.ChemicalWeighing.Product.PptPlan.entity;
using Mesnac.Action.ChemicalWeighing.Technical.PmtRecipe;
using Mesnac.Action.ChemicalWeighing.Technical.PmtRecipe.entity;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Mesnac.Action.ChemicalWeighing.Product.PptPlan
{
    public class PlanDownloadAction : ChemicalWeighingAction, IAction
    {
        public static event EventHandler DownloadPlan;
        private RuntimeParameter _runtime;
        private DbMCControl _clientGridControl = null;      //网格计划控件

        private string selectedPlanId = null;//选中计划号
        private string selectedPlanState = null;


        public void Run(RuntimeParameter runtime)
        {
            base.RunIni(runtime);                   //必须要调用的
            ICSharpCode.Core.LoggingService<AutoDownloadAction>.Debug("下传计划信息...");

            //获取界面控件
            DbMCControl clientGridControl = this.GetDbMCControlByKey(Mesnac.Basic.DataSourceFactory.MCDbType.Local, "Base_PlanInfo").FirstOrDefault();
            if (clientGridControl == null)
            {
                ICSharpCode.Core.LoggingService<PlanDownloadAction>.Error("{生产计划-修改计划信息}  缺少计划列表网格控件...");
                return;
            }
            this._runtime = runtime;
            this._clientGridControl = clientGridControl;
            DataGridView clientGridView = this._clientGridControl.BaseControl as DataGridView;

            if (clientGridView.SelectedRows.Count != 1)
            {
                string msg1_1 = StringParser.Parse(ResourceService.GetString("Mesnac_Action_ChemicalWeighing_Product_PptPlan_ModifyPlanNumAction_msg1_1"));          //请选择
                MessageBox.Show(msg1_1, Mesnac.Basic.LanguageHelper.Caption, MessageBoxButtons.OK, MessageBoxIcon.Information);
                this._runtime.IsReturn = true;
                return;
            }
            
            //获取选中的计划号
            this.selectedPlanId = clientGridView.SelectedRows[0].Cells["plan_Id"].Value as string;
            this.selectedPlanState = clientGridView.SelectedRows[0].Cells["plan_state"].Value as string;


            if (this.selectedPlanState != "待执行")
            {
                if (this.selectedPlanState == "已完成")
                {
                    MessageBox.Show("计划已执行完成请勿重复下传", Mesnac.Basic.LanguageHelper.Caption, MessageBoxButtons.OK, MessageBoxIcon.Information);
                    return;
                }
            }
            if (BasePlcHelper.Instance.GH_PC_ConfirmOnline.NowValue.ToInt() == 1 && BasePlcHelper.Instance.GH_PC_ConfirmRemote.NowValue.ToInt() == 1 && BasePlcHelper.Instance.GH_PC_ConfirmReady.NowValue.ToInt() == 1 && BasePlcHelper.Instance.GH_PC_ConfirmRun.NowValue.ToInt() == 0)
            //if(true)
            {
                //获取当前选中计划
                Base_PlanInfo planInfo = PlanHelper.getPlanInfoByPlanId(this.selectedPlanId);

                //调试时注释
                if (WriteRecipeInfoToPLC(planInfo))
                //if(true)
                {
                    ICSharpCode.Core.LoggingService<StopAction>.Debug("{生产计划-计划下传}  计划下传成功...");
                    planInfo.plan_State = 1;
                    planInfo.plan_beginTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
                    Product.PptPlan.PlanHelper.UpdateBasePlanStateInfo(planInfo);

                }
                else
                {
                    MessageBox.Show("计划下传失败!!!");
                }
                #region 触发事件

                if (DownloadPlan != null)
                {
                    DownloadPlan(runtime.BaseControl.MCRoot, System.EventArgs.Empty);
                }
                #endregion
            }
            else
            {
                MessageBox.Show("下位机信号未准备好!!!");
                return;
            }
            //判断下位机准备好信号,正式调试时需取消注释
            /*if (!(BasePlcHelper.Instance.GH_PC_ConfirmRemote.NowValue.ToInt() == 1 && BasePlcHelper.Instance.GH_PC_ConfirmReady.NowValue.ToInt() == 1))
            {
                MessageBox.Show("下位机未准备好!!!");
                return;
            }*/

            //获取配方编号 recipe_id
            //string reciprId = clientGridView.SelectedRows[0].Cells["recipe_id"].Value as string;

            // writeToPlc(reciprId, this.selectedPlanId);
            //判断下传是否成功

            //if (reciprId == readRecipeId())
            //{
            //    ICSharpCode.Core.LoggingService<StopAction>.Debug("{生产计划-计划下传}  计划下传成功...");
            //    //下传成功后下传RpFinished信号
            //    bool writeRpFinished = BasePlcHelper.Instance.PlcWriteByDataKey(BasePlcHelper.Instance.ChemicalWeighing_PC_RpFinished, new object[] { true });
            //}
            //else
            //{
            //    MessageBox.Show("计划下传失败!!!");
            //}

            //开启线程读取计划执行状态
            //Thread t = new Thread(readPlanState);
            //t.Start();
        }

        /// <summary>
        /// 读取PLC执行的配方编号
        /// </summary>
        /// <returns></returns>
        public string readRecipeId()
        {
            bool readResult = BasePlcHelper.Instance.PlcRead(BasePlcHelper.Instance.ChemicalWeighing_PC_RecipeCode, out int[] res);

            string readRecipeId = intArrayToStr(res);

            return readRecipeId;
        }

        /// <summary>
        /// 读取plc计划执行状态
        /// </summary>
        public void readPlanState()
        {
            while (true)
            {
                var writeResult1 = BasePlcHelper.Instance.PlcRead(BasePlcHelper.Instance.ChemicalWeighing_PC_SetCarNumber, out int[] setAmount);

                //读取完成数量,测试采用设定数量
                //bool finishAmount =  BasePlcHelper.Instance.PlcRead(BasePlcHelper.Instance.ChemicalWeighing_PC_RecipeNum, out int[] res);

                bool finishAmount = BasePlcHelper.Instance.PlcRead(BasePlcHelper.Instance.ChemicalWeighing_PC_SetCarNumber, out int[] res);

                bool planNoResult = BasePlcHelper.Instance.PlcRead(BasePlcHelper.Instance.ChemicalWeighing_PC_PlanNo, out int[] planNo);
                
                bool confirmRunResult = BasePlcHelper.Instance.PlcRead(BasePlcHelper.Instance.GH_PC_ConfirmRun, out int[] confirmRun);

                string planNoStr = intArrayToStr(planNo) == "" ? "030aabf32dbe4f4e8f9eb8bb65b59b69" : intArrayToStr(planNo);

                if (planNoStr != "")
                {
                    //根据计划编号修改计划状态、完成数量
                    Base_PlanInfo planInfo = PlanHelper.getPlanInfoByPlanId(planNoStr);
                    planInfo.real_Amount = Convert.ToInt32(intArrayToStr(res));
                    
                    if (planInfo.plan_Amount == planInfo.real_Amount)
                    {
                        planInfo.plan_State = 2;
                        PlanHelper.UpdateBasePlanInfo(planInfo);

                        //判断完成信号,正式环境需要判断完成状态
                        /*if (confirmRun[1] == 1)
                        {
                            ICSharpCode.Core.LoggingService<StopAction>.Info("{生产计划-计划下传}  计划" + planNoStr + "执行完成...");
                            //判断下一计划的运行方式
                            Base_PlanInfo nextPlanInfo = PlanHelper.getNextPlanInfoByOrder(planInfo.plan_order);

                            if (nextPlanInfo.run_Type == 0)
                            {
                                writeToPlc(nextPlanInfo.recipe_Id, nextPlanInfo.plan_Id);
                            }
                            else
                            {
                                return;
                            }
                        }*/

                        ICSharpCode.Core.LoggingService<StopAction>.Info("{生产计划-计划下传}  计划" + planNoStr + "执行完成...");
                        //判断下一计划的运行方式
                        Base_PlanInfo nextPlanInfo = PlanHelper.getNextPlanInfoByPlanOrder(planInfo.plan_order);

                        if (nextPlanInfo.run_Type == 0)
                        {
                            writeToPlc(nextPlanInfo.recipe_Id, nextPlanInfo.plan_Id);
                        }
                        else
                        {
                            return;
                        }

                    }
                    else
                    {
                        planInfo.plan_State = 1;
                        PlanHelper.UpdateBasePlanInfo(planInfo);
                    }
                }

                Thread.Sleep(1000 * 3);
            }
        }

        public static bool WriteRecipeInfoToPLC(Product.PptPlan.entity.Base_PlanInfo base_PlanInfo)
        {
            try
            {
                Base_RecipeInfo info = Technical.PmtRecipe.RecipeHelper.GetRecipeById(base_PlanInfo.recipe_Id);
                //配方编号
                var plan_Id = Convert.ToInt32(base_PlanInfo.plan_Id);

                object[] recipeidArray = Mesnac.Basic.DataProcessor.ToSiemensPLCDataArray(plan_Id);

                //计划编号
                bool resultPlanNoPlc = BasePlcHelper.Instance.PlcWriteByDataKey(BasePlcHelper.Instance.ChemicalWeighing_PC_PlanNo, recipeidArray);

                //配方编号
                bool resultFromPlc = BasePlcHelper.Instance.PlcWriteByDataKey(BasePlcHelper.Instance.ChemicalWeighing_PC_RecipeCode, new object[] { int.Parse(base_PlanInfo.recipe_Id) });
                //配方名称,测试暂用配方编号代替
                bool writeResult = BasePlcHelper.Instance.PlcWriteByDataKey(BasePlcHelper.Instance.ChemicalWeighing_PC_RecipeName, new object[] { int.Parse(base_PlanInfo.recipe_Id) });
                //设定车数
                var writeResult1 = BasePlcHelper.Instance.PlcWriteByDataKey(BasePlcHelper.Instance.ChemicalWeighing_PC_SetCarNumber, new object[] { base_PlanInfo.car_Amount });
                //格数
                var writeResult2 = BasePlcHelper.Instance.PlcWriteByDataKey(BasePlcHelper.Instance.ChemicalWeighing_PC_SetGeNumber, new object[] { base_PlanInfo.grid_Amount });

                //层数
                var writeResult3 = BasePlcHelper.Instance.PlcWriteByDataKey(BasePlcHelper.Instance.ChemicalWeighing_PC_SetLineNumber, new object[] { base_PlanInfo.line_Amount });

                //通过配方编号获取物料信息、参数信息
                List<Base_RecipeMaterial> recipeMaterials = Technical.PmtRecipe.RecipeHelper.GetRecipeMaterialInfoByRecipeId(info.recipeId);

                //罐1
                //VCC加料
                //Base_RecipeMaterial recipeMaterial = recipeMaterials.Where(x => x.materialName.Contains("VCC")).FirstOrDefault();
                Base_RecipeMaterial recipeMaterial = recipeMaterials[0];
                decimal vccJl = recipeMaterial.materialWeight;
                var writeResult9 = BasePlcHelper.Instance.PlcWriteFloatByDataKey(BasePlcHelper.Instance.ChemicalWeighing_PC_VCCJl, (float)vccJl);
                //罐2
                ////GFA加料
                //Base_RecipeMaterial recipeMaterial2 = recipeMaterials.Where(x => x.materialName.Contains("GFA")).FirstOrDefault();
                Base_RecipeMaterial recipeMaterial2 = recipeMaterials[1];
                decimal gfajl = recipeMaterial2.materialWeight;
                var writeResult10 = BasePlcHelper.Instance.PlcWriteFloatByDataKey(BasePlcHelper.Instance.ChemicalWeighing_PC_GFAJl, (float)gfajl);
                //罐3
                ////树脂加料
                //Base_RecipeMaterial recipeMaterial3 = recipeMaterials.Where(x => x.materialName.Contains("树脂")).FirstOrDefault();
                Base_RecipeMaterial recipeMaterial3 = recipeMaterials[2];
                decimal szjl = recipeMaterial3.materialWeight;
                var writeResult11 = BasePlcHelper.Instance.PlcWriteFloatByDataKey(BasePlcHelper.Instance.ChemicalWeighing_PC_SZJl, (float)szjl);

                //罐A2次加料
                Base_RecipeMaterial recipeMaterial4 = recipeMaterials[3];
                decimal vcc2th = recipeMaterial4.materialWeight;
                var writeResult20 = BasePlcHelper.Instance.PlcWriteFloatByDataKey(BasePlcHelper.Instance.ChemicalWeighing_PC_VCC_2th, (float)vcc2th);

                //罐B2次加料
                Base_RecipeMaterial recipeMaterial5 = recipeMaterials[4];
                decimal gfa2th = recipeMaterial5.materialWeight;
                var writeResult21 = BasePlcHelper.Instance.PlcWriteFloatByDataKey(BasePlcHelper.Instance.ChemicalWeighing_PC_GFA_2th, (float)gfa2th);

                //通过配方编号获取工艺参数信息
                List<Base_RecipeCratParam> recipeCratParams = Technical.PmtRecipe.RecipeHelper.GerCratParamListByRecipeAndMaterial(info.recipeId, string.Empty);

                //混料速度1
                Base_RecipeCratParam base_RecipeCratParam1 = recipeCratParams.Where(x => x.paramName.Contains("混料速度1")).FirstOrDefault();
                int hlsd1 = int.Parse(base_RecipeCratParam1.paramValue);
                var writeResult4 = BasePlcHelper.Instance.PlcWriteByDataKey(BasePlcHelper.Instance.ChemicalWeighing_PC_Hlsd1, new object[] { hlsd1 });

                //混料速度2
                Base_RecipeCratParam base_RecipeCratParam2 = recipeCratParams.Where(x => x.paramName.Contains("混料速度2")).FirstOrDefault();
                int hlsd2 = int.Parse(base_RecipeCratParam2.paramValue);
                var writeResult5 = BasePlcHelper.Instance.PlcWriteByDataKey(BasePlcHelper.Instance.ChemicalWeighing_PC_Hlsd2, new object[] { hlsd2 });

                //混料速度3
                Base_RecipeCratParam base_RecipeCratParam3 = recipeCratParams.Where(x => x.paramName.Contains("混料速度3")).FirstOrDefault();
                int hlsd3 = int.Parse(base_RecipeCratParam3.paramValue);
                var writeResult6 = BasePlcHelper.Instance.PlcWriteByDataKey(BasePlcHelper.Instance.ChemicalWeighing_PC_Hlsd3, new object[] { hlsd3 });

                //进料时间
                Base_RecipeCratParam base_RecipeCratParam4 = recipeCratParams.Where(x => x.paramName.Contains("进料时间")).FirstOrDefault();
                int jlsj = int.Parse(base_RecipeCratParam4.paramValue);
                var writeResult7 = BasePlcHelper.Instance.PlcWriteByDataKey(BasePlcHelper.Instance.ChemicalWeighing_PC_Jlsj, new object[] { jlsj });

                //混料时间
                Base_RecipeCratParam base_RecipeCratParam5 = recipeCratParams.Where(x => x.paramName.Contains("混料时间")).FirstOrDefault();
                int hlsj = int.Parse(base_RecipeCratParam5.paramValue);
                var writeResult8 = BasePlcHelper.Instance.PlcWriteByDataKey(BasePlcHelper.Instance.ChemicalWeighing_PC_Hlsj, new object[] { hlsj });

                //VCC加料误差
                Base_RecipeCratParam base_RecipeCratParam6 = recipeCratParams.Where(x => x.paramName.Contains("罐A加料误差")).FirstOrDefault();
                decimal vccjlwc = decimal.Parse(base_RecipeCratParam6.paramValue);
                var writeResult12 = BasePlcHelper.Instance.PlcWriteFloatByDataKey(BasePlcHelper.Instance.ChemicalWeighing_PC_VCCJlWc, (float)vccjlwc);

                //GFA加料误差
                Base_RecipeCratParam base_RecipeCratParam7 = recipeCratParams.Where(x => x.paramName.Contains("罐B加料误差")).FirstOrDefault();
                decimal gfajlwc = decimal.Parse(base_RecipeCratParam7.paramValue);
                var writeResult13 = BasePlcHelper.Instance.PlcWriteFloatByDataKey(BasePlcHelper.Instance.ChemicalWeighing_PC_GFAJlWc, (float)gfajlwc);

                //树脂加料误差
                Base_RecipeCratParam base_RecipeCratParam8 = recipeCratParams.Where(x => x.paramName.Contains("树脂加料误差")).FirstOrDefault();
                decimal szjlwc = decimal.Parse(base_RecipeCratParam8.paramValue);
                var writeResult14 = BasePlcHelper.Instance.PlcWriteFloatByDataKey(BasePlcHelper.Instance.ChemicalWeighing_PC_SZJlWc, (float)szjlwc);

                //配方下传完成
                bool SaveTime = BasePlcHelper.Instance.PlcRead(BasePlcHelper.Instance.ChemicalWeighing_PC_RpFinished, out int[] GH_PC_SaveTime);
                object[] flag = new object[1] {1};
                var writeResult15 = BasePlcHelper.Instance.PlcWriteByDataKey(BasePlcHelper.Instance.ChemicalWeighing_PC_RpFinished, flag);

                return true;
            }
            catch (Exception ex)
            {
                ICSharpCode.Core.LoggingService<PlanDownloadAction>.Error("{生产计划-计划下传}  计划下传失败..."+ ex);
                return false;
            }
        }

        /// <summary>
        /// 将配方数据写入PLC地址
        /// </summary>
        /// <param name="recipe">配方编号</param>
        /// <param name="planId">计划号</param>
        public void writeToPlc(string recipe,string planId)
        {
            //获取配方信息、获取工艺参数信息
            Base_RecipeInfo info = RecipeHelper.GetRecipeById(recipe);

            //通过计划编号获取选中计划
            Base_PlanInfo planInfo = PlanHelper.getPlanInfoByPlanId(planId);

            #region 下传配方参数

            //配方编号info.recipeId

            string recipeName = info.recipeName;

            var plan_Id = Convert.ToInt32(planId);

            object[] recipeidArray = Mesnac.Basic.DataProcessor.ToSiemensPLCDataArray(plan_Id);

            //计划编号
            bool resultPlanNoPlc = BasePlcHelper.Instance.PlcWriteByDataKey(BasePlcHelper.Instance.ChemicalWeighing_PC_PlanNo, new object[] { recipeidArray });

            //配方编号
            bool resultFromPlc = BasePlcHelper.Instance.PlcWriteByDataKey(BasePlcHelper.Instance.ChemicalWeighing_PC_RecipeCode, recipeidArray);

            //配方名称
            bool writeResult = BasePlcHelper.Instance.PlcWriteByDataKey(BasePlcHelper.Instance.ChemicalWeighing_PC_RecipeName, recipeName);

            //设定车数
            var writeResult1 = BasePlcHelper.Instance.PlcWriteByDataKey(BasePlcHelper.Instance.ChemicalWeighing_PC_SetCarNumber, new object[] { planInfo.car_Amount });

            //格数
            var writeResult2 = BasePlcHelper.Instance.PlcWriteByDataKey(BasePlcHelper.Instance.ChemicalWeighing_PC_SetGeNumber, new object[] { planInfo.grid_Amount });

            //层数
            var writeResult3 = BasePlcHelper.Instance.PlcWriteByDataKey(BasePlcHelper.Instance.ChemicalWeighing_PC_SetLineNumber, new object[] { planInfo.line_Amount });

            //通过配方编号获取物料信息、参数信息
            List<Base_RecipeMaterial> recipeMaterials = RecipeHelper.GetRecipeMaterialInfoByRecipeId(info.recipeId);

            //混料速度1
            var writeResult4 = BasePlcHelper.Instance.PlcWriteByDataKey(BasePlcHelper.Instance.ChemicalWeighing_PC_Hlsd1, new object[] { 18 });

            //混料速度2
            var writeResult5 = BasePlcHelper.Instance.PlcWriteByDataKey(BasePlcHelper.Instance.ChemicalWeighing_PC_Hlsd2, new object[] { 20 });

            //混料速度3
            var writeResult6 = BasePlcHelper.Instance.PlcWriteByDataKey(BasePlcHelper.Instance.ChemicalWeighing_PC_Hlsd3, new object[] { 22 });

            //进料时间
            var writeResult13 = BasePlcHelper.Instance.PlcWriteByDataKey(BasePlcHelper.Instance.ChemicalWeighing_PC_Jlsj, new object[] { 12 });

            //混料时间
            var writeResult14 = BasePlcHelper.Instance.PlcWriteByDataKey(BasePlcHelper.Instance.ChemicalWeighing_PC_Hlsj, new object[] { 17 });

            //VCC加料
            Base_RecipeMaterial recipeMaterial = recipeMaterials.Where(x => x.materialId.Contains("202205280001")).FirstOrDefault();
            decimal vccJl = recipeMaterial.materialWeight;
            var writeResult7 = BasePlcHelper.Instance.PlcWriteFloatByDataKey(BasePlcHelper.Instance.ChemicalWeighing_PC_VCCJl, (float)vccJl);

            ////VCC加料误差
            List<Base_RecipeCratParam> recipeCratParams1 = RecipeHelper.GerCratParamListByRecipeAndMaterial(info.recipeId, "202205280001");
            Base_RecipeCratParam recipeCratParam = recipeCratParams1.Where(x => x.materialId.Equals(recipeMaterial.materialId) && x.paramName.Contains("VCC加料误差")).FirstOrDefault();
            decimal vccjlwc = Convert.ToDecimal(recipeCratParam.paramValue);
            var writeResult8 = BasePlcHelper.Instance.PlcWriteFloatByDataKey(BasePlcHelper.Instance.ChemicalWeighing_PC_VCCJlWc, (float)vccjlwc);

            ////GFA加料
            Base_RecipeMaterial recipeMaterial2 = recipeMaterials.Where(x => x.materialId.Contains("202205280002")).FirstOrDefault();
            decimal gfajl = recipeMaterial2.materialWeight;
            var writeResult9 = BasePlcHelper.Instance.PlcWriteFloatByDataKey(BasePlcHelper.Instance.ChemicalWeighing_PC_GFAJl, (float)gfajl);

            ////GFA加料误差
            List<Base_RecipeCratParam> recipeCratParams2 = RecipeHelper.GerCratParamListByRecipeAndMaterial(info.recipeId, "202205280002");
            Base_RecipeCratParam recipeCratParam2 = recipeCratParams2.Where(x => x.materialId.Equals(recipeMaterial2.materialId) && x.paramName.Contains("GFA加料误差")).FirstOrDefault();
            decimal gfajlwc = Convert.ToDecimal(recipeCratParam2.paramValue);
            var writeResult10 = BasePlcHelper.Instance.PlcWriteFloatByDataKey(BasePlcHelper.Instance.ChemicalWeighing_PC_GFAJlWc, (float)gfajlwc);

            ////树脂加料
            Base_RecipeMaterial recipeMaterial3 = recipeMaterials.Where(x => x.materialId.Contains("202205280003")).FirstOrDefault();
            decimal szjl = recipeMaterial3.materialWeight;
            var writeResult11 = BasePlcHelper.Instance.PlcWriteFloatByDataKey(BasePlcHelper.Instance.ChemicalWeighing_PC_SZJl, (float)szjl);

            ////树脂加料误差
            List<Base_RecipeCratParam> recipeCratParams3 = RecipeHelper.GerCratParamListByRecipeAndMaterial(info.recipeId, "202205280003");
            Base_RecipeCratParam recipeCratParam3 = recipeCratParams3.Where(x => x.materialId.Equals(recipeMaterial3.materialId) && x.paramName.Contains("树脂加料误差")).FirstOrDefault();
            decimal szjlwc = Convert.ToDecimal(recipeCratParam3.paramValue);
            var writeResult12 = BasePlcHelper.Instance.PlcWriteFloatByDataKey(BasePlcHelper.Instance.ChemicalWeighing_PC_SZJlWc, (float)szjlwc);

            #endregion

        }

        public string intArrayToStr(int[] array)
        {
            string str = "";
            if (array.Length > 0)
            {
                for (int i = 0; i < array.Length; i++)
                {
                    if (array[i] > 0)
                    {
                        str = str + array[i];
                    }
                }
            }
            return str;
        }
    }
}