#![allow(dead_code)]
//! 设备连接池管理。
//!
//! 每台设备登录成功后分配一个 `DeviceConnection`，包含命令发送通道。
//! `ConnectionPool` 以 `dev_id`（IMEI）为键，支持并发读写。

use std::collections::HashMap;
use std::sync::Arc;
use std::time::Instant;
use tokio::sync::{mpsc, RwLock};

/// 单台设备的连接状态。
#[allow(dead_code)]
pub struct DeviceConnection {
    pub dev_id: String,
    /// 向设备发送指令的通道。
    pub tx: mpsc::UnboundedSender<String>,
    /// 连接建立时间。
    pub connected_at: Instant,
    /// 最后活跃时间（收到任意消息时更新）。
    pub last_seen: Instant,
    /// 是否已完成登录验证。
    pub authenticated: bool,
}

impl DeviceConnection {
    pub fn new(dev_id: String, tx: mpsc::UnboundedSender<String>) -> Self {
        let now = Instant::now();
        Self { dev_id, tx, connected_at: now, last_seen: now, authenticated: false }
    }

    /// 标记活跃时间。
    pub fn touch(&mut self) {
        self.last_seen = Instant::now();
    }
}

/// 线程安全的设备连接池。
#[derive(Clone)]
pub struct ConnectionPool {
    inner: Arc<RwLock<HashMap<String, DeviceConnection>>>,
}

impl ConnectionPool {
    pub fn new() -> Self {
        Self { inner: Arc::new(RwLock::new(HashMap::new())) }
    }

    /// 注册设备连接。如果已存在则替换旧连接。
    pub async fn register(&self, dev_id: String, conn: DeviceConnection) {
        let mut map = self.inner.write().await;
        map.insert(dev_id, conn);
    }

    /// 移除设备连接（断连时调用）。
    pub async fn remove(&self, dev_id: &str) {
        let mut map = self.inner.write().await;
        map.remove(dev_id);
    }

    /// 向指定设备发送 JSON 指令。
    /// 返回 `Ok(())` 表示已投递到通道；设备可能因缓冲区满而断开。
    pub async fn send_command(&self, dev_id: &str, json: &str) -> Result<(), &'static str> {
        let map = self.inner.read().await;
        match map.get(dev_id) {
            Some(conn) => conn.tx.send(json.to_string()).map_err(|_| "通道已关闭"),
            None => Err("设备不在线"),
        }
    }

    /// 查询设备是否在线且已验证。
    pub async fn is_online(&self, dev_id: &str) -> bool {
        let map = self.inner.read().await;
        map.get(dev_id).map(|c| c.authenticated).unwrap_or(false)
    }

    /// 更新设备活跃时间。
    pub async fn touch(&self, dev_id: &str) {
        let mut map = self.inner.write().await;
        if let Some(conn) = map.get_mut(dev_id) {
            conn.touch();
        }
    }

    /// 标记设备已验证。
    pub async fn set_authenticated(&self, dev_id: &str) {
        let mut map = self.inner.write().await;
        if let Some(conn) = map.get_mut(dev_id) {
            conn.authenticated = true;
        }
    }

    /// 清理超时未活跃的连接（心跳检测）。
    pub async fn cleanup_timeout(&self, timeout: std::time::Duration) -> Vec<String> {
        let mut map = self.inner.write().await;
        let now = Instant::now();
        let mut removed = Vec::new();
        map.retain(|dev_id, conn| {
            if now.duration_since(conn.last_seen) > timeout {
                removed.push(dev_id.clone());
                false
            } else {
                true
            }
        });
        removed
    }

    /// 返回当前在线设备数量。
    pub async fn online_count(&self) -> usize {
        self.inner.read().await.len()
    }
}
