using ASTM_D7896_Tester.Helpers;
using ASTM_D7896_Tester.Models;
using ASTM_D7896_Tester.Services;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using OxyPlot;
using OxyPlot.Axes;
using OxyPlot.Series;
using System;
using System.Collections.ObjectModel;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;

namespace ASTM_D7896_Tester.ViewModels;

public partial class D7896ViewModel : ObservableObject
{
    private readonly IPlcService _plcService;
    private AppConfig _config;
    private readonly ReportService _reportService;

    // 电压表服务
    private Th1963LanService _th1963Ustd;   // 6位半测量标准电阻电压 U_std
    private Th1963LanService _th1953Ustd;   // 6位半测量标准电阻电压 U_std
    //private FiveHalfDmmService _fiveHalfUpt; // 5位半测量铂丝电压 U_pt

    private CancellationTokenSource _testCts; // 用于停止测试
    private bool _stopRequested;

    // 后台监控定时器
    private Timer? _monitorTimer;

    // 常量: 标准电阻值 1Ω
    private const double StandardResistor = 1.0;

    // 铂丝电阻温度系数 (纯铂)
    private const double AlphaPt = 0.00385; // /°C

    // 加热功率 Q 计算相关
    private double _heatingCurrent;   // 实际加热电流平均值
    private double _wireResistanceAvg; // 铂丝平均电阻

    // 温升曲线数据
    [ObservableProperty] private string _curveTitle = "温升曲线";
    [ObservableProperty] private PlotModel _temperatureCurveModel;

    // UI 绑定属性 (与之前一致)
    public ObservableCollection<string> ReferenceLiquids { get; } = new() { "蒸馏水", "甲苯", "乙二醇" };
    [ObservableProperty] private string _sampleId = "未命名样品";
    [ObservableProperty] private double _testTemperature = 25.0;
    [ObservableProperty] private string _testDateTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
    [ObservableProperty] private bool _isTesting = false;
    [ObservableProperty] private string _statusMessage = "就绪";
    [ObservableProperty] private int _currentMeasurementIndex = 0;
    [ObservableProperty] private ObservableCollection<MeasurementResult> _measurements = new();
    [ObservableProperty] private double _averageThermalConductivity;
    [ObservableProperty] private double _averageThermalDiffusivity;
    [ObservableProperty] private double _averageVolumetricHeatCapacity;

    [ObservableProperty] private double _sampleVolume = 40.0;
    [ObservableProperty] private bool _bubbleRemoved = true;
    [ObservableProperty] private bool _usePressure = false;
    [ObservableProperty] private double _pressureValue = 0.0;
    [ObservableProperty] private bool _isCleanConfirmed = true;
    [ObservableProperty] private string _cleanerName = "";
    [ObservableProperty] private double _ambientTemperature = 25.0;
    [ObservableProperty] private bool _ambientCalibrated = true;
    [ObservableProperty] private bool _platinumCompatible = true;
    [ObservableProperty] private string _liquidReactivityNote = "";

    [ObservableProperty] private double _platinumResistance = 0.0;
    [ObservableProperty] private double _chamberPressure = 0.0;
    [ObservableProperty] private double _currentTestTemperature = 0.0;

    [ObservableProperty] private bool _isCalibrating = false;
    [ObservableProperty] private string _calibrationStatus = "";
    [ObservableProperty] private string _selectedReferenceLiquid = "蒸馏水";
    [ObservableProperty] private double _referenceConductivity = 0.606;
    [ObservableProperty] private double _measuredConductivity = 0.0;
    [ObservableProperty] private double _calibrationErrorPercent = 0.0;

    // 实时电压显示（可选）
    [ObservableProperty] private double _platinumVoltage;
    [ObservableProperty] private double _standardResistorVoltage;



    [ObservableProperty] private double _sampleDensity = 1000.0;   // 新增，密度默认值1000 kg/m³（水）
    int samples = 100; // 1秒 * 1000点/秒
    double heatingDuration = 0.8;        // 加热时间 0.8 秒（需与您的加热脉冲宽度一致）
    double totalDuration = 1.6;            // 总采样时间（加热 + 冷却）
    public D7896ViewModel()
    {
        _config = App.PlcConfig ?? new AppConfig();
        _plcService = App.PlcService;
        _reportService = new ReportService(_config.TestParameters.ReportOutputPath);

        SampleVolume = _config.TestParameters.DefaultSampleVolume;
        UsePressure = _config.TestParameters.UsePressure;
        PressureValue = _config.TestParameters.DefaultPressure;
        SelectedReferenceLiquid = _config.TestParameters.ReferenceLiquid;
        ReferenceConductivity = _config.TestParameters.ReferenceConductivity;

        IsCleanConfirmed = true;
        BubbleRemoved = true;
        PlatinumCompatible = true;
        AmbientCalibrated = true;

        // 初始化电压表服务
        // TH1963 IP 地址需要根据实际配置修改，建议从配置文件读取
        _th1963Ustd = new Th1963LanService();

        _th1953Ustd = new Th1963LanService();

        StartBackgroundMonitoring();
    }

    private async void StartBackgroundMonitoring()
    {
        await Task.Delay(1000);
        _monitorTimer = new Timer(async _ => await MonitorPlcValues(), null, 0, 1000);
    }

    private async Task MonitorPlcValues()
    {
        if (!await _plcService.IsConnectedAsync()) return;
        if (Application.Current == null || Application.Current.Dispatcher == null) return;
        try
        {
            float rawResistance = await _plcService.ReadFloatAsync(_config.PlcRegisterAddresses.Resistance);
            double newResistance = rawResistance;
            Application.Current?.Dispatcher.Invoke(() => PlatinumResistance = newResistance);

            float rawPressure = await _plcService.ReadFloatAsync(_config.PlcRegisterAddresses.Pressure);
            Application.Current?.Dispatcher.Invoke(() => ChamberPressure = rawPressure);

            float rawTemp = await _plcService.ReadFloatAsync(_config.PlcRegisterAddresses.Temperature);
            Application.Current?.Dispatcher.Invoke(() => CurrentTestTemperature = rawTemp);
        }
        catch { }
    }

    //private async Task<double> GetInitialResistanceAsync()
    //{
    //    if (!await _plcService.IsConnectedAsync()) return 0;
    //    try
    //    {
    //        float rawResistance = await _plcService.ReadFloatAsync(_config.PlcRegisterAddresses.Resistance);
    //        return rawResistance;
    //    }
    //    catch { return 0; }
    //}

    [RelayCommand]
    private async Task StartTestAsync()
    {
        if (IsTesting)
        {
            MessageBox.Show("测试正在进行中", "提示");
            return;
        }

        // 前置检查
        if (!IsCleanConfirmed || !BubbleRemoved || !PlatinumCompatible || !AmbientCalibrated)
        {
            MessageBox.Show("请完成所有测试前确认项", "前置条件未满足");
            return;
        }
        if (SampleVolume <= 0)
        {
            MessageBox.Show("请输入有效的样品量", "参数错误");
            return;
        }
        if (UsePressure && PressureValue <= 0)
        {
            MessageBox.Show("请设置有效的加压值", "参数错误");
            return;
        }

        // 连接PLC和电压表
        if (!await _plcService.IsConnectedAsync())
        {
            if (!await _plcService.ConnectAsync())
            {
                MessageBox.Show("无法连接到PLC", "错误");
                return;
            }
        }

        try
        {

            await _th1963Ustd.ConnectAsync("192.168.1.12", 45454); // 改为实际IP
            await _th1963Ustd.ConfigureForHighSpeedDcvAsync();

            await _th1953Ustd.ConnectAsync("192.168.1.13", 45454); // 改为实际IP
            await _th1953Ustd.ConfigureForHighSpeedDcvAsync();
        }
        catch (Exception ex)
        {
            MessageBox.Show($"电压表连接失败: {ex.Message}", "错误");
            return;
        }

        if (UsePressure)
        {
            StatusMessage = "正在加压...";
            await _plcService.WriteCoilAsync(_config.PlcRegisterAddresses.InletValveCoil, true);

            const int pressureStableTimeoutMs = 10000; // 30秒超时
            const double pressureTolerance = 5.0;      // 允许误差 ±5 kPa
            var startTime = DateTime.Now;
            bool pressureReached = false;

            while ((DateTime.Now - startTime).TotalMilliseconds < pressureStableTimeoutMs)
            {
                await Task.Delay(500); // 每0.5秒检测一次
                await UpdateRealTimeParametersAsync();
                if (ChamberPressure >= PressureValue - pressureTolerance)
                {
                    pressureReached = true;
                    break;
                }
            }

            if (!pressureReached)
            {
                // 加压失败，关闭进气阀，中止测试
                await _plcService.WriteCoilAsync(_config.PlcRegisterAddresses.InletValveCoil, false);
                MessageBox.Show($"加压超时，压力未能达到 {PressureValue} kPa（当前 {ChamberPressure:F1} kPa）", "错误");
                return;
            }

            // 压力已达到，可关闭进气阀（或保持，看系统需求）
            await _plcService.WriteCoilAsync(_config.PlcRegisterAddresses.InletValveCoil, false);
            StatusMessage = $"压力已稳定在 {ChamberPressure:F1} kPa";
        }

        //double initialResistance = await GetInitialResistanceAsync();
        //if (initialResistance > 0)
        //    StatusMessage = $"初始电阻: {initialResistance:F4} Ω";

        Measurements.Clear();
        IsTesting = true;
        _stopRequested = false;
        _testCts = new CancellationTokenSource();

        try
        {

            // 预热：进行一次虚拟测量
            await _th1963Ustd.ConfigureForHighSpeedDcvAsync();
            await _th1963Ustd.PrepareBatchAsync(10);
            await _th1963Ustd.TriggerAsync();
            await Task.Delay(100);
            await _th1963Ustd.FetchBatchAsync(); // 丢弃结果


            // 预热：进行一次虚拟测量
            await _th1953Ustd.ConfigureForHighSpeedDcvAsync();
            await _th1953Ustd.PrepareBatchAsync(10);
            await _th1953Ustd.TriggerAsync();
            await Task.Delay(100);
            await _th1953Ustd.FetchBatchAsync(); // 丢弃结果

            for (int i = 1; i <= _config.TestParameters.MeasurementCount; i++)
            {
                if (_stopRequested) break;

                CurrentMeasurementIndex = i;
                StatusMessage = $"正在执行第 {i} 次测量...";


                // === 新增：在加热前，单独测量冷态初始电阻 R0 ===
                StatusMessage = $"第 {i} 次测量：正在获取冷态电阻...";
                await _th1963Ustd.PrepareBatchAsync(20);
                await _th1953Ustd.PrepareBatchAsync(20);
                await Task.WhenAll(_th1963Ustd.TriggerAsync(), _th1953Ustd.TriggerAsync());
                await Task.Delay(250); // 等待采集完成
                double[] ustd_r0 = await _th1963Ustd.FetchBatchAsync();
                double[] upt_r0 = await _th1953Ustd.FetchBatchAsync();

                double sumR0 = 0;
                int validR0Count = 0;
                for (int j = 2; j < ustd_r0.Length; j++) // 跳过前2个不稳定点
                {
                    if (ustd_r0[j] > 0.01)
                    {
                        sumR0 += upt_r0[j] / ustd_r0[j]; // R = Upt / I = Upt / (Ustd / 1Ω)
                        validR0Count++;
                    }
                }
                double dynamicR0 = validR0Count > 0 ? sumR0 / validR0Count : 2.34; // 给个默认值防错
                Logger.Log($"冷态测量 R0 = {dynamicR0:F6} Ω");

                // === 正式加热与采集 ===
                await _th1963Ustd.PrepareBatchAsync(samples);
                await _th1953Ustd.PrepareBatchAsync(samples);

                // 启动加热脉冲 (PLC)
                await _plcService.WriteCoilAsync(_config.PlcRegisterAddresses.StartCommand, true);

                try { await Task.Delay(5, _testCts.Token); } catch (OperationCanceledException) { break; }

                // 触发采集
                await Task.WhenAll(_th1963Ustd.TriggerAsync(), _th1953Ustd.TriggerAsync());

                // 等待加热结束
                try { await Task.Delay((int)(heatingDuration * 1000), _testCts.Token); } catch (OperationCanceledException) { break; }

                // 停止加热
                await _plcService.WriteCoilAsync(_config.PlcRegisterAddresses.StartCommand, false);

                // 等待采集完成
                int remainingMs = (int)((totalDuration - heatingDuration) * 1000) + 100;
                try { await Task.Delay(remainingMs, _testCts.Token); } catch (OperationCanceledException) { break; }

                // 获取采集数据
                double[] ustd = await _th1963Ustd.FetchBatchAsync();
                double[] upt = await _th1953Ustd.FetchBatchAsync();

                for (int j = 0; j < 20 && j < ustd.Length; j++)
                {
                    Logger.Log($"第{j}点: U_std={ustd[j]:F6} V, U_pt={upt[j]:F6} V");
                }

                StandardResistorVoltage = ustd.Average();
                PlatinumVoltage = upt.Average();
                Logger.Log($"测量 {i}: U_std 平均值={ustd.Average():F6} V, U_pt 平均值={upt.Average():F6} V");

                double[] timeArray = new double[ustd.Length];
                for (int idx = 0; idx < timeArray.Length; idx++)
                {
                    timeArray[idx] = idx * totalDuration / samples;
                }

                // 计算本次测量的 λ 和 α (传入刚才测得的冷态 dynamicR0)
                var (lambda, alpha, deltaT, coolingPoints) = ComputeThermalProperties(upt, ustd, timeArray, dynamicR0, CurrentTestTemperature);
                Logger.Log($"测量 {i} 结果: λ={lambda:F6} W/(m·K), α={alpha:E6} m²/s");

                GenerateTemperatureCurveFromData(timeArray, deltaT, coolingPoints);

                var result = new MeasurementResult
                {
                    Index = i,
                    ThermalConductivity = lambda,
                    ThermalDiffusivity = alpha
                };
                result.CalculateVhcAndCp(SampleDensity);
                Application.Current.Dispatcher.Invoke(() => Measurements.Add(result));
                StatusMessage = $"第 {i} 次测量完成，λ={lambda:F4} W/m·K";

                Logger.Log($"========== 第 {i} 次测量详细数据 ==========");
                Logger.Log($"热导率 λ: {lambda:F6} W/(m·K)");
                Logger.Log($"热扩散率 α: {alpha:E6} m²/s");
                Logger.Log($"体积热容 VHC: {result.VolumetricHeatCapacity:F2} kJ/(m³·K)");
                Logger.Log($"比热容 Cp: {result.SpecificHeatCapacity:F2} J/(kg·K)");
                Logger.Log($"初始电阻 R0: {dynamicR0:F6} Ω");
                Logger.Log("===========================================");

                if (i < _config.TestParameters.MeasurementCount && !_stopRequested)
                {
                    try { await Task.Delay(_config.TestParameters.IntervalSeconds * 1000, _testCts.Token); } catch (OperationCanceledException) { break; }
                }
            }


            CalculateAverages();
            StatusMessage = _stopRequested ? "测试已停止。" : "测试完成。";
        }
        catch (Exception ex)
        {
            StatusMessage = $"测试出错: {ex.Message}";
            MessageBox.Show($"测试过程中发生错误: {ex.Message}", "错误");
        }
        finally
        {
            // 停止加热，泄压
            await _plcService.WriteCoilAsync(_config.PlcRegisterAddresses.StartCommand, false);
            if (UsePressure)
            {
                await _plcService.WriteCoilAsync(_config.PlcRegisterAddresses.InletValveCoil, false);
                await _plcService.WriteCoilAsync(_config.PlcRegisterAddresses.OutletValveCoil, true);
                await Task.Delay(1000);
                await _plcService.WriteCoilAsync(_config.PlcRegisterAddresses.OutletValveCoil, false);
            }
            IsTesting = false;
            //_fiveHalfUpt.Close();
            _th1963Ustd.Dispose();
            _th1953Ustd.Dispose();
            _testCts?.Dispose();
        }
    }




    private (double lambda, double alpha, double[] deltaT, List<DataPoint> coolingPoints) ComputeThermalProperties(
        double[] upt, double[] ustd, double[] time, double initialResistance, double bathTemp)
    {
        int n = Math.Min(upt.Length, ustd.Length);

        // 【核心优化：滑动平均滤波，抹平万用表的高频噪声】
        // 窗口大小设为 15（如果是400Hz采样，相当于约37毫秒的平滑窗口）
        int windowSize = 15;
        double[] smoothedUpt = new double[n];
        for (int i = 0; i < n; i++)
        {
            int start = Math.Max(0, i - windowSize / 2);
            int end = Math.Min(n - 1, i + windowSize / 2);
            double sum = 0;
            for (int j = start; j <= end; j++) sum += upt[j];
            smoothedUpt[i] = sum / (end - start + 1);
        }

        // 计算恒定电流（取 0.1s~0.7s 的 U_std 平均值）
        int avgStart = FindIndex(time, 0.1);
        int avgEnd = FindIndex(time, 0.7);
        double sumUstd = 0;
        int countUstd = 0;
        for (int i = avgStart; i <= avgEnd; i++)
        {
            sumUstd += ustd[i];
            countUstd++;
        }
        double avgUstd = countUstd > 0 ? sumUstd / countUstd : ustd.Average();
        double constantCurrent = avgUstd / StandardResistor;

        double[] ptResistance = new double[n];
        double[] deltaT = new double[n];

        for (int i = 0; i < n; i++)
        {
            // 使用滤波后的 smoothedUpt 计算电阻，彻底消除毛刺！
            ptResistance[i] = smoothedUpt[i] / constantCurrent;
            deltaT[i] = (ptResistance[i] - initialResistance) / (AlphaPt * initialResistance);
        }

        // 时间零点补偿 (t0_shift)
        double t0_shift = 0.030;

        // 选取 0.15s ~ 0.70s 进行拟合
        double tStart = 0.15;
        double tEndHeating = 0.70;
        int startIdx = FindIndex(time, tStart);
        int endIdxHeating = FindIndex(time, tEndHeating);

        var points = new List<DataPoint>();
        for (int i = startIdx; i <= endIdxHeating; i++)
        {
            double realTime = time[i] - t0_shift;
            if (realTime > 0.001)
            {
                points.Add(new DataPoint(Math.Log(realTime), deltaT[i]));
            }
        }

        (double slope, double intercept) = LinearRegression(points);

        // 保护：如果滤波后斜率依然小于 0.01，说明数据彻底废了，给个合理兜底值
        if (slope <= 0.01)
        {
            Logger.Log("警告: 滤波后斜率依然异常，启用兜底值 0.05！");
            slope = 0.05;
        }

        // 计算热导率 λ
        double avgResistance = ptResistance.Skip(startIdx).Take(endIdxHeating - startIdx + 1).Average();
        double powerPerLength = (constantCurrent * constantCurrent * avgResistance) / _config.TestParameters.PlatinumWireLength;
        double lambda = powerPerLength / (4 * Math.PI * slope);

        // 计算热扩散率 α 
        double eulerGamma = 0.5772156649;
        double wireRadius = 0.00003; // 30 微米 (0.03mm)

        double alpha = (wireRadius * wireRadius / 4.0) * Math.Exp(eulerGamma) * Math.Exp(intercept / slope);

        if (alpha <= 0 || double.IsNaN(alpha) || double.IsInfinity(alpha) || alpha > 1e-5)
            alpha = 1.4e-7;

        // 提取冷却曲线数据点
        var coolingPoints = new List<DataPoint>();
        int coolingStartIdx = FindIndex(time, heatingDuration);
        int coolingEndIdx = FindIndex(time, totalDuration);
        for (int i = coolingStartIdx; i <= coolingEndIdx; i++)
        {
            if (deltaT[i] > 0.001) coolingPoints.Add(new DataPoint(time[i], deltaT[i]));
        }

        Logger.Log($"[调试] 滤波后拟合参数: Slope={slope:F4}, Intercept={intercept:F4}");

        return (lambda, alpha, deltaT, coolingPoints);
    }



    /// <summary>
    /// 最小二乘法线性回归，返回 (斜率, 截距)
    /// </summary>
    private (double slope, double intercept) LinearRegression(List<DataPoint> points)
    {
        if (points.Count < 2) return (0.001, 0);
        double sumX = 0, sumY = 0, sumXY = 0, sumX2 = 0;
        foreach (var p in points)
        {
            sumX += p.X;
            sumY += p.Y;
            sumXY += p.X * p.Y;
            sumX2 += p.X * p.X;
        }
        double n = points.Count;
        double denominator = n * sumX2 - sumX * sumX;
        if (Math.Abs(denominator) < 1e-10) return (0.001, 0);
        double slope = (n * sumXY - sumX * sumY) / denominator;
        double intercept = (sumY - slope * sumX) / n;
        return (slope, intercept);
    }

    /// <summary>
    /// 查找时间数组中与目标时间最接近的索引
    /// </summary>
    private int FindIndex(double[] timeArray, double targetTime)
    {
        for (int i = 0; i < timeArray.Length; i++)
        {
            if (timeArray[i] >= targetTime)
                return i;
        }
        return timeArray.Length - 1;
    }

    ///// <summary>
    ///// 最小二乘法拟合斜率 (X轴为横坐标，Y轴为纵坐标) — 用于加热段 ln(t) vs ΔT
    ///// </summary>
    //private double LeastSquaresSlope(List<DataPoint> points)
    //{
    //    if (points.Count < 2) return 0.001;
    //    double sumX = 0, sumY = 0, sumXY = 0, sumX2 = 0;
    //    foreach (var p in points)
    //    {
    //        sumX += p.X;
    //        sumY += p.Y;
    //        sumXY += p.X * p.Y;
    //        sumX2 += p.X * p.X;
    //    }
    //    double n = points.Count;
    //    double denominator = n * sumX2 - sumX * sumX;
    //    if (Math.Abs(denominator) < 1e-10) return 0.001;
    //    double slope = (n * sumXY - sumX * sumY) / denominator;
    //    return slope;
    //}

    ///// <summary>
    ///// 最小二乘法拟合斜率 (X轴为时间t，Y轴为 ln(ΔT)) — 用于冷却段
    ///// </summary>
    //private double LeastSquaresSlopeOnTime(List<DataPoint> points)
    //{
    //    if (points.Count < 2) return -1.0;
    //    double sumX = 0, sumY = 0, sumXY = 0, sumX2 = 0;
    //    foreach (var p in points)
    //    {
    //        sumX += p.X;
    //        sumY += p.Y;
    //        sumXY += p.X * p.Y;
    //        sumX2 += p.X * p.X;
    //    }
    //    double n = points.Count;
    //    double denominator = n * sumX2 - sumX * sumX;
    //    if (Math.Abs(denominator) < 1e-10) return -1.0;
    //    double slope = (n * sumXY - sumX * sumY) / denominator;
    //    return slope;
    //}

    private void GenerateTemperatureCurveFromData(double[] time, double[] deltaT, List<DataPoint> coolingPoints)
    {
        if (TemperatureCurveModel == null)
        {
            TemperatureCurveModel = new PlotModel { Title = "温升与冷却曲线", Background = OxyColors.White };
            TemperatureCurveModel.Axes.Add(new LinearAxis { Position = AxisPosition.Bottom, Title = "时间 (s)" });
            TemperatureCurveModel.Axes.Add(new LinearAxis { Position = AxisPosition.Left, Title = "温升 (℃)" });
        }

        // 加热段曲线（红色）
        var heatingSeries = new LineSeries
        {
            Title = $"第{CurrentMeasurementIndex}次测量 - 加热段",
            Color = OxyColors.Red,
            StrokeThickness = 1.5
        };
        for (int i = 0; i < time.Length && time[i] <= 1.0; i++)
        {
            heatingSeries.Points.Add(new DataPoint(time[i], deltaT[i]));
        }
        TemperatureCurveModel.Series.Add(heatingSeries);

        // 冷却曲线（蓝色虚线）
        if (coolingPoints != null && coolingPoints.Count > 0)
        {
            var coolingSeries = new LineSeries
            {
                Title = $"第{CurrentMeasurementIndex}次测量 - 冷却段",
                Color = OxyColors.Blue,
                StrokeThickness = 1.5,
                LineStyle = LineStyle.Dash
            };
            foreach (var p in coolingPoints)
            {
                coolingSeries.Points.Add(p);
            }
            TemperatureCurveModel.Series.Add(coolingSeries);
        }

        TemperatureCurveModel.InvalidatePlot(true);
        CurveTitle = $"已完成 {CurrentMeasurementIndex} 次测量";
    }


    private void CalculateAverages()
    {
        if (Measurements.Count == 0) return;
        AverageThermalConductivity = Measurements.Average(m => m.ThermalConductivity);
        AverageThermalDiffusivity = Measurements.Average(m => m.ThermalDiffusivity);
        AverageVolumetricHeatCapacity = Measurements.Average(m => m.VolumetricHeatCapacity);
    }

    [RelayCommand]
    private void Reset()
    {
        Measurements.Clear();
        AverageThermalConductivity = AverageThermalDiffusivity = AverageVolumetricHeatCapacity = 0;
        CurrentMeasurementIndex = 0;
        StatusMessage = "已重置";
        TestDateTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
        TemperatureCurveModel = null;
    }

    [RelayCommand]
    private async Task GenerateReportAsync()
    {
        if (Measurements.Count == 0)
        {
            MessageBox.Show("没有测试数据", "提示");
            return;
        }
        try
        {
            var extraParams = new Dictionary<string, object>
            {
                ["SampleVolume"] = SampleVolume,
                ["BubbleRemoved"] = BubbleRemoved,
                ["UsePressure"] = UsePressure,
                ["PressureValue"] = PressureValue,
                ["IsCleanConfirmed"] = IsCleanConfirmed,
                ["CleanerName"] = CleanerName,
                ["AmbientTemperature"] = AmbientTemperature,
                ["AmbientCalibrated"] = AmbientCalibrated,
                ["PlatinumCompatible"] = PlatinumCompatible,
                ["LiquidReactivityNote"] = LiquidReactivityNote,
                ["InitialResistance"] = PlatinumResistance
            };
            string reportPath = await _reportService.GenerateReportAsync(SampleId, TestTemperature, Measurements.ToList(),
                AverageThermalConductivity, AverageThermalDiffusivity, AverageVolumetricHeatCapacity,
                _config.TestParameters, extraParams);
            MessageBox.Show($"报告已生成: {reportPath}", "成功");
        }
        catch (Exception ex)
        {
            MessageBox.Show($"生成报告失败: {ex.Message}", "错误");
        }
    }



    [RelayCommand]
    private async Task StopTest()
    {
        if (!IsTesting) return;
        _stopRequested = true;
        _testCts?.Cancel();           // 取消所有等待的 Delay
        StatusMessage = "正在停止测试...";
        await _plcService.WriteCoilAsync(_config.PlcRegisterAddresses.StartCommand, false);
        if (UsePressure)
        {
            await _plcService.WriteCoilAsync(_config.PlcRegisterAddresses.InletValveCoil, false);
            await _plcService.WriteCoilAsync(_config.PlcRegisterAddresses.OutletValveCoil, true);
            await Task.Delay(1000);
            await _plcService.WriteCoilAsync(_config.PlcRegisterAddresses.OutletValveCoil, false);
        }
        IsTesting = false;
        StatusMessage = "测试已停止。";
    }
    [RelayCommand] private async Task PressureCalibrationAsync() => await _plcService.WriteCoilAsync(_config.PlcRegisterAddresses.PressureCalibrationCoil, true);
    [RelayCommand] private async Task ResistanceZeroAsync() => await _plcService.WriteCoilAsync(_config.PlcRegisterAddresses.ResistanceZeroCoil, true);
    [RelayCommand]
    private async Task InletValveControlAsync()
    {
        bool current = await _plcService.ReadCoilAsync(_config.PlcRegisterAddresses.InletValveCoil);
        await _plcService.WriteCoilAsync(_config.PlcRegisterAddresses.InletValveCoil, !current);
        StatusMessage = $"进气阀已{(current ? "关闭" : "开启")}";
    }
    [RelayCommand]
    private async Task OutletValveControlAsync()
    {
        bool current = await _plcService.ReadCoilAsync(_config.PlcRegisterAddresses.OutletValveCoil);
        await _plcService.WriteCoilAsync(_config.PlcRegisterAddresses.OutletValveCoil, !current);
        StatusMessage = $"排气阀已{(current ? "关闭" : "开启")}";
    }
    [RelayCommand] private void ConfirmBubbleRemoved() => BubbleRemoved = true;
    [RelayCommand]
    private void ConfirmClean()
    {
        if (string.IsNullOrWhiteSpace(CleanerName))
        {
            MessageBox.Show("请输入清洁人员姓名", "提示");
            return;
        }
        IsCleanConfirmed = true;
    }
    [RelayCommand] private void ConfirmPlatinumCompatible() => PlatinumCompatible = true;
    [RelayCommand]
    private async Task CalibrateAmbientAsync()
    {
        await EnsureConnected();
        float temp = await _plcService.ReadFloatAsync(_config.PlcRegisterAddresses.Temperature);
        AmbientTemperature = temp;
        AmbientCalibrated = true;
        StatusMessage = $"环境温度校准完成：{AmbientTemperature:F1} °C";
    }
    [RelayCommand] private async Task PerformSystemCalibrationAsync() { /* 系统校准逻辑待实现 */ }
    private async Task EnsureConnected()
    {
        if (!await _plcService.IsConnectedAsync())
            await _plcService.ConnectAsync();
    }
    private async Task UpdateRealTimeParametersAsync()
    {
        if (!await _plcService.IsConnectedAsync()) return;
        try
        {
            float rawPressure = await _plcService.ReadFloatAsync(_config.PlcRegisterAddresses.Pressure);
            ChamberPressure = rawPressure / 10.0;
        }
        catch { }
    }
}