//! 设备通讯协议消息类型定义与序列化。
//!
//! 设备与平台间采用 JSON 格式通讯，LF (`\n`) 作为消息边界。
//! 所有 JSON 键名使用蛇形命名（snake_case）。

use serde::{Deserialize, Serialize};
use serde_json::Value;

/// 设备发往平台的消息。
///
/// 字段均为 `Option` 以兼容不同指令所需的参数差异，解析后在 handler 中校验必填字段。
#[derive(Debug, Clone, Deserialize, Serialize)]
#[allow(dead_code)]
pub struct DeviceMessage {
    /// 动作类型：login / auth_str / status_post / pow_fail / bat_in / bat_out / on / off
    pub act: String,
    pub dev_id: Option<String>,
    pub msg_id: Option<u32>,
    /// 登录签名时的时间戳（秒级）
    pub timestamp: Option<u64>,
    /// SHA256 签名尾巴 7 位
    pub sign: Option<String>,
    /// 485 子设备 ID（仓控板 ID 1-6）
    pub sub_device_id: Option<u8>,
    /// 状态上报时的 HEX 数据
    pub status: Option<String>,
    /// 4G 信号强度
    pub rssi: Option<i32>,
    /// 未在顶层定义的扩展字段
    #[serde(flatten)]
    pub extra: Option<Value>,
}

/// 平台回复设备的消息。
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ServerResponse {
    /// 1=成功，0=失败
    pub suc: u8,
    pub msg_id: Option<u32>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub err: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub auth_str: Option<String>,
}

impl ServerResponse {
    /// 创建成功响应。
    pub fn success(msg_id: Option<u32>) -> Self {
        Self { suc: 1, msg_id, err: None, auth_str: None }
    }

    /// 创建失败响应。
    pub fn error(msg_id: Option<u32>, err: impl Into<String>) -> Self {
        Self { suc: 0, msg_id, err: Some(err.into()), auth_str: None }
    }

    /// 序列化为 JSON 字符串（紧凑格式，无多余空格）。
    pub fn to_json(&self) -> String {
        serde_json::to_string(self).expect("ServerResponse 序列化不应失败")
    }
}
