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

namespace DeviceCommand.Devices
{
    #region 枚举定义

    /// <summary>
    /// IT6000C 优先工作模式 (CV优先 / CC优先)
    /// </summary>
    public enum IT6000CPriorityMode
    {
        /// <summary> 恒压优先模式 (CV优先) </summary>
        VOLTage,
        /// <summary> 恒流优先模式 (CC优先) </summary>
        CURRent
    }

    /// <summary>
    /// IT6000C 瞬变功能模式
    /// </summary>
    public enum IT6000CFunctionMode
    {
        /// <summary> 固定模式 (普通输出) </summary>
        FIXed,
        /// <summary> List 列表模式 </summary>
        LIST,
        /// <summary> 电池测试模式 </summary>
        BATTer,
        /// <summary> 光伏/太阳能板曲线模拟模式 </summary>
        SOLar,
        /// <summary> 汽车波形模拟模式 </summary>
        CARProfile
    }

    #endregion

    [ACPCommand]
    public class IT6036C  : Tcp
    {
        // SCPI 指令结束符
        private const string ScpiDelimiter = "\n";

        public IT6036C (TcpConfig config) : base(config)
        {
        }

        #region 1. IEEE 488.2 公共命令

        public virtual async Task 清除状态寄存器(CancellationToken ct = default)
        {
            await SendAsync($"*CLS{ScpiDelimiter}", ct); //[cite: 1]
        }

        public virtual async Task<string> 查询设备标识(CancellationToken ct = default)
        {
            return await WriteReadAsync($"*IDN?{ScpiDelimiter}", ScpiDelimiter, ct); //[cite: 1]
        }

        public virtual async Task 重置设备(CancellationToken ct = default)
        {
            await SendAsync($"*RST{ScpiDelimiter}", ct); //[cite: 1]
        }

        public virtual async Task<string> 查询状态字节(CancellationToken ct = default)
        {
            return await WriteReadAsync($"*STB?{ScpiDelimiter}", ScpiDelimiter, ct); //[cite: 1]
        }

        public virtual async Task<string> 查询SCPI版本号(CancellationToken ct = default)
        {
            return await WriteReadAsync($":SYSTem:VERSion?{ScpiDelimiter}", ScpiDelimiter, ct); //[cite: 1]
        }

        #endregion

        #region 2. 系统远程与状态控制

        public virtual async Task 切换远程控制模式(CancellationToken ct = default)
        {
            await SendAsync($"SYSTem:REMote{ScpiDelimiter}", ct); //[cite: 1]
        }

        public virtual async Task 切换本地控制模式(CancellationToken ct = default)
        {
            await SendAsync($"SYSTem:LOCal{ScpiDelimiter}", ct); //[cite: 1]
        }

        public virtual async Task 锁定远程键盘(CancellationToken ct = default)
        {
            await SendAsync($"SYSTem:RWLock{ScpiDelimiter}", ct); //[cite: 1]
        }

        public virtual async Task<string> 查询错误信息(CancellationToken ct = default)
        {
            return await WriteReadAsync($"SYSTem:ERRor?{ScpiDelimiter}", ScpiDelimiter, ct); //[cite: 1]
        }

        public virtual async Task 清除错误队列(CancellationToken ct = default)
        {
            await SendAsync($"SYSTem:CLEar{ScpiDelimiter}", ct); //[cite: 1]
        }

        #endregion

        #region 3. 功能模式与优先级设置

        /// <summary>
        /// 设置电源优先工作模式 (CV 电压优先 或 CC 电流优先)
        /// </summary>
        public virtual async Task 设置优先模式(IT6000CPriorityMode 模式, CancellationToken ct = default)
        {
            await SendAsync($"FUNCTION {模式}{ScpiDelimiter}", ct); //[cite: 1]
        }

        public virtual async Task<string> 查询优先模式(CancellationToken ct = default)
        {
            return await WriteReadAsync($"FUNCTION?{ScpiDelimiter}", ScpiDelimiter, ct); //[cite: 1]
        }

        /// <summary>
        /// 设置瞬变/功能模式 (固定, LIST, 电池测试, PV曲线, 汽车波形)
        /// </summary>
        public virtual async Task 设置功能模式(IT6000CFunctionMode 模式, CancellationToken ct = default)
        {
            await SendAsync($"FUNCTION:MODE {模式}{ScpiDelimiter}", ct); //[cite: 1]
        }

        public virtual async Task<string> 查询功能模式(CancellationToken ct = default)
        {
            return await WriteReadAsync($"FUNCTION:MODE?{ScpiDelimiter}", ScpiDelimiter, ct); //[cite: 1]
        }

        #endregion

        #region 4. 输出开关与保护清除

        public virtual async Task 设置输出开关(bool 开启, CancellationToken ct = default)
        {
            string 参数 = 开启 ? "ON" : "OFF";
            await SendAsync($"OUTPut {参数}{ScpiDelimiter}", ct); //[cite: 1]
        }

        public virtual async Task<string> 查询输出开关状态(CancellationToken ct = default)
        {
            return await WriteReadAsync($"OUTPut:STATe?{ScpiDelimiter}", ScpiDelimiter, ct); //[cite: 1]
        }

        public virtual async Task 清除保护告警(CancellationToken ct = default)
        {
            await SendAsync($"OUTPut:PROTection:CLEar{ScpiDelimiter}", ct); //[cite: 1]
        }

        #endregion

        #region 5. 输出电压 / 电流设定

        /// <summary>
        /// 设置输出电压 (仅在 CV 模式下生效)
        /// </summary>
        public virtual async Task 设置电压(double 电压, CancellationToken ct = default)
        {
            string cmd = string.Format(CultureInfo.InvariantCulture, "VOLTage {0:F2}{1}", 电压, ScpiDelimiter); //[cite: 1]
            await SendAsync(cmd, ct);
        }

        public virtual async Task<string> 查询电压设定值(CancellationToken ct = default)
        {
            return await WriteReadAsync($"VOLTage?{ScpiDelimiter}", ScpiDelimiter, ct); //[cite: 1]
        }

        /// <summary>
        /// 设置输出电流 (仅在 CC 模式下生效)
        /// </summary>
        public virtual async Task 设置电流(double 电流, CancellationToken ct = default)
        {
            string cmd = string.Format(CultureInfo.InvariantCulture, "CURRent {0:F3}{1}", 电流, ScpiDelimiter); //[cite: 1]
            await SendAsync(cmd, ct);
        }

        public virtual async Task<string> 查询电流设定值(CancellationToken ct = default)
        {
            return await WriteReadAsync($"CURRent?{ScpiDelimiter}", ScpiDelimiter, ct); //[cite: 1]
        }

        /// <summary>
        /// 设置 CV 优先模式下的电流限制上限值 (I+, 限流保护)
        /// </summary>
        public virtual async Task 设置电流限制上限(double 电流, CancellationToken ct = default)
        {
            string cmd = string.Format(CultureInfo.InvariantCulture, "CURRent:LIMit:POSitive {0:F3}{1}", 电流, ScpiDelimiter); //[cite: 1]
            await SendAsync(cmd, ct);
        }

        public virtual async Task<string> 查询电流限制上限(CancellationToken ct = default)
        {
            return await WriteReadAsync($"CURRent:LIMit:POSitive?{ScpiDelimiter}", ScpiDelimiter, ct); //[cite: 1]
        }

        /// <summary>
        /// 设置电压上升/下降斜率 (单位: V/s, 数值越大变化越快)[cite: 1]
        /// </summary>
        public virtual async Task 设置电压斜率(double 斜率Vs, CancellationToken ct = default)
        {
            string cmd = string.Format(CultureInfo.InvariantCulture, "VOLTage:SLEW {0:F4}{1}", 斜率Vs, ScpiDelimiter); //[cite: 1]
            await SendAsync(cmd, ct);
        }

        #endregion

        #region 6. 保护功能配置 (OVP, OCP, OPP)

        /// <summary>
        /// 开启或关闭过压保护 (OVP)[cite: 1]
        /// </summary>
        public virtual async Task 设置过压保护开关(bool 开启, CancellationToken ct = default)
        {
            string 参数 = 开启 ? "ON" : "OFF";
            await SendAsync($"VOLTage:PROTection:STATe {参数}{ScpiDelimiter}", ct); //[cite: 1]
        }

        public virtual async Task 设置过压保护阈值(double 电压, CancellationToken ct = default)
        {
            string cmd = string.Format(CultureInfo.InvariantCulture, "VOLTage:PROTection {0:F2}{1}", 电压, ScpiDelimiter); //[cite: 1]
            await SendAsync(cmd, ct);
        }

        /// <summary>
        /// 开启或关闭过流保护 (OCP)[cite: 1]
        /// </summary>
        public virtual async Task 设置过流保护开关(bool 开启, CancellationToken ct = default)
        {
            string 参数 = 开启 ? "ON" : "OFF";
            await SendAsync($"CURRent:PROTection:STATe {参数}{ScpiDelimiter}", ct); //[cite: 1]
        }

        public virtual async Task 设置过流保护阈值(double 电流, CancellationToken ct = default)
        {
            string cmd = string.Format(CultureInfo.InvariantCulture, "CURRent:PROTection {0:F3}{1}", 电流, ScpiDelimiter); //[cite: 1]
            await SendAsync(cmd, ct);
        }

        /// <summary>
        /// 开启或关闭过功率保护 (OPP)[cite: 1]
        /// </summary>
        public virtual async Task 设置过功率保护开关(bool 开启, CancellationToken ct = default)
        {
            string 参数 = 开启 ? "ON" : "OFF";
            await SendAsync($"POWER:PROTection:STATe {参数}{ScpiDelimiter}", ct); //[cite: 1]
        }

        public virtual async Task 设置过功率保护阈值(double 功率, CancellationToken ct = default)
        {
            string cmd = string.Format(CultureInfo.InvariantCulture, "POWER:PROTection {0:F2}{1}", 功率, ScpiDelimiter); //[cite: 1]
            await SendAsync(cmd, ct);
        }

        #endregion

        #region 7. 测量回读 (MEASure 与 FETCh)

        [Monitorable("直流源载实际电压")]
        public virtual async Task<string> 查询实际电压(CancellationToken ct = default)
        {
            return await WriteReadAsync($"MEASure:VOLTage?{ScpiDelimiter}", ScpiDelimiter, ct); //[cite: 1]
        }

        [Monitorable("直流源载实际电流")]
        public virtual async Task<string> 查询实际电流(CancellationToken ct = default)
        {
            return await WriteReadAsync($"MEASure:CURRent?{ScpiDelimiter}", ScpiDelimiter, ct); //[cite: 1]
        }

        [Monitorable("直流源载实际功率")]
        public virtual async Task<string> 查询实际功率(CancellationToken ct = default)
        {
            return await WriteReadAsync($"MEASure:POWER?{ScpiDelimiter}", ScpiDelimiter, ct); //[cite: 1]
        }

        public virtual async Task<string> 查询瞬时电压最大值(CancellationToken ct = default)
        {
            return await WriteReadAsync($"FETCh:VOLTage:MAXimum?{ScpiDelimiter}", ScpiDelimiter, ct); //[cite: 1]
        }

        public virtual async Task<string> 查询瞬时电流最小值(CancellationToken ct = default)
        {
            return await WriteReadAsync($"FETCh:CURRent:MINimum?{ScpiDelimiter}", ScpiDelimiter, ct); //[cite: 1]
        }

        #endregion

        #region 8. 负载电阻/CR模式设置 (仅限 CC 优先模式)

        /// <summary>
        /// 开启或关闭恒阻 (CR) 负载模式[cite: 1]
        /// </summary>
        /// <remarks>执行该指令前，必须确保设备处于 CC 优先模式，否则会报错</remarks>
        public virtual async Task 设置CR模式开关(bool 开启, CancellationToken ct = default)
        {
            string 参数 = 开启 ? "ON" : "OFF";
            await SendAsync($"SINK:RESistance:STATe {参数}{ScpiDelimiter}", ct); //[cite: 1]
        }

        public virtual async Task<string> 查询CR模式开关(CancellationToken ct = default)
        {
            return await WriteReadAsync($"SINK:RESistance:STATe?{ScpiDelimiter}", ScpiDelimiter, ct); //[cite: 1]
        }

        /// <summary>
        /// 设置恒阻 (CR) 模式下的电阻值 (单位: Ω)[cite: 1]
        /// </summary>
        /// <remarks>必须在先开启 CR 模式才能使用，设置为 0 相当于关闭 CR 模式</remarks>
        public virtual async Task 设置CR电阻值(double 电阻, CancellationToken ct = default)
        {
            string cmd = string.Format(CultureInfo.InvariantCulture, "SINK:RESistance {0:F2}{1}", 电阻, ScpiDelimiter); //[cite: 1]
            await SendAsync(cmd, ct);
        }

        public virtual async Task<string> 查询CR电阻值(CancellationToken ct = default)
        {
            return await WriteReadAsync($"SINK:RESistance?{ScpiDelimiter}", ScpiDelimiter, ct); //[cite: 1]
        }

        #endregion
    }
}