using Modbus.Device;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO.Ports;
using System.Linq;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
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 System.Windows.Threading;
using System.Windows.Media.Animation;
using 自救器呼吸器综合检验仪;
using 自救器呼吸器综合检验仪.Data;

namespace 自救器呼吸器综合检验仪
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow3 : Window
    {
        private MainWindow _mainWindow;
        private MainWindow2 _mainWindow2;
        private MainWindow3 _mainWindow3;
        private MainWindow4 _mainWindow4;

        private ReportWindow3 _reportWindow3;
        private bool _wasRunning = false; // 上次检验的运行状态
        private bool _recordAdded = false;   // 本轮测试是否已插入记录
        private DateTime _testStartTime; // 测试开始时间
        private TcpClient _tcpClient => ModbusResourceManager.Instance.TcpClient;
        private IModbusMaster _modbusMaster => ModbusResourceManager.Instance.ModbusMaster;
        private const byte SlaveId = 1;        // PLC从站地址
                                               // Modbus通信

        private bool _isManualInput = false; // 手动输入标记：true=输入中（暂停读取），false=正常读取
        private readonly DispatcherTimer _readTimer;

        Function ma;
        DataChange c = new DataChange();

        public MainWindow3()
        {
            InitializeComponent();
            _readTimer = InitDispatcherTimer();
            //InitializeModbusTcp();
            BindInputFocusEvents();
        }

        private void BindInputFocusEvents()
        {
            // 地址400输入框（count）
            settingtime.GotFocus += (s, e) => _isManualInput = true;  // 获得焦点→暂停读取
            settingtime.LostFocus += (s, e) => _isManualInput = false; // 失去焦点→恢复读取

            //// 地址404输入框（count2）
            //count2.GotFocus += (s, e) => _isManualInput = true;
            //count2.LostFocus += (s, e) => _isManualInput = false;

            //// 地址406输入框（count3）
            //count3.GotFocus += (s, e) => _isManualInput = true;
            //count3.LostFocus += (s, e) => _isManualInput = false;
        }

        private DispatcherTimer InitDispatcherTimer()
        {
            var timer = new DispatcherTimer
            {
                Interval = TimeSpan.FromMilliseconds(500)
            };
            timer.Tick += async (s, e) =>
            {
                if (!_isManualInput && _modbusMaster != null)
                {

                    try
                    {
                        await ReadAllPlcDataAsync();
                    }
                    catch { }
                }
            };
            return timer;
        }



        //private void InitializeModbusTcp()
        //{
        //    try
        //    {
        //        // 从配置读取PLC连接信息
        //        string plcIp = "192.168.1.10";
        //        int plcPort = 502;

        //        _tcpClient = new TcpClient(plcIp, plcPort);
        //        _modbusMaster = ModbusIpMaster.CreateIp(_tcpClient);
        //        _modbusMaster.Transport.ReadTimeout = 3000;
        //        _modbusMaster.Transport.WriteTimeout = 3000;

        //        // 初始化定时器
        //        //InitializeTimers();
        //        // 初始化数据库
        //        //InitializeDatabase();
        //        _readTimer.Start();
        //        ma = new Function(_modbusMaster);
        //    }
        //    catch (Exception ex)
        //    {
        //        ShowErrorMsg($"Modbus初始化失败: {ex.Message}");
        //    }
        //}
        private async System.Threading.Tasks.Task ReadAllPlcDataAsync()
        {

            // 检查连接状态
            if (_tcpClient == null || !_tcpClient.Connected || _modbusMaster == null)
            {
                return;
            }
            // 仅在非手动输入时读取设置地址（避免覆盖输入）
            if (!_isManualInput)
            {
                await ReadAddr262DataAsync();
                await System.Threading.Tasks.Task.Delay(50);

                await ReadAddr404DataAsync();
                await System.Threading.Tasks.Task.Delay(50);




                await ReadAddr406DataAsync();
                await System.Threading.Tasks.Task.Delay(50);

                await ReadAddr130DataAsync();
                await System.Threading.Tasks.Task.Delay(50);
                await ReadAddr416DataAsync();


                await System.Threading.Tasks.Task.Delay(50);
                await ReadAddr1301DataAsync();

                await System.Threading.Tasks.Task.Delay(50);
                await ReadAddr4161DataAsync();



            }

            await ReadAddrStatusDataAsync();
        }

        private async System.Threading.Tasks.Task ReadAddr262DataAsync()
        {
            try
            {
                ushort[] registers = await System.Threading.Tasks.Task.Run(() =>
                    _modbusMaster?.ReadHoldingRegisters(1, 320, 2)
                );

                if (registers != null)
                {
                    float addr406Value = c.UshortToFloat(registers[1], registers[0]);
                    Dispatcher.Invoke(() => settingtime.Text = addr406Value.ToString("F2"));
                }
            }
            catch (Exception ex)
            {
                //ShowErrorMsg($"读取地址406失败：{ex.Message}");
            }
        }




        private async System.Threading.Tasks.Task ReadAddr416DataAsync()
        {
            try
            {
                ushort[] registers = await System.Threading.Tasks.Task.Run(() =>
                    _modbusMaster?.ReadHoldingRegisters(1, 1110, 2)
                );

                if (registers != null)
                {
                    float addr406Value = c.UshortToFloat(registers[1], registers[0]);
                    Dispatcher.Invoke(() => min3.Text = addr406Value.ToString("F2"));
                }
            }
            catch (Exception ex)
            {
                //ShowErrorMsg($"读取地址406失败：{ex.Message}");
            }
        }


        private async System.Threading.Tasks.Task ReadAddr1301DataAsync()
        {
            try
            {
                ushort[] registers = await System.Threading.Tasks.Task.Run(() =>
                    _modbusMaster?.ReadHoldingRegisters(1, 1112, 2)
                );

                if (registers != null)
                {
                    float addr406Value = c.UshortToFloat(registers[1], registers[0]);
                    Dispatcher.Invoke(() => min4.Text = addr406Value.ToString("F2"));
                }
            }
            catch (Exception ex)
            {
                //ShowErrorMsg($"读取地址406失败：{ex.Message}");
            }
        }

        private async System.Threading.Tasks.Task ReadAddr4161DataAsync()
        {
            try
            {
                ushort[] registers = await System.Threading.Tasks.Task.Run(() =>
                    _modbusMaster?.ReadHoldingRegisters(1, 1116, 2)
                );

                if (registers != null)
                {
                    float addr406Value = c.UshortToFloat(registers[1], registers[0]);
                    Dispatcher.Invoke(() => min5.Text = addr406Value.ToString("F2"));
                }
            }
            catch (Exception ex)
            {
                //ShowErrorMsg($"读取地址406失败：{ex.Message}");
            }
        }

        private async System.Threading.Tasks.Task ReadAddr404DataAsync()
        {
            try
            {
                ushort[] registers = await System.Threading.Tasks.Task.Run(() =>
                    _modbusMaster?.ReadHoldingRegisters(1, 322, 1)
                );

                if (registers != null)
                {
                    int addr406Value = registers[0];
                    Dispatcher.Invoke(() => settingtime2.Text = addr406Value.ToString("F0"));
                }
            }
            catch (Exception ex)
            {
                //ShowErrorMsg($"读取地址406失败：{ex.Message}");
            }
        }

        private async System.Threading.Tasks.Task ReadAddr406DataAsync()
        {
            try
            {
                ushort[] registers = await System.Threading.Tasks.Task.Run(() =>
                    _modbusMaster?.ReadHoldingRegisters(1, 1430, 2)
                );

                if (registers != null)
                {
                    float addr406Value = c.UshortToFloat(registers[1], registers[0]);
                    Dispatcher.Invoke(() => min.Text = addr406Value.ToString("F2"));
                }
            }
            catch (Exception ex)
            {
                //ShowErrorMsg($"读取地址406失败：{ex.Message}");
            }
        }


        private async System.Threading.Tasks.Task ReadAddr130DataAsync()
        {
            try
            {
                ushort[] registers = await System.Threading.Tasks.Task.Run(() =>
                    _modbusMaster?.ReadHoldingRegisters(1, 92, 1)
                );

                if (registers != null)
                {
                    int addr406Value = registers[0];
                    Dispatcher.Invoke(() => min2.Text = addr406Value.ToString("F2"));


                }
            }
            catch (Exception ex)
            {
                //ShowErrorMsg($"读取地址406失败：{ex.Message}");
            }
        }


        private async System.Threading.Tasks.Task ReadAddrStatusDataAsync()
        {
            try
            {
                bool[] result = _modbusMaster?.ReadCoils(0x01, 91, 1);
                bool isTestRunning = result != null && result.Length > 0 && result[0];

                Dispatcher.Invoke(() =>
                {
                    if (isTestRunning)
                    {
                        status.Text = "正在运行";
                        statusPanel.Background = Brushes.Green;
                        if (!_wasRunning)
                        {
                            _testStartTime = DateTime.Now;
                            _recordAdded = false; // 测试刚开始，允许插入记录
                        }
                    }
                    else
                    {
                        status.Text = "空闲";
                        statusPanel.Background = Brushes.Blue;
                        // 状态从“运行”切换到“空闲”，且还没插入记录
                        if (_wasRunning && !_recordAdded)
                        {
                            AddTestRecord();      // 插入记录
                            _recordAdded = true;  // 标记已插入
                        }
                    }
                    _wasRunning = isTestRunning; // 更新上一次状态
                });
            }
            catch (Exception ex)
            {
                //ShowErrorMsg($"读取运行状态失败：{ex.Message}");
            }
        }


        private void ShowErrorMsg(string msg)
        {
            Dispatcher.Invoke(() =>
            {
                MessageBox.Show(msg, "错误", MessageBoxButton.OK, MessageBoxImage.Error);
            });
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            OpenQuantitativeSupplyWindow3();

        }

        private void OpenQuantitativeSupplyWindow3()
        {
            try
            {
                SwitchWindow(ref _reportWindow3, () => new ReportWindow3());
            }
            catch (Exception ex)
            {
                MessageBox.Show($"打开定量供应检验窗口时出错：{ex.Message}", "错误",
                    MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }

        private void Button_Click_1(object sender, RoutedEventArgs e)
        {
            ma.BtnClickFunctionForNew(Function.ButtonType.切换型, 90);

        }

        private void Button_Click_2(object sender, RoutedEventArgs e)
        {
            //ma.BtnClickFunctionForNew(Function.ButtonType.复归型, 93);
            ma.BtnClickFunctionForNew(Function.ButtonType.复归型, 93);

        }

        private void Button_Click_3(object sender, RoutedEventArgs e)
        {
            ma.BtnClickFunctionForNew(Function.ButtonType.切换型, 94);
        }

        private void Button_Click_4(object sender, RoutedEventArgs e)
        {
            SwitchWindow(ref _mainWindow, () => new MainWindow());
        }

        private void Button_Click_5(object sender, RoutedEventArgs e)
        {
            SwitchWindow(ref _mainWindow2, () => new MainWindow2());
        }

        private void Button_Click_6(object sender, RoutedEventArgs e)
        {
            SwitchWindow(ref _mainWindow3, () => new MainWindow3());
        }

        private void Button_Click_7(object sender, RoutedEventArgs e)
        {
            SwitchWindow(ref _mainWindow4, () => new MainWindow4());
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            string plcIp = "192.168.1.10";
            bool initSuccess = Data.ModbusResourceManager.Instance.Init(plcIp, 502);
            if (!initSuccess)
            {
                MessageBox.Show("连接Modbus服务器失败！", "错误");
                this.Close();
                return;
            }

            // 检查连接状态
            if (_tcpClient == null || !_tcpClient.Connected)
            {
                MessageBox.Show("Modbus连接异常！", "错误");
                this.Close();
                return;
            }

            ma = new Function(_modbusMaster);
            ma.BtnClickFunctionForNew(Function.ButtonType.切换型, 63);
            System.Threading.Tasks.Task.Delay(50);
            _readTimer.Start();

            _modbusMaster.WriteSingleCoil(1, 61, false);
            System.Threading.Tasks.Task.Delay(50);

            _modbusMaster.WriteSingleCoil(1, 62, false);
            System.Threading.Tasks.Task.Delay(50);

            _modbusMaster.WriteSingleCoil(1, 63, true);
            System.Threading.Tasks.Task.Delay(50);

            _modbusMaster.WriteSingleCoil(1, 64, false);
            System.Threading.Tasks.Task.Delay(50);
        }

        private void SwitchWindow<T>(ref T windowInstance, Func<T> createFunc) where T : Window, new()
        {
            _readTimer?.Stop();

            if (_tcpClient == null || !_tcpClient.Connected || _modbusMaster == null)
            {
                if (!TryReconnect())
                {
                    MessageBox.Show("TCP连接已断开，请重新连接！", "提示");
                    return;
                }
            }

            Window overlay = null;
            try
            {
                overlay = new Window
                {
                    Owner = this,
                    WindowStyle = WindowStyle.None,
                    AllowsTransparency = true,
                    Background = Brushes.Transparent,
                    ShowInTaskbar = false,
                    ResizeMode = ResizeMode.NoResize,
                    Width = this.ActualWidth,
                    Height = this.ActualHeight,
                    Left = this.Left,
                    Top = this.Top,
                    ShowActivated = false,
                    Topmost = true
                };

                var grid = new Grid();
                var tb = new TextBlock
                {
                    Text = "正在加载，请稍候...",
                    Foreground = Brushes.Black,
                    Background = Brushes.Transparent,
                    HorizontalAlignment = HorizontalAlignment.Center,
                    VerticalAlignment = VerticalAlignment.Bottom,
                    Margin = new Thickness(0, 0, 0, 20),
                    FontSize = 16
                };
                grid.Children.Add(tb);
                overlay.Content = grid;

                overlay.Show();

                void ShowTargetWindow(T target)
                {
                    if (target.IsVisible)
                    {
                        target.Activate();
                        this.Hide();
                        overlay?.Close();
                        return;
                    }

                    target.Opacity = 0;
                    void OnContentRendered(object s, EventArgs e)
                    {
                        target.ContentRendered -= OnContentRendered;
                        var anim = new DoubleAnimation(0, 1, TimeSpan.FromMilliseconds(200));
                        target.BeginAnimation(Window.OpacityProperty, anim);
                        this.Hide();
                        target.Activate();
                        overlay?.Close();
                    }

                    target.ContentRendered += OnContentRendered;
                    target.Show();
                }

                if (windowInstance == null)
                {
                    windowInstance = createFunc();
                    windowInstance.Closed += (s, args) =>
                    {
                        _readTimer?.Start();
                        this.Activate();
                    };

                    ShowTargetWindow(windowInstance);
                }
                else
                {
                    ShowTargetWindow(windowInstance);
                }
            }
            catch (Exception ex)
            {
                overlay?.Close();
                ShowErrorMsg($"切换窗口失败：{ex.Message}");
            }
        }
        // 添加重连方法
        private bool TryReconnect()
        {
            try
            {
                string plcIp = "192.168.1.10";
                bool initSuccess = Data.ModbusResourceManager.Instance.Init(plcIp, 502);
                if (initSuccess)
                {
                    ma = new Function(_modbusMaster);
                    return true;
                }
            }
            catch (Exception ex)
            {
                //ShowErrorMsg($"重新连接失败：{ex.Message}");
            }
            return false;
        }



        private void BtnWrite401_Click(object sender, RoutedEventArgs e)
        {
            if (!double.TryParse(settingtime.Text.Trim(), out double writeValue) ||
                 writeValue > short.MaxValue)
            {
                ShowErrorMsg($"需输入整数（范围：{short.MinValue} ~ {short.MaxValue}）");
                settingtime.Focus();
                return;
            }

            try
            {
                //await System.Threading.Tasks.Task.Run(() =>
                //    _modbusMaster.WriteSingleRegister(SlaveId, Address262, (ushort)writeValue)
                //);

                ma.WriteToPLCForNew(settingtime.Text.Trim(), 320, Function.DataType.浮点型);

                System.Threading.Tasks.Task.Delay(50);
                _isManualInput = false; // 写入后恢复读取
                //await ReadAddr400DataAsync(); // 刷新显示（确认写入成功）

            }
            catch (Exception ex)
            {
                //ShowErrorMsg($"地址400写入失败：{ex.Message}");
            }
        }


        private void BtnWrite402_Click(object sender, RoutedEventArgs e)
        {
            if (!double.TryParse(settingtime2.Text.Trim(), out double writeValue) ||
                 writeValue > short.MaxValue)
            {
                ShowErrorMsg($"需输入整数（范围：{short.MinValue} ~ {short.MaxValue}）");
                settingtime.Focus();
                return;
            }

            try
            {
                //await System.Threading.Tasks.Task.Run(() =>
                //    _modbusMaster.WriteSingleRegister(SlaveId, Address262, (ushort)writeValue)
                //);

                ma.WriteToPLCForNew(settingtime2.Text.Trim(), 322, Function.DataType.整形);

                System.Threading.Tasks.Task.Delay(50);
                _isManualInput = false; // 写入后恢复读取
                //await ReadAddr400DataAsync(); // 刷新显示（确认写入成功）

            }
            catch (Exception ex)
            {
                //ShowErrorMsg($"地址400写入失败：{ex.Message}");
            }
        }


        private void OpenReportWindow()
        {
            try
            {
                if (_reportWindow3 == null)
                {
                    _reportWindow3 = new ReportWindow3();
                }

                // 如果窗口已关闭，重新创建并显示
                if (!_reportWindow3.IsVisible)
                {
                    _reportWindow3 = new ReportWindow3();
                    // 将之前的数据复制到新窗口
                    if (_reportWindow3._records != null)
                    {
                        // 保持数据引用不变
                    }
                }

                _reportWindow3.Show();
                _reportWindow3.Activate();
            }
            catch (Exception ex)
            {
                MessageBox.Show($"打开报表窗口时出错：{ex.Message}", "错误",
                    MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }


        private void AddTestRecord()
        {
            try
            {
                // 计算测试时长
                TimeSpan duration = DateTime.Now - _testStartTime;
                string durationStr = $"{duration.Minutes:00}:{duration.Seconds:00}";

                // 获取当前流量值
                double startPress = 0, endPress = 0, diffPress = 0, ProtectTime = 0;
                if (!string.IsNullOrEmpty(min3.Text) && double.TryParse(min3.Text, out double flow))
                {
                    startPress = flow;
                }

                if (!string.IsNullOrEmpty(min4.Text) && double.TryParse(min4.Text, out double flow2))
                {
                    endPress = flow2;
                }

                if (!string.IsNullOrEmpty(min5.Text) && double.TryParse(min5.Text, out double flow5))
                {
                    diffPress = flow5;
                }

                if (!string.IsNullOrEmpty(min2.Text) && double.TryParse(min2.Text, out double flow3))
                {
                    ProtectTime = flow3;
                }

                // 获取当前时间
                string currentTime = DateTime.Now.ToString("HH:mm");
                string currentDate = DateTime.Now.ToString("yy/MM/dd");

                // 添加到报表窗口（如果存在）
                Dispatcher.Invoke(() =>
                {
                    // 如果窗口不存在，先创建但不显示
                    if (_reportWindow3 == null)
                    {
                        _reportWindow3 = new ReportWindow3();
                    }

                    string testNo = ConfigurationManager.AppSettings["No"].ToString();// 待定
                    // 添加记录到窗口（无论窗口是否显示）
                    _reportWindow3.AddRecord(currentTime, currentDate, startPress, endPress, diffPress, ProtectTime, testNo);
                });

            }
            catch (Exception ex)
            {
                //ShowErrorMsg($"记录测试数据失败：{ex.Message}");
            }
        }
        private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            // 停止定时器
            _readTimer?.Stop();

            // 停止ViewModel的定时器
            if (DataContext is MainViewModel viewModel)
            {
                viewModel.StopTimer();
            }

            // 释放Modbus资源
            ModbusResourceManager.Instance?.Dispose();

            // 确保应用程序完全退出
            Application.Current.Shutdown();
        }
        private void Window_Closed(object sender, EventArgs e)
        {
            // 清理其他窗口实例
            _mainWindow?.Close();
            _mainWindow2?.Close();
            //_mainWindow3?.Close();
            _mainWindow4?.Close();
            _reportWindow3?.Close();
        }
    }
}
