namespace SHH.Contracts
{
    /// <summary>
    /// 通用指令请求载体 (Request)
    /// <para>用于 NetMQ 的 Request-Reply 或 Router-Dealer 模式</para>
    /// </summary>
    public class CommandPayload
    {
        #region --- 0. 协议自描述 ---

        /// <summary>
        /// 协议类型标识
        /// <para>建议值: "COMMAND" 或 "指令包"</para>
        /// </summary>
        public string Protocol { get; set; } = "COMMAND";

        #endregion

        #region --- 核心路由信息 ---

        /// <summary>
        /// 指令代码 (路由键)
        /// <para>示例: "PTZ", "RECORD_START", "SERVER_REGISTER"</para>
        /// </summary>
        public string CmdCode { get; set; } = string.Empty;

        /// <summary>
        /// 目标对象 ID
        /// <para>示例: 摄像头ID "101"，或者系统级指令填 "SYSTEM"</para>
        /// </summary>
        public string TargetId { get; set; } = string.Empty;

        /// <summary>
        /// 业务参数 (JSON 字符串)
        /// <para>根据 CmdCode 的不同，反序列化为不同的 DTO (如 PtzControlDto)</para>
        /// </summary>
        public string JsonParams { get; set; } = string.Empty;

        #endregion

        #region --- 追踪与元数据 ---

        /// <summary>
        /// 请求追踪 ID (UUID)
        /// <para>核心字段：用于实现异步等待 (await)。回执包必须携带此 ID。</para>
        /// </summary>
        public string RequestId { get; set; } = Guid.NewGuid().ToString("N");

        /// <summary>
        /// 发送时间戳
        /// </summary>
        public DateTime Timestamp { get; set; } = DateTime.Now;

        #endregion

        #region --- 可靠性控制字段 (QoS) ---

        /// <summary>
        /// 是否需要回执 (ACK)
        /// <para>true: 发送端会 await 等待结果 (默认)</para>
        /// <para>false: 发后即忘 (Fire-and-Forget)，服务端收到后不回发任何消息，减少带宽</para>
        /// </summary>
        public bool RequireAck { get; set; } = true;

        /// <summary>
        /// 重试计数器
        /// <para>0: 首次发送</para>
        /// <para>1, 2...: 第N次重试</para>
        /// <para>服务端据此判断是否需要查重 (幂等性处理)</para>
        /// </summary>
        public int RetryCount { get; set; } = 0;

        /// <summary>
        /// 消息过期时间 (Unix时间戳)
        /// <para>如果接收端收到时已经超过此时间，直接丢弃，不处理也不回复</para>
        /// </summary>
        public long ExpireTime { get; set; }

        #endregion
    }
}