//! 应用状态管理
//! 集中管理所有服务实例

use once_cell::sync::OnceCell;
use parking_lot::RwLock;
use std::collections::HashMap;
use std::path::PathBuf;
use std::sync::Arc;
use tokio_util::sync::CancellationToken;

use crate::discovery::{DeviceManager, DiscoveryService};
use crate::http::{HttpClient, HttpServer};
use crate::models::DeviceInfo;
use crate::utils::{AppConfig, AppError};
use crate::websocket::{ConnectionManager, WsClient, WsServer};

/// 全局应用状态
static APP_STATE: OnceCell<Arc<AppStateInner>> = OnceCell::new();

/// 应用状态内部结构
pub struct AppStateInner {
    /// 本机设备信息
    pub local_device: RwLock<DeviceInfo>,
    /// 设备管理器
    pub device_manager: DeviceManager,
    /// 发现服务
    pub discovery_service: RwLock<Option<DiscoveryService>>,
    /// WebSocket 服务端
    pub ws_server: RwLock<Option<WsServer>>,
    /// WebSocket 客户端
    pub ws_client: RwLock<Option<WsClient>>,
    /// HTTP 服务端
    pub http_server: RwLock<Option<HttpServer>>,
    /// HTTP 客户端
    pub http_client: HttpClient,
    /// 连接管理器
    pub connection_manager: ConnectionManager,
    /// 应用数据目录
    pub app_data_dir: PathBuf,
    /// 文件传输取消 tokens（file_id -> CancellationToken）
    pub transfer_cancellation_tokens: RwLock<HashMap<String, CancellationToken>>,
}

impl AppStateInner {
    /// 创建新的应用状态
    pub fn new(app_data_dir: PathBuf) -> Self {
        let config = AppConfig::get();
        let local_device = DeviceInfo::new(
            config.device_id.clone(),
            config.device_name.clone(),
            String::new(), // IP 将在启动时确定
            config.ws_port,
            config.http_port,
        );

        Self {
            local_device: RwLock::new(local_device),
            device_manager: DeviceManager::new(),
            discovery_service: RwLock::new(None),
            ws_server: RwLock::new(None),
            ws_client: RwLock::new(None),
            http_server: RwLock::new(None),
            http_client: HttpClient::new(),
            connection_manager: ConnectionManager::new(),
            app_data_dir,
            transfer_cancellation_tokens: RwLock::new(HashMap::new()),
        }
    }

    /// 获取本机 IP 地址
    pub fn get_local_ip() -> Option<String> {
        local_ip_address::local_ip()
            .ok()
            .map(|ip| ip.to_string())
    }

    /// 更新本机 IP
    pub fn update_local_ip(&self) {
        if let Some(ip) = Self::get_local_ip() {
            let mut device = self.local_device.write();
            device.ip = ip;
        }
    }
}

/// 应用状态管理
pub struct AppState;

impl AppState {
    /// 初始化应用状态
    pub fn init(app_data_dir: PathBuf) -> Result<(), AppError> {
        let state = Arc::new(AppStateInner::new(app_data_dir));
        APP_STATE
            .set(state)
            .map_err(|_| AppError::General("App state already initialized".to_string()))?;
        Ok(())
    }

    /// 获取应用状态
    pub fn get() -> Arc<AppStateInner> {
        APP_STATE.get().expect("App state not initialized").clone()
    }

    /// 检查是否已初始化
    pub fn is_initialized() -> bool {
        APP_STATE.get().is_some()
    }
}
