use std::sync::{Mutex, OnceLock};

use serde_json::json;
use sgclaw::config::DeepSeekSettings;
use sgclaw::llm::{ChatMessage, DeepSeekProvider, ToolDefinition};

fn env_lock() -> &'static Mutex<()> {
    static LOCK: OnceLock<Mutex<()>> = OnceLock::new();
    LOCK.get_or_init(|| Mutex::new(()))
}

#[test]
fn deepseek_settings_load_defaults_from_env() {
    let _guard = env_lock().lock().unwrap();
    std::env::set_var("DEEPSEEK_API_KEY", "test-key");
    std::env::remove_var("DEEPSEEK_BASE_URL");
    std::env::remove_var("DEEPSEEK_MODEL");

    let settings = DeepSeekSettings::from_env().unwrap();

    assert_eq!(settings.api_key, "test-key");
    assert_eq!(settings.base_url, "https://api.deepseek.com");
    assert_eq!(settings.model, "deepseek-chat");
}

#[test]
fn deepseek_request_shape_matches_openai_compatible_chat_format() {
    let provider = DeepSeekProvider::new(DeepSeekSettings {
        api_key: "test-key".to_string(),
        base_url: "https://api.deepseek.com".to_string(),
        model: "deepseek-chat".to_string(),
    });
    let messages = vec![
        ChatMessage {
            role: "system".to_string(),
            content: "You are sgClaw.".to_string(),
        },
        ChatMessage {
            role: "user".to_string(),
            content: "打开百度搜索天气".to_string(),
        },
    ];
    let tools = vec![ToolDefinition {
        name: "browser_action".to_string(),
        description: "Execute browser actions".to_string(),
        parameters: json!({
            "type": "object",
            "properties": {
                "action": { "type": "string" }
            },
            "required": ["action"]
        }),
    }];

    let request = provider.build_chat_request(&messages, &tools);
    let serialized = serde_json::to_value(&request).unwrap();

    assert_eq!(serialized["model"], "deepseek-chat");
    assert_eq!(serialized["stream"], false);
    assert_eq!(serialized["messages"][0]["role"], "system");
    assert_eq!(serialized["messages"][1]["content"], "打开百度搜索天气");
    assert_eq!(serialized["tools"][0]["type"], "function");
    assert_eq!(
        serialized["tools"][0]["function"]["name"],
        "browser_action"
    );
}
