using Chloe;
using DNSD_DB;
using DNSD_DB.Entity;
using NDSD_Screwdriver.Tool;
using NDSD_TouchSocket;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Text;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Xml.Serialization;

namespace NDSD_Screwdriver
{
    public partial class MainForm : Form
    {
        /// <summary>
        /// 输出端口操作
        /// </summary>
        private DOperate DOperate;

        /// <summary>
        /// TCP服务器
        /// </summary>
        private TcpServer server = TcpServer.Instance;

        /// <summary>
        /// 前端列表集合
        /// </summary>
        private List<MonitorEntity> monitorEntities;

        private List<RFIDConfigEntity> RFIDConfigEntitys;

        private Random rand = new Random();

        /// <summary>
        /// RFID状态列表
        /// </summary>
        public List<RFIDStatesEntity> RFIDStatesEntities;

        /// <summary>
        /// 报警灯配置实例
        /// </summary>
        public List<LightsEntity> lightsEntities;

        /// <summary>
        /// 日志实例
        /// </summary>
        public List<RFIDLogsEntity> RFIDLogsEntitys;

        /// <summary>
        /// 日志数据库操作实例
        /// </summary>
        public IDbContext LogContext;

        Thread flashThread;

        SerialPortFactory serialPort;

        private CancellationTokenSource cancellationTokenSource;

        public int textRFID = 0;

        Thread alarmThread;

        int FlashIndex = 0;

        public MainForm()
        {
            SqlLiteTool.CreateTable(AppTool.GetDb());
            InitializeComponent();
            LogContext = SqlLiteTool.GetDb(AppTool.GetDb());
            RFIDLogsEntitys = LogContext.Query<RFIDLogsEntity>().OrderByDesc(a => a.CreateTime).Take(200).ToList();
            LogDataGridView.AutoGenerateColumns = false;
            LogDataGridView.DataSource = null;
            LogDataGridView.DataSource = RFIDLogsEntitys;

            DOperate = new DOperate();
            if (!server.ServerOpen(MemorySetting.ServerIP, MemorySetting.ServerPort))
            {
                MessageBox.Show("服务端打开失败！");
                FormUtils.LogInsert(LogContext, "服务端打开失败");
            }
            serialPort = new SerialPortFactory();
            StartLongRunningTask();
        }

        private void MainForm_FormClosed(object sender, FormClosedEventArgs e)
        {
            if (server != null)
            {
                if (!server.ServerStop())
                {
                    MessageBox.Show("服务端关闭失败！");
                    FormUtils.LogInsert(LogContext, "服务端关闭失败");

                }
                if (!server.ServerDispose())
                {
                    MessageBox.Show("服务端释放失败！");
                    FormUtils.LogInsert(LogContext, "服务端释放失败");
                }
            }
            if (flashThread != null)
            {
                flashThread.Abort();
            }
            if (alarmThread != null)
            {
                alarmThread.Abort();
            }
        }

        #region 按钮

        /// <summary>
        /// 打开DO测试
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void DOTest_Click(object sender, EventArgs e)
        {
            //string str = serialPort.Read();
            ScrewdriverTest screwdriverTest = new ScrewdriverTest(server, DOperate);
            screwdriverTest.Show();
        }

        /// <summary>
        /// 初始化按钮
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void InitButton_Click(object sender, EventArgs e)
        {
            FlashIndex = 0;
            textRFID = 0;
            if (flashThread != null)
            {
                flashThread.Abort();
            }
            FlashThread();
            if (alarmThread != null)
            {
                alarmThread.Abort();
            }
            AlarmThread();
            //读取rfid数据
            var ctx = SqlLiteTool.GetDb(AppTool.GetDb());
            var list = ctx.Query<RFIDConfigEntity>().Where(x => x.IsEnable == true).ToList();
            var strs = list.Select(x => x.RfidNo).ToArray();
            RFIDStatesEntities = new List<RFIDStatesEntity>();
            RFIDStatesEntities.Clear();
            foreach (var a in strs)
            {
                RFIDStatesEntities.Add(new RFIDStatesEntity()
                {
                    RFIDValue = a,
                });
            }
            RFIDStatesEntities[0].RFIDState = 2;
            FormUtils.LogInsert(LogContext, "RFID " + 0 + " 准备工作", RFIDStatesEntities[0].RFIDValue);
            GetLog();
            //读取报警灯数据
            lightsEntities = new List<LightsEntity>();
            lightsEntities.Clear();
            for (int i = 0; i < list.Count; i++)
            {
                lightsEntities.Add(new LightsEntity()
                {
                    Green = Convert.ToInt32(list[i].Green),
                    Yellow = Convert.ToInt32(list[i].Yellow),
                    Red = Convert.ToInt32(list[i].Red),
                });
            }
            //初始化列表框架
            monitorEntities = new List<MonitorEntity>();
            monitorEntities.Clear();
            for (int i = 0; i < RFIDStatesEntities.Count; i++)
            {
                monitorEntities.Add(new MonitorEntity()
                {
                    RowIndex = i,
                    RowEntitys = InitRows(i)
                });
            }
            //更新值
            for (int i = 0; i < RFIDStatesEntities.Count; i++)
            {
                monitorEntities[i].RowEntitys[1].Value = RFIDStatesEntities[i].RFIDValue;
            }
            flashThread.Start();
            alarmThread.Start();
            RefreshRoll();
            RefreshIO();
        }

        /// <summary>
        /// 打开设置界面
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void SettingButton_Click(object sender, EventArgs e)
        {
            FrmSetting frmSetting = new FrmSetting();
            frmSetting.Show();
        }

        /// <summary>
        /// 服务端重启按钮
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ServerRestartButton_Click(object sender, EventArgs e)
        {
            if (server.ServerRestart(MemorySetting.ServerIP, MemorySetting.ServerPort))
            {
                MessageBox.Show("服务器重启成功！");
                FormUtils.LogInsert(LogContext, "服务器重启成功");
            }
            else
            {
                MessageBox.Show("服务器重启失败！请手动启动服务器。");
                FormUtils.LogInsert(LogContext, "服务器重启失败");

            }

        }

        /// <summary>
        /// 服务端手动启动
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void StartServerButton_Click(object sender, EventArgs e)
        {
            if (!server.ServerOpen(MemorySetting.ServerIP, MemorySetting.ServerPort))
            {
                MessageBox.Show("服务端打开失败！");
                FormUtils.LogInsert(LogContext, "服务端打开失败");

            }
            else
            {
                MessageBox.Show("服务器启动成功");
                FormUtils.LogInsert(LogContext, "服务器启动成功");
            }
        }

        /// <summary>
        /// 服务端手动停止
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ServerStopButton_Click(object sender, EventArgs e)
        {
            if (server != null)
            {
                if (!server.ServerStop())
                {
                    MessageBox.Show("服务端关闭失败！");
                    FormUtils.LogInsert(LogContext, "服务端关闭失败");

                }
                if (!server.ServerDispose())
                {
                    MessageBox.Show("服务端释放失败！");
                    FormUtils.LogInsert(LogContext, "服务端释放失败");

                }
            }
        }

        /// <summary>
        /// 测试按钮
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void TestButton1_Click(object sender, EventArgs e)
        {
            if (RFIDStatesEntities.Count == 0)
            {
                MessageBox.Show("请先初始化RFID列表！");
            }
            else if (textRFID == RFIDStatesEntities.Count)
            {
                SetNowWorkRow("0000000");
                textRFID = 0;
                return;
            }
            SetNowWorkRow(RFIDStatesEntities[textRFID].RFIDValue);
            if (++textRFID > RFIDStatesEntities.Count)
            {
                textRFID = 0;
                return;
            }

        }

        #endregion

        #region 功能性方法


        /// <summary>
        /// 根据读取到的RFID条码设置当前工作的行 并且更新state
        /// </summary>
        /// <param name="rfid">读取到的RFID</param>
        private void SetNowWorkRow(string rfid)
        {
            //设置RFID状态
            int flag = 0;
            for (int i = 0; i < RFIDStatesEntities.Count; i++)
            {
                if (RFIDStatesEntities[i].RFIDValue == rfid && RFIDStatesEntities[i].RFIDState == 2)
                {
                    RFIDStatesEntities[i].RFIDState = 1;
                    FormUtils.LogInsert(LogContext, "RFID " + i + " 开始工作", RFIDStatesEntities[i].RFIDValue);
                    GetLog();
                    if (i - 1 >= 0)
                    {
                        string rfidValue = RFIDStatesEntities[i - 1].RFIDValue;
                        var leastTime = RFIDLogsEntitys.Where(x => x.RFIDId == rfidValue)/*.OrderByDescending(x => x.CreateTime)*/.FirstOrDefault().CreateTime;
                        double timeSpan = (DateTime.Now - leastTime).TotalSeconds;
                        if (timeSpan >= MemorySetting.AlarmTimeValue)
                        {
                            RFIDStatesEntities[i - 1].RFIDState = 4;
                            FormUtils.LogInsert(LogContext, "RFID " + i + " 超时结束", RFIDStatesEntities[i].RFIDValue);
                        }
                        if (timeSpan < MemorySetting.AlarmTimeValue)
                        {
                            RFIDStatesEntities[i - 1].RFIDState = 3;
                            FormUtils.LogInsert(LogContext, "RFID " + (i - 1) + " 成功结束", RFIDStatesEntities[i].RFIDValue);
                        }
                        GetLog();
                    }
                    if (i + 1 < RFIDStatesEntities.Count)
                    {
                        FormUtils.LogInsert(LogContext, "RFID " + (i + 1) + " 准备工作", RFIDStatesEntities[i].RFIDValue);
                        GetLog();
                        RFIDStatesEntities[i + 1].RFIDState = 2;
                        FlashIndex = i + 1;
                    }
                    else
                    {
                        flashThread.Abort();
                    }
                    flag = 1;
                    break;
                }
            }
            if (flag == 0) //列表里没有已读的RFID
            {
                for (int i = 0; i < RFIDStatesEntities.Count; i++)
                {
                    if (RFIDStatesEntities[i].RFIDState == 1)
                    {
                        string rfidValue = RFIDStatesEntities[i - 1].RFIDValue;
                        var leastTime = RFIDLogsEntitys.Where(x => x.RFIDId == rfidValue)/*.OrderByDescending(x => x.CreateTime)*/.FirstOrDefault().CreateTime;
                        double timeSpan = (DateTime.Now - leastTime).TotalSeconds;
                        if (timeSpan >= MemorySetting.AlarmTimeValue)
                        {
                            RFIDStatesEntities[i].RFIDState = 4;
                            FormUtils.LogInsert(LogContext, "RFID " + i + " 超时结束", RFIDStatesEntities[i].RFIDValue);
                        }
                        if (timeSpan < MemorySetting.AlarmTimeValue)
                        {
                            RFIDStatesEntities[i].RFIDState = 3;
                            FormUtils.LogInsert(LogContext, "RFID " + (i - 1) + " 成功结束", RFIDStatesEntities[i].RFIDValue);
                        }
                    }
                }
            }
            //刷新前端灯的状态
            for (int i = 0; i < RFIDStatesEntities.Count; i++)
            {
                if (RFIDStatesEntities[i].RFIDState == 1)
                {
                    SetRowsLightState(i, 1);
                }
                else if (RFIDStatesEntities[i].RFIDState == 3)
                {
                    SetRowsLightState(i, 0);
                }
                else if (RFIDStatesEntities[i].RFIDState == 4)
                {
                    SetRowsLightState(i, 2);
                }
                else
                {
                    SetRowsLightState(i, Brushes.Transparent);
                }
            }
            if(flashThread.ThreadState == ThreadState.Running)
            {
                flashThread.Suspend();
                Thread.Sleep(100);
            }
            //刷新IO的状态
            for (int i = 0; i < RFIDStatesEntities.Count; i++)
            {
                
                if (RFIDStatesEntities[i].RFIDState == 1)
                {
                    DOperate.DOpen(lightsEntities[i].Yellow);
                    Thread.Sleep(100);
                }
                else if (RFIDStatesEntities[i].RFIDState == 3)
                {
                    DOperate.DOpen(lightsEntities[i].Green);
                    Thread.Sleep(100);
                    DOperate.DClose(lightsEntities[i].Yellow);
                    Thread.Sleep(100);
                }
                else if (RFIDStatesEntities[i].RFIDState == 4)
                {
                    DOperate.DOpen(lightsEntities[i].Red);
                    Thread.Sleep(100);
                    DOperate.DClose(lightsEntities[i].Yellow);
                    Thread.Sleep(100);
                }
            }
            if (flashThread.ThreadState == ThreadState.Stopped)
            {
                flashThread.Resume();
            }
            RefreshRoll();
        }

        /// <summary>
        /// 初始化一行
        /// </summary>
        /// <param name="rowNo">当前的初始化行数</param>
        /// <returns></returns>
        private List<RowEntity> InitRows(int rowNo)
        {
            List<RowEntity> rowEntities = new List<RowEntity>();
            for (int i = 0; i < 3; i++)
            {
                rowEntities.Add(new RowEntity()
                {
                    ColumnIndex = i,
                });
            }
            return rowEntities;
        }

        /// <summary>
        /// 刷新列表
        /// </summary>
        private void RefreshRoll()
        {
            List<string[]> values = new List<string[]>();
            for (int i = 0; i < RFIDStatesEntities.Count; i++)
            {
                values.Add(new string[]
                {
                    "", "", ""
                });
            }
            ScrewdriverMonitor.SetTableValue(values);

        }

        private void SetRowsLightState(int index, LightState lightState)
        {
            SetRowsLightState(index, FormUtils.EnumColorToBrush(lightState));
        }

        private void SetRowsLightState(int index, int lightState)
        {
            SetRowsLightState(index, (LightState)lightState);
        }

        /// <summary>
        /// 设置指定行指示灯的状态以及工作的行的标识
        /// </summary>
        /// <param name="brush"></param>
        private void SetRowsLightState(int index, Brush brush)
        {
            monitorEntities[index].RowEntitys[2].Color = brush;
            //工作中箭头指示
            for (int i = 0; i < RFIDStatesEntities.Count; i++)
            {
                monitorEntities[i].RowEntitys[0].Value = RFIDStatesEntities[i].RFIDState == 1 ? "=>" : "";
            }
        }

        /// <summary>
        /// IO控制
        /// </summary>
        private void LightControl()
        {

        }

        private void ComDataAnalysis(string str)
        {

        }

        /// <summary>
        /// 列表回调函数
        /// </summary>
        /// <param name="g"></param>
        /// <param name="rowIndex"></param>
        /// <param name="colIndex"></param>
        /// <param name="rectangle"></param>
        /// <param name="value"></param>
        /// <param name="sf"></param>
        private void ScrewdriverMonitor_OnDrawCellTextEvent(Graphics g, int rowIndex, int colIndex, RectangleF rectangle, string value, StringFormat sf)
        {
            foreach (MonitorEntity entity in monitorEntities)
            {
                if (rowIndex == entity.RowIndex)
                {
                    foreach (RowEntity rowEneiey in entity.RowEntitys)
                    {
                        if (colIndex == rowEneiey.ColumnIndex)
                        {
                            g.FillRectangle(rowEneiey.Color, rectangle);
                            g.DrawString(rowEneiey.Value, this.ScrewdriverMonitor.Font, Brushes.Black, rectangle, sf);
                        }
                    }
                }
            }
        }

        /// <summary>
        /// RFID刷新任务
        /// </summary>
        private void StartLongRunningTask()
        {
            cancellationTokenSource = new CancellationTokenSource();
            Task.Run(() =>
            {
                while (!cancellationTokenSource.Token.IsCancellationRequested)
                {
                    // 这里是你的长期运行逻辑
                    Thread.Sleep(rand.Next(4, 16) * 1000); // 模拟一些长时间的工作
                }
            }, cancellationTokenSource.Token);
        }

        /// <summary>
        /// 等待工作指示灯闪烁进程
        /// </summary>
        private void FlashThread()
        {
            //等待闪烁线程
            flashThread = new Thread(() =>
            {
                while (true)
                {
                    DOperate.DTimeOpen(lightsEntities[FlashIndex].Yellow, 1);
                    monitorEntities[FlashIndex].RowEntitys[2].Color = Brushes.Yellow;
                    RefreshRoll();
                    Thread.Sleep(1000);
                    monitorEntities[FlashIndex].RowEntitys[2].Color = Brushes.Transparent;
                    RefreshRoll();
                    Thread.Sleep(1000);
                }
            });
        }

        /// <summary>
        /// 获取Log
        /// </summary>
        private void GetLog()
        {
            RFIDLogsEntitys = LogContext.Query<RFIDLogsEntity>().OrderByDesc(a => a.CreateTime).Take(200).ToList();
            LogDataGridView.DataSource = null;
            LogDataGridView.DataSource = RFIDLogsEntitys;
        }

        /// <summary>
        /// 等待工作指示灯闪烁进程
        /// </summary>
        private void AlarmThread()
        {
            //等待闪烁线程
            alarmThread = new Thread(() =>
            {
                while (true)
                {

                    Thread.Sleep(500);
                }
            });
        }


        /// <summary>
        /// 获取准备行
        /// </summary>
        /// <returns>准备行index</returns>
        private int GetReadyRowIndex()
        {
            for (int i = 0; i < RFIDStatesEntities.Count; i++)
            {
                if (RFIDStatesEntities[i].RFIDState == 2)
                {
                    return i;
                }
            }
            return -1;
        }

        /// <summary>
        /// 获取正在工作的行
        /// </summary>
        /// <returns>工作行index</returns>
        private int GetNowRowIndex()
        {
            for (int i = 0; i < RFIDStatesEntities.Count; i++)
            {
                if (RFIDStatesEntities[i].RFIDState == 1)
                {
                    return i;
                }
            }
            return -1;
        }

        private void RefreshIO()
        {
            for (int i = 0; i < RFIDStatesEntities.Count; i++)
            {
                DOperate.DClose(lightsEntities[i].Yellow);
                Thread.Sleep(100);
                DOperate.DClose(lightsEntities[i].Red);
                Thread.Sleep(100);
                DOperate.DClose(lightsEntities[i].Green);
                Thread.Sleep(100);
            }
        }
        #endregion

    }
}
