//! 节点心跳超时检测协程
//!
//! 定期检查设备服务节点的心跳状态，移除超时节点。
//! 心跳时间从 Redis 读取（RFC3339 字符串），与 device-server 写入的格式一致。

use std::time::Duration;

use crate::commands::NodeRegistry;

/// 启动节点心跳超时检测
///
/// 每 30 秒检查一次，移除超过 `timeout_secs` 未发送心跳的节点。
pub async fn run(nodes: NodeRegistry, timeout_secs: u64) {
    let timeout = Duration::from_secs(timeout_secs);
    let check_interval = Duration::from_secs(30);

    loop {
        tokio::time::sleep(check_interval).await;

        let node_list = nodes.list().await;
        let now = chrono::Utc::now();

        for node in &node_list {
            let last_hb = match &node.last_heartbeat {
                Some(hb) => match chrono::DateTime::parse_from_rfc3339(hb) {
                    Ok(dt) => dt.with_timezone(&chrono::Utc),
                    Err(_) => {
                        tracing::warn!("[node_checker] 无效的心跳时间格式 node_id={}", node.node_id);
                        continue;
                    }
                },
                None => {
                    tracing::warn!("[node_checker] 节点缺少心跳时间 node_id={}", node.node_id);
                    continue;
                }
            };

            let elapsed = now - last_hb;
            if elapsed > chrono::Duration::from_std(timeout).unwrap_or_default() {
                tracing::warn!(
                    "[node_checker] 节点心跳超时 node_id={} 距最后心跳={}秒",
                    node.node_id,
                    elapsed.num_seconds()
                );
                nodes.remove(&node.node_id).await;
            }
        }
    }
}
