//! 服务层

pub mod auth;
pub mod device;
pub mod session;

use crate::config::Config;
use crate::db::Database;
use std::collections::HashMap;
use tokio::sync::RwLock;

/// WebSocket连接信息
pub struct WsConnection {
    pub device_id: String,
    pub user_id: Option<String>,
    pub tx: tokio::sync::mpsc::Sender<String>,
}

/// 应用状态
pub struct AppState {
    pub db: Database,
    pub config: Config,
    /// 在线设备的WebSocket连接 (device_id -> connection)
    pub connections: RwLock<HashMap<String, WsConnection>>,
    /// 活跃的远程控制会话 (session_id -> (controller_ws, controlled_ws))
    pub active_sessions: RwLock<HashMap<String, (String, String)>>,
}

impl AppState {
    pub fn new(db: Database, config: Config) -> Self {
        Self {
            db,
            config,
            connections: RwLock::new(HashMap::new()),
            active_sessions: RwLock::new(HashMap::new()),
        }
    }

    /// 添加WebSocket连接
    pub async fn add_connection(&self, device_id: String, user_id: Option<String>, tx: tokio::sync::mpsc::Sender<String>) {
        let mut connections = self.connections.write().await;
        connections.insert(device_id.clone(), WsConnection { device_id, user_id, tx });
    }

    /// 移除WebSocket连接
    pub async fn remove_connection(&self, device_id: &str) {
        let mut connections = self.connections.write().await;
        connections.remove(device_id);
    }

    /// 发送消息给指定设备
    pub async fn send_to_device(&self, device_id: &str, message: &str) -> bool {
        let connections = self.connections.read().await;
        if let Some(conn) = connections.get(device_id) {
            conn.tx.send(message.to_string()).await.is_ok()
        } else {
            false
        }
    }

    /// 检查设备是否在线
    pub async fn is_device_online(&self, device_id: &str) -> bool {
        let connections = self.connections.read().await;
        connections.contains_key(device_id)
    }

    /// 获取在线设备数量
    pub async fn count_online_devices(&self) -> usize {
        let connections = self.connections.read().await;
        connections.len()
    }
}
