using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using MESClassLibrary.BLL.Log;
using OPCAutomation;
using PunchAndWeld.DataSouce;

namespace PunchAndWeld
{
    public partial class FrmDoorSill_214_3 : Form
    {
        private FrmDoorSill_214_3_Condition _conditionDialog = null;
        private OPCHelper opcHelper = new OPCHelper();
        private int stationState = 0;
        private string _produceModel = string.Empty;
        private SynchronizationContext _syncontext = SynchronizationContext.Current; //同步上下文
        private string _lastScan = string.Empty;
        private string _leftScanCode = string.Empty;
        private string _rightScanCode = string.Empty;
        public FrmDoorSill_214_3()
        {
            InitializeComponent();

            this.Hide();
            ShowParamDialog("","");
             
        }

        #region event 

        private void FrmDoorSill_214_3_Load(object sender, EventArgs e)
        {
            _syncontext = SynchronizationContext.Current;
            lbVer.Text = "当前版本:" + Assembly.GetExecutingAssembly().GetName().Version;
            lbBegin.Text = DateTime.Now.ToShortDateString() + " 00:00:00";
            lbEnd.Text = DateTime.Now.ToShortDateString() + " 23:59:59";
            dgridScanRecords.RowsAdded += DgridScanRecords_RowsAdded;
            ClearDisplay();
            InitPLC();
            GetScanRecords();
            LoadScanBoxEnabled();

           
            
        }
       
        private void DgridScanRecords_RowsAdded(object sender, DataGridViewRowsAddedEventArgs e)
        {
            for (int i = 0; i < e.RowCount; i++)
            {
                ((DataGridView)sender).Rows[e.RowIndex + i].HeaderCell.Style.Alignment = DataGridViewContentAlignment.MiddleRight;
                ((DataGridView)sender).Rows[e.RowIndex + i].HeaderCell.Value = (e.RowIndex + i + 1).ToString();
            }
        }

        void LoadScanBoxEnabled()
        {
            txtLeftScan.Enabled = true;
            _produceModel = txtProduceModel.Text.Trim();
        }

        private void btnOpenParamDialog_Click(object sender, EventArgs e)
        {
            string cf = txtConfig.Text;
            string pm = txtProduceModel.Text;
            ShowParamDialog(cf, pm);
           
            LoadScanBoxEnabled();
        }
        private void txtLeftScan_KeyDown(object sender, KeyEventArgs e)
        {
             if(e.KeyCode == Keys.Enter)
            {
                ScanBarCode(txtLeftScan);
            }
        }

        private void txtRightScan_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
               // ScanBarCode(txtRightScan,"右");
            }
        }

       

        private void focusTimer_Tick(object sender, EventArgs e)
        {
            if (string.IsNullOrEmpty(_produceModel)) return;

            //if(_produceModel == "左")
            //{
                txtLeftScan.Focus();
                txtLeftScan.SelectAll();
            //}
            //else if (_produceModel == "右")
            //{
            //    txtRightScan.Focus();
            //    txtRightScan.SelectAll();
            //}
            //else if (_produceModel == "左右")
            //{
 
            //}
        }
        //void LeftAndRightFocus()
        //{
        //    if(string.IsNullOrEmpty( _lastScan))
        //    {
        //        txtLeftScan.Focus();
        //        txtLeftScan.SelectAll();
        //    }
        //    else if (_lastScan == "右")
        //    {
        //        txtLeftScan.Focus();
        //        txtLeftScan.SelectAll();
        //    }
        //    else
        //    {
        //        txtRightScan.Focus();
        //        txtRightScan.SelectAll();
        //    }
        //    //if (string.IsNullOrEmpty(txtLeftScan.Text))
        //    //{
        //    //    txtLeftScan.Focus();
        //    //    txtLeftScan.SelectAll();
        //    //}
        //    //else if (string.IsNullOrEmpty(txtRightScan.Text))
        //    //{
        //    //    txtRightScan.Focus();
        //    //    txtRightScan.SelectAll();
        //    //}
        //    //else
        //    //{
        //    //    txtLeftScan.Focus();
        //    //    txtLeftScan.SelectAll();
        //    //}
        //}
        #endregion

        #region PLC
        void InitPLC()
        {
            if (ConfigurationManager.AppSettings["IsHaveVisual"] == "1")
            {
                try
                {
                    if (opcHelper.CreateServer())
                    {
                        if (opcHelper.ConnectServer("", "Kepware.KEPServerEX.V6"))
                        {
                            LogHelper.WriteErrLogBase("Kepware.KEPServerEX.V6"+":连接成功", "InitPLC");
                            opcHelper.Connected = true;
                            ShowLinkState(true);

                            opcHelper.opcGroups = opcHelper.opcServer.OPCGroups;
                            opcHelper.opcGroup1 = opcHelper.opcGroups.Add("Right");
                            opcHelper.SetGroupProperty(opcHelper.opcGroup1, 500);


                            opcHelper.opcItems1 = opcHelper.opcGroup1.OPCItems;
                            opcHelper.opcItems1.DefaultIsActive = true;

                            Dictionary<int, string> dict = GetDevInfo();
                            opcHelper.opcItemm1 = new OPCItem[dict.Count];
                            foreach (var dictItem in dict)
                            {
                                opcHelper.opcItemm1[dictItem.Key] = opcHelper.opcItems1.AddItem(dictItem.Value, dictItem.Key);
                            }

                            opcHelper.opcGroup1.DataChange += new DIOPCGroupEvent_DataChangeEventHandler(opcGroup1_DataChange);
                            stationState = opcHelper.ReadSingleValueFromOPC2(1);

                            //Thread t1 = new Thread(new ThreadStart(TimeGo1));
                            //t1.Start();

                        }
                    }
                    else
                    {
                        MessageBox.Show("创建OPC服务失败!", "提示", MessageBoxButtons.OK);
                        opcHelper.Connected = false;
                        LogHelper.WriteErrLogBase("工位:" + label1.Text + "创建OPC服务失败!", MethodBase.GetCurrentMethod().Name);
                        return;
                    }
                }
                catch (Exception ex)
                {
                    LogHelper.WriteErrLogBase(ex.ToString(), MethodBase.GetCurrentMethod().Name);
                    ShowLinkState(false);
                    ShowHint("初始化设备时失败,请检查KepServer配置, 堆栈原因:" + ex.Message, true);
                }
            }
            else
            {
                ShowLinkState(null);
            }
            
        }

       
        /// <summary>
        /// 
        /// </summary>
        /// <param name="config">配置 1高配,2低配 </param>
        /// <param name="leftOrRight">1左右,2左,3右</param>
        /// <param name="state">1允许生产,0生产完成</param>
        public void SendToPLC(int config, int leftOrRight, int state)
        {
            if (ConfigurationManager.AppSettings["IsHaveVisual"] == "1")
            {
                if (opcHelper.opcItemm1.Count() == 0)
                {
                    throw new Exception("没有加载设备地址标记,地址标记列表为空.");
                }
                ShowDevState(true);
                //opcItemm1[2].ItemID
                opcHelper.opcItemm1[0].Write(config);//配置 
                opcHelper.opcItemm1[1].Write(leftOrRight); //左右
                opcHelper.opcItemm1[2].Write(state); //完成信号, 发送时写1,完成时写0
                                                     //opcHelper.opcItemm1[3].Write(1);  

                ShowDevState(true);
                //LogHelper.Write($"向设备发送工位[{stationCode}],配置[{cfg}]");
            }

        }

        void opcGroup1_DataChange(int TransactionID, int NumItems, ref Array ClientHandles, ref Array ItemValues, ref Array Qualities, ref Array TimeStamps)
        {
            try
            {
                for (int i = 1; i <= NumItems; i++)
                {
                    int handle = Convert.ToInt32(ClientHandles.GetValue(i).ToString().Trim());
                    string value = ItemValues.GetValue(i).ToString();
                    string address = opcHelper.opcItemm1[(Convert.ToInt32(ClientHandles.GetValue(i)))].ItemID;

                    if (handle == 2)
                    {
                        if (value == "0")
                        {
                            ShowDevState(false);

                        }
                        else if (value == "1")
                        {
                            ShowDevState(true);
                        }
                       
                    }
                    if (handle == 1)
                    {

                    }
                }
            }
            catch (Exception ex)
            {
                LogErrBLL.AddInfo(ex.ToString(), MethodBase.GetCurrentMethod());
            }
        }
        Dictionary<int, string> GetDevInfo()
        {
            Dictionary<int, string> dict = new Dictionary<int, string>();

            //正式
            //dict.Add(0, "BBMPT.ZP214.Config");
            //dict.Add(1, "BBMPT.ZP214.LeftOrRight");
            //dict.Add(2, "BBMPT.ZP214.State");
            //dict.Add(3, "BBMPT.ZP214.Pulse");

            //测试
            dict.Add(0, "BBMPT_TEST.Dev1.Config");
            dict.Add(1, "BBMPT_TEST.Dev1.LeftOrRight");
            dict.Add(2, "BBMPT_TEST.Dev1.State");
            dict.Add(3, "BBMPT_TEST.Dev1.Pulse");

            return dict;
        }


        #endregion

        #region business
        void ShowParamDialog(string cfg, string pm)
        {
            _conditionDialog = new FrmDoorSill_214_3_Condition(cfg, pm);
            _conditionDialog.AfterOkButtonClick += (configCode, produceModel) => {
                if ((txtConfig.Text?.Trim()+ txtProduceModel.Text?.Trim()) != (configCode+ produceModel) )
                {
                    _leftScanCode = "";
                    _rightScanCode = "";
                    txtLastScanL.Text = "";
                    txtLastScanR.Text = "";
                    txtConfig.Text = "";
                    txtProduceModel.Text = "";
                }
                
                txtConfig.Text = configCode;
                txtProduceModel.Text = produceModel;
                this.Show();
                _conditionDialog.Hide();
            };

            if (string.IsNullOrEmpty(cfg))
            {
                _conditionDialog.FormClosed += (arg1, arg2) => {
                    this.Close();
                    this.Dispose();

                };
            }
           
            _conditionDialog.ShowDialog();

        }
        void ScanBarCode(TextBox scanBox)
        {
            try
            {
                string leftOrRightModel = txtProduceModel.Text?.Trim();
                //_lastScan = 
                if (lbScanState.Text.StartsWith("处理中"))
                {
                    ShowHint($"设备正在处理中,请等待完成后,再重新操作", true);
                    scanBox.Focus();
                    scanBox.SelectAll();
                    return;
                }
               
                ShowHint("", true);
                int produceModel = 0;
                int config = 0;
                string barCode = string.Empty;
                string tableName = string.Empty;
                if (VerifyConfig(ref produceModel, ref config, ref barCode, ref tableName) == false)
                    return;


                if (ProScreenFunc.IsBarCodeExsit214(barCode) == false)
                {
                    ShowHint($"条码[{barCode}]在系统中不存在,请扫新的条码", true);
                    scanBox.Focus();
                    scanBox.SelectAll();
                    return;
                }
                if (ProScreenFunc.IsScanNew(barCode, tableName) == true)
                {
                    ShowHint($"条码[{barCode}]已存在扫码记录,请扫新的条码", true);
                    scanBox.Focus();
                    scanBox.SelectAll();
                    return;
                }
                string scanLeftOrRight = string.Empty;
                if( ProScreenFunc.GetPartNameByStock(barCode.Substring(0, 10)).Contains("左"))
                {
                    scanLeftOrRight = "左";
                }
                else
                {
                    scanLeftOrRight = "右";
                }

                if((leftOrRightModel =="左" && scanLeftOrRight == "右")|| (leftOrRightModel == "右" && scanLeftOrRight == "左"))
                {
                    ShowHint($"生产模式为[{leftOrRightModel}],当前扫码为[{scanLeftOrRight}],与设置不匹配", true);
                    return;
                }

                if (scanLeftOrRight == "左")
                {
                    txtLastScanL.Text = barCode;
                    _leftScanCode = barCode;
                }
                else
                {
                    txtLastScanR.Text = barCode;
                    _rightScanCode = barCode;
                }

                txtLeftScan.Text = "";
                if (leftOrRightModel == "左右")
                {
                    if (string.IsNullOrEmpty(_leftScanCode) || string.IsNullOrEmpty(_rightScanCode))   // txtLeftScan
                    {
                        ShowHint($"扫描条码{scanLeftOrRight}条码:{barCode}", false);
                        return;
                    }
                    if (_leftScanCode == _rightScanCode)
                    {
                        _leftScanCode = string.Empty;
                        _rightScanCode = string.Empty;
                        ShowHint($"左侧条码和右侧条码不能相同,请重新扫描条码", true);
                        return;
                    }


                    ProScreenFunc.AddScanRecordNew(_leftScanCode, "LR", "左", tableName);
                    ProScreenFunc.AddScanRecordNew(_rightScanCode, "RL", "右", tableName);

                    ShowHint($"操作条码左:{_leftScanCode} 右:{_rightScanCode} ,操作成功", false);
                    _leftScanCode = string.Empty;
                    _rightScanCode = string.Empty;
                }
                else
                {
                    ProScreenFunc.AddScanRecordNew(barCode, "", scanLeftOrRight, tableName);
                    ShowHint($"操作{scanLeftOrRight}条码:{_leftScanCode},操作成功", false);
                }

                SendToPLC(config, produceModel, 1);

                txtLastScanL.Text = "";
                txtLastScanR.Text = "";

                //if (model == "左右")
                //{
                //    LeftAndRightFocus();
                //}
                Action searchAction = GetScanRecords;
                searchAction.BeginInvoke(null, null);

            }
            catch(Exception ex)
            {
                ShowHint("扫码处理时发生错误,错误内容:" + ex.Message, true);
            }
            


        }
        void GetScanRecords()
        {
            DateTime timeFr = DateTime.Now;
            DateTime timeTo = DateTime.Now;
            _syncontext.Send(rst1 =>
            {
                DateTime.TryParse(lbBegin.Text, out timeFr);
                DateTime.TryParse(lbEnd.Text, out timeTo);

                DataTable dt = ProScreenFunc.GetScanRecord_Lasers(timeFr, timeTo,"");
                dgridScanRecords.DataSource = dt;

                txtAllQty.Text = dt.Rows.Count.ToString();

                var grp1 = dt.AsEnumerable().GroupBy(p => p.Field<string>("LeftOrRight"));
                foreach (var item1 in grp1)
                {
                    if (item1.Key == "左")
                    {
                        txtLeftQty.Text = item1.ToList().Count.ToString();
                    }
                    else
                    {
                        txtRightQty.Text = item1.ToList().Count.ToString();
                    }
                }

                var grp2 = dt.AsEnumerable().GroupBy(p => p.Field<string>("Cfg"));
                foreach (var item2 in grp2)
                {
                    if (item2.Key == "高")
                    {
                        txtHighQty.Text = item2.ToList().Count.ToString();
                    }
                    else
                    {
                        txtLowQty.Text = item2.ToList().Count.ToString();
                    }
                }
            }, null);

           
        }
        bool VerifyConfig( ref int produceModel,ref int config,ref string barCode,ref string tableName)
        {
            int cfg = 1;
            string leftOrRight = txtProduceModel.Text?.Trim();
            if (string.IsNullOrEmpty(leftOrRight))
            {
                ShowHint("生产模式不能为空", true);
                return false;
            };
            if (string.IsNullOrEmpty(txtConfig.Text))
            {
                ShowHint("当前配置不能为空", true);
                return false;
            };
            if (txtConfig.Text?.Trim() == "高配")
            {
                config = 1;
                tableName = "tb_ScanRecord_Laser";
            }
            else if (txtConfig.Text?.Trim() == "低配")
            {
                config = 2;
                tableName = "tb_ScanRecord_LaserL";
            }
            else
            {
                ShowHint("当前配置内容格式错误", true);
                return false;
            }

            //string model = txtProduceModel.Text?.Trim();
            //if (model!="左右" &&  model.Contains(leftOrRight)==false)
            //{
            //    ShowHint($"当前输入框为[{leftOrRight}],当前生产模式为[{model}],二者不匹配.", true);
            //    return false;
            //}
            if(leftOrRight == "左")
            {
                produceModel = 2;
                
            }
            else if (leftOrRight == "右")
            {
                produceModel = 3;
            }
            else if (leftOrRight == "左右")
            {
                produceModel = 1;
            }
            else
            {
                ShowHint("生产模式内容格式错误", true);
                return false;
            }

            //if (leftOrRight == "左")
            //{
                barCode = txtLeftScan.Text?.Trim();
            //}
            //else
            //{
            //    barCode = txtRightScan.Text?.Trim();
            //}

            if (string.IsNullOrEmpty(barCode))
            {
                ShowHint("扫描条码为空", true);
                return false;
            }
            if (barCode.Length!=20)
            {
                ShowHint("请扫20位塑件码", true);
                return false;
            }
            return true;
        }
        #endregion

        #region tools



        void ShowHint(string txt, bool isErr)
        {
            lbMsg.Text = txt;
            if (isErr)
            {
                lbMsg.ForeColor = Color.Red;
            }
            else
            {
                lbMsg.ForeColor = Color.Green;
            }
        }

        /// <summary>
        /// 显示PLC连接状态
        /// </summary>
        /// <param name="isLink"></param>
        void ShowLinkState(bool? isLink)
        {
            if (isLink==true)
            {
                lbLinkState.Text = "连接成功";
                lbLinkState.BackColor = Color.Green;
            }
            else if (isLink == false)
            {
                lbLinkState.Text = "连接失败";
                lbLinkState.BackColor = Color.Red;
            }
            else if (isLink == null)
            {
                lbLinkState.Text = "离线模式";
                lbLinkState.BackColor = Color.Red;
            }
        }

        /// <summary>
        /// 显示设备状态
        /// </summary>
        /// <param name="isBusy"></param>
        void ShowDevState(bool isBusy)
        {
            if (isBusy)
            {
                lbScanState.Text = "处理中...";
                lbScanState.BackColor = Color.Red;
            }
            else
            {
                lbScanState.Text = "允许扫码";
                lbScanState.BackColor = Color.Green;
            }

        }

        void ClearDisplay()
        {
            lbLinkState.Text = "";
            lbScanState.Text = "";
            txtLeftScan.Text = "";
            txtAllQty.Text = "0";
            txtLeftQty.Text = "0";
            txtRightQty.Text = "0";
            txtHighQty.Text = "0";
            txtLowQty.Text = "0";
            lbMsg.Text = "";
        }





        #endregion

        private void btnSearch_Click(object sender, EventArgs e)
        {
            FrmDoorSill_214_3_Grid gridFrm = new FrmDoorSill_214_3_Grid();
            gridFrm.Show();
        }

        private void dateTimer_Tick(object sender, EventArgs e)
        {
            lbTime.Text = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
        }

        private void dgridScanRecords_CellContentClick(object sender, DataGridViewCellEventArgs e)
        {

        }
    }
}