using HighWayIot.Log4net;
using HighWayIot.Plc;
using HighWayIot.Plc.PlcHelper;
using HighWayIot.Repository.domain;
using HighWayIot.Repository.service;
using Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Xml.Schema;
using Timer = System.Threading.Timer;

namespace HighWayIot.Winform.Business
{
    /// <summary>
    /// 排程信号业务类
    /// </summary>
    public class RecipeSendBusiness
    {
        private Timer GetSchedulingTimer;

        private RecipeSignal recipeSignal = new RecipeSignal();

        private ZxSchedulingService zxSchedulingService = ZxSchedulingService.Instance;

        private ZxRecipeParaService zxRecipeParaService = ZxRecipeParaService.Instance;

        private ZxRecipePositionParaService zxRecipePositionParaService = ZxRecipePositionParaService.Instance;

        private RecipeParaHelper recipeParaHelper = new RecipeParaHelper();

        public static int RecipeNeededVehicleNo = 0;
            
        public RecipeSendBusiness()
        {
            GetSchedulingTimer = new Timer(new System.Threading.TimerCallback(ReadSignal), null, 0, 1500);
        }

        /// <summary>
        /// 重复读取
        /// </summary>
        /// <param name="o"></param>
        public void ReadSignal(object o)
        {
            Dictionary<int, bool> a = recipeSignal.ReadSchedulingSignal();

            if (a == null)
            {
                return;
            }

            int destinationVulcanizationNo;
            var ares = a.Where(x => x.Value == true).ToList();
            if (ares.Count == 1)
            {
                destinationVulcanizationNo = ares[0].Key;
            }
            else
            {
                if(ares.Count > 1)
                {
                    LogHelper.Instance.Error($"排程信号True值不唯一 {string.Join(", " , ares.Select(x => x.Key).ToList())}");
                }
                return;
            }

            var schedulingInfo = zxSchedulingService.GetSchedulingInfo();
            string recipeNo;
            ZxRecipeParaEntity recipeParaInfo;
            List<ZxRecipePositionParaEntity> zxRecipePositionParaEntities;
            if ((destinationVulcanizationNo + 1) <= 62)
            {
                recipeNo = schedulingInfo.Single(x => x.Id == destinationVulcanizationNo + 1).RecipeCode1;
                recipeParaInfo = zxRecipeParaService.GetRecipeParaInfoByRecipeCode(recipeNo).FirstOrDefault();
                zxRecipePositionParaEntities = zxRecipePositionParaService.GetRecipePositionParaInfos(x => x.RecipeCode == recipeNo);
                if (recipeParaInfo == null)
                {
                    LogHelper.Instance.Error("配方信息获取失败");
                    return;
                }
                if (recipeParaHelper.UploadToPLC(recipeParaInfo, zxRecipePositionParaEntities))
                {
                    PlcConnect.PlcWrite2($"B{(destinationVulcanizationNo + 0x901).ToString("X")}", false, DataTypeEnum.Bool);
                    int deviceNo = schedulingInfo.Single(x => x.Id == destinationVulcanizationNo + 1).DeviceNo ?? 0;
                    //MonitorInsert(recipeNo, $"{deviceNo}上模");
                    LogHelper.Instance.Info($"配方上传成功,配方号：{recipeNo},模具号：{deviceNo}上模");
                }
                else
                {
                    LogHelper.Instance.Error("配方上传失败");
                    return;
                }
            }
            else
            {
                recipeNo = schedulingInfo.Single(x => x.Id == destinationVulcanizationNo + 1 - 62).RecipeCode2;
                recipeParaInfo = zxRecipeParaService.GetRecipeParaInfoByRecipeCode(recipeNo).FirstOrDefault();
                zxRecipePositionParaEntities = zxRecipePositionParaService.GetRecipePositionParaInfos(x => x.RecipeCode == recipeNo);
                if (recipeParaInfo == null)
                {
                    LogHelper.Instance.Error("配方信息获取失败");
                    return;
                }
                if (recipeParaHelper.UploadToPLC(recipeParaInfo, zxRecipePositionParaEntities))
                {
                    PlcConnect.PlcWrite2($"B{(destinationVulcanizationNo - 62 + 0x941).ToString("X")}", false, DataTypeEnum.Bool);
                    int deviceNo = schedulingInfo.Single(x => x.Id == destinationVulcanizationNo + 1 - 62).DeviceNo ?? 0;
                    //MonitorInsert(recipeNo, $"{deviceNo}下模");
                    LogHelper.Instance.Info($"配方上传成功,配方号：{recipeNo},模具号：{deviceNo}下模");
                }
                else
                {
                    LogHelper.Instance.Error("配方上传失败");
                    return;
                }
            }

        }

        /// <summary>
        /// 监控画面信息插入
        /// </summary>
        public void MonitorInsert(string recipeCode, string deviceNo)
        {
            ZxRecipeEntity recipeEntity = ZxRecipeService.Instance.GetRecipeInfosByRecipeCode(recipeCode).FirstOrDefault();
            if (recipeEntity == null)
            {
                return;
            }

            ZxDailyReportEntity entity = new ZxDailyReportEntity()
            {
                Uuid = Guid.NewGuid().ToString("N"),
                VulcanizationNo = deviceNo,
                StartTime = DateTime.Now,
                RecipeName = recipeEntity.RecipeName,
                RecipeCode = recipeEntity.RecipeCode,
                SpecCode = recipeEntity.RecipeSpecCode,
                DeviceNo = RecipeNeededVehicleNo,
                RawTireWeight = (int)ZxRecipeParaService.Instance.GetRecipeParaInfoByRecipeCode(recipeCode).FirstOrDefault()?.TireWeight,
                IsDone = 0
            };

            ZxDailyReportService.Instance.InsertDailyReportInfo(entity);
        }
    }
}
