//! 应用配置模块

use once_cell::sync::Lazy;
use parking_lot::RwLock;
use serde::{Deserialize, Serialize};
use uuid::Uuid;

/// 默认 UDP 广播端口
pub const DEFAULT_UDP_PORT: u16 = 53317;

/// 默认 WebSocket 端口
pub const DEFAULT_WS_PORT: u16 = 53318;

/// 默认 HTTP 端口
pub const DEFAULT_HTTP_PORT: u16 = 53319;

/// UDP 广播间隔 (毫秒)
pub const DISCOVERY_INTERVAL_MS: u64 = 3000;

/// 设备离线超时 (毫秒)
pub const DEVICE_TIMEOUT_MS: u64 = 15000;

/// 心跳间隔 (毫秒)
pub const HEARTBEAT_INTERVAL_MS: u64 = 5000;

/// 心跳超时 (毫秒)
pub const HEARTBEAT_TIMEOUT_MS: u64 = 15000;

/// 文件分块大小 (字节)
pub const FILE_CHUNK_SIZE: usize = 64 * 1024; // 64KB

/// 应用配置
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct AppConfig {
    /// 设备唯一标识符
    pub device_id: String,
    /// 设备名称
    pub device_name: String,
    /// UDP 广播端口
    pub udp_port: u16,
    /// WebSocket 服务端口
    pub ws_port: u16,
    /// HTTP 服务端口
    pub http_port: u16,
    /// 文件下载保存目录
    pub download_dir: String,
    /// 是否自动接受文件
    pub auto_accept_files: bool,
    /// 最大文件大小限制 (字节, 0 表示不限制)
    pub max_file_size: u64,
}

impl Default for AppConfig {
    fn default() -> Self {
        // 从环境变量读取端口偏移量 (用于测试多实例)
        // 设置 FLASH_SEND_PORT_OFFSET=100 可运行第二个实例
        let port_offset: u16 = std::env::var("FLASH_SEND_PORT_OFFSET")
            .ok()
            .and_then(|s| s.parse().ok())
            .unwrap_or(0);

        // 从环境变量读取实例名称后缀
        let instance_suffix = std::env::var("FLASH_SEND_INSTANCE")
            .ok()
            .map(|s| format!(" ({})", s))
            .unwrap_or_default();

        // 获取主机名作为默认设备名
        let device_name = hostname::get()
            .map(|h| format!("{}{}", h.to_string_lossy(), instance_suffix))
            .unwrap_or_else(|_| format!("Unknown Device{}", instance_suffix));

        // 获取默认下载目录
        let download_dir = dirs::download_dir()
            .or_else(dirs::home_dir)
            .map(|p| p.to_string_lossy().to_string())
            .unwrap_or_else(|| ".".to_string());

        // 如果有端口偏移，生成不同的设备ID（用于多实例测试）
        let device_id = if port_offset > 0 {
            // 为测试实例生成固定但不同的 UUID
            format!("test-instance-{:04}", port_offset)
        } else {
            Uuid::new_v4().to_string()
        };

        Self {
            device_id,
            device_name,
            udp_port: DEFAULT_UDP_PORT,  // UDP广播端口必须固定，所有实例使用同一端口才能互相发现
            ws_port: DEFAULT_WS_PORT + port_offset,
            http_port: DEFAULT_HTTP_PORT + port_offset,
            download_dir,
            auto_accept_files: false,
            max_file_size: 0,
        }
    }
}

/// 全局配置单例
pub static APP_CONFIG: Lazy<RwLock<AppConfig>> = Lazy::new(|| {
    RwLock::new(AppConfig::default())
});

impl AppConfig {
    /// 获取当前配置副本
    pub fn get() -> AppConfig {
        APP_CONFIG.read().clone()
    }

    /// 更新配置
    pub fn update<F>(f: F)
    where
        F: FnOnce(&mut AppConfig),
    {
        let mut config = APP_CONFIG.write();
        f(&mut config);
    }

    /// 设置设备名称
    pub fn set_device_name(name: String) {
        Self::update(|c| c.device_name = name);
    }

    /// 设置下载目录
    pub fn set_download_dir(dir: String) {
        Self::update(|c| c.download_dir = dir);
    }
}
