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 N36200 : Tcp
    {
        //只有一个，八台产品一起用一个
        // 手册第 9 页 2.2.4 明确规定：命令结束符为换行符 (ASCII 字符 LF，即 \n)
        private const string ScpiDelimiter = "\n";

        /// <summary>
        /// 构造函数：传入 <see cref="TcpConfig"/> 一次性初始化 N36200/N36300 设备通信参数。
        /// </summary>
        public N36200(TcpConfig config) : base(config)
        {
        }

        #region 3.1. IEEE 488.2 公共命令

        /// <summary>
        /// 3.1.1. 清除标准事件状态寄存器和错误队列
        /// </summary>
        public virtual async Task 清除错误队列和状态字节(CancellationToken ct = default)
        {
            await SendAsync($"*CLS{ScpiDelimiter}", ct);
        }

        /// <summary>
        /// 3.1.4. 读取直流电源相关信息（制造商、产品型号、系统 SN、软件版本号）
        /// </summary>
        public virtual async Task<string> 查询设备标识(CancellationToken ct = default)
        {
            return await WriteReadAsync($"*IDN?{ScpiDelimiter}", ScpiDelimiter, ct);
        }

        /// <summary>
        /// 3.1.7. 恢复出厂设置 (注意：设备重置保存数据大约需要 10 秒)
        /// </summary>
        public virtual async Task 重置设备(CancellationToken ct = default)
        {
            await SendAsync($"*RST{ScpiDelimiter}", ct);
        }

        /// <summary>
        /// 3.1.8. 读取状态字节寄存器（只读寄存器，读取时不会清除位）
        /// </summary>
        public virtual async Task<string> 读取状态字节(CancellationToken ct = default)
        {
            return await WriteReadAsync($"*STB?{ScpiDelimiter}", ScpiDelimiter, ct);
        }

        #endregion

        #region 3.2. 设定输出电压与限流值

        /// <summary>
        /// 3.2.1. 设定输出电压值 (单位: V)
        /// </summary>
        public virtual async Task 设置电压(double 电压, CancellationToken ct = default)
        {
            string cmd = string.Format(CultureInfo.InvariantCulture, "SOURce:VOLTage {0:F3}{1}", 电压, ScpiDelimiter);
            await SendAsync(cmd, ct);
        }

        /// <summary>
        /// 3.2.1. 查询输出电压设定值 (单位: V)
        /// </summary>
        public virtual async Task<string> 查询电压设定(CancellationToken ct = default)
        {
            return await WriteReadAsync($"SOURce:VOLTage?{ScpiDelimiter}", ScpiDelimiter, ct);
        }

        /// <summary>
        /// 3.2.2. 设置输出限流值 (单位: A)
        /// </summary>
        public virtual async Task 设置电流(double 电流, CancellationToken ct = default)
        {
            string cmd = string.Format(CultureInfo.InvariantCulture, "SOURce:CURRent {0:F3}{1}", 电流, ScpiDelimiter);
            await SendAsync(cmd, ct);
        }

        /// <summary>
        /// 3.2.2. 查询输出限流值设定值 (单位: A)
        /// </summary>
        public virtual async Task<string> 查询电流设定(CancellationToken ct = default)
        {
            return await WriteReadAsync($"SOURce:CURRent?{ScpiDelimiter}", ScpiDelimiter, ct);
        }

        /// <summary>
        /// 3.2.3. 设置输出模拟内阻值 (单位: mΩ)
        /// </summary>
        public virtual async Task 设置内阻(double 内阻, CancellationToken ct = default)
        {
            string cmd = string.Format(CultureInfo.InvariantCulture, "SOURce:INTErnalres {0:F1}{1}", 内阻, ScpiDelimiter);
            await SendAsync(cmd, ct);
        }

        /// <summary>
        /// 3.2.4. 保存当前测试参数到指定存储组 (范围: 1-10)
        /// </summary>
        public virtual async Task 保存测试参数(int 组别, CancellationToken ct = default)
        {
            if (组别 < 1 || 组别 > 10) throw new ArgumentOutOfRangeException(nameof(组别), "组别有效范围为 1~10");
            await SendAsync($"SOURce:FUNCtion:SAVe {组别}{ScpiDelimiter}", ct);
        }

        /// <summary>
        /// 3.2.5. 调用指定存储组的测试参数 (范围: 1-10)
        /// </summary>
        public virtual async Task 调用测试参数(int 组别, CancellationToken ct = default)
        {
            if (组别 < 1 || 组别 > 10) throw new ArgumentOutOfRangeException(nameof(组别), "组别有效范围为 1~10");
            await SendAsync($"SOURce:FUNCtion:RECAll {组别}{ScpiDelimiter}", ct);
        }

        #endregion

        #region 3.3. 输出控制及状态

        /// <summary>
        /// 3.3.1. 控制电源输出开关 (True: 开启, False: 关闭)
        /// </summary>
        public virtual async Task 设置DC输出(bool 开启, CancellationToken ct = default)
        {
            string 参数 = 开启 ? "ON" : "OFF";
            await SendAsync($"OUTPut:ONOFF {参数}{ScpiDelimiter}", ct);
        }

        /// <summary>
        /// 3.3.1. 查询电源输出开关状态 (返回 "ON" 或 "OFF")
        /// </summary>
        public virtual async Task<string> 查询DC输出开关状态(CancellationToken ct = default)
        {
            return await WriteReadAsync($"OUTPut:ONOFF?{ScpiDelimiter}", ScpiDelimiter, ct);
        }

        /// <summary>
        /// 3.3.2. 设定电源工作模式 
        /// (NORMal: 普通模式, CHARge: 电池充电, SEQuence: 序列模式, CPOWer: 恒功率模式, CARWave: 汽车测试, APG: 外部编程)
        /// </summary>
        public virtual async Task 设置运行模式(string 模式, CancellationToken ct = default)
        {
            await SendAsync($"OUTPut:MODE {模式}{ScpiDelimiter}", ct);
        }

        /// <summary>
        /// 3.3.2. 查询电源当前运行工作模式
        /// </summary>
        public virtual async Task<string> 查询运行模式(CancellationToken ct = default)
        {
            return await WriteReadAsync($"OUTPut:MODE?{ScpiDelimiter}", ScpiDelimiter, ct);
        }

        /// <summary>
        /// 3.3.11. 设置电源输出 CV/CC 优先权 (CV 或 CC)
        /// </summary>
        public virtual async Task 设置CVCC优先权(string 优先模式, CancellationToken ct = default)
        {
            if (优先模式 != "CV" && 优先模式 != "CC") throw new ArgumentException("优先模式只能为 'CV' 或 'CC'");
            await SendAsync($"OUTPut:PRIority {优先模式}{ScpiDelimiter}", ct);
        }

        /// <summary>
        /// 3.3.12. 获取电源状态字（通过解析返回整数的二进制 Bit 位获取全状态环路及告警）
        /// </summary>
        public virtual async Task<string> 查询设备状态字(CancellationToken ct = default)
        {
            return await WriteReadAsync($"OUTPut:STATe?{ScpiDelimiter}", ScpiDelimiter, ct);
        }

        /// <summary>
        /// 3.3.13. 获取电源事件告警状态值 (返回整数通过位定义标识 UVP/OVP/OCP/OPP/OTP)
        /// </summary>
        public virtual async Task<string> 查询事件告警状态(CancellationToken ct = default)
        {
            return await WriteReadAsync($"OUTPut:EVENT?{ScpiDelimiter}", ScpiDelimiter, ct);
        }

        /// <summary>
        /// 3.3.13. 清除当前的告警状态
        /// </summary>
        public virtual async Task 清除告警(CancellationToken ct = default)
        {
            await SendAsync($"OUTPut:EVENT 0{ScpiDelimiter}", ct);
        }

        /// <summary>
        /// 3.3.16. 打开/关闭设备定时关机功能
        /// </summary>
        public virtual async Task 设置定时关机开关(bool 开启, CancellationToken ct = default)
        {
            string 参数 = 开启 ? "ON" : "OFF";
            await SendAsync($"OUTPut:TIMing:SWITch {参数}{ScpiDelimiter}", ct);
        }

        /// <summary>
        /// 3.3.17. 设定设备定时关机倒计时时间 (单位: s)
        /// </summary>
        public virtual async Task 设置定时关机时间(double 秒数, CancellationToken ct = default)
        {
            string cmd = string.Format(CultureInfo.InvariantCulture, "OUTPut:TIMing:DWELI {0:F1}{1}", 秒数, ScpiDelimiter);
            await SendAsync(cmd, ct);
        }

        /// <summary>
        /// 3.3.18. 控制泄放电路(Bleeder)开关状态
        /// </summary>
        public virtual async Task 设置泄放电路开关(bool 开启, CancellationToken ct = default)
        {
            string 参数 = 开启 ? "ON" : "OFF";
            await SendAsync($"OUTPut:DISRes {参数}{ScpiDelimiter}", ct);
        }

        #endregion

        #region 3.4. 读取输出电压电流及功率值 (实时轮询核心)

        /// <summary>
        /// 3.4.1. 回读通道输出端子上的实时测得电压值 (单位: V)
        /// </summary>
        [Monitorable("高压直流电源电压")]
        public virtual async Task<string> 查询实际电压(CancellationToken ct = default)
        {
            return await WriteReadAsync($"MEASure:VOLTage?{ScpiDelimiter}", ScpiDelimiter, ct);
        }

        /// <summary>
        /// 3.4.2. 回读通道输出端子上的实时测得电流值 (单位: A)
        /// </summary>
        [Monitorable("高压直流电源电流")]
        public virtual async Task<string> 查询实际电流(CancellationToken ct = default)
        {
            return await WriteReadAsync($"MEASure:CURRent?{ScpiDelimiter}", ScpiDelimiter, ct);
        }

        /// <summary>
        /// 3.4.3. 回读通道输出端子上的实时测得功率值 (单位: W)
        /// </summary>
       [Monitorable("高压直流电源功率")]
        public virtual async Task<string> 查询实际功率(CancellationToken ct = default)
        {
            return await WriteReadAsync($"MEASure:POWer?{ScpiDelimiter}", ScpiDelimiter, ct);
        }

        /// <summary>
        /// 3.4.4. 回读电池充电模式下当前累计已充入的容量值 (单位: mAh)
        /// </summary>
        public virtual async Task<string> 查询已充电容量MAH(CancellationToken ct = default)
        {
            return await WriteReadAsync($"MEASure:MAH?{ScpiDelimiter}", ScpiDelimiter, ct);
        }

        /// <summary>
        /// 3.4.5. 获取当前电源的硬件额定电压上限值 (单位: V)
        /// </summary>
        public virtual async Task<string> 获取设备额定电压(CancellationToken ct = default)
        {
            return await WriteReadAsync($"MEASure:VOLTage:MAXimum?{ScpiDelimiter}", ScpiDelimiter, ct);
        }

        /// <summary>
        /// 3.4.6. 获取当前电源的硬件额定电流上限值 (单位: A)
        /// </summary>
        public virtual async Task<string> 获取设备额定电流(CancellationToken ct = default)
        {
            return await WriteReadAsync($"MEASure:CURRent:MAXimum?{ScpiDelimiter}", ScpiDelimiter, ct);
        }

        #endregion

        #region 3.5. 保护功能

        /// <summary>
        /// 3.5.1. 设置欠压保护门限值 (单位: V)
        /// </summary>
        public virtual async Task 设置过欠压保护_UVP(double 电压, CancellationToken ct = default)
        {
            string cmd = string.Format(CultureInfo.InvariantCulture, "PROTect:LESS:VOLTage {0:F3}{1}", 电压, ScpiDelimiter);
            await SendAsync(cmd, ct);
        }

        /// <summary>
        /// 3.5.4. 设置过压保护门限值 (单位: V)
        /// </summary>
        public virtual async Task 设置过压保护_OVP(double 电压, CancellationToken ct = default)
        {
            string cmd = string.Format(CultureInfo.InvariantCulture, "PROTect:OVER:VOLTage {0:F3}{1}", 电压, ScpiDelimiter);
            await SendAsync(cmd, ct);
        }

        /// <summary>
        /// 3.5.6. 设置硬件硬件过流保护硬指标参数 (单位: A)
        /// </summary>
        public virtual async Task 设置过流保护_OCP(double 电流, CancellationToken ct = default)
        {
            string cmd = string.Format(CultureInfo.InvariantCulture, "PROTect:CURRent {0:F3}{1}", 电流, ScpiDelimiter);
            await SendAsync(cmd, ct);
        }

        /// <summary>
        /// 3.5.8. 设置硬件过功率保护门限值 (单位: W)
        /// </summary>
        public virtual async Task 设置过功率保护_OPP(double 功率, CancellationToken ct = default)
        {
            string cmd = string.Format(CultureInfo.InvariantCulture, "PROTect:POWer {0:F3}{1}", 功率, ScpiDelimiter);
            await SendAsync(cmd, ct);
        }

        /// <summary>
        /// 3.5.12. 设置可调节的用户软输出电压下限值 (单位: V)
        /// </summary>
        public virtual async Task 设置电压下限(double 电压, CancellationToken ct = default)
        {
            string cmd = string.Format(CultureInfo.InvariantCulture, "SOURce:VOLTage:LEVel:LIMit:LOW {0:F3}{1}", 电压, ScpiDelimiter);
            await SendAsync(cmd, ct);
        }

        /// <summary>
        /// 3.5.13. 设置可调节的用户软输出电压上限值 (单位: V)
        /// </summary>
        public virtual async Task 设置电压上限(double 电压, CancellationToken ct = default)
        {
            string cmd = string.Format(CultureInfo.InvariantCulture, "SOURce:VOLTage:LEVel:LIMit {0:F3}{1}", 电压, ScpiDelimiter);
            await SendAsync(cmd, ct);
        }

        /// <summary>
        /// 3.5.14. 设置可调节的用户软输出电流下限值 (单位: A)
        /// </summary>
        public virtual async Task 设置电流下限(double 电流, CancellationToken ct = default)
        {
            string cmd = string.Format(CultureInfo.InvariantCulture, "SOURce:CURRent:LEVel:LIMit:LOW {0:F3}{1}", 电流, ScpiDelimiter);
            await SendAsync(cmd, ct);
        }

        /// <summary>
        /// 3.5.15. 设置可调节的用户软输出电流上限值 (单位: A)
        /// </summary>
        public virtual async Task 设置电流上限(double 电流, CancellationToken ct = default)
        {
            string cmd = string.Format(CultureInfo.InvariantCulture, "SOURce:CURRent:LEVel:LIMit {0:F3}{1}", 电流, ScpiDelimiter);
            await SendAsync(cmd, ct);
        }

        #endregion

        #region 3.6. 恒功率模式配置 (CPOWer)

        /// <summary>
        /// 3.6.1. 设定恒功率工作模式下的限定电压值 (单位: V)
        /// </summary>
        public virtual async Task 设置恒功率模式电压(double 电压, CancellationToken ct = default)
        {
            string cmd = string.Format(CultureInfo.InvariantCulture, "CPOWer:VOLTage {0:F3}{1}", 电压, ScpiDelimiter);
            await SendAsync(cmd, ct);
        }

        /// <summary>
        /// 3.6.2. 设定恒功率工作模式下的限定电流值 (单位: A)
        /// </summary>
        public virtual async Task 设置恒功率模式电流(double 电流, CancellationToken ct = default)
        {
            string cmd = string.Format(CultureInfo.InvariantCulture, "CPOWer:CURRent {0:F3}{1}", 电流, ScpiDelimiter);
            await SendAsync(cmd, ct);
        }

        /// <summary>
        /// 3.6.3. 设定恒功率工作模式下的运行功率目标值 (单位: W)
        /// </summary>
        public virtual async Task 设置恒功率模式功率(double 功率, CancellationToken ct = default)
        {
            string cmd = string.Format(CultureInfo.InvariantCulture, "CPOWer:POWer {0:F3}{1}", 功率, ScpiDelimiter);
            await SendAsync(cmd, ct);
        }

        #endregion
    }
}