using Microsoft.Win32;
using Modbus.Device;
using Modbus;
using OfficeOpenXml;
using System;
using System.Configuration;
using System.Data.SQLite;
using System.IO;
using System.Net.Sockets;
using System.Threading.Tasks;
using System.Timers;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using 口罩泄露定制款;
using static ShanghaiEnvironmentalTechnology.Window5;

namespace ShanghaiEnvironmentalTechnology
{
    /// <summary>
    /// 气阻测试相关参数监控窗口（Modbus通信+数据处理）
    /// </summary>
    public partial class Window4 : Window, IDisposable
    {
        DataChange c = new DataChange();

        #region 寄存器/线圈地址定义（按功能分组，对应物理意义）
        // 基础参数地址
        private readonly ushort _pressureSettingRegisterAddress = 0x013A; // 单一故障气阻设置流量（D314）
        private readonly ushort _noseRegisterAddress = 0x055C; // 鼻口压力地址
        private readonly ushort _modifiedNoseRegisterAddress = 0x0048; // 鼻口压力校准地址（M72）
        private readonly ushort _outRegisterAddress = 120; // 呼流量地址
        private readonly ushort _inRegisterAddress = 1400; // 吸流量地址


        private readonly ushort _BreathOutRegisterAddress = 316; // 记录呼气阻力实时显示
        private readonly ushort _BreathInRegisterAddress = 318; // 记录吸气阻力实时显示

        // 线圈地址（控制指令）
        private readonly ushort _testStartAddress = 0x0020; // 单一故障气阻测试启动（M32）


        #endregion

        #region 私有字段
        private TcpClient _tcpClient;
        private IModbusMaster _modbusMaster;
        Function fc;
        // 定时器
        private System.Timers.Timer _outReadTimer; // 呼流量读取
        private System.Timers.Timer _inReadTimer; // 吸流量读取
        private System.Timers.Timer _noseReadTimer; // 鼻口压力读取
        private System.Timers.Timer _settingReadTimer2; //
        private System.Timers.Timer startTimer; // 启动状态实时定时器
        #endregion

        public Window4()
        {
            InitializeComponent();
            InitializeModbusTcp();
            Loaded += Window_Loaded;
        }

        #region 初始化与资源释放
        /// <summary>
        /// 初始化Modbus连接和定时器
        /// </summary>
        private void InitializeModbusTcp()
        {
            try
            {
                string plcIp = ConfigurationManager.AppSettings["PLC1_IP"];
                int plcPort = int.Parse(ConfigurationManager.AppSettings["PLC1_Port"]);

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

                // 初始化定时器
                InitializeTimers();

                fc = new Function(_modbusMaster);
                // 初始化数据库
                InitializeDatabase();
            }
            catch (Exception ex)
            {
                ShowError($"Modbus初始化失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 统一初始化所有定时器
        /// </summary>
        private void InitializeTimers()
        {
            _outReadTimer = CreateTimer(1000, OnOutTimerElapsed);
            _inReadTimer = CreateTimer(1000, OnInTimerElapsed);
            _noseReadTimer = CreateTimer(1000, OnNoseTimerElapsed);
            _settingReadTimer2 = CreateTimer(1000, OnSettingReadTimerTimerElapsed2);
            startTimer = CreateTimer(1000, OnStartTimerElapsed);
        }

        /// <summary>
        /// 实时流量读取定时器（修正跨线程访问UI问题）
        /// </summary>
        private void OnStartTimerElapsed(object sender, ElapsedEventArgs e)
        {
            try
            {
                bool[] result = _modbusMaster?.ReadCoils(0x01, 33, 1);
                bool isTestRunning = result != null && result.Length > 0 && result[0];

                string lang = ConfigurationManager.AppSettings["Language"] ?? "zh-CN";
                string running = lang == "en-US" ? "Test Running" : "测试启动成功";
                string ready = lang == "en-US" ? "Start Test" : "测试启动";

                TestStartButton.Dispatcher.Invoke(() =>
                {
                    if (isTestRunning)
                    {

                        btnsetting.IsEnabled = false;
                        btnsetting2.IsEnabled = false;
                        TestStartButton.Content = running;
                        TestStartButton.Foreground = Brushes.LightGreen;
                    }
                    else
                    {
                        btnsetting.IsEnabled = true;
                        btnsetting2.IsEnabled = true;

                        TestStartButton.Content = ready;
                        TestStartButton.Foreground = Brushes.White;
                    }
                });
            }
            catch (Exception ex)
            {
                Console.WriteLine($"读取线圈或更新UI失败：{ex.Message}");
            }
        }

        private void OnSettingReadTimerTimerElapsed2(object sender, ElapsedEventArgs e)
        {
            ReadAndUpdateRegister(
                _pressureSettingRegisterAddress, true,
                value => UpdateSettingUI2(value.ToString())
            );
        }

        private void UpdateSettingUI2(string value)
        {
            string lang = ConfigurationManager.AppSettings["Language"] ?? "zh-CN";
            string disconnect = lang == "en-US" ? "Disconnected" : "连接断开";
            UpdateUiSafely(() => clostTxt.Text = IsModbusConnected() ? value : disconnect);
        }

        /// <summary>
        /// 通用定时器创建方法
        /// </summary>
        private System.Timers.Timer CreateTimer(int intervalMs, ElapsedEventHandler elapsedAction)
        {
            var timer = new System.Timers.Timer(intervalMs)
            {
                AutoReset = true,
                Enabled = true
            };
            timer.Elapsed += elapsedAction;
            return timer;
        }

        /// <summary>
        /// 释放资源
        /// </summary>
        public void Dispose()
        {
            // 释放定时器
            _outReadTimer?.Dispose();
            _inReadTimer?.Dispose();
            _noseReadTimer?.Dispose();

            // 释放Modbus连接
            _tcpClient?.Close();
            _tcpClient?.Dispose();
            _modbusMaster = null;
        }

        /// <summary>
        /// 窗口关闭时释放资源
        /// </summary>
        protected override void OnClosed(EventArgs e)
        {
            base.OnClosed(e);
            Dispose();
        }
        #endregion

        #region 定时器读取逻辑（寄存器读取+UI更新）
        /// <summary>
        /// 呼流量读取定时器
        /// </summary>
        private void OnOutTimerElapsed(object sender, ElapsedEventArgs e)
        {
            ReadAndUpdateRegister(
                _outRegisterAddress, true,
                value => UpdateOutUI(value.ToString())
            );
        }

        /// <summary>
        /// 吸流量读取定时器
        /// </summary>
        private void OnInTimerElapsed(object sender, ElapsedEventArgs e)
        {
            ReadAndUpdateRegister(
                _inRegisterAddress, true,
                value => UpdateInUI(value.ToString())
            );
        }

        /// <summary>
        /// 鼻口压力读取定时器
        /// </summary>
        private void OnNoseTimerElapsed(object sender, ElapsedEventArgs e)
        {
            ReadAndUpdateRegister(
                _noseRegisterAddress, true,
                value => UpdateNoseUI(value.ToString())
            );
        }

        /// <summary>
        /// 通用寄存器读取并更新UI，支持16位整数和32位浮点数
        /// </summary>
        /// <param name="address">起始地址</param>
        /// <param name="isFloat">是否为浮点型（占用2个寄存器）</param>
        /// <param name="updateAction">更新UI的回调函数</param>
        private void ReadAndUpdateRegister(ushort address, bool isFloat, Action<object> updateAction)
        {
            if (!IsModbusConnected())
            {
                updateAction?.Invoke(isFloat ? (object)float.NaN : (ushort)0);
                return;
            }

            try
            {
                // 根据数据类型确定读取的寄存器数量
                int registerCount = isFloat ? 2 : 1;
                ushort[] data = _modbusMaster?.ReadHoldingRegisters(0x01, address, (ushort)registerCount);

                if (isFloat)
                {
                    // 浮点型转换（2个16位寄存器组合为32位浮点数）
                    if (data.Length >= 2)
                    {


                        // 2. 解析寄存器值（data[0]是D312，data[1]是D313）
                        ushort a = data[0];  // 高位寄存器值
                        ushort b = data[1];  // 低位寄存器值

                        float floatValue = c.UshortToFloat(b, a);
                        floatValue = (float)Math.Round(floatValue, 2);
                        updateAction?.Invoke(floatValue);
                    }
                    else
                    {
                        updateAction?.Invoke(float.NaN);
                    }
                }
                else
                {
                    // 16位整数直接返回
                    updateAction?.Invoke(data.Length > 0 ? data[0] : (ushort)0);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"读取寄存器[{address:X4}]失败: {ex.Message}");
                // 异常时根据类型返回对应的值
                updateAction?.Invoke(isFloat ? (object)float.NaN : (ushort)0);
            }
        }
        #endregion

        #region UI更新（线程安全处理）
        /// <summary>
        /// 更新呼流量UI
        /// </summary>
        private void UpdateOutUI(string value)
        {
            string lang = ConfigurationManager.AppSettings["Language"] ?? "zh-CN";
            string disconnect = lang == "en-US" ? "Disconnected" : "连接断开";
            UpdateUiSafely(() => outTxt.Text = IsModbusConnected() ? value : disconnect);
        }

        /// <summary>
        /// 更新吸流量UI
        /// </summary>
        private void UpdateInUI(string value)
        {
            string lang = ConfigurationManager.AppSettings["Language"] ?? "zh-CN";
            string disconnect = lang == "en-US" ? "Disconnected" : "连接断开";
            UpdateUiSafely(() => InTxt.Text = IsModbusConnected() ? value : disconnect);
        }

        /// <summary>
        /// 更新鼻口压力UI
        /// </summary>
        private void UpdateNoseUI(string value)
        {
            string lang = ConfigurationManager.AppSettings["Language"] ?? "zh-CN";
            string disconnect = lang == "en-US" ? "Disconnected" : "连接断开";
            UpdateUiSafely(() => NoseTxt.Text = IsModbusConnected() ? value : disconnect);
        }

        /// <summary>
        /// 更新测试按钮状态UI
        /// </summary>
        private void UpdateButtonStatus(string text, Brush color)
        {
            UpdateUiSafely(() =>
            {
                TestStartButton.Content = text;
                TestStartButton.Foreground = color;
            });
        }

        /// <summary>
        /// 线程安全的UI更新通用方法（统一实现）
        /// </summary>
        private void UpdateUiSafely(Action action)
        {
            if (action == null) return;


            if (Dispatcher.HasShutdownStarted)
            {
                return;
            }

            try
            {
                if (!Dispatcher.CheckAccess())
                {

                    Dispatcher.Invoke(action, TimeSpan.FromSeconds(2));
                }
                else
                {
                    action.Invoke();
                }
            }
            catch (TaskCanceledException)
            {

            }
            catch (Exception ex)
            {
                Console.WriteLine($"UI更新失败：{ex.Message}");
            }
        }
        #endregion

        #region 按钮事件（功能操作）
        ///// <summary>
        ///// 流量值设置（settingTxt）
        ///// </summary>
        //private async void Button_Click(object sender, RoutedEventArgs e)
        //{
        //    await WriteRegisterWithValidation(
        //        inputControl: settingTxt,
        //        registerAddress: _pressureSettingRegisterAddress,
        //        minValue: 0,
        //        maxValue: 10000,
        //        successMsg: value => $"设置流量值: {value} L/min"
        //    );
        //}

        /// <summary>
        /// 鼻口压力校准（M72线圈）
        /// </summary>
        private async void Button_Click_1(object sender, RoutedEventArgs e)
        {
            string lang = ConfigurationManager.AppSettings["Language"] ?? "zh-CN";
            string success = lang == "en-US" ? "Calibration OK (verified)" : "校准指令已被设备接收并执行（二次验证通过）";
            string fail = lang == "en-US" ? "Calibration timeout" : "校准执行超时，状态异常";
            string log = lang == "en-US" ? "Calibration done" : "校准指令执行成功";

            await WriteCoilWithCheck(_modifiedNoseRegisterAddress, true, success, fail, log);
        }

        /// <summary>
        /// 单一故障气阻测试停止（M34线圈）
        /// </summary>
        private async void Button_Click_3(object sender, RoutedEventArgs e)
        {
            string lang = ConfigurationManager.AppSettings["Language"] ?? "zh-CN";
            string fail = lang == "en-US" ? "Test stop timeout" : "单一故障气阻测试停止超时，状态异常";
            string log = lang == "en-US" ? "Test stopped" : "单一故障气阻测试停止";
            string start = lang == "en-US" ? "Start Test" : "测试启动";

            await WriteCoilWithCheck(0x0022, true, null, fail, log);
            TestStartButton.Content = start;
            TestStartButton.Foreground = Brushes.White;
        }

        /// <summary>
        /// 单一故障气阻测试启动（M20线圈）
        /// </summary>
        private async void Button_Click_4(object sender, RoutedEventArgs e)
        {
            string lang = ConfigurationManager.AppSettings["Language"] ?? "zh-CN";

            if (!IsModbusConnected())
            {
                UpdateButtonStatus(lang == "en-US" ? "Disconnected" : "连接断开", Brushes.Red);
                ShowError(lang == "en-US" ? "Modbus TCP not connected" : "Modbus TCP 未连接");
                return;
            }

            try
            {
                UpdateButtonStatus(lang == "en-US" ? "Starting..." : "正在启动...", Brushes.LightGreen);
                await Task.Run(() => _modbusMaster.WriteSingleCoilAsync(0x01, _testStartAddress, true));
                await Task.Delay(100);
                await Task.Run(() => _modbusMaster.WriteSingleCoilAsync(0x01, _testStartAddress, false));
                await Task.Delay(100);
                UpdateButtonStatus(lang == "en-US" ? "Test Started" : "测试启动成功", Brushes.LightGreen);
            }
            catch (Exception ex)
            {
                UpdateButtonStatus(lang == "en-US" ? "Start Failed" : "测试启动失败", Brushes.Red);
                ShowError(lang == "en-US" ? $"Error: {ex.Message}" : $"操作异常: {ex.Message}");
            }
        }

        /// <summary>
        /// 读取呼气阻力（D136）并保存
        /// </summary>
        private async void Button_Click_5(object sender, RoutedEventArgs e)
        {
            string lang = ConfigurationManager.AppSettings["Language"] ?? "zh-CN";

            if (!IsModbusConnected())
            {
                saveFlowOutTxt.Text = lang == "en-US" ? "Disconnected" : "连接断开";
                ShowError(lang == "en-US" ? "Modbus TCP not connected" : "Modbus TCP 未连接");
                return;
            }

            fc.BtnClickFunctionForNew(Function.ButtonType.切换型, 192);
            fc.BtnClickFunctionForNew(Function.ButtonType.切换型, 192);

            ReadAndUpdateRegister(_BreathOutRegisterAddress, true, value => UpdateFlowFlowUI(value.ToString()));
            //ReadAndUpdateRegister(_BreathInRegisterAddress, true, value => UpdateCloseFlowUI2(value.ToString()));

            if (float.TryParse(saveFlowOutTxt.Text, out float flowValue))
            {
                SaveRecordToDatabase(flowValue, 0);
            }
            else
            {
                ShowError(lang == "en-US" ? "Invalid data format" : "流量或压力值格式不正确，请检查输入");
            }

            List<CO2Record> records = ReadCO2RecordsFromDatabase();
            if (records == null || records.Count == 0)
            {
                string msg = lang == "en-US" ? "No data to export" : "单一故障气阻表中无数据，无法导出";
                MessageBox.Show(msg, "Info", MessageBoxButton.OK, MessageBoxImage.Warning);
                return;
            }

            bool exportSuccess = ExportCO2RecordsToExcel(records);
            if (exportSuccess)
            {
                string msg = lang == "en-US" ? "Export successful" : "数据已成功导出到Excel";
                MessageBox.Show(msg, "Success", MessageBoxButton.OK, MessageBoxImage.Information);
            }
            else
            {
                //string msg = lang == "en-US" ? "Export failed" : "Excel导出失败，请检查文件是否被占用";
                //MessageBox.Show(msg, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }



        private async void Button_Click_6(object sender, RoutedEventArgs e)
        {
            string lang = ConfigurationManager.AppSettings["Language"] ?? "zh-CN";

            if (!IsModbusConnected())
            {
                saveFlowOutTxt.Text = lang == "en-US" ? "Disconnected" : "连接断开";
                ShowError(lang == "en-US" ? "Modbus TCP not connected" : "Modbus TCP 未连接");
                return;
            }

            fc.BtnClickFunctionForNew(Function.ButtonType.切换型, 193);
            fc.BtnClickFunctionForNew(Function.ButtonType.切换型, 193);

            //ReadAndUpdateRegister(_BreathOutRegisterAddress, true, value => UpdateFlowFlowUI(value.ToString()));
            ReadAndUpdateRegister(_BreathInRegisterAddress, true, value => UpdateCloseFlowUI2(value.ToString()));

            if (
               float.TryParse(saveFlowInTxt.Text, out float pressureValue))
            {
                SaveRecordToDatabase(0, pressureValue);
            }
            else
            {
                ShowError(lang == "en-US" ? "Invalid data format" : "流量或压力值格式不正确，请检查输入");
            }

            List<CO2Record> records = ReadCO2RecordsFromDatabase();
            if (records == null || records.Count == 0)
            {
                string msg = lang == "en-US" ? "No data to export" : "单一故障气阻表中无数据，无法导出";
                MessageBox.Show(msg, "Info", MessageBoxButton.OK, MessageBoxImage.Warning);
                return;
            }

            bool exportSuccess = ExportCO2RecordsToExcel(records);
            if (exportSuccess)
            {
                string msg = lang == "en-US" ? "Export successful" : "数据已成功导出到Excel";
                MessageBox.Show(msg, "Success", MessageBoxButton.OK, MessageBoxImage.Information);
            }
            else
            {
                //string msg = lang == "en-US" ? "Export failed" : "Excel导出失败，请检查文件是否被占用";
                //MessageBox.Show(msg, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }

        private bool ExportCO2RecordsToExcel(List<CO2Record> records)
        {
            try
            {
                SaveFileDialog saveDialog = new SaveFileDialog
                {
                    Filter = "Excel(*.xlsx)|*.xlsx",
                    FileName = $"AirResistance_{DateTime.Now:yyyyMMddHHmmss}.xlsx",
                    Title = "Export Air Resistance Data"
                };

                if (saveDialog.ShowDialog() != true) return false;
                ExcelPackage.LicenseContext = LicenseContext.NonCommercial;

                using (var package = new ExcelPackage(new FileInfo(saveDialog.FileName)))
                {
                    var ws = package.Workbook.Worksheets.Add("Records");
                    ws.Cells[1, 1].Value = "Expiratory Pa";
                    ws.Cells[1, 2].Value = "Inspiratory Pa";
                    ws.Cells[1, 3].Value = "Time";

                    for (int i = 0; i < records.Count; i++)
                    {
                        ws.Cells[i + 2, 1].Value = records[i].Flow;
                        ws.Cells[i + 2, 2].Value = records[i].Pressure;
                        ws.Cells[i + 2, 3].Value = records[i].RecordTime.ToString("yyyy-MM-dd HH:mm:ss");
                    }

                    ws.Cells.AutoFitColumns();
                    package.Save();
                }
                return true;
            }
            catch (Exception ex)
            {
                string lang = ConfigurationManager.AppSettings["Language"] ?? "zh-CN";
                string err = lang == "en-US" ? "Export failed" : "导出失败";
                MessageBox.Show($"{err}: {ex.Message}", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
                return false;
            }
        }


        /// <summary>
        /// 
        /// </summary>
        private List<CO2Record> ReadCO2RecordsFromDatabase()
        {
            List<CO2Record> records = new List<CO2Record>();
            try
            {
                using (SQLiteConnection conn = new SQLiteConnection(CSConstant.DbConnectionString))
                {
                    conn.Open();
                    // 查询CO2表所有记录（按时间排序）
                    string query = "SELECT Flow, Pressure, RecordTime FROM ExpiratoryResistance ORDER BY RecordTime desc limit 1 ";
                    using (SQLiteCommand cmd = new SQLiteCommand(query, conn))
                    {
                        using (SQLiteDataReader reader = cmd.ExecuteReader())
                        {
                            while (reader.Read())
                            {
                                records.Add(new CO2Record
                                {
                                    Flow = reader.GetDouble(0),               // 二氧化碳浓度（%）
                                    Pressure = reader.GetDouble(1),          // 压力（pa）                                 
                                    RecordTime = reader.GetDateTime(2)       // 时间
                                });
                            }
                        }
                    }
                }
                return records;
            }
            catch (Exception ex)
            {
                MessageBox.Show($"读取单一故障气阻表失败：{ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
                return null;
            }
        }


        private void UpdateFlowFlowUI(string value)
        {
            string lang = ConfigurationManager.AppSettings["Language"] ?? "zh-CN";
            string disconnect = lang == "en-US" ? "Disconnected" : "连接断开";
            UpdateUiSafely(() => saveFlowOutTxt.Text = IsModbusConnected() ? value : disconnect);
        }
        private void UpdateCloseFlowUI2(string value)
        {
            string lang = ConfigurationManager.AppSettings["Language"] ?? "zh-CN";
            string disconnect = lang == "en-US" ? "Disconnected" : "连接断开";
            UpdateUiSafely(() => saveFlowInTxt.Text = IsModbusConnected() ? value : disconnect);
        }

        ///// <summary>
        ///// 读取吸气阻力（D318）并保存
        ///// </summary>
        //private async void Button_Click_6(object sender, RoutedEventArgs e)
        //{
        //    await ReadAndSaveRegister(
        //        address: _flowInRegisterAddress,
        //        control: saveFlowInTxt,
        //        isFlow: false
        //    );
        //}

        /// <summary>
        /// 返回主窗口
        /// </summary>
        private void Button_Click_2(object sender, RoutedEventArgs e)
        {
            var mainWindow = MainWindow.Instance;

            // 检查窗口状态，只在窗口未显示时调用ShowDialog
            if (!mainWindow.IsVisible)
            {
                mainWindow.ShowDialog();
            }
            else
            {
                // 如果窗口已显示，可将其激活到前台
                mainWindow.Activate();
            }

            Close();
        }

        /// <summary>
        /// 打开报告窗口
        /// </summary>
        private void Button_Click_7(object sender, RoutedEventArgs e)
        {
            new ReportWindow4().ShowDialog();
        }
        #endregion

        #region 通用操作方法（提取重复逻辑）
        private async Task WriteRegisterWithValidation(
                   TextBox inputControl,
                   ushort registerAddress,
                   float minValue,
                   float maxValue)
        {
            string lang = ConfigurationManager.AppSettings["Language"] ?? "zh-CN";

            if (!IsModbusConnected())
            {
                ShowError(lang == "en-US" ? "Modbus TCP not connected" : "Modbus TCP 未连接");
                return;
            }

            if (!float.TryParse(inputControl.Text.Trim(), out float value) || value < minValue || value > maxValue)
            {
                string msg = lang == "en-US" ? $"Enter {minValue}~{maxValue}" : $"请输入{minValue}~{maxValue}的数字";
                ShowWarning(msg);
                return;
            }

            try
            {
                inputControl.Text = lang == "en-US" ? "Processing..." : "操作中...";
                Function ma = new Function(_modbusMaster);
                ma.WriteToPLCForNew(value.ToString(), registerAddress, Function.DataType.浮点型);
                await Task.Delay(300);
                ReadAndUpdateRegister(registerAddress, true, v => UpdatePressureUI(v.ToString()));
            }
            catch (Exception ex)
            {
                string err = lang == "en-US" ? $"Failed: {ex.Message}" : $"操作失败: {ex.Message}";
                ShowError(err);
            }
            finally
            {
                inputControl.Text = value.ToString();
            }
        }

        private void UpdatePressureUI(string value)
        {
            UpdateUiSafely(() => clostTxt.Text = value);
        }

        /// <summary>
        /// 写入线圈并验证状态
        /// </summary>
        private async Task WriteCoilWithCheck(
            ushort coilAddress,
            bool value,
            string successMsg,
            string failMsg,
            string logMsg)
        {
            string lang = ConfigurationManager.AppSettings["Language"] ?? "zh-CN";

            if (_modbusMaster == null)
            {
                // ShowError(lang == "en-US" ? "Modbus TCP not connected" : "Modbus TCP 未连接");
                return;
            }

            if (!IsModbusConnected())
            {
                InitializeModbusTcp();
                return;
            }

            try
            {
                // 写入线圈
                await Task.Run(() =>
                    _modbusMaster.WriteSingleCoilAsync(0x01, coilAddress, value)
                );
                Thread.Sleep(200);

                // ==============================
                // 兼容：中文 停止/校准 + 英文 Stop/Calib
                // ==============================
                bool needReset = false;
                if (failMsg != null)
                {
                    bool hasStop = failMsg.Contains("停止") || failMsg.Contains("Stop") || failMsg.Contains("stop");
                    bool hasCalib = failMsg.Contains("校准") || failMsg.Contains("Calib") || failMsg.Contains("calib");
                    needReset = hasStop || hasCalib;
                }

                if (failMsg != null && needReset)
                {
                    // 写入线圈
                    await Task.Run(() =>
                        _modbusMaster.WriteSingleCoilAsync(0x01, coilAddress, false)
                    );
                }

                Thread.Sleep(100);

                // 等待并验证
                await Task.Delay(500);
                bool[] status = await _modbusMaster?.ReadCoilsAsync(0x01, coilAddress, 1);

                // ==============================
                // 同样兼容中英文判断
                // ==============================
                bool noResetCheck = false;
                if (failMsg != null)
                {
                    bool hasStop = failMsg.Contains("停止") || failMsg.Contains("Stop") || failMsg.Contains("stop");
                    bool hasCalib = failMsg.Contains("校准") || failMsg.Contains("Calib") || failMsg.Contains("calib");
                    noResetCheck = !hasStop && !hasCalib;
                }

                if (failMsg != null && noResetCheck)
                {
                    if (status != null && status.Length > 0 && status[0] == value)
                    {
                        // 写入日志
                        WriteLog($"{logMsg} - 地址：{coilAddress}，状态：{value}");
                        if (!string.IsNullOrEmpty(successMsg))
                        {
                            ShowSuccess(successMsg);
                        }
                    }
                    else
                    {
                        ShowError(failMsg);
                    }
                }
            }
            catch (Exception ex)
            {
                ShowError(lang == "en-US" ? $"Communication error: {ex.Message}" : $"通信错误: {ex.Message}");
            }
        }


        #endregion

        #region 数据库与日志操作
        /// <summary>
        /// 初始化数据库
        /// </summary>
        private void InitializeDatabase()
        {
            try
            {
                using (var conn = new SQLiteConnection(CSConstant.DbConnectionString))
                {
                    conn.Open();
                    string createSql = @"
                        CREATE TABLE IF NOT EXISTS ExpiratoryResistance (
                            Id INTEGER PRIMARY KEY AUTOINCREMENT,
                            Flow REAL NOT NULL,
                            Pressure REAL NOT NULL,
                            RecordTime DATETIME NOT NULL
                        );";
                    using (var cmd = new SQLiteCommand(createSql, conn))
                    {
                        cmd.ExecuteNonQuery();
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"数据库初始化失败: {ex.Message}");
                ShowError($"数据库错误: {ex.Message}");
            }
        }

        /// <summary>
        /// 保存记录到数据库
        /// </summary>
        private void SaveRecordToDatabase(double flow, double pressure)
        {
            try
            {
                flow = Math.Round(flow, 2);
                pressure = Math.Round(pressure, 2);
                using (var conn = new SQLiteConnection(CSConstant.DbConnectionString))
                {
                    conn.Open();
                    string insertSql = @"
                        INSERT INTO ExpiratoryResistance(Flow, Pressure, RecordTime)
                        VALUES (@Flow, @Pressure, @RecordTime);";
                    using (var cmd = new SQLiteCommand(insertSql, conn))
                    {
                        cmd.Parameters.AddWithValue("@Flow", flow);
                        cmd.Parameters.AddWithValue("@Pressure", pressure);
                        cmd.Parameters.AddWithValue("@RecordTime", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
                        cmd.ExecuteNonQuery();
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"保存数据库失败: {ex.Message}");
                ShowWarning($"数据保存失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 日志路径
        /// </summary>
        private string logPath => System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "modbus_log.txt");

        /// <summary>
        /// 写入操作日志
        /// </summary>
        private void WriteLog(string content)
        {
            try
            {
                string log = $"[{DateTime.Now:yyyy-MM-dd HH:mm:ss}] {content}\r\n";
                System.IO.File.AppendAllText(logPath, log);
            }
            catch (Exception ex)
            {
                Console.WriteLine($"写入日志失败: {ex.Message}");
            }
        }
        #endregion

        #region 辅助方法（连接检查、消息提示、背景加载）
        /// <summary>
        /// 检查Modbus连接状态
        /// </summary>
        private bool IsModbusConnected()
        {
            return _modbusMaster != null && _tcpClient?.Connected == true;
        }

        /// <summary>
        /// 加载窗口背景
        /// </summary>
        private async void Window_Loaded(object sender, RoutedEventArgs e)
        {
            try
            {
                string imgPath = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Resources/sleep2.jpg");
                if (System.IO.File.Exists(imgPath))
                {
                    Background = new ImageBrush
                    {
                        ImageSource = new BitmapImage(new Uri(imgPath, UriKind.Absolute))
                    };
                }
                else
                {
                    Console.WriteLine($"背景图片不存在: {imgPath}");
                }

                await LoadBreathTypeSelection();



            }
            catch (Exception ex)
            {
                Console.WriteLine($"加载背景失败: {ex.Message}");
            }
        }



        private async Task LoadBreathTypeSelection()
        {
            try
            {
                // 读取线圈 36（假设 36 为呼吸类型：true=吸气/Inhale，false=呼气/Exhale）
                bool[] result = await _modbusMaster?.ReadCoilsAsync(1, 36, 1);
                bool isInhale = result != null && result.Length > 0 && result[0];

                // 获取当前语言
                string currentLanguage = ConfigurationManager.AppSettings["Language"] ?? "zh-CN";
                string expectedContent;
                if (currentLanguage == "en-US")
                {
                    expectedContent = isInhale ? "Inhale" : "Exhale";
                }
                else
                {
                    expectedContent = isInhale ? "吸气" : "呼气";
                }

                // 查找并设置选中项
                foreach (ComboBoxItem item in CaptureModeComboBox.Items)
                {
                    if (item.Content?.ToString() == expectedContent)
                    {
                        CaptureModeComboBox.SelectedItem = item;
                        break;
                    }
                }
            }
            catch (Exception ex)
            {
                // 记录错误，可选用日志或 Console
                Console.WriteLine($"加载呼吸类型失败: {ex.Message}");
            }
        }

        /// <summary>
        /// clostTxt输入验证（仅允许数字和小数点）
        /// </summary>
        private void ClostTxt_PreviewTextInput(object sender, TextCompositionEventArgs e)
        {
            var isNumber = System.Text.RegularExpressions.Regex.IsMatch(e.Text, @"^[0-9]*(?:\.[0-9]*)?$");
            e.Handled = !isNumber;
        }


        private void UpdateClosePressureUI(string value)
        {
            UpdateUiSafely(() => clostTxt.Text = value);
        }

        // 消息提示封装
        private void ShowSuccess(string msg) => MessageBox.Show(msg, "成功", MessageBoxButton.OK, MessageBoxImage.Information);
        private void ShowWarning(string msg) => MessageBox.Show(msg, "提示", MessageBoxButton.OK, MessageBoxImage.Warning);
        private void ShowError(string msg) => MessageBox.Show(msg, "错误", MessageBoxButton.OK, MessageBoxImage.Error);
        #endregion


        /// <summary>
        /// 下拉框选择变化事件处理
        /// </summary>
        private async void CaptureModeComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (sender == null) return;
            var comboBox = sender as ComboBox;
            if (comboBox == null) return;
            var selectedItem = comboBox.SelectedItem as ComboBoxItem;
            if (selectedItem == null) return;
            var content = selectedItem.Content?.ToString();
            if (string.IsNullOrEmpty(content)) return;

            switch (content)
            {
                case "呼气":
                case "Exhale":
                    await WriteCoilWithCheck(36, false, null, "Breath Type", "Breath Type");
                    break;
                case "吸气":
                case "Inhale":
                    await WriteCoilWithCheck(36, true, null, "Breath Type", "Breath Type");
                    break;
                default:
                    return;
            }
        }

        private async void Button_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                await WriteRegisterWithValidation(
                    inputControl: clostTxt,
                    registerAddress: _pressureSettingRegisterAddress,
                    minValue: 0,
                    maxValue: 10000
                );
                //_settingReadTimer2.Start();
            }
            finally
            {

            }
        }
    }
}