using ConductivityApp.GBStandard;
using iTextSharp.text;
using iTextSharp.text.pdf;
using Modbus.Device;
using OxyPlot;
using OxyPlot.Series;
using S7.Net;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Threading;

namespace ConductivityApp
{
    public partial class MainWindow : Window
    {
        #region 字段和属性
        private GBStandard.GB32064Calculator _calculator;
        private Plc _plc;
        private SerialPort _serialPort;
        private IModbusSerialMaster _modbusMaster;
        private DispatcherTimer _dataTimer;
        private PlotModel _plotModel;
        private LineSeries _temperatureSeries;
        private List<double> Ttime2 = new List<double>();
        private List<double> Tempreture2 = new List<double>();
        private List<double> DianYa2 = new List<double>();
        // 最小有效电压变化阈值（小于此视为噪声并跳过）
        private const double MIN_DELTA_U = 1e-5; // 10 µV，按需调整
        // 测试数据
        private readonly List<TestDataPoint> _testData = new List<TestDataPoint>();
        private DateTime _testStartTime;
        private bool _isTesting = false;

        //// 默认配置（根据您的探头）
        //private const double DefaultProbeR0 = 36.0;           // Ω
        //private const double DefaultProbeAlpha = 0.006;     // 1/K (镍)
        //private const double DefaultProbeRadiusMM = 15.0;     // mm
        //private const int DefaultProbeCoilCount = 24;         // 环数

        //private const double DefaultBridgeRs = 36.05;         // Ω
        //private const double DefaultBridgeRL = 0.05;          // Ω

        // 探头物理参数（供应商数据 - 探头2）
        private double DefaultProbeR0 = 34.7;           // Ω，初始电阻
        private double DefaultProbeAlpha = 0.008;      // 1/K，温度系数
        private double DefaultProbeRadiusMM = 14;   // mm，探头半径

        private int DefaultProbeCoilCount = 27;        // 环数

        // 电桥电路参数
        private double DefaultBridgeRs = 34.7;         // Ω，初始探头电阻（=R0）
        private double DefaultBridgeRL = 0.0267;       // Ω，引线电阻（26.7mΩ）
        private static double r = 0;
        private static double a = 0;


        #endregion

        #region 构造函数和初始化
        public MainWindow()
        {
            string desktop = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
            string logFile = Path.Combine(desktop, $"ConductivityLog_{DateTime.Now:yyyyMMdd_HHmmss}.txt");

            try
            {
                // 创建日志文件
                File.WriteAllText(logFile, $"=== 程序启动 {DateTime.Now:yyyy-MM-dd HH:mm:ss} ===\n");

                // 设置日志输出到文件
                var fileStream = new FileStream(logFile, FileMode.Append, FileAccess.Write, FileShare.Read);
                var streamWriter = new StreamWriter(fileStream) { AutoFlush = true };

                // 创建能同时输出到控制台和文件的写入器
                var multiWriter = new WpfApp1.MultiTextWriter(Console.Out, streamWriter);
                Console.SetOut(multiWriter);

                Console.WriteLine($"日志文件: {logFile}");
            }
            catch (Exception ex)
            {
                // 如果创建文件失败，至少还能用控制台
                Console.WriteLine($"创建日志文件失败: {ex.Message}");
            }

            InitializeComponent();
            InitializeUI();
            InitializeHardware();
            InitializeCalculator();
        }




        private void InitializeUI()
        {
            // 初始化图表
            _plotModel = new PlotModel
            {
                Title = "温度-时间曲线",
                Subtitle = "GB/T 32064-2015 瞬态平面热源测试法"
            };

            _plotModel.Axes.Add(new OxyPlot.Axes.LinearAxis
            {
                Position = OxyPlot.Axes.AxisPosition.Bottom,
                Title = "时间 (s)",
                Minimum = 0
            });

            _plotModel.Axes.Add(new OxyPlot.Axes.LinearAxis
            {
                Position = OxyPlot.Axes.AxisPosition.Left,
                Title = "温度变化 ΔT (K)"
            });

            _temperatureSeries = new LineSeries
            {
                Title = "温度变化",
                Color = OxyColors.Blue,
                MarkerType = MarkerType.Circle,
                MarkerSize = 3
            };

            _plotModel.Series.Add(_temperatureSeries);
            plotView.Model = _plotModel;

            // 设置默认参数
            SetDefaultParameters();
        }

        private void SetDefaultParameters()
        {
            // 设置默认参数（基于探头规格，非经验值）
            txtProbeR0.Text = DefaultProbeR0.ToString();
            txtProbeAlpha.Text = DefaultProbeAlpha.ToString();
            txtProbeRadius.Text = DefaultProbeRadiusMM.ToString();
            txtProbeCoils.Text = DefaultProbeCoilCount.ToString();

            txtBridgeRs.Text = DefaultBridgeRs.ToString();
            txtBridgeRL.Text = DefaultBridgeRL.ToString();

            // 测试功率根据电流计算：P = I²R
            double defaultCurrent = 120.0; // mA
            double defaultPower = Math.Pow(defaultCurrent / 1000.0, 2) * DefaultProbeR0;
            txtTestPower.Text = defaultPower.ToString("F4");
            txtCurrent.Text = defaultCurrent.ToString("F0");

            // 移除经验性密度设置
            // txtSampleDensity.Text = "1800"; // 应由用户输入
        }
        string COM = ConfigurationManager.AppSettings["COM"];
        private void InitializeHardware()
        {
            try
            {
                // 从配置文件读取参数
                string plcIp = "192.168.2.1";

                string comPort = COM;
                int baudRate = 9600;

                Console.WriteLine($"尝试初始化硬件: PLC={plcIp}, COM={comPort}");

                // 初始化PLC
                if (!string.IsNullOrEmpty(plcIp))
                {
                    try
                    {
                        _plc = new Plc(CpuType.S7200Smart, plcIp, 0, 1);
                        Console.WriteLine($"PLC对象创建成功: IP={plcIp}");
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine($"创建PLC对象失败: {ex.Message}");
                    }
                }

                // 初始化串口（用于Modbus）
                if (!string.IsNullOrEmpty(comPort))
                {
                    try
                    {
                        _serialPort = new SerialPort(comPort, baudRate, Parity.None, 8, StopBits.One);
                        _serialPort.ReadTimeout = 2000;
                        _serialPort.WriteTimeout = 2000;

                        Console.WriteLine($"串口对象创建成功: {comPort}");

                        // 尝试打开串口，但不要在这里失败
                        try
                        {
                            _serialPort.Open();
                            _modbusMaster = ModbusSerialMaster.CreateRtu(_serialPort);
                            Console.WriteLine($"串口打开成功: {comPort}, {baudRate}bps");
                        }
                        catch (Exception ex)
                        {
                            Console.WriteLine($"⚠️ 串口打开失败: {ex.Message}，将在使用时重试");
                            // 这里不抛出异常，允许后续重试
                        }
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine($"创建串口对象失败: {ex.Message}");
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"硬件初始化过程中出现异常: {ex.Message}");
                // 不抛出异常，允许程序继续运行
            }
        }

        private void InitializeCalculator()
        {
            try
            {
                var bridgeConfig = new GBStandard.GB32064Calculator.BridgeConfig
                {
                    Rs = double.Parse(txtBridgeRs.Text),
                    RL = double.Parse(txtBridgeRL.Text)
                };

                var probeConfig = new GBStandard.GB32064Calculator.ProbeConfig
                {
                    R0 = double.Parse(txtProbeR0.Text),
                    Alpha = double.Parse(txtProbeAlpha.Text),
                    RadiusMM = double.Parse(txtProbeRadius.Text),
                    CoilCount = int.Parse(txtProbeCoils.Text)
                };

                if (txtTestPower == null)
                { return; }

                //if (a > 0 && r > 0)
                //{
                //    probeConfig.RadiusMM = r;
                //    probeConfig.Alpha = a;
                //}

                var testConfig = new GBStandard.GB32064Calculator.TestConfig
                {

                    P0 = double.Parse(txtTestPower?.Text),
                    SampleDensity = double.Parse(txtSampleDensity?.Text),
                    cmbSampleType = cmbSampleType?.Text,
                    yangpinalpha = double.Parse(txtyangpin.Text)
                };

                _calculator = new GBStandard.GB32064Calculator(bridgeConfig, probeConfig, testConfig);
                LogInfo("GB/T 32064-2015 计算器初始化完成");
            }
            catch (Exception ex)
            {
                LogError($"计算器初始化失败: {ex.Message}");
                MessageBox.Show($"计算器初始化失败: {ex.Message}", "错误",
                              MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }
        #endregion

        #region 测试控制

        private DateTime _lastTestCompletedTime = DateTime.MinValue;
        private void btnStartTest_Click(object sender, RoutedEventArgs e)
        {
            if (_isTesting)
            {
                MessageBox.Show("测试正在进行中", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
                return;
            }

            if (_lastTestCompletedTime != DateTime.MinValue)
            {
                double elapsedSeconds = (DateTime.Now - _lastTestCompletedTime).TotalSeconds;
                if (elapsedSeconds < 60)
                {
                    MessageBox.Show($"需等待{60 - elapsedSeconds:F0}秒冷却时间后再启动测试",
                                  "冷却中", MessageBoxButton.OK, MessageBoxImage.Information);
                    return;
                }
            }

            if (!ValidateInputParameters())
                return;

            StartTest();
        }

        private void btnStopTest_Click(object sender, RoutedEventArgs e)
        {
            StopTest();
        }

        private void btnCalculate_Click(object sender, RoutedEventArgs e)
        {
            if (_testData.Count < 20)
            {
                MessageBox.Show("数据点不足，无法计算", "提示",
                              MessageBoxButton.OK, MessageBoxImage.Warning);
                return;
            }

            CalculateResults();
        }

        private bool ValidateInputParameters()
        {
            // 验证探头参数
            if (!double.TryParse(txtProbeR0.Text, out double r0) || r0 <= 0)
            {
                MessageBox.Show("请输入有效的探头初始电阻 (Ω)", "参数错误",
                              MessageBoxButton.OK, MessageBoxImage.Error);
                return false;
            }

            if (!double.TryParse(txtProbeAlpha.Text, out double alpha) || alpha <= 0)
            {
                MessageBox.Show("请输入有效的探头温度系数 (1/K)", "参数错误",
                              MessageBoxButton.OK, MessageBoxImage.Error);
                return false;
            }

            if (!double.TryParse(txtProbeRadius.Text, out double radius) || radius <= 0)
            {
                MessageBox.Show("请输入有效的探头半径 (mm)", "参数错误",
                              MessageBoxButton.OK, MessageBoxImage.Error);
                return false;
            }

            if (!int.TryParse(txtProbeCoils.Text, out int coils) || coils < 10)
            {
                MessageBox.Show("探头环数应不少于10", "参数错误",
                              MessageBoxButton.OK, MessageBoxImage.Error);
                return false;
            }

            // 验证电桥参数
            if (!double.TryParse(txtBridgeRs.Text, out double rs) || rs <= 0)
            {
                MessageBox.Show("请输入有效的串联电阻 (Ω)", "参数错误",
                              MessageBoxButton.OK, MessageBoxImage.Error);
                return false;
            }

            if (!double.TryParse(txtBridgeRL.Text, out double rl) || rl < 0)
            {
                MessageBox.Show("请输入有效的引线电阻 (Ω)", "参数错误",
                              MessageBoxButton.OK, MessageBoxImage.Error);
                return false;
            }

            // 验证样品参数
            if (!double.TryParse(txtSampleDensity.Text, out double density) || density <= 0)
            {
                MessageBox.Show("请输入有效的样品密度 (kg/m³)", "参数错误",
                              MessageBoxButton.OK, MessageBoxImage.Error);
                return false;
            }

            if (!double.TryParse(txtTestPower.Text, out double power) || power <= 0 || power > 4)
            {
                MessageBox.Show("测试功率应在0-4W范围内", "参数错误",
                              MessageBoxButton.OK, MessageBoxImage.Error);
                return false;
            }

            // 验证采集参数
            if (!int.TryParse(txtSampleCount.Text, out int count) || count < 20)
            {
                MessageBox.Show("采集点数应不少于20", "参数错误",
                              MessageBoxButton.OK, MessageBoxImage.Error);
                return false;
            }

            if (!double.TryParse(txtSampleInterval.Text, out double interval) || interval <= 0)
            {
                MessageBox.Show("请输入有效的采集间隔 (s)", "参数错误",
                              MessageBoxButton.OK, MessageBoxImage.Error);
                return false;
            }

            return true;
        }

        private double _initialVoltage = 0;
        private void StartTest()
        {
            try
            {
                Console.WriteLine("=== 开始测试 ===");

                // 根据参数计算建议的测试时间
                double recommendedTime = CalculateRecommendedTestTime();
                Console.WriteLine($"建议测试时间: {recommendedTime:F1} 秒");

                // 如果设置的测试时间不足，提示用户
                int sampleCount = int.Parse(txtSampleCount.Text);
                double sampleInterval = double.Parse(txtSampleInterval.Text);
                double totalTime = sampleCount * sampleInterval;

                if (totalTime < recommendedTime)
                {
                    Console.WriteLine($"⚠️ 警告：测试时间({totalTime:F0}s)不足，建议至少{recommendedTime:F0}s");
                    Console.WriteLine($"当前设置: {sampleCount}点 × {sampleInterval}s = {totalTime:F0}s");
                }

                // 1. 重置状态
                ResetVoltageReadState();
                InitializeCalculator();
                _testData.Clear();
                _temperatureSeries.Points.Clear();

                // 2. 连接PLC
                //if (_plc != null && !_plc.IsConnected)
                //{
                _plc.Open();

                Console.WriteLine("PLC连接成功");
                _plc.Write("M1.1", true);
                Console.WriteLine("加热启动");

                // 等待加热稳定（1秒）
                Thread.Sleep(1000);
                //}




                // 3. 电压校准（读取稳定状态）
                Console.WriteLine("=== 电压校准阶段 ===");
                List<double> initialReadings = new List<double>();

                // 第一次读取会有2秒延迟
                double firstVoltage = ReadForceDataAsync();
                initialReadings.Add(firstVoltage);
                Console.WriteLine($"第一次校准: {firstVoltage:F6}V");

                // 再读取4次，每次间隔500ms
                for (int i = 0; i < 4; i++)
                {
                    Thread.Sleep(500);
                    double voltage = ReadForceDataAsync();
                    initialReadings.Add(voltage);
                    Console.WriteLine($"校准读数{i + 2}: {voltage:F6}V");
                }

                _initialVoltage = initialReadings.Average();
                Console.WriteLine($"校准完成：初始电压 = {_initialVoltage:F6}V");
                Console.WriteLine($"电压稳定性：{(initialReadings.Max() - initialReadings.Min()):F6}V");



                // 5. 开始数据采集
                _testStartTime = DateTime.Now;
                _isTesting = true;

                // 立即读取第一个数据点
                DataTimer_Tick(null, EventArgs.Empty);

                // 启动定时器
                _dataTimer = new DispatcherTimer
                {
                    Interval = TimeSpan.FromSeconds(double.Parse(txtSampleInterval.Text))
                };
                _dataTimer.Tick += DataTimer_Tick;
                _dataTimer.Start();

                UpdateTestControls(true);
                Console.WriteLine($"测试开始，预计采集{int.Parse(txtSampleCount.Text)}个点");
            }
            catch (Exception ex)
            {
                Console.WriteLine($"❌ 启动测试失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 重置电压读取状态（在测试开始时调用）
        /// </summary>
        private void ResetVoltageReadState()
        {
            ResetFirstRead();

            _initialVoltage = 0; // 重置初始电压
            Console.WriteLine("电压读取状态已重置");

        }

        private static bool _isFirstRead = true;
        public void ResetFirstRead()
        {
            _isFirstRead = true;
        }

        /// <summary>
        /// 重新初始化Modbus连接
        /// </summary>
        private void ReinitializeModbusConnection()
        {
            try
            {
                Console.WriteLine("=== 重新初始化Modbus连接 ===");

                // 1. 关闭现有连接
                if (_modbusMaster != null)
                {
                    try
                    {
                        _modbusMaster.Dispose();
                    }
                    catch { }
                    _modbusMaster = null;
                }

                if (_serialPort != null && _serialPort.IsOpen)
                {
                    try
                    {
                        _serialPort.Close();
                    }
                    catch { }
                }

                Thread.Sleep(1000); // 等待1秒

                // 2. 重新初始化
                string comPort = "COM2"; // 或从配置读取
                int baudRate = 9600;

                _serialPort = new SerialPort(comPort, baudRate, Parity.None, 8, StopBits.One);

                try
                {
                    _serialPort.Open();
                    _serialPort.ReadTimeout = 2000; // 设置读取超时
                    _serialPort.WriteTimeout = 2000; // 设置写入超时

                    _modbusMaster = ModbusSerialMaster.CreateRtu(_serialPort);

                    Console.WriteLine($"Modbus重新初始化成功: {comPort}, {baudRate}bps");
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"重新初始化失败: {ex.Message}");
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"ReinitializeModbusConnection 错误: {ex.Message}");
            }
        }

        private float ReadForceDataAsync()
        {
            float measuredValue = 0;
            try
            {
                // 第一次读取延迟2秒，之后延迟500ms
                if (_isFirstRead)
                {
                    Thread.Sleep(2000);
                    _isFirstRead = false;
                }
                else
                {
                    Thread.Sleep(500);
                }

                // ====== 关键修改：检查串口状态 ======
                if (_serialPort == null)
                {
                    Console.WriteLine("⚠️ _serialPort 为 null，尝试重新初始化");
                    InitializeHardware();
                    return 0;
                }

                if (!_serialPort.IsOpen)
                {
                    try
                    {
                        Console.WriteLine("串口未打开，尝试打开...");
                        _serialPort.Open();
                        _modbusMaster = ModbusSerialMaster.CreateRtu(_serialPort);
                        Console.WriteLine("串口已重新打开");
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine($"打开串口失败: {ex.Message}");
                        return 0;
                    }
                }

                if (_modbusMaster == null)
                {
                    Console.WriteLine("⚠️ _modbusMaster 为 null，尝试重新创建");
                    try
                    {
                        _modbusMaster = ModbusSerialMaster.CreateRtu(_serialPort);
                        Console.WriteLine("Modbus Master 已重新创建");
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine($"创建 Modbus Master 失败: {ex.Message}");
                        return 0;
                    }
                }
                // ====== 修改结束 ======

                ushort[] registers = null;
                try
                {
                    Console.WriteLine("尝试读取Modbus寄存器...");
                    registers = _modbusMaster.ReadHoldingRegisters(0x01, 42, 2);
                    Console.WriteLine($"读取成功，寄存器数量: {registers?.Length}");
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"⚠️ Modbus 读取异常: {ex.Message}");
                    // 尝试重新初始化硬件
                    ReinitializeModbusConnection();
                    return 0;
                }

                if (registers != null && registers.Length == 2)
                {
                    measuredValue = ModbusUshortToFloat(registers[0], registers[1]);
                    Console.WriteLine($"读取到电压值: {measuredValue:F6}V");

                    double displayValue = measuredValue;
                    txtCurrentVoltage.Text = $"{displayValue:F6} V";
                    return (float)displayValue;
                }
                else
                {
                    Console.WriteLine($"⚠️ 寄存器数据异常: registers={(registers == null ? "null" : registers.Length.ToString())}");
                    return 0;
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"ReadForceDataAsync 读取错误: {ex.Message}");
                return 0;
            }
        }
        private void StopTest()
        {
            LogInfo("=== 停止测试 ===");

            if (_dataTimer != null)
            {
                _dataTimer.Stop();
                _dataTimer.Tick -= DataTimer_Tick;
                _dataTimer = null;
            }

            if (_plc != null && _plc.IsConnected)
            {
                // 停止加热
                _plc.Write("M1.1", false);
                LogInfo("加热停止");
            }

            _isTesting = false;
            //_lastTestCompletedTime = DateTime.Now;
            UpdateTestControls(false);
            UpdateStatusBar($"测试完成，采集了{_testData.Count}个数据点");

            // 如果数据足够，提示可以计算
            if (_testData.Count >= 20)
            {
                LogInfo($"数据采集完成，共{_testData.Count}个点，可以点击'计算结果'");
            }
        }

        private void DataTimer_Tick(object sender, EventArgs e)
        {
            try
            {
                double timeElapsed = (DateTime.Now - _testStartTime).TotalSeconds;

                // 读取电压和温度数据
                double voltage = ReadForceDataAsync();
                //double pressure = ReadPressureData();//压力暂时去掉
                double pressure = ReadTemperatureData();//温度
                // 若尚未有初始电压（理论上应在校准阶段设置），则设定并跳过当前点
                if (_initialVoltage == 0)
                {
                    _initialVoltage = voltage;
                    Console.WriteLine($"首次采样，设定初始电压: {_initialVoltage:F6}V，跳过该点");
                    return;
                }

                // 计算电压变化量 ΔU = 初始电压 - 当前电压
                double deltaU = voltage - _initialVoltage;

                // 如果电压变化在噪声范围内，跳过本次读数（不计入采样点）
                if (Math.Abs(deltaU) < MIN_DELTA_U)
                {
                    Console.WriteLine($"t={timeElapsed:F3}s: 读数ΔU={deltaU:E6}V 小于阈值 {MIN_DELTA_U:E6}V，跳过该点，等待下一次读取");
                    // 不添加到 _testData，也不更新图表或计数
                    return;
                }

                // 计算温度变化
                double temperature = CalculateTemperatureFromVoltage(voltage);

                // 创建数据点并添加
                var dataPoint = new TestDataPoint
                {
                    Time = timeElapsed,
                    Voltage = voltage,
                    Pressure = pressure,
                    Temperature = temperature
                };

                _testData.Add(dataPoint);

                // 更新图表
                _temperatureSeries.Points.Add(new OxyPlot.DataPoint(timeElapsed, temperature));
                _plotModel.InvalidatePlot(true);

                // 更新实时显示
                UpdateRealtimeDisplay(dataPoint);

                // 更新状态栏
                UpdateStatusBar($"采集中... {_testData.Count}/{int.Parse(txtSampleCount.Text)}");

                // 检查是否达到采集点数
                if (_testData.Count >= int.Parse(txtSampleCount.Text))
                {
                    StopTest();
                    CalculateResults();
                }
            }
            catch (Exception ex)
            {
                LogError($"数据采集错误: {ex.Message}");
            }
        }

        private double CalculateRecommendedTestTime()
        {
            // 符合国标：t_max 需要满足 0.3 ≤ t_max * α / r² ≤ 1.0
            // 精确计算需要样品热扩散系数 α，若界面未提供 α，则返回满足国标最小采样要求的保守默认值 10s
            try
            {
                double r = double.Parse(txtProbeRadius.Text) / 1000.0; // mm -> m

                // 如果界面上有已知的热扩散系数（txtDiffusivity），则使用它计算推荐时间
                if (double.TryParse(txtDiffusivity.Text, out double alpha) && alpha > 0)
                {
                    // 取τ²的中间合规值 0.65 (位于0.3-1.0之间)，可以改为用户可调
                    double tauSquared = 0.65;
                    double recommended = (tauSquared * r * r) / alpha;
                    // 最低限制为10s以满足采样次数>100且采样间隔>=0.1s
                    if (recommended < 10) recommended = 10;
                    return recommended;
                }

                // 否则返回保守默认值
                return 10.0;
            }
            catch
            {
                return 10.0;
            }
        }

        private double ReadPressureData()
        {
            try
            {
                if (_plc != null && _plc.IsConnected)
                {
                    object pressureObj = _plc.Read(DataType.DataBlock, 1, 18, VarType.Real, 1);
                    return Convert.ToDouble(pressureObj);
                }

                return 0.0;
            }
            catch
            {
                return 0.0;
            }
        }

        private double ReadTemperatureData()
        {
            try
            {
                if (_plc != null && _plc.IsConnected)
                {
                    object pressureObj = _plc.Read(DataType.DataBlock, 1, 120, VarType.Real, 1);
                    return Convert.ToDouble(pressureObj);
                }

                return 0.0;
            }
            catch
            {
                return 0.0;
            }
        }

        private double CalculateTemperatureFromVoltage(double voltage)
        {
            try
            {
                // 如果初始电压尚未通过校准设置，则以第一次读数为初始并返回0
                if (_initialVoltage == 0)
                {
                    _initialVoltage = voltage;
                    Console.WriteLine($"初始电压(未校准时自动设定): {_initialVoltage:F6}V");
                    return 0;
                }

                // 修正ΔU方向: ΔU = 初始电压 - 当前电压
                double deltaU = voltage - _initialVoltage;

                // 若ΔU非常小（噪声），返回0（调用处一般会跳过该点）
                if (Math.Abs(deltaU) < MIN_DELTA_U)
                {
                    Console.WriteLine($"ΔU={deltaU:E6}V 小于阈值 {MIN_DELTA_U:E6}V，视为噪声，返回0");
                    return 0;
                }

                // 获取参数
                double rs = double.Parse(txtBridgeRs.Text);
                double rl = double.Parse(txtBridgeRL.Text);
                double r0 = double.Parse(txtProbeR0.Text);
                double alpha = double.Parse(txtProbeAlpha.Text);

                // 获取电流（mA转A）
                double currentMA;
                if (!double.TryParse(txtCurrent.Text, out currentMA))
                {
                    currentMA = 120.0;
                }
                double I0 = currentMA / 1000.0;

                // 国标公式(3): ΔT(t) = (Rs + RL + R0) × ΔU(t) / [(I0 × Rs - ΔU(t)) × α × R0]
                double numerator = (rs + rl + r0) * deltaU;
                double denominator = (I0 * rs - deltaU) * alpha * r0;

                if (Math.Abs(denominator) < 1e-10)
                {
                    LogWarning($"分母接近0 (I0*Rs-ΔU={I0 * rs - deltaU:E6}), 跳过该点");
                    return 0;
                }

                double deltaT = numerator / denominator;

                if (Math.Abs(deltaT) > 100)
                {
                    LogWarning($"温度变化过大: ΔT = {deltaT:F2}K，请检查参数设置或采集数据");
                }

                return deltaT;
            }
            catch (Exception ex)
            {
                LogError($"温度计算错误: {ex.Message}");
                return 0;
            }
        }
        private float ModbusUshortToFloat(ushort highReg, ushort lowReg)
        {
            byte[] floatBytes = new byte[4];
            floatBytes[0] = (byte)(highReg >> 8);
            floatBytes[1] = (byte)highReg;
            floatBytes[2] = (byte)(lowReg >> 8);
            floatBytes[3] = (byte)lowReg;

            if (BitConverter.IsLittleEndian)
            {
                Array.Reverse(floatBytes);
            }

            return BitConverter.ToSingle(floatBytes, 0);
        }
        #endregion

        #region 结果计算和显示



        private void CalculateResults()
        {
            LogInfo("=== 开始计算导热系数和热扩散系数 ===");

            try
            {
                // 重新初始化计算器以确保使用最新参数
                InitializeCalculator();

                // 准备计算数据
                double[] timeArray = _testData.Select(d => d.Time).ToArray();
                double initialVoltage = _testData.Count > 0 ? _testData[0].Voltage : 0;
                double[] deltaUArray = _testData.Select(d => d.Voltage - initialVoltage).ToArray();


                // 获取电流值
                double currentMA;
                if (!double.TryParse(txtCurrent.Text, out currentMA))
                {
                    currentMA = 120.0;
                    LogWarning($"使用默认电流值: {currentMA}mA");
                }

                // 执行计算
                var result = _calculator.Calculate(timeArray, deltaUArray, currentMA);


                // 检查是否有效
                if (!result.IsValid)
                {
                    Console.WriteLine("计算失败！");
                    Console.WriteLine(result.ValidationMessage);
                    Console.WriteLine("详细日志：");
                    Console.WriteLine(result.CalculationLog);
                }
                else
                {
                    Console.WriteLine($"导热系数: {result.ThermalConductivity:F6} W/(m·K)");
                    Console.WriteLine($"热扩散系数: {result.ThermalDiffusivity:E6} m²/s");
                    Console.WriteLine($"比热容: {result.SpecificHeatCapacity:F2} J/(kg·K)");

                    // 保存日志到文件
                    File.WriteAllText($"calculation_log_{DateTime.Now:yyyyMMdd_HHmmss}.txt",
                        result.CalculationLog);
                }



                // 显示结果
                DisplayResults(result);

                // 生成报告
                GenerateReport(result);
                _lastTestCompletedTime = DateTime.Now;
                LogInfo("计算完成");
            }
            catch (Exception ex)
            {
                LogError($"计算错误: {ex.Message}");
                MessageBox.Show($"计算失败: {ex.Message}", "错误",
                              MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }

        private void DisplayResults(GBStandard.GB32064Calculator.CalculationResult result)
        {
            // 显示主要结果
            txtConductivity.Text = result.ThermalConductivity.ToString("F6");
            txtDiffusivity.Text = result.ThermalDiffusivity.ToString("E6");
            // 计算器返回的 SpecificHeatCapacity 为质量比热容 (J/(kg·K))
            txtSampleSpecificHeat.Text = result.SpecificHeatCapacity.ToString("F2");
            txtCorrectionTime.Text = result.CorrectionTime.ToString("F4");
            txtRSquared.Text = result.RSquared.ToString("F4");
            txtValidation.Text = result.ValidationMessage;

            // 根据验证结果设置颜色
            if (result.IsValid)
            {
                txtValidation.Foreground = System.Windows.Media.Brushes.Green;
                txtValidation.FontWeight = System.Windows.FontWeights.Normal;
            }
            else
            {
                txtValidation.Foreground = System.Windows.Media.Brushes.Red;
                txtValidation.FontWeight = System.Windows.FontWeights.Bold;
            }

            // 显示消息框（注意单位：Cp 为 J/(kg·K)）
            if (result.IsValid)
            {
                MessageBox.Show(
                    $"计算成功！\n" +
                    $"导热系数 λ = {result.ThermalConductivity:F4} W/(m·K)\n" +
                    $"热扩散系数 α = {result.ThermalDiffusivity:E6} m²/s\n" +
                    $"比热容 Cp = {result.SpecificHeatCapacity:F2} J/(kg·K)\n" +
                    $"拟合优度 R² = {result.RSquared:F4}",
                    "计算结果",
                    MessageBoxButton.OK,
                    MessageBoxImage.Information
                );
            }
            else
            {
                MessageBox.Show(
                    $"计算完成，但结果验证失败：\n{result.ValidationMessage}\n\n" +
                    $"建议：\n" +
                    $"1. 检查样品与探头接触\n" +
                    $"2. 调整测试时间或功率\n" +
                    $"3. 重新测试",
                    "验证警告",
                    MessageBoxButton.OK,
                    MessageBoxImage.Warning
                );
            }
        }

        private void GenerateReport(GBStandard.GB32064Calculator.CalculationResult result)
        {
            try
            {
                string report = $"=== 导热系数测试报告 ===\n\n" +
                              $"测试信息\n" +
                              $"{"测试时间:",-20} {DateTime.Now:yyyy-MM-dd HH:mm:ss}\n" +
                              $"{"测试标准:",-20} GB/T 32064-2015\n" +
                              $"{"数据点数:",-20} {_testData.Count}\n" +
                              $"{"测试时长:",-20} {_testData.Last().Time:F2} s\n\n" +

                              $"样品参数\n" +
                              $"{"样品密度 ρ:",-20} {txtSampleDensity.Text} kg/m³\n\n" +

                              $"探头参数\n" +
                              $"{"初始电阻 R₀:",-20} {txtProbeR0.Text} Ω\n" +
                              $"{"探头半径 r:",-20} {txtProbeRadius.Text} mm\n" +
                              $"{"探头环数 n:",-20} {txtProbeCoils.Text}\n" +
                              $"{"测试功率 P₀:",-20} {txtTestPower.Text} W\n\n" +

                              $"计算结果\n" +
                              $"{"导热系数 λ:",-20} {result.ThermalConductivity:F6} W/(m·K)\n" +
                              $"{"热扩散系数 α:",-20} {result.ThermalDiffusivity:E6} m²/s\n" +
                              $"{"比热容 Cp:",-20} {result.SpecificHeatCapacity:F2} J/(kg·K)\n" +
                              $"{"校正时间 t_c:",-20} {result.CorrectionTime:F4} s\n" +
                              $"{"拟合优度 R²:",-20} {result.RSquared:F4}\n" +

                              $"{"验证状态:",-20} {(result.IsValid ? "通过" : "未通过")}\n\n" +

                              $"验证信息\n" +
                              $"{result.ValidationMessage}\n\n" +

                              $"备注\n" +
                              $"根据公式 α = λ / (ρ × Cp)，质量比热容 Cp = λ / (ρ × α) 计算得到。";

                txtReport.Text = report;

                // 自动保存报告到桌面
                //SaveReportToFile(report);
            }
            catch (Exception ex)
            {
                LogError($"生成报告失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 导出PDF报告按钮点击事件
        /// </summary>
        private void btnExportReport_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                // 检查是否有测试数据
                if (_testData == null || _testData.Count == 0)
                {
                    MessageBox.Show("没有可导出的测试数据，请先进行测试", "提示",
                                  MessageBoxButton.OK, MessageBoxImage.Information);
                    return;
                }

                // 检查计算结果是否为空
                if (string.IsNullOrEmpty(txtConductivity.Text) ||
                    string.IsNullOrEmpty(txtDiffusivity.Text))
                {
                    MessageBox.Show("请先点击'计算结果'按钮计算导热系数", "提示",
                                  MessageBoxButton.OK, MessageBoxImage.Information);
                    return;
                }

                // 生成PDF报告
                PrintReportWithiTextSharp();
            }
            catch (Exception ex)
            {
                MessageBox.Show($"导出报告失败：{ex.Message}", "错误",
                              MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }

        /// <summary>
        /// 使用iTextSharp生成PDF报告
        /// </summary>
        private void PrintReportWithiTextSharp()
        {
            try
            {
                string desktopPath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
                string fileName = $"导热系数测试报告_{DateTime.Now:yyyyMMdd_HHmmss}.pdf";
                string pdfFilePath = Path.Combine(desktopPath, fileName);

                // 创建PDF文档
                Document document = new Document(iTextSharp.text.PageSize.A4, 50, 50, 50, 50);
                PdfWriter.GetInstance(document, new FileStream(pdfFilePath, FileMode.Create));
                document.Open();

                // 配置中文字体
                string fontPath = @"C:\Windows\Fonts\simsun.ttc,0";
                if (!File.Exists(fontPath.Replace(",0", "")))
                {
                    // 如果宋体不存在，尝试使用其他字体
                    fontPath = BaseFont.HELVETICA;
                }

                BaseFont baseFont = BaseFont.CreateFont(
                    fontPath,
                    BaseFont.IDENTITY_H,
                    BaseFont.EMBEDDED
                );

                Font titleFont = new Font(baseFont, 18, Font.BOLD);
                Font headerFont = new Font(baseFont, 12, Font.BOLD);
                Font contentFont = new Font(baseFont, 10, Font.NORMAL);
                Font smallFont = new Font(baseFont, 9, Font.NORMAL);

                // 添加标题
                iTextSharp.text.Paragraph titlePara = new iTextSharp.text.Paragraph("导热系数测试报告", titleFont);
                titlePara.Alignment = iTextSharp.text.Element.ALIGN_CENTER;
                titlePara.SpacingAfter = 20;
                document.Add(titlePara);

                // 测试基本信息
                iTextSharp.text.Paragraph infoPara = new iTextSharp.text.Paragraph($"报告生成时间：{DateTime.Now:yyyy-MM-dd HH:mm:ss}", contentFont);
                infoPara.SpacingAfter = 10;
                document.Add(infoPara);

                // 测试信息表格
                PdfPTable table = new PdfPTable(2);
                table.WidthPercentage = 100;
                table.SpacingBefore = 10f;
                table.SpacingAfter = 10f;

                // 表格内容
                AddTableHeader(table, headerFont);

                // 探头参数
                AddTableRow(table, "探头初始电阻 (Ω)", txtProbeR0.Text, contentFont);
                AddTableRow(table, "探头温度系数 (1/K)", txtProbeAlpha.Text, contentFont);
                AddTableRow(table, "探头半径 (mm)", txtProbeRadius.Text, contentFont);
                AddTableRow(table, "探头环数", txtProbeCoils.Text, contentFont);

                // 电桥参数
                AddTableRow(table, "串联电阻 (Ω)", txtBridgeRs.Text, contentFont);
                AddTableRow(table, "引线电阻 (Ω)", txtBridgeRL.Text, contentFont);

                // 测试参数
                AddTableRow(table, "测试电流 (mA)", txtCurrent.Text, contentFont);
                AddTableRow(table, "测试功率 (W)", txtTestPower.Text, contentFont);
                AddTableRow(table, "样品密度 (kg/m³)", txtSampleDensity.Text, contentFont);
                AddTableRow(table, "采集点数", txtSampleCount.Text, contentFont);
                AddTableRow(table, "采集间隔 (s)", txtSampleInterval.Text, contentFont);

                // 计算结果
                if (!string.IsNullOrEmpty(txtConductivity.Text))
                {
                    AddTableRow(table, "导热系数 (W/(m·K))", txtConductivity.Text, contentFont);
                }

                if (!string.IsNullOrEmpty(txtDiffusivity.Text))
                {
                    AddTableRow(table, "热扩散系数 (m²/s)", txtDiffusivity.Text, contentFont);
                }

                if (!string.IsNullOrEmpty(txtSampleSpecificHeat.Text))
                {
                    AddTableRow(table, "样品比热容 (J/(kg·K))", txtSampleSpecificHeat.Text, contentFont);
                }

                if (!string.IsNullOrEmpty(txtRSquared.Text))
                {
                    AddTableRow(table, "拟合优度 R²", txtRSquared.Text, contentFont);
                }

                document.Add(table);

                // 添加测试曲线图像
                AddTemperatureCurveToPdf(document);

                // 添加数据点表格
                AddDataPointsTable(document);

                // 测试标准说明
                iTextSharp.text.Paragraph standardPara = new iTextSharp.text.Paragraph("测试标准：GB/T 32064-2015 建筑用材料导热系数和热扩散系数瞬态平面热源测试法", contentFont);
                standardPara.SpacingBefore = 20;
                document.Add(standardPara);

                // 验证信息
                if (!string.IsNullOrEmpty(txtValidation.Text))
                {
                    iTextSharp.text.Paragraph validationPara = new iTextSharp.text.Paragraph($"验证信息：{txtValidation.Text}", contentFont);
                    validationPara.SpacingBefore = 10;
                    document.Add(validationPara);
                }

                document.Close();

                MessageBox.Show($"测试报告已生成：\n{pdfFilePath}\n\n文件已保存到桌面。", "报告生成成功",
                               MessageBoxButton.OK, MessageBoxImage.Information);
            }
            catch (Exception ex)
            {
                MessageBox.Show($"生成报告失败：{ex.Message}", "错误",
                               MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }

        /// <summary>
        /// 添加表格表头
        /// </summary>
        private void AddTableHeader(PdfPTable table, Font font)
        {
            table.AddCell(new PdfPCell(new Phrase("参数名称", font))
            {
                BackgroundColor = new BaseColor(220, 220, 220),
                HorizontalAlignment = iTextSharp.text.Element.ALIGN_CENTER,
                Padding = 8
            });
            table.AddCell(new PdfPCell(new Phrase("参数值", font))
            {
                BackgroundColor = new BaseColor(220, 220, 220),
                HorizontalAlignment = iTextSharp.text.Element.ALIGN_CENTER,
                Padding = 8
            });
        }

        /// <summary>
        /// 添加表格行
        /// </summary>
        private void AddTableRow(PdfPTable table, string label, string value, Font font)
        {
            table.AddCell(new PdfPCell(new Phrase(label, font))
            {
                HorizontalAlignment = iTextSharp.text.Element.ALIGN_LEFT,
                Padding = 6
            });
            table.AddCell(new PdfPCell(new Phrase(value, font))
            {
                HorizontalAlignment = iTextSharp.text.Element.ALIGN_LEFT,
                Padding = 6
            });
        }

        /// <summary>
        /// 添加数据点表格到PDF
        /// </summary>
        private void AddDataPointsTable(Document document)
        {
            try
            {
                if (_testData == null || _testData.Count == 0)
                    return;

                // 准备数据点列表（从_testData中提取）
                Ttime2 = _testData.Select(d => d.Time).ToList();
                Tempreture2 = _testData.Select(d => d.Temperature).ToList();
                DianYa2 = _testData.Select(d => d.Voltage).ToList();

                // 添加数据点表格标题
                BaseFont baseFont = BaseFont.CreateFont(
                    @"C:\Windows\Fonts\simsun.ttc,0",
                    BaseFont.IDENTITY_H,
                    BaseFont.EMBEDDED
                );
                Font titleFont = new Font(baseFont, 12, Font.BOLD);
                Font tableFont = new Font(baseFont, 8);

                iTextSharp.text.Paragraph dataPointsTitle = new iTextSharp.text.Paragraph("测试数据点详情", titleFont);
                dataPointsTitle.SpacingBefore = 20;
                dataPointsTitle.SpacingAfter = 10;
                document.Add(dataPointsTitle);

                // 创建数据点表格（4列：序号、时间、温度变化、电压）
                PdfPTable dataTable = new PdfPTable(4);
                dataTable.WidthPercentage = 100;
                dataTable.SpacingBefore = 10f;
                dataTable.SpacingAfter = 10f;

                // 添加表头
                dataTable.AddCell(new PdfPCell(new Phrase("序号", tableFont))
                {
                    BackgroundColor = new BaseColor(200, 200, 200),
                    HorizontalAlignment = iTextSharp.text.Element.ALIGN_CENTER,
                    Padding = 4
                });
                dataTable.AddCell(new PdfPCell(new Phrase("时间 (s)", tableFont))
                {
                    BackgroundColor = new BaseColor(200, 200, 200),
                    HorizontalAlignment = iTextSharp.text.Element.ALIGN_CENTER,
                    Padding = 4
                });
                dataTable.AddCell(new PdfPCell(new Phrase("温度变化 ΔT (K)", tableFont))
                {
                    BackgroundColor = new BaseColor(200, 200, 200),
                    HorizontalAlignment = iTextSharp.text.Element.ALIGN_CENTER,
                    Padding = 4
                });
                dataTable.AddCell(new PdfPCell(new Phrase("电压 (V)", tableFont))
                {
                    BackgroundColor = new BaseColor(200, 200, 200),
                    HorizontalAlignment = iTextSharp.text.Element.ALIGN_CENTER,
                    Padding = 4
                });

                // 添加数据行（限制最多显示100行，避免PDF过大）
                int maxRows = Math.Min(100, Ttime2.Count);
                for (int i = 0; i < maxRows; i++)
                {
                    dataTable.AddCell(new PdfPCell(new Phrase((i + 1).ToString(), tableFont))
                    {
                        HorizontalAlignment = iTextSharp.text.Element.ALIGN_CENTER,
                        Padding = 3
                    });
                    dataTable.AddCell(new PdfPCell(new Phrase(Ttime2[i].ToString("F2"), tableFont))
                    {
                        HorizontalAlignment = iTextSharp.text.Element.ALIGN_CENTER,
                        Padding = 3
                    });
                    dataTable.AddCell(new PdfPCell(new Phrase(Tempreture2[i].ToString("E3"), tableFont))
                    {
                        HorizontalAlignment = iTextSharp.text.Element.ALIGN_CENTER,
                        Padding = 3
                    });
                    dataTable.AddCell(new PdfPCell(new Phrase(DianYa2[i].ToString("F6"), tableFont))
                    {
                        HorizontalAlignment = iTextSharp.text.Element.ALIGN_CENTER,
                        Padding = 3
                    });
                }

                // 如果数据太多，添加提示
                if (Ttime2.Count > maxRows)
                {
                    dataTable.AddCell(new PdfPCell(new Phrase($"... (仅显示前{maxRows}条，共{Ttime2.Count}条)", tableFont))
                    {
                        Colspan = 4,
                        HorizontalAlignment = iTextSharp.text.Element.ALIGN_CENTER,
                        BackgroundColor = new BaseColor(240, 240, 240)
                    });
                }

                // 添加统计信息
                dataTable.AddCell(new PdfPCell(new Phrase("统计信息", tableFont))
                {
                    Colspan = 4,
                    BackgroundColor = new BaseColor(220, 220, 220),
                    HorizontalAlignment = iTextSharp.text.Element.ALIGN_CENTER,
                    Padding = 4
                });
                dataTable.AddCell(new PdfPCell(new Phrase($"总数据点数: {Ttime2.Count}", tableFont)) { Colspan = 2 });
                dataTable.AddCell(new PdfPCell(new Phrase($"测试时长: {Ttime2.Last():F1} s", tableFont)) { Colspan = 2 });
                dataTable.AddCell(new PdfPCell(new Phrase($"温度变化范围: {Tempreture2.Min():E3} ~ {Tempreture2.Max():E3} K", tableFont)) { Colspan = 2 });
                dataTable.AddCell(new PdfPCell(new Phrase($"电压范围: {DianYa2.Min():F4} ~ {DianYa2.Max():F4} V", tableFont)) { Colspan = 2 });

                document.Add(dataTable);
            }
            catch (Exception ex)
            {
                Console.WriteLine($"添加数据点表格失败: {ex.Message}");
                // 即使表格失败，也继续生成报告
                iTextSharp.text.Paragraph errorPara = new iTextSharp.text.Paragraph("数据点表格生成失败，但不影响其他内容", new Font(Font.FontFamily.HELVETICA, 10));
                errorPara.SpacingBefore = 20;
                document.Add(errorPara);
            }
        }

        /// <summary>
        /// 将温度曲线添加到PDF
        /// </summary>
        private void AddTemperatureCurveToPdf(Document document)
        {
            try
            {
                if (_temperatureSeries == null || _temperatureSeries.Points.Count == 0)
                {
                    iTextSharp.text.Paragraph noDataPara = new iTextSharp.text.Paragraph("暂无温度曲线数据", new Font(Font.FontFamily.HELVETICA, 10));
                    noDataPara.SpacingBefore = 20;
                    document.Add(noDataPara);
                    return;
                }

                // 创建临时图像文件
                string tempImagePath = Path.GetTempFileName() + ".png";

                // 使用System.Drawing创建曲线图像
                CreateTemperatureCurveImageUsingSystemDrawing(tempImagePath);

                // 将图像添加到PDF
                if (File.Exists(tempImagePath))
                {
                    // 添加曲线标题
                    BaseFont baseFont = BaseFont.CreateFont(
                        @"C:\Windows\Fonts\simsun.ttc,0",
                        BaseFont.IDENTITY_H,
                        BaseFont.EMBEDDED
                    );
                    Font titleFont = new Font(baseFont, 12, Font.BOLD);

                    iTextSharp.text.Paragraph curveTitle = new iTextSharp.text.Paragraph("温度-时间曲线", titleFont);
                    curveTitle.SpacingBefore = 20;
                    curveTitle.SpacingAfter = 10;
                    document.Add(curveTitle);

                    // 添加图像
                    iTextSharp.text.Image chartImage = iTextSharp.text.Image.GetInstance(tempImagePath);

                    // 调整图像大小以适应页面
                    chartImage.ScaleToFit(500, 300);
                    chartImage.Alignment = iTextSharp.text.Image.ALIGN_CENTER;
                    document.Add(chartImage);

                    // 添加曲线统计信息
                    AddCurveStatistics(document);

                    // 清理临时文件
                    try
                    {
                        File.Delete(tempImagePath);
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine($"删除临时文件失败: {ex.Message}");
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"添加温度曲线到PDF失败: {ex.Message}");

                // 即使图像添加失败，也继续生成报告
                iTextSharp.text.Paragraph errorPara = new iTextSharp.text.Paragraph("温度曲线生成失败，但不影响其他内容", new Font(Font.FontFamily.HELVETICA, 10));
                errorPara.SpacingBefore = 20;
                document.Add(errorPara);
            }
        }

        /// <summary>
        /// 使用System.Drawing创建温度曲线图像
        /// </summary>
        private void CreateTemperatureCurveImageUsingSystemDrawing(string imagePath)
        {
            try
            {
                if (_testData == null || _testData.Count == 0)
                    return;

                // 获取数据范围
                double minTime = _testData.Min(d => d.Time);
                double maxTime = _testData.Max(d => d.Time);
                double minTemp = _testData.Min(d => d.Temperature);
                double maxTemp = _testData.Max(d => d.Temperature);

                // 创建图像
                int imageWidth = 800;
                int imageHeight = 500;
                using (System.Drawing.Bitmap bitmap = new System.Drawing.Bitmap(imageWidth, imageHeight))
                using (System.Drawing.Graphics graphics = System.Drawing.Graphics.FromImage(bitmap))
                {
                    // 设置背景色
                    graphics.Clear(System.Drawing.Color.White);

                    // 设置绘图区域（留出边距用于坐标轴）
                    int margin = 60;
                    System.Drawing.Rectangle chartArea = new System.Drawing.Rectangle(
                        margin, margin,
                        imageWidth - 2 * margin,
                        imageHeight - 2 * margin
                    );

                    // 绘制坐标轴
                    DrawAxisTicksUsingSystemDrawing(graphics, chartArea, minTime, maxTime, minTemp, maxTemp);

                    // 绘制曲线
                    using (System.Drawing.Pen curvePen = new System.Drawing.Pen(System.Drawing.Color.Blue, 2))
                    {
                        for (int i = 0; i < _testData.Count - 1; i++)
                        {
                            var point1 = _testData[i];
                            var point2 = _testData[i + 1];

                            float x1 = (float)(chartArea.Left + (point1.Time - minTime) * chartArea.Width / (maxTime - minTime));
                            float y1 = (float)(chartArea.Bottom - (point1.Temperature - minTemp) * chartArea.Height / (maxTemp - minTemp));
                            float x2 = (float)(chartArea.Left + (point2.Time - minTime) * chartArea.Width / (maxTime - minTime));
                            float y2 = (float)(chartArea.Bottom - (point2.Temperature - minTemp) * chartArea.Height / (maxTemp - minTemp));

                            graphics.DrawLine(curvePen, x1, y1, x2, y2);
                        }
                    }

                    // 绘制数据点
                    using (System.Drawing.Brush pointBrush = new System.Drawing.SolidBrush(System.Drawing.Color.Red))
                    {
                        int pointCount = Math.Min(20, _testData.Count); // 只绘制部分点避免太密集
                        int step = _testData.Count / pointCount;

                        for (int i = 0; i < _testData.Count; i += step)
                        {
                            var point = _testData[i];
                            float x = (float)(chartArea.Left + (point.Time - minTime) * chartArea.Width / (maxTime - minTime));
                            float y = (float)(chartArea.Bottom - (point.Temperature - minTemp) * chartArea.Height / (maxTemp - minTemp));

                            graphics.FillEllipse(pointBrush, x - 3, y - 3, 6, 6);
                        }
                    }

                    // 添加标题
                    using (System.Drawing.Font titleFont = new System.Drawing.Font("Arial", 14, System.Drawing.FontStyle.Bold))
                    {
                        System.Drawing.SizeF titleSize = graphics.MeasureString("温度-时间曲线", titleFont);
                        graphics.DrawString("温度-时间曲线", titleFont, System.Drawing.Brushes.Black,
                                          (imageWidth - titleSize.Width) / 2, 20);
                    }

                    // 保存图像
                    bitmap.Save(imagePath, System.Drawing.Imaging.ImageFormat.Png);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"创建温度曲线图像失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 使用System.Drawing绘制坐标轴刻度
        /// </summary>
        private void DrawAxisTicksUsingSystemDrawing(System.Drawing.Graphics graphics, System.Drawing.Rectangle chartArea,
                                                   double minTime, double maxTime, double minTemp, double maxTemp)
        {
            using (System.Drawing.Pen axisPen = new System.Drawing.Pen(System.Drawing.Color.Black, 1))
            using (System.Drawing.Font tickFont = new System.Drawing.Font("Arial", 8))
            using (System.Drawing.Font axisFont = new System.Drawing.Font("Arial", 10, System.Drawing.FontStyle.Regular))
            {
                // X轴刻度（时间）
                int xTicks = 10;
                double xStep = (maxTime - minTime) / xTicks;
                for (int i = 0; i <= xTicks; i++)
                {
                    double timeValue = minTime + i * xStep;
                    float xPos = (float)(chartArea.Left + (timeValue - minTime) * chartArea.Width / (maxTime - minTime));

                    // 绘制刻度线
                    graphics.DrawLine(axisPen, xPos, chartArea.Bottom, xPos, chartArea.Bottom + 5);

                    // 绘制刻度标签
                    string label = timeValue.ToString("F1");
                    System.Drawing.SizeF textSize = graphics.MeasureString(label, tickFont);
                    graphics.DrawString(label, tickFont, System.Drawing.Brushes.Black,
                                      xPos - textSize.Width / 2, chartArea.Bottom + 8);
                }

                // Y轴刻度（温度）
                int yTicks = 8;
                double yStep = (maxTemp - minTemp) / yTicks;
                for (int i = 0; i <= yTicks; i++)
                {
                    double tempValue = minTemp + i * yStep;
                    float yPos = (float)(chartArea.Bottom - (tempValue - minTemp) * chartArea.Height / (maxTemp - minTemp));

                    // 绘制刻度线
                    graphics.DrawLine(axisPen, chartArea.Left - 5, yPos, chartArea.Left, yPos);

                    // 绘制刻度标签
                    string label = tempValue.ToString("E2");
                    System.Drawing.SizeF textSize = graphics.MeasureString(label, tickFont);
                    graphics.DrawString(label, tickFont, System.Drawing.Brushes.Black,
                                      chartArea.Left - textSize.Width - 8, yPos - textSize.Height / 2);
                }

                // 绘制坐标轴线
                graphics.DrawLine(axisPen, chartArea.Left, chartArea.Top, chartArea.Left, chartArea.Bottom); // Y轴
                graphics.DrawLine(axisPen, chartArea.Left, chartArea.Bottom, chartArea.Right, chartArea.Bottom); // X轴

                // 添加坐标轴标签
                System.Drawing.SizeF xLabelSize = graphics.MeasureString("时间 (s)", axisFont);
                graphics.DrawString("时间 (s)", axisFont, System.Drawing.Brushes.Black,
                                  chartArea.Left + (chartArea.Width - xLabelSize.Width) / 2,
                                  chartArea.Bottom + 30);

                System.Drawing.SizeF yLabelSize = graphics.MeasureString("温度变化 ΔT (K)", axisFont);
                graphics.TranslateTransform(20, chartArea.Top + (chartArea.Height + yLabelSize.Width) / 2);
                graphics.RotateTransform(-90);
                graphics.DrawString("温度变化 ΔT (K)", axisFont, System.Drawing.Brushes.Black, 0, 0);
                graphics.ResetTransform();
            }
        }

        /// <summary>
        /// 添加曲线统计信息
        /// </summary>
        private void AddCurveStatistics(Document document)
        {
            if (_testData == null || _testData.Count == 0) return;

            try
            {
                // 计算统计信息
                double minTime = _testData.Min(d => d.Time);
                double maxTime = _testData.Max(d => d.Time);
                double minTemp = _testData.Min(d => d.Temperature);
                double maxTemp = _testData.Max(d => d.Temperature);
                double avgTemp = _testData.Average(d => d.Temperature);
                double tempRange = maxTemp - minTemp;

                // 计算温升速率（使用最后20%的数据）
                double heatingRate = 0;
                int last20Percent = (int)(_testData.Count * 0.2);
                if (last20Percent > 1)
                {
                    var lastPoints = _testData.Skip(_testData.Count - last20Percent).ToList();
                    double startTemp = lastPoints.First().Temperature;
                    double endTemp = lastPoints.Last().Temperature;
                    double timeSpan = lastPoints.Last().Time - lastPoints.First().Time;
                    heatingRate = (endTemp - startTemp) / timeSpan;
                }

                // 创建统计表格
                PdfPTable statsTable = new PdfPTable(2);
                statsTable.WidthPercentage = 80;
                statsTable.SpacingBefore = 10f;
                statsTable.SpacingAfter = 10f;
                statsTable.HorizontalAlignment = iTextSharp.text.Element.ALIGN_CENTER;

                // 添加统计信息
                BaseFont baseFont = BaseFont.CreateFont(
                    @"C:\Windows\Fonts\simsun.ttc,0",
                    BaseFont.IDENTITY_H,
                    BaseFont.EMBEDDED
                );
                Font statsFont = new Font(baseFont, 9);

                AddTableRow(statsTable, "数据点数", _testData.Count.ToString(), statsFont);
                AddTableRow(statsTable, "测试时长", $"{maxTime:F2} s", statsFont);
                AddTableRow(statsTable, "温度变化范围", $"{tempRange:E3} K", statsFont);
                AddTableRow(statsTable, "平均温度变化", $"{avgTemp:E3} K", statsFont);
                AddTableRow(statsTable, "温升速率", $"{heatingRate:E3} K/s", statsFont);
                AddTableRow(statsTable, "数据质量", heatingRate > 0 ? "良好" : "稳定", statsFont);

                document.Add(statsTable);
            }
            catch (Exception ex)
            {
                Console.WriteLine($"添加曲线统计信息失败: {ex.Message}");
            }
        }
        #endregion

        #region UI更新方法
        private void UpdateTestControls(bool isTesting)
        {
            Dispatcher.Invoke(() =>
            {
                // 控制按钮状态
                btnStartTest.IsEnabled = !isTesting;
                btnStopTest.IsEnabled = isTesting;
                btnCalculate.IsEnabled = !isTesting && _testData.Count >= 20;

                // 参数输入框状态
                txtProbeR0.IsEnabled = !isTesting;
                txtProbeAlpha.IsEnabled = !isTesting;
                txtProbeRadius.IsEnabled = !isTesting;
                txtProbeCoils.IsEnabled = !isTesting;
                txtBridgeRs.IsEnabled = !isTesting;
                txtBridgeRL.IsEnabled = !isTesting;
                txtSampleDensity.IsEnabled = !isTesting;
                txtTestPower.IsEnabled = !isTesting;
                txtSampleCount.IsEnabled = !isTesting;
                txtSampleInterval.IsEnabled = !isTesting;
            });
        }

        private void UpdateRealtimeDisplay(TestDataPoint data)
        {
            Dispatcher.Invoke(() =>
            {
                txtCurrentTime.Text = data.Time.ToString("F2");
                txtCurrentVoltage.Text = data.Voltage.ToString("F6");
                txtCurrentPressure.Text = data.Pressure.ToString("F3");
                txtCurrentTemperature.Text = data.Temperature.ToString("F4");
            });
        }

        private void UpdateStatusBar(string message)
        {
            Dispatcher.Invoke(() =>
            {
                txtStatus.Text = message;
            });
        }

        private void LogInfo(string message)
        {
            Dispatcher.Invoke(() =>
            {
                string logEntry = $"[INFO] {DateTime.Now:HH:mm:ss}: {message}\n";
                txtLog.AppendText(logEntry);
                txtLog.ScrollToEnd();
            });
        }

        private void LogWarning(string message)
        {
            Dispatcher.Invoke(() =>
            {
                string logEntry = $"[WARN] {DateTime.Now:HH:mm:ss}: {message}\n";
                txtLog.AppendText(logEntry);
                txtLog.ScrollToEnd();
            });
        }

        private void LogError(string message)
        {
            Dispatcher.Invoke(() =>
            {
                if (txtLog != null)
                {
                    string logEntry = $"[ERROR] {DateTime.Now:HH:mm:ss}: {message}\n";
                    txtLog?.AppendText(logEntry);
                    txtLog?.ScrollToEnd();
                }
            });
        }

        private void btnClearLog_Click(object sender, RoutedEventArgs e)
        {
            txtLog.Clear();
            LogInfo("日志已清空");
        }
        #endregion

        #region 窗口事件
        private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            // 停止测试
            if (_isTesting)
            {
                StopTest();
            }

            // 关闭硬件连接
            if (_plc != null && _plc.IsConnected)
            {
                _plc.Close();
            }

            if (_serialPort != null && _serialPort.IsOpen)
            {
                _serialPort.Close();
            }

            LogInfo("应用程序关闭");
        }
        #endregion

        #region 数据类
        private class TestDataPoint
        {
            public double Time { get; set; }        // 时间 (s)
            public double Voltage { get; set; }     // 电压 (V)
            public double Pressure { get; set; }    // 温度 (N)
            public double Temperature { get; set; } // 温度变化 ΔT (K)
        }
        #endregion

        private void txtdianliu_TextChanged(object sender, TextChangedEventArgs e)
        {
            if (double.TryParse(txtCurrent.Text, out double currentmA) &&
                double.TryParse(txtProbeR0.Text, out double probeR0))
            {
                double currentA = currentmA / 1000.0;
                double power = Math.Pow(currentA, 2) * probeR0;
                if (txtTestPower != null)
                {
                    txtTestPower.Text = power.ToString("F4");

                }


                // 验证功率是否合理
                Console.WriteLine($"电流: {currentmA}mA = {currentA}A");
                Console.WriteLine($"探头电阻: {probeR0}Ω");
                Console.WriteLine($"计算功率: {power}W");

                if (power < 0.1 || power > 5.0)
                {
                    Console.WriteLine($"⚠️ 功率异常: {power}W，建议调整电流");
                }
            }
        }

        private void btnShowLog_Click(object sender, RoutedEventArgs e)
        {
            // 方法1：直接在消息框显示关键信息
            StringBuilder sb = new StringBuilder();
            sb.AppendLine("=== 当前系统状态 ===");
            sb.AppendLine($"时间: {DateTime.Now:HH:mm:ss}");
            sb.AppendLine($"测试状态: {(_isTesting ? "进行中" : "已停止")}");
            sb.AppendLine($"数据点数: {_testData?.Count ?? 0}");

            if (_testData != null && _testData.Count > 0)
            {
                sb.AppendLine($"\n=== 数据摘要 ===");
                sb.AppendLine($"时间范围: {_testData[0].Time:F1}s ~ {_testData.Last().Time:F1}s");
                sb.AppendLine($"电压范围: {_testData.Min(d => d.Voltage):F4}V ~ {_testData.Max(d => d.Voltage):F4}V");
                sb.AppendLine($"ΔT范围: {_testData.Min(d => d.Temperature):E2}K ~ {_testData.Max(d => d.Temperature):E2}K");

                // 检查ΔT是否正常
                double avgDeltaT = _testData.Average(d => d.Temperature);
                sb.AppendLine($"平均ΔT: {avgDeltaT:E2}K");

                if (Math.Abs(avgDeltaT) < 0.001)
                {
                    sb.AppendLine("\n⚠️ 警告：ΔT太小！这可能导致计算失败！");
                }
            }

            // 显示参数
            sb.AppendLine($"\n=== 当前参数 ===");
            sb.AppendLine($"探头电阻: {txtProbeR0.Text}Ω");
            sb.AppendLine($"温度系数: {txtProbeAlpha.Text}/K");
            sb.AppendLine($"电流: {txtCurrent.Text}mA");
            sb.AppendLine($"功率: {txtTestPower.Text}W");

            MessageBox.Show(sb.ToString(), "系统状态", MessageBoxButton.OK, MessageBoxImage.Information);

            // 方法2：同时输出到控制台
            Console.WriteLine("\n" + new string('=', 60));
            Console.WriteLine("【手动触发日志输出】");
            Console.WriteLine($"触发时间: {DateTime.Now:HH:mm:ss.fff}");
            Console.WriteLine($"数据点数: {_testData?.Count ?? 0}");

            // 输出更多详细信息到控制台
            if (_testData != null && _testData.Count > 0)
            {
                Console.WriteLine("最后3个数据点的详细计算:");
                int start = Math.Max(0, _testData.Count - 3);
                for (int i = start; i < _testData.Count; i++)
                {
                    var data = _testData[i];
                    Console.WriteLine($"点{i}: t={data.Time:F3}s, V={data.Voltage:F6}V, ΔT={data.Temperature:E6}K");
                }
            }

            Console.WriteLine(new string('=', 60));
        }

        private void btnStartTest1_Click(object sender, RoutedEventArgs e)
        {
            try
            {

                //if (_plc == null || !_plc.IsConnected)
                //{
                _plc?.Open();
                //}
                _plc?.Write("M1.0", true); // 夹紧
                Console.WriteLine("执行夹紧操作");
            }
            catch (Exception ex)
            {
                MessageBox.Show($"夹紧操作失败：{ex.Message}");
            }
        }

        private void btnStartTest2_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                //if (_plc == null || !_plc.IsConnected)
                //{
                _plc?.Open();
                //}
                _plc?.Write("M1.0", false); // 松开
                Console.WriteLine("执行松开操作");
            }
            catch (Exception ex)
            {
                MessageBox.Show($"松开操作失败：{ex.Message}");
            }
        }

        private void cmbSampleType_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            // 获取选中的ComboBoxItem项
            var selectedItem = cmbSampleType.SelectedItem as ComboBoxItem;
            if (selectedItem == null) return; // 无选中项时直接返回
            string type = selectedItem.Content.ToString();
            switch (type)
            {
                case "干土":
                    {
                        txtSampleCount.Text = "150";
                        txtSampleInterval.Text = "0.8";
                        txtyangpin0.Visibility = Visibility.Collapsed;
                        txtyangpin.Visibility = Visibility.Collapsed;

                        //DefaultProbeAlpha = 0.006;      // 1/K，温度系数
                        //DefaultProbeRadiusMM = 12;   // mm，探头半径

                        break;
                    }
                case "湿土":
                    {
                        txtSampleCount.Text = "120";
                        txtSampleInterval.Text = "1";
                        txtyangpin0.Visibility = Visibility.Collapsed;
                        txtyangpin.Visibility = Visibility.Collapsed;
                        //DefaultProbeAlpha = 0.008;      // 1/K，温度系数
                        //DefaultProbeRadiusMM = 14;   // mm，探头半径
                        break;
                    }
                case "冻土":
                    {
                        txtSampleCount.Text = "150";
                        txtSampleInterval.Text = "0.4";
                        txtyangpin0.Visibility = Visibility.Collapsed;
                        txtyangpin.Visibility = Visibility.Collapsed;
                        //DefaultProbeAlpha = 0.008;      // 1/K，温度系数
                        //DefaultProbeRadiusMM = 14;   // mm，探头半径
                        break;
                    }
                case "不锈钢":
                    {
                        txtSampleCount.Text = "120";
                        txtSampleInterval.Text = "0.1";
                        txtyangpin0.Visibility = Visibility.Collapsed;
                        txtyangpin.Visibility = Visibility.Collapsed;
                        //DefaultProbeAlpha = 0.008;      // 1/K，温度系数
                        //DefaultProbeRadiusMM = 14;   // mm，探头半径
                        break;
                    }

                case "自定义":
                    {
                        txtyangpin0.Visibility = Visibility.Visible;
                        txtyangpin.Visibility = Visibility.Visible;
                        break;
                    }
            }
            //r = DefaultProbeRadiusMM;
            //a = DefaultProbeAlpha;
            //InitializeCalculator(DefaultProbeRadiusMM, DefaultProbeAlpha);
        }

        private void cmbtt_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            // 获取选中的ComboBoxItem项
            var selectedItem = cmbtt.SelectedItem as ComboBoxItem;
            if (selectedItem == null) return; // 无选中项时直接返回
            string type = selectedItem.Content.ToString();
            switch (type)
            {
                case "14mm":
                    {
                        if (txtProbeRadius == null)
                            return;
                        txtProbeR0.Text = "34.7";
                        txtProbeRadius.Text = "14";
                        txtProbeCoils.Text = "27";
                        txtBridgeRs.Text = "34.7";
                        txtBridgeRL.Text = "0.0267";
                        DefaultProbeR0 = 34.7;           // Ω，初始电阻
                        DefaultProbeRadiusMM = 14;   // mm，探头半径
                        DefaultProbeCoilCount = 27;        // 环数
                        // 电桥电路参数
                        DefaultBridgeRs = 34.7;         // Ω，初始探头电阻（=R0）
                        DefaultBridgeRL = 0.0267;       // Ω，引线电阻（26.7mΩ）
                        break;
                    }
                case "6.4mm":
                    {
                        if (txtProbeR0 == null)
                            return;
                        txtProbeR0.Text = "7.34";
                        txtProbeRadius.Text = "6.4";
                        txtProbeCoils.Text = "13";
                        txtBridgeRs.Text = "7.34";
                        txtBridgeRL.Text = "0.0243";
                        DefaultProbeR0 = 7.34;           // Ω，初始电阻
                        DefaultProbeRadiusMM = 6.4;   // mm，探头半径
                        DefaultProbeCoilCount = 13;        // 环数
                        // 电桥电路参数
                        DefaultBridgeRs = 7.34;         // Ω，初始探头电阻（=R0）
                        DefaultBridgeRL = 0.0243;       // Ω，引线电阻（26.7mΩ）
                        break;
                    }


            }
            DefaultProbeAlpha = 0.008;      // 1/K，温度系数
            //SetDefaultParameters();
        }


        // IMG文件夹路径（可根据实际路径修改）
        // 方式1：程序运行目录下的IMG文件夹
        private readonly string _imgFolderPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "IMG");
        // 方式2：固定绝对路径（示例）
        // private readonly string _imgFolderPath = @"D:\Project\IMG";

        private void name1_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                // 获取IMG下所有图片文件
                var imageExtensions = new[] { ".jpg", ".jpeg", ".png", ".gif", ".bmp" };
                var imageFiles = Directory.GetFiles(_imgFolderPath)
                                          .Where(file => imageExtensions.Contains(Path.GetExtension(file).ToLower()))
                                          .ToList();

                if (imageFiles.Count == 0)
                {
                    MessageBox.Show("IMG文件夹下暂无图片！", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
                    return;
                }

                // 仅保留弹窗预览（单张/多张可选）
                // 方案1：预览第一张图片
                PreviewImageInDialog(imageFiles[0]);

                // 方案2：预览所有图片（带上下张切换）
                // PreviewAllImagesInDialog(imageFiles);
            }
            catch (Exception ex)
            {
                MessageBox.Show($"预览图片失败：{ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }

        #region 弹窗预览单张图片（核心保留）
        private void PreviewImageInDialog(string imagePath)
        {
            var dialog = new Window
            {
                Title = $"预览：{Path.GetFileName(imagePath)}",
                Width = 600,
                Height = 500,
                WindowStartupLocation = WindowStartupLocation.CenterOwner,
                Owner = this
            };

            var image = new System.Windows.Controls.Image
            {
                Stretch = Stretch.Uniform,
                Margin = new Thickness(10)
            };
            // 加载图片（避免文件占用）
            var bitmap = new BitmapImage();
            bitmap.BeginInit();
            bitmap.UriSource = new Uri(imagePath);
            bitmap.CacheOption = BitmapCacheOption.OnLoad;
            bitmap.EndInit();
            image.Source = bitmap;

            dialog.Content = image;
            dialog.ShowDialog();
        }
        #endregion

        #region 扩展：弹窗预览所有图片（可选保留）


        // 辅助：更新图片源
        private void UpdateImageSource(System.Windows.Controls.Image image, string path)
        {
            var bitmap = new BitmapImage();
            bitmap.BeginInit();
            bitmap.UriSource = new Uri(path);
            bitmap.CacheOption = BitmapCacheOption.OnLoad;
            bitmap.EndInit();
            image.Source = bitmap;
        }
        #endregion




        private void OnParameterAnalysisClick(object sender, RoutedEventArgs e)
        {
            try
            {
                // 检查是否有计算结果
                if (string.IsNullOrEmpty(txtConductivity.Text) || _testData.Count == 0)
                {
                    MessageBox.Show("请先进行测试并计算导热系数", "提示",
                                  MessageBoxButton.OK, MessageBoxImage.Warning);
                    return;
                }

                // 获取正向计算结果
                var forwardResult = new GBStandard.GB32064Calculator.CalculationResult
                {
                    ThermalConductivity = double.Parse(txtConductivity.Text),
                    ThermalDiffusivity = double.Parse(txtDiffusivity.Text),
                    SpecificHeatCapacity = double.Parse(txtSampleSpecificHeat.Text),
                    CorrectionTime = double.Parse(txtCorrectionTime.Text),
                    RSquared = double.Parse(txtRSquared.Text),
                    IsValid = txtValidation.Foreground == Brushes.Green
                };

                // 准备数据
                double[] timeArray = _testData.Select(d => d.Time).ToArray();
                double[] deltaTArray = _testData.Select(d => d.Temperature).ToArray();
                double initialVoltage = _testData.Count > 0 ? _testData[0].Voltage : 0;
                double[] deltaUArray = _testData.Select(d => d.Voltage - initialVoltage).ToArray();

                double currentMA = double.TryParse(txtCurrent.Text, out double c) ? c : 120.0;

                // 执行逆向分析
                var inverseResult = _calculator.InverseAnalysis(
                    forwardResult, timeArray, deltaTArray, deltaUArray, currentMA);

                // 显示结果
                ShowInverseAnalysisWindow(inverseResult);

                // 保存报告
                SaveInverseAnalysisReport(inverseResult);
            }
            catch (Exception ex)
            {
                MessageBox.Show($"逆向分析失败: {ex.Message}", "错误",
                               MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }

        private void ShowInverseAnalysisWindow(GBStandard.GB32064Calculator.InverseAnalysisResult result)
        {
            // 创建新窗口显示逆向分析结果
            var window = new Window
            {
                Title = "逆向分析报告",
                Width = 900,
                Height = 700,
                WindowStartupLocation = WindowStartupLocation.CenterOwner,
                Owner = this
            };

            var textBox = new TextBox
            {
                Text = result.AnalysisReport,
                FontFamily = new FontFamily("Consolas"),
                FontSize = 12,
                IsReadOnly = true,
                VerticalScrollBarVisibility = ScrollBarVisibility.Auto,
                HorizontalScrollBarVisibility = ScrollBarVisibility.Auto,
                TextWrapping = TextWrapping.Wrap
            };

            // 添加参数范围表格
            var tabControl = new TabControl();

            // 报告标签页
            var reportTab = new TabItem { Header = "分析报告" };
            reportTab.Content = new ScrollViewer { Content = textBox };

            // 参数范围标签页
            if (result.ParameterRanges != null)
            {
                var paramTab = new TabItem { Header = "参数范围" };
                paramTab.Content = CreateParameterRangesGrid(result.ParameterRanges);
                tabControl.Items.Add(paramTab);
            }

            // 敏感性分析标签页
            if (result.Sensitivity.SensitivityCoefficients != null)
            {
                var sensitivityTab = new TabItem { Header = "敏感性分析" };
                sensitivityTab.Content = CreateSensitivityChart(result.Sensitivity);
                tabControl.Items.Add(sensitivityTab);
            }

            // 建议标签页
            if (result.Recommendations != null && result.Recommendations.Count > 0)
            {
                var recommendationTab = new TabItem { Header = "优化建议" };
                recommendationTab.Content = CreateRecommendationsGrid(result.Recommendations);
                tabControl.Items.Add(recommendationTab);
            }

            tabControl.Items.Add(reportTab);

            window.Content = tabControl;
            window.ShowDialog();
        }




        /// <summary>
        /// 创建优化建议表格（简化稳定版）
        /// </summary>
        private FrameworkElement CreateRecommendationsGrid(List<GBStandard.GB32064Calculator.ParameterRecommendation> recommendations)
        {
            try
            {
                // 如果没有建议，显示提示
                if (recommendations == null || recommendations.Count == 0)
                {
                    return new TextBlock
                    {
                        Text = "无需优化建议，所有参数都在合理范围内",

                        FontSize = 16,
                        Foreground = Brushes.Green,
                        Margin = new Thickness(10),
                        TextWrapping = TextWrapping.Wrap
                    };
                }

                // 使用简单的StackPanel，避免复杂的DataGrid绑定
                var mainStack = new StackPanel
                {
                    Margin = new Thickness(10),
                    Background = Brushes.White
                };

                // 添加标题
                mainStack.Children.Add(new TextBlock
                {
                    Text = $"优化建议 ({recommendations.Count} 项)",
                    FontSize = 18,
                    FontWeight = System.Windows.FontWeights.Bold,
                    Margin = new Thickness(0, 0, 0, 10),
                    Foreground = Brushes.DarkBlue
                });

                // 添加统计信息
                double avgImprovement = recommendations.Average(r => r.ExpectedImprovement);
                mainStack.Children.Add(new TextBlock
                {
                    Text = $"总体预期改进: {avgImprovement:F1}%",
                    FontSize = 14,
                    FontWeight = System.Windows.FontWeights.SemiBold,
                    Margin = new Thickness(0, 0, 0, 10),
                    Foreground = Brushes.DarkGreen
                });

                // 创建简单的建议列表（使用Border而不是DataGrid）
                int priority = 1;
                foreach (var rec in recommendations.OrderByDescending(r => r.ExpectedImprovement))
                {
                    // 每个建议项用一个Border包裹 
                    var itemBorder = new Border
                    {
                        BorderBrush = Brushes.LightGray,
                        BorderThickness = new Thickness(1),
                        CornerRadius = new CornerRadius(5),
                        Background = Brushes.AliceBlue,
                        Margin = new Thickness(0, 0, 0, 8),
                        Padding = new Thickness(10)
                    };

                    var itemStack = new StackPanel();

                    // 优先级和参数
                    itemStack.Children.Add(new TextBlock
                    {
                        Text = $"{priority}. 【{rec.Parameter}】 - 预期改进: {rec.ExpectedImprovement:F1}%",
                        FontWeight = System.Windows.FontWeights.Bold,
                        FontSize = 15,
                        Foreground = Brushes.DarkSlateBlue,
                        Margin = new Thickness(0, 0, 0, 5)
                    });

                    // 问题描述
                    itemStack.Children.Add(new TextBlock
                    {
                        Text = $"问题: {rec.Issue}",
                        FontSize = 14,
                        Foreground = Brushes.DarkRed,
                        Margin = new Thickness(5, 0, 0, 3),
                        TextWrapping = TextWrapping.Wrap
                    });

                    // 建议措施
                    itemStack.Children.Add(new TextBlock
                    {
                        Text = $"建议: {rec.Recommendation}",
                        FontSize = 14,
                        Foreground = Brushes.DarkGreen,
                        Margin = new Thickness(5, 0, 0, 0),
                        TextWrapping = TextWrapping.Wrap
                    });

                    itemBorder.Child = itemStack;
                    mainStack.Children.Add(itemBorder);

                    priority++;
                }

                // 添加导出按钮
                var exportButton = new Button
                {
                    Content = "导出建议列表",
                    Width = 120,
                    Height = 30,
                    Margin = new Thickness(0, 10, 0, 0),

                    Background = Brushes.SteelBlue,
                    Foreground = Brushes.White
                };
                exportButton.Click += (s, e) => ExportSimpleRecommendations(recommendations);

                var buttonPanel = new StackPanel
                {
                    Orientation = Orientation.Horizontal,

                    Margin = new Thickness(0, 10, 0, 0)
                };
                buttonPanel.Children.Add(exportButton);
                mainStack.Children.Add(buttonPanel);

                // 返回带滚动条的容器
                return new ScrollViewer
                {
                    Content = mainStack,
                    VerticalScrollBarVisibility = ScrollBarVisibility.Auto,
                    HorizontalScrollBarVisibility = ScrollBarVisibility.Disabled
                };
            }
            catch (Exception ex)
            {
                // 返回简单的错误信息，避免二次崩溃
                return new TextBlock
                {
                    Text = $"显示建议列表时出错: {ex.Message}\n\n建议内容:\n" +
                          string.Join("\n", recommendations?.Select(r => $"- {r.Parameter}: {r.Issue}") ?? new[] { "无建议数据" }),
                    Foreground = Brushes.Red,
                    Margin = new Thickness(10),
                    TextWrapping = TextWrapping.Wrap
                };
            }
        }

        /// <summary>
        /// 简化的敏感性分析图表
        /// </summary>
        private FrameworkElement CreateSensitivityChart(GBStandard.GB32064Calculator.SensitivityAnalysis sensitivity)
        {
            try
            {
                var mainStack = new StackPanel
                {
                    Margin = new Thickness(10),
                    Background = Brushes.White
                };

                // 如果没有数据，显示提示
                if (sensitivity.SensitivityCoefficients == null || sensitivity.SensitivityCoefficients.Count == 0)
                {
                    mainStack.Children.Add(new TextBlock
                    {
                        Text = "无敏感性分析数据",

                        FontSize = 16,
                        Margin = new Thickness(0, 20, 0, 0)
                    });
                    return mainStack;
                }

                // 添加标题
                mainStack.Children.Add(new TextBlock
                {
                    Text = "参数敏感性分析",
                    FontSize = 18,
                    FontWeight = System.Windows.FontWeights.Bold,
                    Margin = new Thickness(0, 0, 0, 15),

                    Foreground = Brushes.DarkBlue
                });

                // 添加关键统计
                mainStack.Children.Add(new TextBlock
                {
                    Text = $"最敏感参数: {sensitivity.MostSensitiveParameter}",
                    FontWeight = System.Windows.FontWeights.Bold,
                    Margin = new Thickness(0, 0, 0, 5),
                    FontSize = 15
                });

                mainStack.Children.Add(new TextBlock
                {
                    Text = $"最不敏感参数: {sensitivity.LeastSensitiveParameter}",
                    FontWeight = System.Windows.FontWeights.Bold,
                    Margin = new Thickness(0, 0, 0, 15),
                    FontSize = 15
                });

                // 创建简单的水平柱状图
                double maxAbsValue = sensitivity.SensitivityCoefficients.Max(kvp => Math.Abs(kvp.Value));

                foreach (var kvp in sensitivity.SensitivityCoefficients.OrderByDescending(k => Math.Abs(k.Value)))
                {
                    var itemStack = new StackPanel
                    {
                        Margin = new Thickness(0, 0, 0, 8)
                    };

                    // 参数名和数值
                    var headerStack = new StackPanel
                    {
                        Orientation = Orientation.Horizontal,
                        Margin = new Thickness(0, 0, 0, 3)
                    };

                    headerStack.Children.Add(new TextBlock
                    {
                        Text = kvp.Key,
                        Width = 80,
                        FontWeight = System.Windows.FontWeights.SemiBold
                    });

                    headerStack.Children.Add(new TextBlock
                    {
                        Text = $": {kvp.Value:F3}",
                        FontWeight = System.Windows.FontWeights.Bold,
                        Foreground = kvp.Value >= 0 ? Brushes.DarkBlue : Brushes.DarkRed
                    });

                    itemStack.Children.Add(headerStack);

                    // 柱状条
                    double barWidthPercent = Math.Abs(kvp.Value) / maxAbsValue * 100;
                    var barContainer = new Border
                    {
                        BorderBrush = Brushes.LightGray,
                        BorderThickness = new Thickness(1),
                        Background = Brushes.WhiteSmoke,
                        Height = 20,
                        CornerRadius = new CornerRadius(3)
                    };

                    var bar = new Border
                    {
                        Background = kvp.Value >= 0 ? Brushes.SteelBlue : Brushes.OrangeRed,
                        Width = barWidthPercent * 5, // 简单缩放
                        Height = 18,

                        CornerRadius = new CornerRadius(2),
                        Margin = new Thickness(1)
                    };

                    // 添加ToolTip
                    bar.ToolTip = $"敏感系数: {kvp.Value:F3}\n(参数每±1%变化，λ变化{kvp.Value:F2}%)";

                    barContainer.Child = bar;
                    itemStack.Children.Add(barContainer);

                    mainStack.Children.Add(itemStack);
                }

                // 添加图例
                var legendStack = new StackPanel
                {
                    Orientation = Orientation.Horizontal,

                    Margin = new Thickness(0, 15, 0, 0)
                };

                var positiveLegend = CreateLegendItem("正敏感", Brushes.SteelBlue, "参数增加→λ增加");
                var negativeLegend = CreateLegendItem("负敏感", Brushes.OrangeRed, "参数增加→λ减少");

                legendStack.Children.Add(positiveLegend);
                legendStack.Children.Add(new TextBlock { Text = "   ", Margin = new Thickness(20, 0, 20, 0) });
                legendStack.Children.Add(negativeLegend);

                mainStack.Children.Add(legendStack);

                // 返回带滚动条的容器
                return new ScrollViewer
                {
                    Content = mainStack,
                    VerticalScrollBarVisibility = ScrollBarVisibility.Auto,
                    HorizontalScrollBarVisibility = ScrollBarVisibility.Disabled
                };
            }
            catch (Exception ex)
            {
                return new TextBlock
                {
                    Text = $"显示敏感性图表时出错: {ex.Message}",
                    Foreground = Brushes.Red,
                    Margin = new Thickness(10),
                    TextWrapping = TextWrapping.Wrap
                };
            }
        }

        /// <summary>
        /// 创建图例项
        /// </summary>
        private FrameworkElement CreateLegendItem(string text, Brush color, string tooltip)
        {
            var stack = new StackPanel
            {
                Orientation = Orientation.Horizontal,
                ToolTip = tooltip,
                Margin = new Thickness(5)
            };

            stack.Children.Add(new Border
            {
                Width = 15,
                Height = 15,
                Background = color,
                Margin = new Thickness(0, 0, 5, 0),
                CornerRadius = new CornerRadius(2)
            });

            stack.Children.Add(new TextBlock
            {
                Text = text,
            });

            return stack;
        }

        /// <summary>
        /// 简化导出建议
        /// </summary>
        private void ExportSimpleRecommendations(List<GBStandard.GB32064Calculator.ParameterRecommendation> recommendations)
        {
            try
            {
                StringBuilder sb = new StringBuilder();
                sb.AppendLine("=".PadRight(50, '='));
                sb.AppendLine("参数优化建议");
                sb.AppendLine("=".PadRight(50, '='));
                sb.AppendLine($"生成时间: {DateTime.Now:yyyy-MM-dd HH:mm:ss}");
                sb.AppendLine($"建议数量: {recommendations.Count}");
                sb.AppendLine();

                int priority = 1;
                foreach (var rec in recommendations.OrderByDescending(r => r.ExpectedImprovement))
                {
                    sb.AppendLine($"{priority}. {rec.Parameter}");
                    sb.AppendLine($"   问题: {rec.Issue}");
                    sb.AppendLine($"   建议: {rec.Recommendation}");
                    sb.AppendLine($"   预期改进: {rec.ExpectedImprovement:F1}%");
                    sb.AppendLine();
                    priority++;
                }

                sb.AppendLine("统计:");
                sb.AppendLine($"   平均预期改进: {recommendations.Average(r => r.ExpectedImprovement):F1}%");
                sb.AppendLine($"   最大预期改进: {recommendations.Max(r => r.ExpectedImprovement):F1}%");
                sb.AppendLine($"   最小预期改进: {recommendations.Min(r => r.ExpectedImprovement):F1}%");

                // 保存到文件
                string desktop = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
                string fileName = $"优化建议_{DateTime.Now:yyyyMMdd_HHmmss}.txt";
                string filePath = Path.Combine(desktop, fileName);

                File.WriteAllText(filePath, sb.ToString(), Encoding.UTF8);

                MessageBox.Show($"优化建议已导出到桌面: {fileName}", "导出成功",
                               MessageBoxButton.OK, MessageBoxImage.Information);
            }
            catch (Exception ex)
            {
                MessageBox.Show($"导出失败: {ex.Message}", "错误",
                               MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }


        ///// <summary>
        ///// 导出建议
        ///// </summary>
        //private void ExportRecommendations(List<GBStandard.GB32064Calculator.ParameterRecommendation> recommendations)
        //{
        //    try
        //    {
        //        StringBuilder sb = new StringBuilder();
        //        sb.AppendLine("参数优化建议");
        //        sb.AppendLine("=".PadRight(60, '='));
        //        sb.AppendLine($"生成时间: {DateTime.Now:yyyy-MM-dd HH:mm:ss}");
        //        sb.AppendLine($"建议数量: {recommendations.Count}");
        //        sb.AppendLine("=".PadRight(60, '='));
        //        sb.AppendLine();

        //        int priority = 1;
        //        foreach (var rec in recommendations.OrderByDescending(r => r.ExpectedImprovement))
        //        {
        //            sb.AppendLine($"{priority}. {rec.Parameter}");
        //            sb.AppendLine($"   问题: {rec.Issue}");
        //            sb.AppendLine($"   建议: {rec.Recommendation}");
        //            sb.AppendLine($"   预期改进: {rec.ExpectedImprovement:F1}%");
        //            sb.AppendLine();
        //            priority++;
        //        }

        //        sb.AppendLine("总计:");
        //        sb.AppendLine($"  平均预期改进: {recommendations.Average(r => r.ExpectedImprovement):F1}%");
        //        sb.AppendLine($"  最大预期改进: {recommendations.Max(r => r.ExpectedImprovement):F1}%");
        //        sb.AppendLine($"  最小预期改进: {recommendations.Min(r => r.ExpectedImprovement):F1}%");

        //        // 保存到文件
        //        string desktop = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
        //        string fileName = $"优化建议_{DateTime.Now:yyyyMMdd_HHmmss}.txt";
        //        string filePath = Path.Combine(desktop, fileName);

        //        File.WriteAllText(filePath, sb.ToString(), Encoding.UTF8);

        //        MessageBox.Show($"优化建议已导出到桌面: {fileName}", "导出成功",
        //                       MessageBoxButton.OK, MessageBoxImage.Information);
        //    }
        //    catch (Exception ex)
        //    {
        //        MessageBox.Show($"导出失败: {ex.Message}", "错误",
        //                       MessageBoxButton.OK, MessageBoxImage.Error);
        //    }
        //}

        private Grid CreateParameterRangesGrid(Dictionary<string, GBStandard.GB32064Calculator.ParameterRange> ranges)
        {
            var grid = new Grid();
            grid.Margin = new Thickness(10);

            // 添加列定义
            for (int i = 0; i < 7; i++)
            {
                grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });
            }

            // 添加行定义（标题行 + 数据行）
            grid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto });
            for (int i = 0; i <= ranges.Count; i++)
            {
                grid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto });
            }

            // 添加标题
            string[] headers = { "参数", "单位", "当前值", "最小值", "最大值", "建议值", "置信度" };
            for (int col = 0; col < headers.Length; col++)
            {
                var header = new TextBlock
                {
                    Text = headers[col],
                    FontWeight = System.Windows.FontWeights.Bold,
                    Margin = new Thickness(5),

                };
                Grid.SetRow(header, 0);
                Grid.SetColumn(header, col);
                grid.Children.Add(header);
            }

            // 添加数据
            int row = 1;
            foreach (var kvp in ranges)
            {
                var range = kvp.Value;
                var paramName = new TextBlock { Text = range.ParameterName, Margin = new Thickness(5) };
                var unit = new TextBlock { Text = range.Unit, Margin = new Thickness(5) };
                var current = new TextBlock { Text = range.CurrentValue.ToString("F3"), Margin = new Thickness(5) };
                var min = new TextBlock { Text = range.MinValue.ToString("F3"), Margin = new Thickness(5) };
                var max = new TextBlock { Text = range.MaxValue.ToString("F3"), Margin = new Thickness(5) };
                var suggested = new TextBlock { Text = range.SuggestedValue.ToString("F3"), Margin = new Thickness(5) };
                var confidence = new TextBlock
                {
                    Text = range.Confidence,
                    Foreground = range.Confidence == "高" ? Brushes.Green :
                                range.Confidence == "中" ? Brushes.Orange : Brushes.Red,
                    Margin = new Thickness(5)
                };

                Grid.SetRow(paramName, row); Grid.SetColumn(paramName, 0);
                Grid.SetRow(unit, row); Grid.SetColumn(unit, 1);
                Grid.SetRow(current, row); Grid.SetColumn(current, 2);
                Grid.SetRow(min, row); Grid.SetColumn(min, 3);
                Grid.SetRow(max, row); Grid.SetColumn(max, 4);
                Grid.SetRow(suggested, row); Grid.SetColumn(suggested, 5);
                Grid.SetRow(confidence, row); Grid.SetColumn(confidence, 6);

                grid.Children.Add(paramName);
                grid.Children.Add(unit);
                grid.Children.Add(current);
                grid.Children.Add(min);
                grid.Children.Add(max);
                grid.Children.Add(suggested);
                grid.Children.Add(confidence);

                row++;
            }

            return grid;
        }

        private void SaveInverseAnalysisReport(GBStandard.GB32064Calculator.InverseAnalysisResult result)
        {
            try
            {
                string desktop = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
                string fileName = $"逆向分析报告_{DateTime.Now:yyyyMMdd_HHmmss}.txt";
                string filePath = Path.Combine(desktop, fileName);

                File.WriteAllText(filePath, result.AnalysisReport);

                MessageBox.Show($"逆向分析报告已保存到桌面: {fileName}", "保存成功",
                               MessageBoxButton.OK, MessageBoxImage.Information);
            }
            catch (Exception ex)
            {
                MessageBox.Show($"保存报告失败: {ex.Message}", "错误",
                               MessageBoxButton.OK, MessageBoxImage.Warning);
            }
        }


    }
}