using Common.Attributes;
using DeviceCommand.Base;
using Model.Models;
using System;
using System.Globalization;
using System.Threading;
using System.Threading.Tasks;

namespace DeviceCommand.Devices
{
    [ADPCommand]
    public class SPAW7000 : Tcp
    {
        //只有两个，八台产品公用两两分组各用一个
        // 根据通用 SCPI 与远宽指令规范，使用换行符 (ASCII 字符 LF，即 \n) 作为标准结束符
        private const string ScpiDelimiter = "\n";

        /// <summary>
        /// 构造函数：传入 <see cref="TcpConfig"/> 一次性初始化 SPAW7000 功率分析记录仪通信参数。
        /// </summary>
        public SPAW7000(TcpConfig config) : base(config)
        {
        }

        #region 1. IEEE 488.2 公共命令

        /// <summary>
        /// 清除状态命令。清除标准事件状态寄存器和错误队列
        /// </summary>
        public virtual async Task 清除错误队列和状态字节(CancellationToken ct = default)
        {
            await SendAsync($"*CLS{ScpiDelimiter}", ct);
        }
        /// <summary>
        /// 查询错误信息 发hsl居然可以但是手册上没有而且软件上也用不了这个命令
        /// </summary>
        //public virtual async Task<string> 查询错误信息(CancellationToken ct = default)
        //{
        //    string query = string.Format(":SYSTem:ERRor?", ScpiDelimiter);
        //    return await WriteReadAsync(query, ScpiDelimiter, ct);
        //}
        /// <summary>
        /// 读取功率分析仪识别字符串（制造商、产品型号、系统 SN、软件版本号）
        /// </summary>
        public virtual async Task<string> 查询设备标识(CancellationToken ct = default)
        {
            return await WriteReadAsync($"*IDN?{ScpiDelimiter}", ScpiDelimiter, ct);
        }

        /// <summary>
        /// 复位命令。使功率分析仪恢复到出厂默认配置状态
        /// </summary>
        public virtual async Task 重置设备(CancellationToken ct = default)
        {
            await SendAsync($"*RST{ScpiDelimiter}", ct);
        }

        /// <summary>
        /// 读取标准状态字节寄存器
        /// </summary>
        public virtual async Task<string> 读取状态字节(CancellationToken ct = default)
        {
            return await WriteReadAsync($"*STB?{ScpiDelimiter}", ScpiDelimiter, ct);
        }

        #endregion

        #region 2. NUMeric 核心数据测量与轮询 (动态单项读取)

        /// <summary>
        /// 查询指定通道的实时 RMS 电压值 (单位: V)
        /// </summary>
        public virtual async Task<string> 查询实际电压(int channel, CancellationToken ct = default)
        {
            // 1. 先配置 ITEM1 为指定通道的电压有效值 (URMS)
            string setItem = string.Format(CultureInfo.InvariantCulture, ":NUMeric:NORMal:ITEM1 URMS,{0}{1}", channel, ScpiDelimiter);
            await SendAsync(setItem, ct);

            // 2. 再读取 ITEM1 的值
            string query = string.Format(CultureInfo.InvariantCulture, ":NUMeric:NORMal:VALue? 1{0}", ScpiDelimiter);
            return await WriteReadAsync(query, ScpiDelimiter, ct);
        }

        /// <summary>
        /// 查询指定通道的实时 RMS 电流值 (单位: A)
        /// </summary>
        public virtual async Task<string> 查询实际电流(int channel, CancellationToken ct = default)
        {
            // 1. 配置 ITEM1 为指定通道的电流有效值 (IRMS)
            string setItem = string.Format(CultureInfo.InvariantCulture, ":NUMeric:NORMal:ITEM1 IRMS,{0}{1}", channel, ScpiDelimiter);
            await SendAsync(setItem, ct);

            // 2. 读取 ITEM1 的值
            string query = string.Format(CultureInfo.InvariantCulture, ":NUMeric:NORMal:VALue? 1{0}", ScpiDelimiter);
            return await WriteReadAsync(query, ScpiDelimiter, ct);
        }

        /// <summary>
        /// 查询指定通道的实时有功功率值 (单位: W)
        /// </summary>
        public virtual async Task<string> 查询实际功率(int channel, CancellationToken ct = default)
        {
            // 1. 配置 ITEM1 为指定通道的有功功率 (P)
            string setItem = string.Format(CultureInfo.InvariantCulture, ":NUMeric:NORMal:ITEM1 P,{0}{1}", channel, ScpiDelimiter);
            await SendAsync(setItem, ct);

            // 2. 读取 ITEM1 的值
            string query = string.Format(CultureInfo.InvariantCulture, ":NUMeric:NORMal:VALue? 1{0}", ScpiDelimiter);
            return await WriteReadAsync(query, ScpiDelimiter, ct);
        }

        /// <summary>
        /// 查询指定通道的实时频率值 (单位: Hz)
        /// </summary>
        public virtual async Task<string> 查询频率(int channel, CancellationToken ct = default)
        {
            // 1. 配置 ITEM1 为指定通道的电压频率 (FU)
            string setItem = string.Format(CultureInfo.InvariantCulture, ":NUMeric:NORMal:ITEM1 FU,{0}{1}", channel, ScpiDelimiter);
            await SendAsync(setItem, ct);

            // 2. 读取 ITEM1 的值
            string query = string.Format(CultureInfo.InvariantCulture, ":NUMeric:NORMal:VALue? 1{0}", ScpiDelimiter);
            return await WriteReadAsync(query, ScpiDelimiter, ct);
        }

        /// <summary>
        /// 查询指定通道的功率因数 (Power Factor)
        /// </summary>
        public virtual async Task<string> 查询功率因数(int channel, CancellationToken ct = default)
        {
            // 1. 配置 ITEM1 为指定通道的功率因数 (LAMBda)
            string setItem = string.Format(CultureInfo.InvariantCulture, ":NUMeric:NORMal:ITEM1 LAMBda,{0}{1}", channel, ScpiDelimiter);
            await SendAsync(setItem, ct);

            // 2. 读取 ITEM1 的值
            string query = string.Format(CultureInfo.InvariantCulture, ":NUMeric:NORMal:VALue? 1{0}", ScpiDelimiter);
            return await WriteReadAsync(query, ScpiDelimiter, ct);
        }

        #endregion

        #region 3. INPut 通道电气参数配置
        /// <summary>
        /// SPAW7000 电压量程枚举 (单位: V)
        /// </summary>
        public enum VoltageRange
        {
            V_15 = 15,
            V_30 = 30,
            V_60 = 60,
            V_100 = 100,
            V_150 = 150,
            V_300 = 300,
            V_600 = 600,
            V_1000 = 1000
        }

        /// <summary>
        /// SPAW7000 电流量程枚举 (单位: A)
        /// </summary>
        public enum CurrentRange
        {
            A_1 = 1,
            A_2 = 2,
            A_5 = 5,
            A_10 = 10,
            A_20 = 20,
            A_50 = 50
        }
        /// <summary>
        /// 设置指定通道的电压量程
        /// </summary>
        /// <param name="channel">通道号/单元号 (1 - 7)</param>
        /// <param name="range">电压量程枚举</param>
        /// <param name="ct">取消令牌</param>
        public virtual async Task 设置电压量程(int channel, VoltageRange range, CancellationToken ct = default)
        {
            // 正确格式例如： :INPut:VOLTage:RANGe:ELEMent1 300\n
            string cmd = string.Format(CultureInfo.InvariantCulture,
                ":INPut:VOLTage:RANGe:ELEMent{0} {1}{2}",
                channel, (int)range, ScpiDelimiter);

            await SendAsync(cmd, ct);
        }

        /// <summary>
        /// 设置指定通道的电流量程
        /// </summary>
        /// <param name="channel">通道号/单元号 (1 - 7)</param>
        /// <param name="range">电流量程枚举</param>
        /// <param name="ct">取消令牌</param>
        public virtual async Task 设置电流量程(int channel, CurrentRange range, CancellationToken ct = default)
        {
            // 正确格式例如： :INPut:CURRent:RANGe:ELEMent1 5\n
            string cmd = string.Format(CultureInfo.InvariantCulture,
                ":INPut:CURRent:RANGe:ELEMent{0} {1}{2}",
                channel, (int)range, ScpiDelimiter);

            await SendAsync(cmd, ct);
        }
        #endregion

        #region 4. SYSTem 系统设置与状态查询
        /// <summary>
        /// 14. 查询仪器型号名称
        /// </summary>
        public virtual async Task<string> 查询设备型号(CancellationToken ct = default)
        {
            return await WriteReadAsync($":SYSTem:MODel?{ScpiDelimiter}", ScpiDelimiter, ct); //
        }

        /// <summary>
        /// 16. 查询仪器唯一序列号
        /// </summary>
        public virtual async Task<string> 查询设备序列号(CancellationToken ct = default)
        {
            return await WriteReadAsync($":SYSTem:SERial?{ScpiDelimiter}", ScpiDelimiter, ct); //
        }

        /// <summary>
        /// 15. 设置数值数据显示的分辨率 (5位或6位)
        /// </summary>
        /// <param name="resolution">有效值只能为 5 或 6</param>
        public virtual async Task 设置显示分辨率(int resolution, CancellationToken ct = default)
        {
            if (resolution != 5 && resolution != 6) throw new ArgumentException("分辨率只能设置为 5 或 6 位");
            await SendAsync($":SYSTem:RESolution {resolution}{ScpiDelimiter}", ct); //
        }

        /// <summary>
        /// 13. 设置或查询屏幕 LCD 的亮度级别 (1-10)
        /// </summary>
        public virtual async Task 设置显示亮度(int brightness, CancellationToken ct = default)
        {
            if (brightness < 1 || brightness > 10) throw new ArgumentOutOfRangeException(nameof(brightness), "亮度范围必须在 1~10 之间");
            await SendAsync($":SYSTem:LCD:BRIGhtness {brightness}{ScpiDelimiter}", ct); //
        }

        /// <summary>
        /// 18. 设置或查询触摸锁的开/关状态 (锁定时防止人工误触触控屏)
        /// </summary>
        public virtual async Task 设置屏幕触摸锁定(bool isLocked, CancellationToken ct = default)
        {
            string state = isLocked ? "ON" : "OFF";
            await SendAsync($":SYSTem:TLOCK {state}{ScpiDelimiter}", ct); //
        }

        /// <summary>
        /// 17. 设置或读取分析仪当前的系统内部时间
        /// </summary>
        /// <param name="timeStr">格式必须为 "HH:MM:SS"</param>
        public virtual async Task 设置系统时间(string timeStr, CancellationToken ct = default)
        {
            await SendAsync($":SYSTem:TIME \"{timeStr}\"{ScpiDelimiter}", ct); //
        }

        #endregion
    }
}