using Microsoft.Win32;
using Modbus.Device;
using Sunny.UI;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Timers;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using 头罩视野.Services;
using 头罩视野.Services.Data;
using static 头罩视野.TestDataStore;
namespace 头罩视野.Views
{
    /// <summary>
    /// RecordDate.xaml 的交互逻辑
    /// </summary>
    /// 

    public partial class RecordDate : Page

    {
        private IModbusMaster _modbusMaster => ModbusResourceManager.Instance.ModbusMaster;
        private System.Timers.Timer? _plcReadTimer;
        // 表跟数据存储列表
        public List<dynamic> LeftEyeDataList = new List<dynamic>();
        public List<dynamic> RightEyeDataList = new List<dynamic>();

        public List<dynamic> CalLeftData = new List<dynamic>();
        public List<dynamic> CalRightData = new List<dynamic>();

        // 配置：和你PLC地址完全对应  左目
        private const int LeftEyeStartAddress = 1362; // D1362
        private const int ChannelCount = 72;          // 72个通道
        private const int RegistersPerChannel = 1;   // 每个通道2个寄存器（Float）

        //右目
     
        private const int RightEyeStartAddress = 1218; // D1218
        //// 长按清除用
        private bool _isClearPressed = false;
        private Thread _clearThread;

        public RecordDate()
        {
            InitializeComponent();
            DynamicHeader();
            // 2. 调用（名字和上面的变量一致）
            // 2. 启动定时器，定时读取数据（每100ms读一次）
            StartPlcReadTimer(1000);

            //// 判断连接
            if (!ModbusHelper.IsConnected)
            {
                MessageBox.Show("未连接");
                return;
            }
        }
        //动态生成表头
        void DynamicHeader()
        {
            // 2. 循环生成 72 个 ch 列
            for (int i = 1; i <= ChannelCount; i++)
            {
                dataGrid1.Columns.Add(new DataGridTextColumn
                {
                    Header = $"ch.{i}",
                    Binding = new System.Windows.Data.Binding($"Ch{i}")
                });
                dataGrid2.Columns.Add(new DataGridTextColumn
                {
                    Header = $"ch.{i}",
                    Binding = new System.Windows.Data.Binding($"Ch{i}")
                });
            }
        }
        public void StopPlcTimer()
        {
            if (_plcReadTimer != null)
            {
                _plcReadTimer.Stop();
                _plcReadTimer.Dispose();
                _plcReadTimer = null;
        
            }
        }
        //定时读取 PLC 数据
        public void StartPlcReadTimer(int intervalMs)
             
        {
            // 防止重复创建
            if (_plcReadTimer != null && _plcReadTimer.Enabled)
                return;
            _plcReadTimer = new System.Timers.Timer(intervalMs);
            _plcReadTimer.Elapsed += ReadPlcData;
            _plcReadTimer.Start();
        }

        private void ReadPlcData(object? sender, ElapsedEventArgs e)
        {
            // 左通道
            ReadPlcDataGeneric(
                slaveAddress: 1,
                startAddress: LeftEyeStartAddress,
                count: 72,
                dataList: LeftEyeDataList,
                dataGrid: dataGrid1);

            //// 右通道
            //ReadPlcDataGeneric(
            //    slaveAddress: 1,
            //    startAddress: RightEyeStartAddress,
            //    count: (ushort)(ChannelCount * RegistersPerChannel),
            //    dataList: RightEyeDataList,
            //    dataGrid: dataGrid2);
        }

        /// <summary>
        /// 读取PLC HoldingRegisters 并更新到列表和DataGrid

        /// <param name="slaveAddress">设备站号（一般是1）</param>
        /// <param name="startAddress">起始地址</param>
        /// <param name="count">寄存器总数</param>
        /// <param name="dataList">数据缓存列表</param>
        /// <param name="dataGrid">要更新的DataGrid控件</param>


        /// 通用PLC读取方法（左右通道通用）
        /// </summary>
        private void ReadPlcDataGeneric(
            byte slaveAddress,
            ushort startAddress,
            ushort count,
            List<dynamic> dataList,
            DataGrid dataGrid)
        {
            if (_modbusMaster == null || !ModbusHelper.TcpClient.Connected)
                return;

            try
            {
                // 读取寄存器
                ushort[] registers = _modbusMaster.ReadHoldingRegisters(
                    slaveAddress: slaveAddress,
                    startAddress: startAddress,
                    numberOfPoints: (ushort)count);

                uint[] data32 = ConvertRegistersToUInt32(registers, true);
                // 先把变量存为局部变量，解决闭包问题
                var regCopy = data32;
                var listCopy = dataList;
                var gridCopy = dataGrid;

                // 交给UI线程更新数据和表格
                Dispatcher.Invoke(() =>
                {
                    AddPlcDataRow(regCopy, listCopy, gridCopy);
                });

                System.Diagnostics.Debug.WriteLine("读取寄存器数据" );
            }
            catch (Exception ex)
            {
                Console.WriteLine($"PLC读取失败: {ex.Message}");
            }
        }

        private uint[] ConvertRegistersToUInt32(ushort[] registers, bool isLittleEndian)
        {
            if (registers == null || registers.Length % 2 != 0)
                throw new ArgumentException("寄存器数量必须是偶数");

            uint[] result = new uint[registers.Length / 2];
            for (int i = 0; i < result.Length; i++)
            {
                ushort low = registers[i * 2];
                ushort high = registers[i * 2 + 1];

                if (isLittleEndian)
                    result[i] = (uint)(low | (high << 16));
                else
                    result[i] = (uint)(high | (low << 16));
            }
            return result;
        }
        /// <summary>
        /// 把PLC数据添加到动态表格

        private int _rowIndex = 1;

        private void AddPlcDataRow(uint[] registers, List<dynamic> dataList, DataGrid dg)
        {
            // 1. 先清空临时列表，不影响历史数据
            //dataList.Clear();

            // 2. 构建一次采集的单行数据（包含所有通道）
            dynamic newRow = new System.Dynamic.ExpandoObject();
            var dict = (IDictionary<string, object>)newRow;

            // 固定列：编号、时间、日期（每次采集的这一行）
            dict["Id"] = _rowIndex++;
            dict["Time"] = DateTime.Now.ToString("HH:mm:ss");
            dict["Date"] = DateTime.Now.ToString("yyyy-MM-dd");

            // 关键：循环给所有通道赋值，一行里包含所有通道值
            for (int i = 0; i < registers.Length; i++)
            {
                // 字段名和你界面列绑定的名称必须完全一致，比如 ch.1 / Ch1
                dict[$"Ch{i + 1}"] = registers[i];
                //dict[$"ch.{i + 1}"] = registers[i];
            }

            // 3. 把这一行加到历史列表，实现“读多行”
            dataList.Add(newRow);

            // 4. 强制刷新DataGrid，让界面显示多行
            dg.Dispatcher.Invoke(() =>
            {
                dg.ItemsSource = null;
                dg.ItemsSource = dataList;
                dg.Items.Refresh(); // 强制刷新视图，避免不渲染
            });
        }

        //面积的计算方法
        //public void getAllData(List<dynamic> leftEyeDataList, List<dynamic> RightEyeDataList, int perAngle)

        //{

        //    // 1. 先去除异常值，生成新列表（不修改原列表）
        //    var filteredLeft = GetArea.RemoveOutliers(leftEyeDataList);
        //    var filteredRight = GetArea.RemoveOutliers(RightEyeDataList);
    
        //    //左目视野面积
        //    GlobalData.LeftEyeArea = GetArea.CalculateEyeArea(filteredLeft);
        //    //右目视野面积
        //    GlobalData.RightEyeArea = GetArea.CalculateEyeArea(filteredRight);
        //    //双目视野面积
        //    GlobalData.BinocularArea = GetArea.CalcBinocularArea(filteredLeft, filteredRight);

        //    //// 总视野面积
        //    GlobalData.TotalEyeArea = GlobalData.LeftEyeArea + GlobalData.RightEyeArea - GlobalData.BinocularArea;

        //    //// 空白视野面积
        //    GlobalData.BlankArea = GetArea.StandardTotal - GlobalData.TotalEyeArea;

        //    //视野保存率

        //    // 左眼平均值数组
        //    double[] leftAvg = GetArea.GetEyeAvgArray(filteredLeft);

        //    // 右眼平均值数组
        //    double[] rightAvg = GetArea.GetEyeAvgArray(RightEyeDataList);

        //    double leftLowerAngle = GetArea.CalcLowerAngle(leftAvg,  perAngle);
        //    double rightLowerAngle = GetArea.CalcLowerAngle(rightAvg, perAngle);
        //    //下方视野
        //    GlobalData.LowerVision = Math.Min(leftLowerAngle, rightLowerAngle);

        //    //视野保存率
        //    GlobalData.VisionRetentionRate = GetArea.CalcVisionRate(GlobalData.LeftEyeArea, GlobalData.RightEyeArea);

        //    //打印数值显示在系统上面
        //    System.Diagnostics.Debug.WriteLine("左目视野面积" + GlobalData.LeftEyeArea);
        //    System.Diagnostics.Debug.WriteLine("右目视野面积" + GlobalData.RightEyeArea);
        //    System.Diagnostics.Debug.WriteLine("双目视野面积" + GlobalData.BinocularArea);
        //    System.Diagnostics.Debug.WriteLine("总视野面积" + GlobalData.TotalEyeArea);
        //    System.Diagnostics.Debug.WriteLine("下方视野" + GlobalData.LowerVision);
        //    System.Diagnostics.Debug.WriteLine("视野保存率" + GlobalData.VisionRetentionRate);

        //}

 
        //#endregion

        // 保存左眼
        private void btnSaveLeft_Click(object sender, RoutedEventArgs e)
        {
            //SaveToCsv(LeftEyeDataList, $"左眼数据_{DateTime.Now:yyyyMMddHHmmss}.csv");
            ModbusHelper.SaveToCsv(LeftEyeDataList, $"左眼数据_{DateTime.Now:yyyyMMddHHmmss}.csv");
        }


        // 保存右眼
        private void btnSaveRight_Click(object sender, RoutedEventArgs e)
        {
            ModbusHelper.SaveToCsv(RightEyeDataList,$"右眼数据_{DateTime.Now:yyyyMMddHHmmss}.csv");
        }

        //清除
        private void btnClear_MouseDown(object sender, MouseButtonEventArgs e)
        {
            //_isClearPressed = true;
            //_clearThread = new Thread(() =>
            //{
            //    Thread.Sleep(500); // 长按1秒触发
            //    if (_isClearPressed)
            //    {
            //        Application.Current.Dispatcher.Invoke(() => ClearAllData());
            //    }
            //});
            //_clearThread.Start();
            _plcReadTimer?.Stop();
        }
        // 清除所有数据
        private void ClearAllData()
        {
            LeftEyeDataList.Clear();
            dataGrid1.Items.Clear();
            RightEyeDataList.Clear();
            dataGrid2.Items.Clear();

            MessageBox.Show("数据已清除");
        }

        private void btnClear_MouseUp(object sender, MouseButtonEventArgs e)
        {
            _isClearPressed = false;
            _clearThread?.Join(100); // 等待线程结束最多100毫秒，然后强制结束
        }
        private void Page_Unloaded(object sender, RoutedEventArgs e)
        {
            _plcReadTimer?.Stop();
            _plcReadTimer?.Dispose();
            //_modbusMaster?.Dispose();
            //ModbusHelper.TcpClient?.Close();

        }
        private void Page_Loaded(object sender, RoutedEventArgs e)
        {

        }
       

        private void GoHome(object s, RoutedEventArgs e) => NavigationService.Content = null;
        private void GoTest(object s, RoutedEventArgs e) => NavigationService.Content = new Views.PageTest();
        private void GoRecord(object s, RoutedEventArgs e) => NavigationService.Content = new Views.RecordDate();
        private void GoView(object s, RoutedEventArgs e) => NavigationService.Content = new Views.RecordPage();

      

        //NavigationService.Navigate(new Views.RecordDate()); 页面相互跳转
    }



    }
