using System;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
using System.Globalization; // 确保添加此命名空间

namespace ASTM_D7896_Tester.Services
{
    /// <summary>
    /// 胜利 VICTOR 8255 5位半万用表 LAN (TCP/IP) 通信服务
    /// 支持 SCPI 命令，实现高速批量采集
    /// 根据其技术规格，通过优化命令可实现 150 次/秒 的读数速率
    /// </summary>
    public class Victory8255LanService : IDisposable
    {
        private TcpClient _tcpClient;
        private NetworkStream _stream;
        private bool _disposed = false;
        private readonly object _lock = new object();

        /// <summary>
        /// 连接到 VICTOR 8255 万用表
        /// </summary>
        /// <param name="ipAddress">仪器 IP 地址，如 "192.168.1.100"</param>
        /// <param name="port">端口号，胜利仪器通常使用 5025，请参照说明书确认</param>
        public async Task ConnectAsync(string ipAddress, int port = 5025)
        {
            if (_tcpClient != null && _tcpClient.Connected)
                return;

            _tcpClient = new TcpClient();
            await _tcpClient.ConnectAsync(ipAddress, port);
            _stream = _tcpClient.GetStream();
        }

        /// <summary>
        /// 发送 SCPI 命令并等待响应
        /// </summary>
        public async Task<string> QueryAsync(string command)
        {
            await SendCommandAsync(command);
            byte[] buffer = new byte[1024];
            int bytesRead = await _stream.ReadAsync(buffer, 0, buffer.Length);
            return Encoding.ASCII.GetString(buffer, 0, bytesRead).Trim();
        }

        /// <summary>
        /// 发送命令但不等待响应
        /// </summary>
        public async Task SendCommandAsync(string command)
        {
            if (_stream == null) throw new InvalidOperationException("未连接到仪器，请先调用 ConnectAsync");
            byte[] cmdBytes = Encoding.ASCII.GetBytes(command + "\n");
            await _stream.WriteAsync(cmdBytes, 0, cmdBytes.Length);
        }

        /// <summary>
        /// 配置为高速直流电压测量模式
        /// </summary>
        public async Task ConfigureForHighSpeedDcvAsync()
        {
            await SendCommandAsync("CONF:VOLT:DC AUTO");
            // 设置到最快测量速率 (4.5位, 高速)
            await SendCommandAsync("SENS:VOLT:DC:RES FAST");
            // 关闭自动归零以提高速度
            await SendCommandAsync("SENS:VOLT:DC:ZERO:AUTO OFF");
            // 使用软件触发模式
            await SendCommandAsync("TRIG:SOUR BUS");
        }

        /// <summary>
        /// 预置采样点数并进入等待触发状态
        /// </summary>
        public async Task PrepareBatchAsync(int sampleCount)
        {
            await SendCommandAsync($"SAMP:COUN {sampleCount}");
            await SendCommandAsync("INIT");
        }

        /// <summary>
        /// 发送软件触发信号
        /// </summary>
        public async Task TriggerAsync()
        {
            await SendCommandAsync("*TRG");
        }

        /// <summary>
        /// 获取批量采集结果
        /// </summary>
        public async Task<double[]> FetchBatchAsync()
        {
            string response = await QueryAsync("FETCh?");
            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], NumberStyles.Float, CultureInfo.InvariantCulture, out values[i]))
                    throw new Exception($"解析电压值失败: {parts[i]}");
            }
            return values;
        }

        /// <summary>
        /// 获取单次读数（用于实时监控）
        /// </summary>
        public async Task<double> ReadVoltageAsync()
        {
            string response = await QueryAsync("MEAS:VOLT:DC?");
            if (double.TryParse(response, NumberStyles.Float, CultureInfo.InvariantCulture, out double value))
                return value;
            throw new Exception($"电压读数无效: {response}");
        }

        public bool IsConnected => _tcpClient != null && _tcpClient.Connected;

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