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>
    /// 信号发生器输出波形类型
    /// </summary>
    public enum SignalWaveform
    {
        /// <summary> 正弦波 </summary>
        SINusoid,
        /// <summary> 方波 </summary>
        SQUare,
        /// <summary> 锯齿波 </summary>
        RAMP,
        /// <summary> 脉冲波 (重点用于CP信号模拟) </summary>
        PULSe,
        /// <summary> 噪声 </summary>
        NOISe,
        /// <summary> 任意波 (USER) </summary>
        USER
    }

    /// <summary>
    /// 频率计输入信号的耦合方式
    /// </summary>
    public enum CounterCoupling
    {
        /// <summary> 交流耦合 </summary>
        AC,
        /// <summary> 直流耦合 </summary>
        DC
    }

    #endregion

    [ACPCommand]
    public class DG1000Z : Tcp
    {
        // 使用换行符 \n (ASCII 0x0A) 作为 SCPI 结束符
        private const string ScpiDelimiter = "\n";

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

        #region 1. IEEE 488.2 公共命令

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

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

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

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

        #endregion

        #region 2. 通道输出控制 (CH1 / CH2)

        /// <summary>
        /// 打开或关闭指定通道的输出
        /// </summary>
        /// <param name="通道号">通道 1 或 2，默认 1</param>
        /// <param name="开启">true为开启，false为关闭</param>
        public virtual async Task 设置通道输出状态(int 通道号 = 1, bool 开启 = true, CancellationToken ct = default)
        {
            string 参数 = 开启 ? "ON" : "OFF";
            await SendAsync($":OUTPut{通道号}:STATe {参数}{ScpiDelimiter}", ct);
        }

        public virtual async Task<string> 查询通道输出状态(int 通道号 = 1, CancellationToken ct = default)
        {
            return await WriteReadAsync($":OUTPut{通道号}:STATe?{ScpiDelimiter}", ScpiDelimiter, ct);
        }

        #endregion

        #region 3. 波形、频率与幅度设置 (基础输出)

        /// <summary>
        /// 设置指定通道的波形类型 (如正弦波、方波等)
        /// </summary>
        public virtual async Task 设置波形类型(int 通道号 = 1, SignalWaveform 波形 = SignalWaveform.SINusoid, CancellationToken ct = default)
        {
            await SendAsync($":SOURce{通道号}:FUNCtion:SHAPe {波形}{ScpiDelimiter}", ct);
        }

        /// <summary>
        /// 设置指定通道的输出频率 (单位: Hz)
        /// </summary>
        public virtual async Task 设置频率(int 通道号 = 1, double 频率Hz = 1000, CancellationToken ct = default)
        {
            string cmd = string.Format(CultureInfo.InvariantCulture, ":SOURce{0}:FREQuency {1:F2}{2}", 通道号, 频率Hz, ScpiDelimiter);
            await SendAsync(cmd, ct);
        }

        public virtual async Task<string> 查询频率(int 通道号 = 1, CancellationToken ct = default)
        {
            return await WriteReadAsync($":SOURce{通道号}:FREQuency?{ScpiDelimiter}", ScpiDelimiter, ct);
        }

        /// <summary>
        /// 设置指定通道的输出幅度 (单位: Vpp，峰峰值)
        /// </summary>
        public virtual async Task 设置幅度(int 通道号 = 1, double 幅度Vpp = 5, CancellationToken ct = default)
        {
            string cmd = string.Format(CultureInfo.InvariantCulture, ":SOURce{0}:VOLTage:AMPLitude {1:F2}{2}", 通道号, 幅度Vpp, ScpiDelimiter);
            await SendAsync(cmd, ct);
        }

        public virtual async Task<string> 查询幅度(int 通道号 = 1, CancellationToken ct = default)
        {
            return await WriteReadAsync($":SOURce{通道号}:VOLTage:AMPLitude?{ScpiDelimiter}", ScpiDelimiter, ct);
        }

        /// <summary>
        /// 设置指定通道的直流偏移电压 (单位: Vdc)
        /// </summary>
        public virtual async Task 设置偏移电压(int 通道号 = 1, double 偏移Vdc = 0, CancellationToken ct = default)
        {
            string cmd = string.Format(CultureInfo.InvariantCulture, ":SOURce{0}:VOLTage:OFFSet {1:F2}{2}", 通道号, 偏移Vdc, ScpiDelimiter);
            await SendAsync(cmd, ct);
        }

        public virtual async Task<string> 查询偏移电压(int 通道号 = 1, CancellationToken ct = default)
        {
            return await WriteReadAsync($":SOURce{通道号}:VOLTage:OFFSet?{ScpiDelimiter}", ScpiDelimiter, ct);
        }

        #endregion

        #region 4. 方波 / 脉冲波占空比设置 (重点用于CP信号模拟)

        /// <summary>
        /// 设置方波信号的占空比 (0.01% ~ 99.99%)[cite: 1]
        /// </summary>
        public virtual async Task 设置方波占空比(int 通道号 = 1, double 占空比 = 50.0, CancellationToken ct = default)
        {
            string cmd = string.Format(CultureInfo.InvariantCulture, ":SOURce{0}:FUNCtion:SQUare:DCYCle {1:F2}{2}", 通道号, 占空比, ScpiDelimiter);
            await SendAsync(cmd, ct);
        }

        /// <summary>
        /// 设置脉冲波信号的占空比 (0.01% ~ 99.99%)[cite: 1]
        /// 注意：使用此命令前必须先设置为 PULSe 波形类型
        /// </summary>
        public virtual async Task 设置脉冲波占空比(int 通道号 = 1, double 占空比 = 50.0, CancellationToken ct = default)
        {
            string cmd = string.Format(CultureInfo.InvariantCulture, ":SOURce{0}:FUNCtion:PULSe:DCYCle {1:F2}{2}", 通道号, 占空比, ScpiDelimiter);
            await SendAsync(cmd, ct);
        }

        #endregion

        #region 5. 频率计测量功能 (高频数据轮询核心)

        /// <summary>
        /// 打开或关闭内置频率计功能
        /// </summary>
        public virtual async Task 设置频率计开关(bool 开启 = true, CancellationToken ct = default)
        {
            string 参数 = 开启 ? "ON" : "OFF";
            await SendAsync($":COUNter:STATe {参数}{ScpiDelimiter}", ct);
        }

        public virtual async Task<string> 查询频率计开关状态(CancellationToken ct = default)
        {
            return await WriteReadAsync($":COUNter:STATe?{ScpiDelimiter}", ScpiDelimiter, ct);
        }

        /// <summary>
        /// 设置频率计输入信号的耦合方式
        /// </summary>
        public virtual async Task 设置频率计耦合方式(CounterCoupling 耦合 = CounterCoupling.AC, CancellationToken ct = default)
        {
            await SendAsync($":COUNter:COUPling {耦合}{ScpiDelimiter}", ct);
        }

        /// <summary>
        /// 设置频率计的触发电平 (单位: V)
        /// </summary>
        public virtual async Task 设置频率计触发电平(double 电平V = 0.1, CancellationToken ct = default)
        {
            string cmd = string.Format(CultureInfo.InvariantCulture, ":COUNter:LEVel {0:F2}{1}", 电平V, ScpiDelimiter);
            await SendAsync(cmd, ct);
        }

        [Monitorable("信号发生器频率计测量值")]
        public virtual async Task<string> 查询频率计测量值(CancellationToken ct = default)
        {
            // 返回格式: 频率, 周期, 占空比, 正脉宽, 负脉宽
            return await WriteReadAsync($":COUNter:MEASure?{ScpiDelimiter}", ScpiDelimiter, ct);
        }

        #endregion

        #region 6. 系统维护与远程控制扩展命令

        public virtual async Task 切换远程控制模式(CancellationToken ct = default)
        {
            // 信号发生器通常通过 LAN/USB 和 VISA 通信即自动进入远程控制，
            // 但为了兼容模板，保留一个类似的方法。
            await Task.CompletedTask;
        }

        public virtual async Task 切换本地控制模式(CancellationToken ct = default)
        {
            // 通常通过前面板按键退出远程。不过可提供 SCPI 关闭屏幕保护等。
            await Task.CompletedTask;
        }

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

        #endregion
    }
}