/// 请求来源信息（IP 地址 + User-Agent）。
///
/// 通过 `tokio::task_local!` 在请求生命周期内传递，
/// JWT 中间件设置，审计服务自动读取。
#[derive(Debug, Clone, Default)]
pub struct RequestInfo {
    pub ip_address: Option<String>,
    pub user_agent: Option<String>,
}

tokio::task_local! {
    /// 当前请求的来源信息。
    ///
    /// 在 JWT 中间件中通过 `REQUEST_INFO.scope(info, future)` 设置，
    /// 在 `audit_service::record()` 中自动读取。
    pub static REQUEST_INFO: RequestInfo;
}

impl RequestInfo {
    /// 从 HTTP 请求头中提取 IP 地址和 User-Agent。
    ///
    /// IP 优先级：X-Forwarded-For > X-Real-IP > 直接连接（不记录）。
    pub fn from_headers(headers: &axum::http::HeaderMap) -> Self {
        let ip_address = headers
            .get("X-Forwarded-For")
            .and_then(|v| v.to_str().ok())
            .map(|s| {
                // X-Forwarded-For 可能包含多个 IP，取第一个（客户端真实 IP）
                s.split(',').next().unwrap_or(s).trim().to_string()
            })
            .or_else(|| {
                headers
                    .get("X-Real-IP")
                    .and_then(|v| v.to_str().ok())
                    .map(|s| s.trim().to_string())
            });

        let user_agent = headers
            .get("user-agent")
            .and_then(|v| v.to_str().ok())
            .map(|s| s.to_string());

        Self {
            ip_address,
            user_agent,
        }
    }

    /// 尝试从 task_local 中读取当前请求信息。
    /// 如果不在请求上下文中（如后台任务），返回 None。
    pub fn try_current() -> Option<Self> {
        REQUEST_INFO.try_with(|info| info.clone()).ok()
    }
}
