using System;
using System.IO.Ports;
using System.Threading.Tasks;
using System.Linq;

namespace ASTM_D7896_Tester.Services
{
    public class FiveHalfDmmService : IDisposable
    {
        private SerialPort _serialPort;
        private bool _disposed;

        public FiveHalfDmmService(string portName, int baudRate = 115200)
        {
            _serialPort = new SerialPort(portName, baudRate, Parity.None, 8, StopBits.One);
            _serialPort.ReadTimeout = 5000;      // 增加超时，批量数据可能需要更长时间
            _serialPort.WriteTimeout = 1000;
            _serialPort.NewLine = "\n";          // 结束符为 LF
        }

        public void Open()
        {
            if (!_serialPort.IsOpen)
                _serialPort.Open();
        }

        public void Close()
        {
            if (_serialPort.IsOpen)
                _serialPort.Close();
        }

        public bool IsOpen => _serialPort?.IsOpen == true;

        // ========== 核心通信方法 ==========
        private async Task<string> QueryAsync(string command)
        {
            if (!_serialPort.IsOpen) throw new InvalidOperationException("串口未打开");
            return await Task.Run(() =>
            {
                lock (_serialPort)
                {
                    _serialPort.DiscardInBuffer();
                    _serialPort.DiscardOutBuffer();
                    _serialPort.WriteLine(command);
                    System.Diagnostics.Debug.WriteLine($"[发送] {command}");

                    // 读取直到遇到换行符（批量数据可能很长，但 ReadLine 会一直读到 \n）
                    string response = _serialPort.ReadLine();
                    System.Diagnostics.Debug.WriteLine($"[接收] {response}");
                    return response.Trim();
                }
            });
        }

        private async Task SendCommandAsync(string command)
        {
            if (!_serialPort.IsOpen) throw new InvalidOperationException("串口未打开");
            await Task.Run(() =>
            {
                lock (_serialPort)
                {
                    _serialPort.WriteLine(command);
                }
            });
        }

        // ========== 配置高速直流电压测量（基于8255文档） ==========
        public async Task ConfigureHighSpeedDcvAsync()
        {
            // 1. 复位到已知状态（可选）
            await SendCommandAsync("*RST");
            await Task.Delay(100);

            // 2. 固定量程（推荐手动设定，例如 1V，根据实际信号调整）
            //    文档中量程可选 200mV, 2V, 20V, 200V, 1000V
            await SendCommandAsync("VOLT:DC:RANG 1");

            // 3. 设置分辨率为 FAST（高速模式）
            await SendCommandAsync("VOLT:DC:RES FAST");

            // 4. 触发源设为 BUS（软件触发）
            await SendCommandAsync("TRIG:SOUR BUS");

            // 5. 关闭自动延迟，延迟设为 0
            await SendCommandAsync("TRIG:DEL:AUTO OFF");
            await SendCommandAsync("TRIG:DEL 0");
        }

        // ========== 方案一：READ? 一次性批量采集（推荐，稳定可靠） ==========
        /// <summary>
        /// 批量读取指定数量的电压值（使用 READ? 命令）
        /// </summary>
        /// <param name="sampleCount">采样点数，如 400</param>
        /// <returns>电压值数组（单位：伏特）</returns>
        public async Task<double[]> ReadBatchAsync(int sampleCount)
        {
            // 设置采样点数
            await SendCommandAsync($"SAMP:COUN {sampleCount}");

            // 发送 READ?，仪器将自动完成触发、采集并返回所有结果
            string response = await QueryAsync("READ?");

            // 解析逗号分隔的数值
            return ParseResponse(response, sampleCount);
        }

        // ========== 方案二：INIT + *TRG + FETCh? 流程（保留，以备特殊场景） ==========
        public async Task PrepareBatchAsync(int sampleCount)
        {
            await SendCommandAsync($"SAMP:COUN {sampleCount}");
            await SendCommandAsync("INIT");
        }

        public async Task TriggerAsync()
        {
            await SendCommandAsync("*TRG");
        }

        public async Task<double[]> FetchBatchAsync()
        {
            string response = await QueryAsync("FETCh?");
            return ParseResponse(response, null); // 不检查数量，直接解析
        }

        // ========== 辅助方法 ==========
        private double[] ParseResponse(string response, int? expectedCount = null)
        {
            if (string.IsNullOrWhiteSpace(response))
                throw new Exception("返回数据为空");

            string[] parts = response.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
            double[] values = new double[parts.Length];
            for (int i = 0; i < parts.Length; i++)
            {
                if (!double.TryParse(parts[i].Trim(),
                        System.Globalization.NumberStyles.Float,
                        System.Globalization.CultureInfo.InvariantCulture,
                        out values[i]))
                {
                    throw new Exception($"解析失败: {parts[i]}，原始响应: {response}");
                }
            }

            if (expectedCount.HasValue && values.Length != expectedCount.Value)
                System.Diagnostics.Debug.WriteLine($"警告：实际点数 {values.Length}，期望 {expectedCount.Value}");

            return values;
        }

        // ========== 单次读取（保留兼容） ==========
        public async Task<double> ReadVoltageAsync()
        {
            string resp = await QueryAsync("MEAS:VOLT:DC?");
            if (double.TryParse(resp,
                    System.Globalization.NumberStyles.Float,
                    System.Globalization.CultureInfo.InvariantCulture,
                    out double value))
                return value;
            throw new Exception($"无效响应: {resp}");
        }

        public void Dispose()
        {
            if (!_disposed)
            {
                Close();
                _serialPort?.Dispose();
                _disposed = true;
            }
        }
    }
}