using AntdUI;
using AntdUI.Svg;
using DH.Commons.Base;
using DH.Commons.Enums;
using DH.Commons.Helper;
using DH.Commons.Models;
using DH.Devices.Camera;
using DH.Devices.Motion;
using DH.Devices.PLC;
using DH.Devices.Vision;
using DH.RBAC.Model.Sys;
using DHSoftware.Languages;
using DHSoftware.Models;
using DHSoftware.Utils;
using DHSoftware.Views;
using DVPCameraType;
using HalconDotNet;
using Microsoft.VisualBasic.Logging;
using Microsoft.Win32;
using OpenCvSharp;
using SqlSugar;
using System;
using System.CodeDom;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using XKRS.UI.Device.Winform;
using static AntdUI.Math3D;
using static DH.Commons.Enums.EnumHelper;
using Button = System.Windows.Forms.Button;
using Camera = DHSoftware.Models.Camera;
using Label = AntdUI.Label;
using LogLevel = DH.Commons.Enums.EnumHelper.LogLevel;
using Point = System.Drawing.Point;
using ResultState = DH.Commons.Base.ResultState;
using Timer = System.Threading.Timer;

namespace DHSoftware
{
    public partial class MainWindow : AntdUI.Window
    {
        private Dictionary<string, List<string>> _cameraRelatedDetectionDict = null;
        public event Action<LogMsg> OnLog;

        public List<CameraSummary> CameraSummaries { get; set; } = new List<CameraSummary>();
        public List<ProductSummary> ProductSummaries = new List<ProductSummary>();
        static object _productSummaryLock = new object();
        public event Action<DateTime, object, string> OnUpdateResult;
        public event Action<DateTime, object, string> OnUpdateCamResult;

     


        public List<SysPermission> ButtonPermissionList
        {
            set
            {
                lbName.Text = DH.RBAC.Common.GlobalConfig.CurrentUser.Account;
                List<SysPermission> list = value;
                SetPermission(list, this.Controls);
            }
        }
        public  void ResetAllCameraCounts()
        {
            CameraSummaries.ForEach(camera =>
            {
                camera.OKCount = 0;
                camera.NGCount = 0;
                camera.TiggerCount = 0;
            });
        }
        private void SetPermission(List<SysPermission> list, Control.ControlCollection controls)
        {
            foreach (Control control in controls)
            {
                if (control.HasChildren)
                {
                    SetPermission(list, control.Controls);
                    continue;
                }

                if (control is AntdUI.Button button)
                {
                    HandleButtonVisibility(button, list);
                    continue;
                }
                if (control is AntdUI.Label label)
                {
                    HandleLabelVisibility(label, list);
                    continue;
                }

                if (control is AntdUI.Segmented segmented && control.Name == "segmented1")
                {
                    HandleSegmentedItems(segmented, list);
                }
            }
        }

        /// <summary>
        /// 处理 Segmented 控件的权限逻辑
        /// </summary>
        private void HandleSegmentedItems(Segmented segmented, List<SysPermission> permissions)
        {

            SysPermission permission = permissions.FirstOrDefault(p => p.EnCode == itemToHide.ID);

            bool itemExists = segmented.Items.Contains(itemToHide);

            if (permission != null)
            {

                if (!itemExists)
                {
                    segmented.Items.Insert(4, itemToHide);
                }
            }
            else
            {
                if (itemExists)
                {
                    segmented.Items.Remove(itemToHide);
                }
            }
        }

        /// <summary>
        /// 处理 Button 可见性
        /// </summary>
        private void HandleButtonVisibility(AntdUI.Button button, List<SysPermission> permissions)
        {
            if (button.Tag is string tag && !string.IsNullOrEmpty(tag))
            {
                bool hasPermission = permissions.Any(p => p.EnCode == tag);
                button.Visible = hasPermission;
            }
        }

        /// <summary>
        /// 处理 Label 可见性
        /// </summary>
        private void HandleLabelVisibility(AntdUI.Label label, List<SysPermission> permissions)
        {
            if (label.Tag is string tag && !string.IsNullOrEmpty(tag))
            {
                bool hasPermission = permissions.Any(p => p.EnCode == tag);
                label.Visible = hasPermission;
            }
        }
        public MainWindow()
        {
            InitializeComponent();
            //refreshTimer.Start();
            //初始化数据
            InitData();
            //绑定事件
            BindEventHandler();
            //UserConfigFrm userControlFrm = new UserConfigFrm();

            //userControlFrm.Window = this;
            //userControlFrm.Dock = DockStyle.Fill;
            //tabPage2.Controls.Add(userControlFrm);
        }
        //#region OEE
        // public event Action<RunState> OnProcessRunStateChanged;
        #region INotifyPropertyChanged
        public event PropertyChangedEventHandler PropertyChanged;
        public virtual void Set<T>(ref T field, T newValue, [CallerMemberName] string propName = null)
        {
            if (!field.Equals(newValue))
            {
                field = newValue;
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propName));
            }
        }
        #endregion
        #region Properties
        private int uph = 0;
        private int upm = 0;

        private DateTime? startTime = null;
        private TimeSpan runTime = new TimeSpan();
        private TimeSpan idleTime = new TimeSpan();
        private TimeSpan downTime = new TimeSpan();
        private TimeSpan totalTime = new TimeSpan();
        private int qty_OEE = 0;
        private int qty_OEE_OK = 0;
        private float oee = 0;

        public int UPH
        {
            get => uph;
            set => Set(ref uph, value);
        }
        public int UPM
        {
            get => upm;
            set => Set(ref upm, value);
        }
        public DateTime? StartTime
        {
            get => startTime;
            set => Set(ref startTime, value);
        }

        /// <summary>
        /// 有效运行时间
        /// </summary>
        public TimeSpan RunTime
        {
            get => runTime;
            set => Set(ref runTime, value);
        }

        /// <summary>
        /// 空闲待机时间
        /// </summary>
        public TimeSpan IdleTime
        {
            get => idleTime;
            set => Set(ref idleTime, value);
        }

        /// <summary>
        /// 故障宕机时间
        /// </summary>
        public TimeSpan DownTime
        {
            get => downTime;
            set => Set(ref downTime, value);
        }

        /// <summary>
        /// 总开机时间
        /// </summary>
        public TimeSpan TotalTime
        {
            get => totalTime;
            set => Set(ref totalTime, value);
        }

        public float OEE
        {
            get => oee;
            set => Set(ref oee, value);
        }
        #endregion
        #region Timer
        System.Threading.Timer _runTimer = null;
        System.Threading.Timer _idleTimer = null;
        System.Threading.Timer _downTimer = null;
        System.Threading.Timer _checkIdleTimer = null;
        //System.Threading.Timer _calculateTimer = null;

        private RunState? currentState = null;
        public RunState? CurrentState
        {
            get => currentState;
            set
            {
                if (value != null)
                {
                    if (value.Value == RunState.Running)
                    {
                        _checkIdleTimer?.Change(10 * 1000, -1);
                    }

                    if (currentState != value.Value)
                    {
                        switch (currentState)
                        {
                            case RunState.Idle:
                                //AddRunEventInBuffer(DateTime.Now, RunEvent_EventType.Idle, false);
                                break;
                            case RunState.Down:
                                //AddRunEventInBuffer(DateTime.Now, RunEvent_EventType.Down, false);
                                break;
                        }

                        switch (value.Value)
                        {
                            case RunState.Stop:
                                _runTimer?.Change(-1, -1);
                                _idleTimer?.Change(-1, -1);
                                _downTimer?.Change(-1, -1);
                                break;
                            case RunState.Running:
                                _idleTimer?.Change(-1, -1);
                                _downTimer?.Change(-1, -1);
                                _runTimer?.Change(0, 1000);
                                break;
                            case RunState.Idle:
                                _runTimer?.Change(-1, -1);
                                _downTimer?.Change(-1, -1);
                                _idleTimer?.Change(0, 1000);

                                //AddRunEventInBuffer(DateTime.Now, RunEvent_EventType.Idle, true);
                                break;
                            case RunState.Down:
                                _idleTimer?.Change(-1, -1);
                                _runTimer?.Change(-1, -1);
                                _downTimer?.Change(0, 1000);

                                //AddRunEventInBuffer(DateTime.Now, RunEvent_EventType.Down, true);
                                break;
                        }

                        currentState = value;


                    }
                }
            }
        }

        private void CheckIdleTimeStart(object state)
        {
            if (CurrentState == RunState.Running)
            {
                RunTime = RunTime.Add(new TimeSpan(0, 0, 0 - 10));
                IdleTime = IdleTime.Add(new TimeSpan(0, 0, 10));

                CurrentState = RunState.Idle;
            }
        }

        public void InitialOEEStatistic()
        {
            InitialStatisticTimers();
            ResetOEETimeDistribute();
            ResetProductSummaries();
        }

        public void ResetProductSummaries()
        {
            ProductSummaries = new List<ProductSummary>();
        }
        private void InitialStatisticTimers()
        {
            if (_checkIdleTimer == null)
            {
                _checkIdleTimer = new Timer(new TimerCallback(CheckIdleTimeStart), null, -1, -1);
            }

            if (_runTimer == null)
            {
                _runTimer = new System.Threading.Timer(RunTimerCallBack, null, -1, -1);
            }

            if (_idleTimer == null)
            {
                _idleTimer = new System.Threading.Timer(IdleTimerCallBack, null, -1, -1);
            }

            if (_downTimer == null)
            {
                _downTimer = new System.Threading.Timer(DownTimerCallBack, null, -1, -1);
            }

            StartTime = DateTime.Now;
            DownTime = IdleTime = RunTime = new TimeSpan(0, 0, 0);
            CurrentState = RunState.Running;
        }

        private void DownTimerCallBack(object state)
        {
            DownTime = DownTime.Add(new TimeSpan(0, 0, 1));
            GetTotalTime();
        }

        private void IdleTimerCallBack(object state)
        {
            IdleTime = IdleTime.Add(new TimeSpan(0, 0, 1));
            GetTotalTime();
        }

        private void RunTimerCallBack(object state)
        {
            RunTime = RunTime.Add(new TimeSpan(0, 0, 1));
            GetTotalTime();
        }

        private void GetTotalTime()
        {
            TotalTime = RunTime + IdleTime + DownTime;
        }

        public void ResetOEETimeDistribute()
        {
            StartTime = DateTime.Now;
            DownTime = IdleTime = RunTime = new TimeSpan(0, 0, 0);

            ProductNum_Total = ProductNum_OK = 0;
        }

        public void CloseStatisticTimers()
        {
            CloseTimer(ref _checkIdleTimer);
            CloseTimer(ref _runTimer);
            CloseTimer(ref _idleTimer);
            CloseTimer(ref _downTimer);

            CurrentState = RunState.Stop;
        }

        private void CloseTimer(ref System.Threading.Timer timer)
        {
            timer?.Change(-1, -1);
            timer?.Dispose();
            timer = null;
        }
        #endregion

        #region CameraSum
        private void InitialCameraSumsView()
        {



            dgvCamreaNums.Columns.Clear();

            // 添加 CCD 列
            dgvCamreaNums.Columns.Add(new DataGridViewTextBoxColumn
            {
                HeaderText = "CCD",
                DataPropertyName = "CameraName"
            });
            // 添加 触发数 列
            var TiggerCountColumn = new DataGridViewTextBoxColumn
            {
                HeaderText = "触发数",
                DataPropertyName = "TiggerCount"
            };

            dgvCamreaNums.Columns.Add(TiggerCountColumn);

            // 添加 合格 列
            var okColumn = new DataGridViewTextBoxColumn
            {
                HeaderText = "合格",
                DataPropertyName = "OKCount"
            };
            okColumn.DefaultCellStyle.ForeColor = Color.Green; // 设置背景为绿色
            dgvCamreaNums.Columns.Add(okColumn);

            // 添加 不合格 列
            var ngColumn = new DataGridViewTextBoxColumn
            {
                HeaderText = "不合格",
                DataPropertyName = "NGCount"
            };
            ngColumn.DefaultCellStyle.ForeColor = Color.LightCoral; // 设置背景为红色
            dgvCamreaNums.Columns.Add(ngColumn);

            // 添加 总数 列
            dgvCamreaNums.Columns.Add(new DataGridViewTextBoxColumn
            {
                HeaderText = "总数",
                DataPropertyName = "TotalCount"

            });

            // 添加 良率 列
            dgvCamreaNums.Columns.Add(new DataGridViewTextBoxColumn
            {
                HeaderText = "良率",
                DataPropertyName = "YieldStr"
            });
            dgvCamreaNums.AutoGenerateColumns = false;
            dgvCamreaNums.DataSource = new BindingList<CameraSummary>(CameraSummaries);
        }
        #endregion

        /// <summary>
        /// 窗体对象实例
        /// </summary>
        private static MainWindow _instance;

        internal static MainWindow Instance
        {
            get
            {
                if (_instance == null)
                    _instance = new MainWindow();
                return _instance;
            }
        }

        private SegmentedItem itemToHide;

        private void InitData()
        {
            itemToHide = segmented1.Items[4];
            segmented1.Items.Remove(itemToHide);
        }

  

        public void ConnectCamera()
        {
            Cameras.Clear();
            HKCameras.Clear();
            if (ConfigModel.CameraBaseList.Count > 0)
            {
                for (int i = 0; i < ConfigModel.CameraBaseList.Count; i++)
                {
                    var cameraBase = ConfigModel.CameraBaseList[i];
                    if (cameraBase.CamType == EnumCamType.度申Do3think)
                    {


                        Do3ThinkCamera cam = new Do3ThinkCamera();
                        cam.IsSavePicEnabled = cameraBase.IsSavePicEnabled;
                        cam.CameraName = cameraBase.CameraName;
                        cam.CameraIP = cameraBase.CameraIP;
                        cam.IsEnabled = cameraBase.IsEnabled;
                        cam.IsZoomCamera = cameraBase.IsZoomCamera;
                        cam.Exposure = cameraBase.Exposure;
                        cam.Gain = cameraBase.Gain;
                        cam.RotateImage = cameraBase.RotateImage;
                        cam.IsAllPicEnabled=cameraBase.IsAllPicEnabled;
                        cam.ROIX= cameraBase.ROIX;
                        cam.ROIH= cameraBase.ROIH;
                        cam.ROIW= cameraBase.ROIW;
                        cam.ROIY=cameraBase.ROIY;
                        cam.ImageSaveDirectory = Path.Combine("D://Projects", cameraBase.CameraName);
                        Cameras.Add(cam);
                        if (cameraBase.IsEnabled)
                        {
                            cam.OnLog -= _visionEngine_OnLog;
                            cam.OnLog += _visionEngine_OnLog;
                            cam.OnHImageOutput += OnCameraHImageOutput;
                           
                            Button CamLabel = new Button();
                            CamLabel.Name = cameraBase.CameraName;
                            CamLabel.Text = cameraBase.CameraName; // 关键1:必须有文本
                            CamLabel.AutoSize = true;
                            CamLabel.Size = new System.Drawing.Size(20, 20); // 关键2:自动调整大小
                            CamLabel.Location = new Point(20 + 50 * i, 12); // 关键3:明确位置
                            if (cam.CameraConnect())
                                CamLabel.BackColor = Color.Green;  // 关键4:避免透明
                            else
                                CamLabel.BackColor = Color.Yellow;  // 关键4:避免透明
                            CamLabel.ForeColor = Color.Black;  // 关键4:避免透明
                            CamLabel.Font = new Font("Microsoft YaHei", 9); // 可选:字体

                            // 关键5:确保添加到父控件
                            if (pageHeader1 != null && !pageHeader1.Controls.Contains(CamLabel))
                            {
                                pageHeader1.Controls.Add(CamLabel);
                            }

                        }

                    }
                    else if (cameraBase.CamType == EnumCamType.海康hik)
                    {
                        HikVisionCamera cam = new HikVisionCamera();
                        cam.CameraName = cameraBase.CameraName;
                        cam.CameraIP = cameraBase.CameraIP;
                        cam.IsEnabled = cameraBase.IsEnabled;
                        HKCameras.Add(cam);
                        // cam.CameraConnect();
                        //cam.OnHImageOutput += OnCameraHImageOutput;
                    }
                }
            }
        }
       
        public void ConnectPLC()
        {
            try
            {
                if (ConfigModel.PLCBaseList.Count > 0)
                {
                    for (int i = 0; i < ConfigModel.PLCBaseList.Count; i++)
                    {
                        var plcBase = ConfigModel.PLCBaseList[i];
                        if (plcBase.PLCType == EnumPLCType.信捷XC网口 || plcBase.PLCType == EnumPLCType.信捷XD网口)
                        {
                            PLC.IP = plcBase.IP;
                            PLC.PLCType = plcBase.PLCType;
                            PLC.Enable = plcBase.Enable;
                            PLC.PLCName = plcBase.PLCName;
                            PLC.PLCItemList = plcBase.PLCItemList;
                            PLC.Port = plcBase.Port;
                            PLC.OnLog -= _visionEngine_OnLog;
                            PLC.OnLog += _visionEngine_OnLog;
                            if (PLC.Enable)
                            {
                                PLC.PLCConnect();
                                Button CamLabel = new Button();
                                CamLabel.Name = PLC.PLCName;
                                CamLabel.Text = PLC.PLCName; // 关键1:必须有文本
                                CamLabel.AutoSize = true;
                                CamLabel.Size = new System.Drawing.Size(20, 20); // 关键2:自动调整大小
                                CamLabel.Location = new Point(20 + 50 * (i + ConfigModel.CameraBaseList.Count), 12); // 关键3:明确位置
                                if (PLC.Connected)
                                    CamLabel.BackColor = Color.Green;  // 关键4:避免透明
                                else
                                    CamLabel.BackColor = Color.Yellow;  // 关键4:避免透明
                                CamLabel.ForeColor = Color.Black;  // 关键4:避免透明
                                                                   //CamLabel.ForeColor = Color.Green;  // 关键4:避免透明
                                CamLabel.Font = new Font("Microsoft YaHei", 9); // 可选:字体

                                // 关键5:确保添加到父控件
                                if (pageHeader1 != null && !pageHeader1.Controls.Contains(CamLabel))
                                {
                                    pageHeader1.Controls.Add(CamLabel);
                                }

                            }

                        }
                    }

                }
            }
            catch (Exception ex) 
            {
            
            }
        }
        FrmLog frmLog;
        public void InitModel()
        {
            Dectection.Clear();
            _cameraRelatedDetectionDict = new();

            if (ConfigModel.DetectionList.Count > 0)
            {
                for (int i = 0; i < ConfigModel.DetectionList.Count; i++)
                {
                    DetectionConfig detectionConfig = ConfigModel.DetectionList[i];
                    var detection = ConfigModel.DetectionList[i];
                    detectionConfig.CameraCollects = detection.CameraCollects;
                    detectionConfig.ModelconfThreshold = detection.ModelconfThreshold;
                    detectionConfig.ModelWidth = detection.ModelWidth;
                    detectionConfig.ModelHeight = detection.ModelHeight;
                    detectionConfig.In_lable_path = detection.In_lable_path;
                    detectionConfig.IsEnabled = detection.IsEnabled;
                    detectionConfig.ImageSaveDirectory = "D://Projects//Images";

                    detectionConfig.ShowLocation.X = (i + 1) % 5 + (i + 1) / 5;
                    //  detectionConfig.ShowLocation.X = detection.ShowLocation.X;
                    detectionConfig.ShowLocation.Y = (i + 1) / 5 + 1;
                    // detectionConfig.ShowLocation.Y = detection.ShowLocation.Y;
                    DetectionConfigs.Add(detectionConfig);
                }
            }
            DetectionConfigs.ForEach(detection =>
            {
                detection.CameraCollects.ForEach(cam =>
                {
                    List<string> Dets = new List<string>
                   {
                        detection.Id
                   };
                    if (!_cameraRelatedDetectionDict.ContainsKey(cam.CameraSourceId))
                    {
                        _cameraRelatedDetectionDict.Add(cam.CameraSourceId, Dets);
                    }
                    else
                    {
                        _cameraRelatedDetectionDict[cam.CameraSourceId].Add(detection.Id);
                    }
                }
               );
            });
            string inferenceDevice = "CPU";

            frmLog = new FrmLog();
            frmLog.Dock = DockStyle.Fill;
            pnlLog.Controls.Add(frmLog);
            //
            _visionEngine = new SimboVisionDriver();
            _visionEngine.DetectionConfigs = DetectionConfigs;
            _visionEngine.LoggerHelper.LogPath = "D://PROJECTS//Logs//";
            _visionEngine.LoggerHelper.LogPrefix = "Vision";
            _visionEngine.OnLog += _visionEngine_OnLog;
            //初始化模型 加载模型
            _visionEngine.Init();

            CtrlVisionRunBase ctrlVisionRun = new CtrlVisionRunBase(_visionEngine);
            ctrlVisionRun.Dock = DockStyle.Fill;
            tabImgDisplay.Controls.Add(ctrlVisionRun);

        }

        private void _visionEngine_OnLog(LogMsg msg)
        {
            //OnLog?.Invoke(msg);
            LogDisplay(msg);
        }
        private void LogDisplay(LogMsg msg)
        {

            //frmLog?.LogDisplay(msg);
            frmLog?.AddLog(msg);
        }
        public LoggerHelper LoggerHelper { get; set; } = new LoggerHelper();
        public virtual void LogAsync(LogMsg msg)
        {
            //if (IConfig != null)
            //{
            //    LoggerHelper.SetLogLevel(IConfig.DefaultLogLevel);
            //}
            //else
            //{
            //    LoggerHelper.SetLogLevel(LogLevel.Assist);
            //}

            msg.ThreadId = Thread.CurrentThread.ManagedThreadId;

            OnLog?.Invoke(msg);
            //if (IConfig?.IsLogEnabled ?? true)
            //{
            LoggerHelper.LogAsync(msg);
            //}
        }
        public virtual void LogAsync(DateTime dt, LogLevel logLevel, string msg)
        {
            LogAsync(new LogMsg(dt, logLevel, msg));

        }
        System.Windows.Forms.Timer _refreshUITimer = new System.Windows.Forms.Timer();
        private void BindEventHandler()
        {
            btnAddProject.Click += BtnAddProject_Click;
            btnDeleteProject.Click += BtnDeleteProject_Click;
            btnLoadProject.Click += BtnLoadProject_Click;
            LoggerHelper.LogPath = "D://PROJECTS//Logs//";
            LoggerHelper.LogPrefix = "Process";
            OnLog -= LogDisplay;
            OnLog += LogDisplay;
            OnUpdateCamResult -= UpdateCamResult;

            OnUpdateCamResult += UpdateCamResult;
            OnUpdateResult -= UpdateResult;
            OnUpdateResult += UpdateResult;
            Load += (s, e) =>
            {
                _refreshUITimer.Interval = 1000;
                _refreshUITimer.Tick += _refreshUITimer_Tick;
                _refreshUITimer.Enabled = true;
            };
            lbInBackend.Click += LbInBackend_Click;
        }

        private void LbInBackend_Click(object? sender, EventArgs e)
        {
            DH.RBAC.RBACWindow.Instance.Show();


        }
        private void _refreshUITimer_Tick(object sender, EventArgs e)
        {
            _refreshUITimer.Enabled = false;

            if (this != null)
            {
                lblStartTime.Text = StartTime == null ? "" : StartTime.Value.ToString("yyyy/MM/dd HH:mm:ss");
                lblTotalTime.Text = TotalTime.ToString(); // 运行时间
                                                          //  lblRunTime.Text = RunTime.ToString(); // 有效时间
                                                          //  lblIdleTime.Text = ProcessControl.IdleTime.ToString(); // 空闲时间
                                                          //  lblDownTime.Text = ProcessControl.DownTime.ToString(); // 宕机时间

                lblOEE_Total.Text = ProductNum_Total.ToString();
                //  lblOEE_OK.Text = ProcessControl.ProductNum_OK.ToString();
            }

            _refreshUITimer.Enabled = true;
        }
        private void UpdateCamResult(DateTime updateTime, object objData, string customMessage)
        {
            this.Invoke(new Action(() =>
            {

                BindingList<CameraSummary> cameraSummaries = new BindingList<CameraSummary>(CameraSummaries);
                dgvCamreaNums.DataSource = cameraSummaries;

            }));

        }
        private void UpdateResult(DateTime updateTime, object objData, string result)
        {
            this.Invoke(new Action(() =>
            {

             

                //if (dgvProductNums.Rows.Count > 0)
                //{
                //    dgvProductNums.Height = dgvProductNums.Rows[0].Height * dgvProductNums.Rows.Count + 15;
                //}
                //else
                //{
                //    dgvProductNums.Height = 35;
                //}

                //lblOEE_Rate.Text = ProcessControl.OEE.ToString("f2") + " %";
                lblUPH.Text = UPM.ToString();
            }));
        }
        public void LoadScheme()
        {
            try
            {
                // 初始化方案配置(会自动创建默认方案)
                SchemeHelper.Initialize();

                // 读取方案列表
                var schemes = SchemeHelper.GetAllSchemes();
                sltProjects.Items.Clear();

                // 绑定方案到下拉列表
                foreach (var scheme in schemes)
                {
                    sltProjects.Items.Add(scheme);
                }

                // 设置当前选中的方案
                string currentScheme = SchemeHelper.GetCurrentScheme();
                sltProjects.SelectedValue = currentScheme;
                SystemModel.CurrentScheme = currentScheme;

                // 加载当前方案配置
                ConfigHelper.LoadConfig();
            }
            catch (Exception ex)
            {
                AntdUI.Message.error(this, ex.Message, autoClose: 3);
            }
        }
        private void BtnDeleteProject_Click(object? sender, EventArgs e)
        {
            try
            {
                if (sltProjects.Items.Count == 0 || sltProjects.SelectedIndex == -1) return;

                var result = AntdUI.Modal.open(this, "删除警告!", "确认要删除该方案吗?", TType.Warn);
                if (result == DialogResult.OK)
                {
                    string schemeToDelete = sltProjects.Text;
                    int selectedIndex = sltProjects.SelectedIndex;

                    // 删除方案(SchemeHelper会自动处理当前方案的切换)
                    SchemeHelper.DeleteScheme(schemeToDelete);
                    ConfigHelper.DeleteSchemeConfig(schemeToDelete);

                    // 刷新UI
                    LoadScheme();

                    AntdUI.Message.success(this, $"删除方案{schemeToDelete}成功!", autoClose: 3);

                    // 如果没有方案了,提示用户
                    if (sltProjects.Items.Count == 0)
                    {
                        AntdUI.Modal.open(this, "空方案警告!", "当前方案全部删除,需重启程序!", TType.Warn);
                    }
                }
            }
            catch (Exception ex)
            {
                AntdUI.Message.error(this, ex.Message, autoClose: 3);
            }
        }

        private void BtnLoadProject_Click(object? sender, EventArgs e)
        {
            try
            {
                if (sltProjects.Items.Count == 0 || sltProjects.SelectedIndex == -1) return;

                string selectedScheme = sltProjects.Text;

                if (SystemModel.CurrentScheme == selectedScheme)
                {
                    AntdUI.Message.warn(this, "当前已是该方案,无需重复载入!", autoClose: 3);
                    return;
                }

                // 设置当前方案
                SchemeHelper.SetCurrentScheme(selectedScheme);
                SystemModel.CurrentScheme = selectedScheme;

                // 加载配置
                ConfigHelper.LoadConfig();

                AntdUI.Message.success(this, $"载入方案{selectedScheme}成功!", autoClose: 3);
            }
            catch (Exception ex)
            {
                AntdUI.Message.error(this, ex.Message, autoClose: 3);
            }
        }

        private void BtnAddProject_Click(object? sender, EventArgs e)
        {
            try
            {
                var form = new AddSchemeControl(this, "新增方案操作") { Size = new System.Drawing.Size(400, 300) };
                AntdUI.Modal.open(new AntdUI.Modal.Config(this, "", form, TType.None)
                {
                    BtnHeight = 0,
                });

                if (form.submit)
                {
                    string schemeName = form.SchemeName;

                    // 保存到方案配置
                    SchemeHelper.AddScheme(schemeName);

                    // 根据选择初始化配置
                    if (form.NullScheme)
                    {
                        ConfigHelper.InitializeScheme(schemeName);
                    }
                    else
                    {
                        ConfigHelper.DeriveScheme(schemeName);
                    }

                    // 刷新UI
                    LoadScheme();
                    AntdUI.Message.success(this, $"新增方案{schemeName}成功!", autoClose: 3);
                }
            }
            catch (Exception ex)
            {
                AntdUI.Message.error(this, ex.Message, autoClose: 3);
            }
        }

        public List<HikVisionCamera> HKCameras { get; } = new List<HikVisionCamera>();
        public List<Do3ThinkCamera> Cameras { get; } = new List<Do3ThinkCamera>();
        public Dictionary<string, SimboObjectDetection> Dectection { get; } = new Dictionary<string, SimboObjectDetection>();
        public XinJEPLCTcpNet PLC { get; } = XinJEPLCTcpNet.Instance;
        private SLDMotion sLDMotion = new SLDMotion();
        // 线程控制标志
        private volatile bool _isRunning = false;
        private Thread _monitorThread;
        private void MainWindow_Load(object sender, EventArgs e)
        {
         
            //开启按钮监听
            // 启动所有监控线程
            StartAllMonitors();
        }

        private void StartAllMonitors()
        {
            if (PLC.Connected)
            {
                if (_monitorThread == null || !_monitorThread.IsAlive)
                {
                    //关闭按钮自身功能(比如按按钮转盘自己启动等)
                    PLC.WriteBool("M40", true);
                    _isRunning = true;
                    _monitorThread = new Thread(MonitorPlcButtons);
                    _monitorThread.IsBackground = true; // 后台线程
                    _monitorThread.Start();
                }
            }
           
        }

        private void MonitorPlcButtons(object? obj)
        {
            while (_isRunning)
            {
                try
                {
                    // 读取 PLC 输入点状态
                    bool startPressed = PLC.ReadBool("X3");
                    bool resetPressed = PLC.ReadBool("X4");
                    bool stopPressed = PLC.ReadBool("X5");
                    bool eStopPressed = PLC.ReadBool("X6");

                    // 处理按钮状态变化
                    if (startPressed)
                    {
                        PLC.TurnSpeed(0);
                        PLC.TurnStart(false);
                        HandleStartButton();
                    }
                    if (resetPressed)
                    {
                        //ResetProcess();
                    }
                    if (stopPressed)
                    {
                        HandleStopButton();
                    }
                    if (eStopPressed)
                    {
                        //EmergencyStop(null, null, null);
                    }

                    Thread.Sleep(50); 
                }
                catch (Exception ex)
                {
                    _isRunning = false;
                    // 记录错误并停止线程
                //    throw new ProcessException($"按钮监听线程:{ex.Message}");

                }
            }
        }

        // 停止监听线程
        private void StopMonitoring()
        {
            _isRunning = false;
            if (_monitorThread != null && _monitorThread.IsAlive)
            {
                _monitorThread.Join(1000); // 等待线程退出
            }
            PLC.WriteBool("M40", false);
        }
        private bool _isClosing = false; // 状态标志

        private void MainWindow_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (_isClosing) return;
            _isClosing = true;
            // 取消默认关闭行为
            e.Cancel = true;

            // 立即隐藏主窗口
            this.Hide();

            // 显示关闭界面
            CloseWindow.Instance.Show();
            Thread.Sleep(200);
            try
            {
                // 执行关闭操作
                foreach (var camera in Cameras)
                {
                    camera.CameraDisConnect();
                }
                foreach (var camera in HKCameras)
                {
                    camera.CameraDisConnect();
                }
                StopMonitoring();
                if (PLC != null)
                {
                    PLC.CloseProcess();
            
                }
              
                _visionEngine.Stop();//释放模型
                CloseWindow.Instance.Close();// 关闭提示窗口
                                             //Application.Exit();
                System.Environment.Exit(0);
            }
            catch (Exception ex)
            {
                CloseWindow.Instance.Close();

                System.Environment.Exit(0);
            }
        }

        private void segmented1_SelectIndexChanged(object sender, EventArgs e)
        {
            // Get the index of the selected item
            int selectedIndex = segmented1.SelectIndex;

            // Handle each button based on its index
            switch (selectedIndex)
            {
                case 0: // "启动" (Start)
                    HandleStartButton();
                    break;

                case 1: // "停止" (Stop)
                    HandleStopButton();
                    break;

                case 2: // "复位" (Reset)
                    HandleResetButton();
                    break;

                case 3: // "设置" (Settings)
                    HandleLoginButton();
                    break;

                case 4: // "登录" (Login)
                    HandleSettingsButton();
                    break;

                default:
                    break;
            }
            segmented1.SelectIndex = -1;
        }

        private void segmented2_SelectIndexChanged(object sender, IntEventArgs e)
        {
        
            int selectedIndex = segmented2.SelectIndex;

           
            switch (selectedIndex)
            {
                case 0:
                    HandleVisualLocalizationButton();
                    break;

                default:
                    break;
            }
            segmented2.SelectIndex = -1;
        }



        public string BatchNO { get; set; }
        public bool CurrentMachine = false;
        public volatile int ProductNum_Total = 0;
        public volatile int ProductNum_OK = 0;
        private readonly object _cameraSummaryLock = new object();
        public SimboVisionDriver? _visionEngine = null;

        public PLCBase? _PLCConfig = null;
        private List<DetectionConfig> DetectionConfigs = new List<DetectionConfig>();
        private List<SimboStationMLEngineSet> SimboStationMLEngineList = new List<SimboStationMLEngineSet>();
        private Dictionary<string, HDevEngineTool> HalconToolDict = new Dictionary<string, HDevEngineTool>();
        public List<RecongnitionLabel> RecongnitionLabelList { get; set; } = new List<RecongnitionLabel>();
        public DateTime ProcessstartTime;
        private void PrepareBatchNO()
        {
            BatchNO = string.IsNullOrEmpty(BatchNO) ? SystemModel.CurrentScheme + "-" + DateTime.Now.ToString("yyyyMMddHHmmss") : BatchNO;
            // DataSavePath = string.IsNullOrEmpty(DataSavePath) ? Path.Combine(X018PLCConfig.ImgDirectory, DateTime.Now.ToString("yyyyMMdd"), BatchNO) : DataSavePath;

        }
       
        private void HandleStartButton()
        {
            lock (_stopLock)
            {
                if (_isStopProcessing) return;
                _isStopProcessing = true;
            }
            try
            {
                if (SystemModel.CurrentStatus == EnumStatus.待机中)
                {
                    InitialCameraSumsView();
                    LogAsync(DateTime.Now, LogLevel.Information, "流程启动中,请稍候...");
                    ResetAllCameraCounts();
                    //开始流程

                    StartProcess();
                    SystemModel.CurrentStatus = EnumStatus.运行中;
                    this.BeginInvoke(new MethodInvoker(delegate ()
                    {
                        tagMachineStatus.Type = TTypeMini.Success;
                        tagMachineStatus.Text = "运行中";
                    }));
                    LogAsync(DateTime.Now, LogLevel.Action, "流程启动完成!");

                }
                else if (SystemModel.CurrentStatus == EnumStatus.运行中)
                {
                    LogAsync(DateTime.Now, LogLevel.Warning, "设备正在运行,无需启动!");
                }
                else if (SystemModel.CurrentStatus == EnumStatus.清料中)
                {
                    LogAsync(DateTime.Now, LogLevel.Warning, "设备正在清料,请稍候!");
                }
                else if (SystemModel.CurrentStatus == EnumStatus.警告)
                {
                    LogAsync(DateTime.Now, LogLevel.Warning, "设备报警,请复位后重试!");
                }
                else if (SystemModel.CurrentStatus == EnumStatus.异常)
                {
                    LogAsync(DateTime.Now, LogLevel.Warning, "设备异常,请检查!");
                }

            }
            finally
            {
                lock (_stopLock)
                {
                    _isStopProcessing = false;
                }
            }



        }



        private async void StartProcess()
        {
            try
            {
      

                BatchNO = textBoxBatchNO.Text;
                textBoxBatchNO.ReadOnly = true;
                btnCreateBatchNO.Enabled = false;
                PrepareBatchNO();//生成批次号
                ProcessstartTime = DateTime.Now;
                lblStartTime.Text = ProcessstartTime.ToString("yyyy-MM-dd HH:mm:ss");
                //计数清零
                PieceCount = 0;

                //CameraSummaries.Clear();

                if (PLC?.Enable == true)
                {
                    PLC.OnNewPieces -= MainMotion_NewPieces;
                    PLC.OnNewPieces += MainMotion_NewPieces;
                }

                Cameras.ForEach(d =>
                {
                    if (d is CameraBase cam)
                    {
                        cam.SnapshotCount = 0;
                    }
                });

                //PrepareBatchNO();
                // isInPositionChecking = false;
                //isFullTrayChecking = false;
                //队列清空
                // var temp = new List<ITriggerSet>();
                // temp.AddRange(XKRSPLCConfig.TriggerConfigCollection);
                // temp.AddRange(XKRSPLCConfig.SnapshotTriggerConfigCollection);

                //temp.ForEach(t =>
                //{
                //    var diskInfo = XKRSPLCConfig.DiskInfoList.FirstOrDefault(u => u.DiskName == t.DiskName);
                //    if (diskInfo != null)
                //    {
                //        t.AxisNum = diskInfo.DiskAxisNum;
                //    }
                //    else
                //    {
                //        t.AxisNum = -1;
                //    }
                //});

                //if (temp.Any(u => u.AxisNum < 0))
                //{
                //    LogAsync(DateTime.Now, LogLevel.Error, "触发信号归属转盘未确认");
                //    return new ProcessResponse(false);
                //}

                // _diskInfoListInOrder = XKRSPLCConfig.DiskInfoList.OrderBy(u => u.DiskSequence).ToList();
                //  var axisNumList = _diskInfoListInOrder.Select(u => u.DiskAxisNum).ToList();

                /// PrepareMLEngine();

                // if (_PLCConfig?.Enable == true)
                //挡料电机操作
                //  _PLC.FeedingMotor(_PLCConfig.CunToZeroSpeed, _PLCConfig.CunPos, _PLCConfig.CunSpeed, _PLCConfig.CunDirection);

                //流程开启操作配置
                // ProcessInitialAction();
                //  if (_PLC?Enabled == true)
                //皮带
                //   _PLC.Belt(true);

                //DeviceCollection.ForEach(d =>
                //{
                //    if (d is CameraBase c)
                //    {
                //        c.OnHImageOutput -= OnCameraHImageOutput;
                //        c.OnHImageOutput += OnCameraHImageOutput;
                //        c.SnapshotCount = 0;
                //    }
                //});
                _productLists.Clear();

                #region 虚拟相机

                //mOfflineImageTimer = new System.Timers.Timer();

                //mOfflineImageTimer.Elapsed += OnEmitSerialPortAsync;
                //mOfflineImageTimer.Interval = 1000;
                //mOfflineImageTimer.Start();

                #endregion 虚拟相机
     
           
                ///这里会执行完成后,会造成后台线程断断续续,会造成界面UI卡顿
                //var settings = ConfigModel.DetectionList.Where(u => u.IsEnabled && u.IsAddStation).ToList();
                //if (settings != null)
                //{
                //    settings = settings.Where(s => s.IsEnabled).ToList();
                //    ProductBaseCount = settings.Count;

                //    for (int i = 0; i < ProductBaseCount * ProductListMulti; i++)
                //    {
                //        ConcurrentDictionary<uint, ProductData> products = new ConcurrentDictionary<uint, ProductData>();
                //        _productLists.Add(products);
                //    }
                //}


                await Task.Run(() =>
                {
                    var settings = ConfigModel.DetectionList.Where(u => u.IsEnabled && u.IsAddStation).ToList();
                    if (settings != null)
                    {
                        ProductBaseCount = settings.Count;
                        _productLists.Clear(); // 清空旧数据

                        // 预分配列表容量(减少动态扩容开销)
                        _productLists.Capacity = ProductBaseCount * ProductListMulti;

                        for (int i = 0; i < ProductBaseCount * ProductListMulti; i++)
                        {
                            _productLists.Add(new ConcurrentDictionary<uint, ProductData>());
                        }
                    }
                });
                //   _MGSCameraList = DeviceCollection
                //.OfType<MGSCameraDriver>()  // 直接筛选出 MGSCameraDriver 类型的元素
                //.Where(camera => camera.IConfig != null && camera.IConfig.IsEnabled)  // 进一步筛选 IConfig 不为 null 且 IsEnabled 为 true
                //.ToList();

                //   ProductBaseCount = _MGSCameraList.Count;




                InitialOEEStatistic();
                //流程执行时PLC
                PLC.StartProcess();
                CurrentMachine = true;
            }
            catch (Exception ex)
            {
            }


        }


        private uint PieceCount = 0;
        private List<ConcurrentDictionary<uint, ProductData>> _productLists = new List<ConcurrentDictionary<uint, ProductData>>();
        private int ProductListMulti = 1;
        private int ProductBaseCount = 0;

        private int PieceNumberToIndex(uint pn)
        {
            // 物料编号,取余 集合数量

            int ret = (int)(pn % (ProductBaseCount * ProductListMulti));
            return ret;
        }

        private DateTime _ctTime = DateTime.Now;

        public async void MainMotion_NewPieces(int axisIndex, uint pieceNumber)
        {
            //if (MachineState != MachineState.Running && MachineState != MachineState.Warning)
            //{
            //    return;
            //}

            PieceCount++;

            int index = PieceNumberToIndex(pieceNumber);
            // productDatas.Add(pData);
            //转盘2 的物料是不是重新覆盖之前的pDta
            if (axisIndex == 1)
            {
                ProductData pData = new ProductData("", pieceNumber, ProductBaseCount);
                _productLists[index][pieceNumber] = pData;
                LogAsync(DateTime.Now, LogLevel.Action, $">> 轴{axisIndex}新产品{pieceNumber}加入队列{index}----板卡计数{PieceCount}");

            }

            DateTime dtNow = DateTime.Now;
            UpdateCT(null, (float)(dtNow - _ctTime).TotalSeconds);
            _ctTime = dtNow;
        }

        public async Task UpdateCT(object objData, float ctTime)
        {
            await Task.Run(() =>
            {
                //OnUpdateCT?.Invoke(objData, ctTime);
            });
        }

        /// <summary>
        /// 相机回调
        /// </summary>
        /// <param name="dt"></param>
        /// <param name="camera"></param>
        /// <param name="imageSet"></param>
        private void OnCameraHImageOutput(DateTime dt, CameraBase camera, MatSet imageSet)
        {
            //if (camera.CameraName.Equals("cam1", StringComparison.OrdinalIgnoreCase))
            //{
            //    Console.WriteLine();
            //}
            //if (camera.CameraName.Equals("cam2", StringComparison.OrdinalIgnoreCase))
            //{
            //    Console.WriteLine();
            //}

            // 获取该相机的拍照计数
            uint productNumber = (uint)camera.SnapshotCount;

            Task.Run(async () =>
            {
                //using (Mat localImageSet = imageSet._mat.Clone())  // 复制 Mat 避免并发问题
                {
                    // imageSet?.Dispose();
                    // 拍照计数与物件编号一致,查找对应的产品
                    ProductData product = null;
                    //内外壁模组多个相机的处理方法
                    //计算队列的方法不变
                    int index = PieceNumberToIndex(productNumber);
                    // 找到产品存放在哪个队列里
                    ConcurrentDictionary<uint, ProductData> tmpDic = _productLists[index];

                    try
                    {
                        int retryTimes = 100;
                        while (product == null && retryTimes > 0)
                        {
                            if (tmpDic.ContainsKey(productNumber))
                            {
                                product = tmpDic[productNumber];
                            }
                            else
                            {
                                Thread.Sleep(20);
                                //await Task.Delay(20);
                            }
                            retryTimes--;
                        }
                        // 如果产品为空,则销毁图片,提示错误
                        if (null == product)
                        {
                            List<uint> pnList = tmpDic.Keys.ToList();

                            string pnStr = "";
                            if (pnList != null && pnList.Count > 0)
                            {
                                pnStr = string.Join(",", pnList);
                            }

                            //LogAsync(DateTime.Now, LogLevel.Error, $"{camera.Name} 未找到产品,编号:{productNumber},队列{index}数量:{tmpDic.Count},列表:{pnStr}");
                            imageSet.Dispose();

                            return;
                        }

                        LogAsync(DateTime.Now, LogLevel.Information, $"{camera.CameraName} 找到产品{productNumber},队列{index}数量:{tmpDic.Count}");

                        if (!_cameraRelatedDetectionDict.ContainsKey(camera.CameraName))
                        {
                            imageSet.Dispose();



                            LogAsync(DateTime.Now, LogLevel.Warning, $"{camera.CameraName} 找到产品{productNumber},但是没有推理1");

                            return;
                        }

                        double totalTime = 0.0;
                        List<ResultState> resultStates = new List<ResultState>();
                        List<string>? detectionDict = _cameraRelatedDetectionDict[camera.CameraName];
                        Stopwatch stopwatch = new Stopwatch();
                        stopwatch.Start();
                        for (int i = 0; i < detectionDict.Count; i++)
                        {
                            string detectionId = detectionDict[i];
                            var tmpImgSet = camera.CopyImageSet(imageSet as MatSet);
                            //imageSet
                            //  using (Mat inferenceImage = localImageSet.Clone()) // 仅在此处克隆,确保推理过程中 Mat 有独立副本

                            DetectStationResult temp1 = _visionEngine.RunInference(tmpImgSet, detectionId);

                            resultStates.Add(temp1.ResultState);

                            product.ResultCollection.Add(temp1);

                            if (temp1 != null)
                            {
                                UpdateResultTigger(dt, temp1.DetectName, (int)productNumber);
                                //if (tmpModuleData.CamIDs.Count == 1)
                                //{
                                //    UpdateResultoverride(dt, temp1.DetectName, resultStates, totalTime, _cameraRelatedDetectionDict.Keys.Count);
                                //}
                                //else //合图的合成一列
                                //{
                                //    UpdateResultoverride(dt, temp1.DetectName, resultStates, totalTime, _cameraRelatedDetectionDict.Keys.Count);
                                //}
                                if (product.ResultCollection.Count != 0)
                                    UpdateResultoverride(dt, temp1.DetectName, resultStates, totalTime, _cameraRelatedDetectionDict.Keys.Count);

                            }


                        }
                        stopwatch.Stop();


                        product.InferenceOne();

                        // LogAsync(DateTime.Now, LogLevel.Information, $"{camera.Name} 推理完成,产品{productNumber}");

                        if (!product.InferenceFinished())
                        {
                            return;
                        }

                        #region 6. 统计产品结果

                        product.ProductResult = product.ResultCollection.Any(u => u.ResultState != ResultState.OK)
                            ? ResultState.B_NG
                            : ResultState.OK;
                        product.ProductLabelCategory = product.ProductResult.GetEnumDescription();
                        product.ProductLabel = product.ProductResult.GetEnumDescription();
                        UpdateResultPro(DateTime.Now, null, product.ProductResult.GetEnumDescription());

                        LogAsync(DateTime.Now, LogLevel.Information, $"产品{product.PieceNumber}获取结果:{product.ProductResult} {(product.IsA2B ? "产品IsA2B" : "")}");



                        if (product.ProductResult == ResultState.OK)
                        {
                            PLC.Blowing(productNumber, 1);
                            LogAsync(DateTime.Now, LogLevel.Action, $"产品{product.PieceNumber}PLC,OK吹气");

                        }
                        else
                        {
                            PLC.Blowing(productNumber, 2);
                            LogAsync(DateTime.Now, LogLevel.Action, $"产品{product.PieceNumber}PLC,NG吹气");
                        }


                        #endregion 6. 统计产品结果

                        // 出列
                        ProductData temp = null;

                        int tryTimes = 10;
                        while (temp == null && tryTimes > 0)
                        {
                            if (tmpDic.TryRemove(productNumber, out temp))
                            {
                                break;
                            }

                            tryTimes--;
                            Thread.Sleep(5);
                        }
                        if (temp == null)
                        {
                            string logStr = $"{DateTime.Now}产品{productNumber}出列失败:true," +
                               $"当前队列产品数量:{tmpDic.Count}";
                            this.BeginInvoke(new MethodInvoker(delegate ()
                            {
                                // int currentScrollPosition = richTextBox1.GetPositionFromCharIndex(richTextBox1.TextLength).Y;

                                // richTextBox1.AppendText(logStr);

                                // 设置回原来的滚动位置
                                // richTextBox1.SelectionStart = richTextBox1.TextLength;
                                //richTextBox1.ScrollToCaret();
                            }));
                        }
                        else
                        {
                            try
                            {
                                string logStr = $"{DateTime.Now}产品{productNumber}出列成功:true," +
                              $"产品结果:{temp.ProductResult.GetEnumDescription()}," +
                              $"当前队列产品数量:{tmpDic.Count}";
                                this.BeginInvoke(new MethodInvoker(delegate ()
                                {
                                    //int currentScrollPosition = richTextBox1.GetPositionFromCharIndex(richTextBox1.TextLength).Y;

                                    // richTextBox1.AppendText(logStr);

                                    // 设置回原来的滚动位置
                                    // richTextBox1.SelectionStart = richTextBox1.TextLength;
                                    //richTextBox1.ScrollToCaret();
                                }));
                                //重新生成实例 销毁之前的实例
                                var saveData = temp.GetProductData();

                            }
                            catch (Exception) { }
                            finally
                            {
                                // temp.Dispose();
                                temp = null;
                            }
                        }

                        // UpdateCT((float)(dtNow - _ctTime).TotalSeconds);
                        //_ctTime = dtNow;
                        // });
                    }
                    catch (Exception ex)
                    {
                        //LogAsync(DateTime.Now, LogLevel.Error, $"流程检测未捕获的异常:{ex.GetExceptionMessage()}");
                        product?.Dispose();
                    }
                }
            });
        }
        public virtual void AddOKProduct(string resultStr)
        {
            if (resultStr.ToLower() == "ok")
            {
                ProductNum_OK++;
            }
        }
        public async Task UpdateResultTigger(DateTime dt, string objData, int _cameraDictCount)
        {
            CurrentState = RunState.Running;



            // 根据相机名称找到对应的信息(假设有一个字典或其他集合保存相机相关信息)
            var cameraName = objData; // 假设 CameraBase 有 Name 属性
            if (string.IsNullOrEmpty(cameraName))
            {
                throw new ArgumentException("相机名称不能为空");
            }



            lock (_cameraSummaryLock)
            {
                // 查找或添加相机统计项
                var summary = CameraSummaries.FirstOrDefault(c => c.CameraName == cameraName)
                              ?? new CameraSummary { CameraName = cameraName };

                if (!CameraSummaries.Contains(summary))
                {
                    CameraSummaries.Add(summary);
                }


                summary.TiggerCount = _cameraDictCount;
            }

            await Task.Run(() =>
            {
                OnUpdateCamResult?.Invoke(dt, objData, "");
            });
        }
        public async Task UpdateResultoverride(DateTime dt, string objData, List<ResultState> resultStr, double total, int _cameraDictCount)
        {
            // CurrentState = RunState.Running;



            // 根据相机名称找到对应的信息(假设有一个字典或其他集合保存相机相关信息)
            var cameraName = objData; // 假设 CameraBase 有 Name 属性
            if (string.IsNullOrEmpty(cameraName))
            {
                throw new ArgumentException("相机名称不能为空");
            }



            lock (_cameraSummaryLock)
            {
                // 查找或添加相机统计项
                var summary = CameraSummaries.FirstOrDefault(c => c.CameraName == cameraName)
                              ?? new CameraSummary { CameraName = cameraName };

                if (!CameraSummaries.Contains(summary))
                {
                    CameraSummaries.Add(summary);
                }

                if (resultStr.Any(u => u.ToString().ToLower() == "ok"))
                {
                    summary.OKCount++;
                }

                else /*if (resultStr.Equals("TBD", StringComparison.OrdinalIgnoreCase))*/
                {
                    summary.NGCount++;
                }

            }

            await Task.Run(() =>
            {
                OnUpdateCamResult?.Invoke(dt, objData, "");
            });
        }

        public async Task UpdateResultPro(DateTime dt, object objData, string resultStr)
        {
            CurrentState = RunState.Running;

            ProductNum_Total++;
            AddOKProduct(resultStr);



            lock (_productSummaryLock)
            {
                var product = ProductSummaries.FirstOrDefault(u => u.ResultDesc == resultStr);
                if (product != null)
                {
                    product.ProductAmount++;
                }
                else
                {
                    product = new ProductSummary();
                    product.ResultDesc = resultStr;
                    product.ProductAmount = 1;

                    ProductSummaries.Add(product);
                }

                int totalNum = ProductSummaries.Sum(p => p.ProductAmount);
                ProductSummaries.ForEach(p => p.PercentStr = ((double)p.ProductAmount * 100.0 / totalNum).ToString("f2") + " %");
            }

            CalculateOEE();

            await Task.Run(() =>
            {
                OnUpdateResult?.Invoke(dt, objData, resultStr);
            });
            lock (_cameraSummaryLock)
            {
                // 查找或添加相机统计项
                var summary = CameraSummaries.FirstOrDefault(c => c.CameraName == "合计")
                              ?? new CameraSummary { CameraName = "合计" };

                summary.OKCount = ProductNum_OK;
                summary.NGCount = ProductNum_Total - ProductNum_OK;
                if (!CameraSummaries.Contains(summary))
                {
                    CameraSummaries.Add(summary);
                }





            }
            await Task.Run(() =>
            {
                OnUpdateCamResult?.Invoke(dt, objData, "合计");
            });


        }

        private readonly object _stopLock = new object(); // 锁对象
        private bool _isStopProcessing = false;          // 状态标志
        private async void HandleStopButton()
        {   
            // 通过锁和状态标志实现双重检查
            lock (_stopLock)
            {
                if (_isStopProcessing) return;
                _isStopProcessing = true;
            }
            try
            {
                if (SystemModel.CurrentStatus == EnumStatus.待机中)
                {
                    LogAsync(DateTime.Now, LogLevel.Warning, "设备待机中,无需停止!");
                }
                else if (SystemModel.CurrentStatus == EnumStatus.运行中)
                {
                    textBoxBatchNO.ReadOnly = false;
                    btnCreateBatchNO.Enabled = true;

                    // Cameras.Clear();
                    // Dectection.Clear();
                    // Add the code for the "停止" button click here
                    PLC.StopProcess();
                    SystemModel.CurrentStatus = EnumStatus.待机中;
                    this.BeginInvoke(new MethodInvoker(delegate ()
                    {
                        tagMachineStatus.Type = TTypeMini.Primary;
                        tagMachineStatus.Text = "待机中";
                    }));
                    LogAsync(DateTime.Now, LogLevel.Action, $"流程停止!");
                  await  Task.Run(async () =>
                    {

                        await ExecuteClearDelayAsync();
                    });
                }
                else if (SystemModel.CurrentStatus == EnumStatus.清料中)
                {
                    LogAsync(DateTime.Now, LogLevel.Warning, "设备正在清料,请稍候!");
                }
                else if (SystemModel.CurrentStatus == EnumStatus.警告)
                {
                    LogAsync(DateTime.Now, LogLevel.Warning, "设备报警,请复位后重试!");
                }
                else if (SystemModel.CurrentStatus == EnumStatus.异常)
                {
                    LogAsync(DateTime.Now, LogLevel.Warning, "设备异常,请检查!");
                }
            }

            finally
            {
                lock (_stopLock)
                {
                    _isStopProcessing = false;
                }
            }


            //sLDMotion.Stop();
        }

        private async Task ExecuteClearDelayAsync()
        {
            LogAsync(DateTime.Now, LogLevel.Action, $"转盘清料开始");
            SystemModel.CurrentStatus = EnumStatus.清料中;
            this.BeginInvoke(new MethodInvoker(delegate ()
            {
                tagMachineStatus.Type = TTypeMini.Warn;
                tagMachineStatus.Text = "清料中";
            }));
            await PLC.ExecuteClearDelayAsync();
            LogAsync(DateTime.Now, LogLevel.Action, $"转盘清料完成");

            SystemModel.CurrentStatus = EnumStatus.待机中;
            this.BeginInvoke(new MethodInvoker(delegate ()
            {
                tagMachineStatus.Type = TTypeMini.Primary;
                tagMachineStatus.Text = "待机中";
            }));
        }

        public void CalculateOEE()
        {
            if (TotalTime.TotalHours == 0)
            {
                UPH = 0;
                UPM = 0;
            }
            else
            {
                UPH = (int)(ProductNum_Total / RunTime.TotalHours) + 100;
                UPM = (int)UPH / 60;
            }


            //TimeSpan timeSpan = DateTime.Now - ProcessstartTime;

            //UPH = (int)(ProductNum_Total / timeSpan.TotalHours) + 100;
            ////UPM = (int)UPH / 60;
            //this.BeginInvoke(new MethodInvoker(delegate ()
            //{
            //    lblNowtime.Text = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
            //    lblUPH.Text = UPH.ToString();
            //    lblNum.Text = ProductNum_Total.ToString();

            //}));
        }

        private void HandleResetButton()
        {
            // Add the code for the "复位" button click here
            MessageBox.Show("复位按钮按下");
        }

        private void HandleSettingsButton()
        {
            // Add the code for the "设置" button click here

            SettingWindow.Instance.Show();
        }

        private void HandleLoginButton()
        {
            // Add the code for the "登录" button click here
            LoginWindow.Instance.parentForm = this;
            LoginWindow.Instance.Show();
        }
        private void HandleVisualLocalizationButton()
        {
            VisualLocalizationWindow.Instance.Show();
        }
        private void btnCreateBatchNO_Click(object sender, EventArgs e)
        {
            textBoxBatchNO.Text = SystemModel.CurrentScheme + "-" + DateTime.Now.ToString("yyyyMMddHHmmss");
        }

       
    }
}