//! Minimax Tool Calling Example
//!
//! Demonstrates tool calling with Minimax models
//! using OpenAI-compatible endpoints.
//!
//! Run: cargo run --example minimax_tools

use dotenvy::dotenv;
use llm_connector::{
    LlmClient,
    types::{ChatRequest, Message, ToolDefinition, ToolChoice, ToolOutput},
};
use serde_json::json;
use std::env;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    dotenv().ok();
    println!("🤖 Minimax Tool Calling Example\n");

    let api_key = env::var("MINIMAX_API_KEY").expect("MINIMAX_API_KEY not set");
    let region = env::var("MINIMAX_REGION")
        .or_else(|_| env::var("REGION"))
        .unwrap_or_else(|_| "global".to_string());
    let model = env::var("MINIMAX_MODEL").unwrap_or_else(|_| "abab6.5s-chat".to_string()); // abab6.5s is good for tools

    // Fetch endpoint from llm-providers
    let endpoint_id = format!("minimax:{}", region);
    let (_, endpoint) = llm_providers::get_endpoint(&endpoint_id)
        .ok_or_else(|| format!("Endpoint {} not found", endpoint_id))?;

    println!("📍 Testing Region: {}", endpoint.label);
    println!("🔗 Base URL: {}", endpoint.base_url);
    println!("🤖 Model: {}\n", model);

    // Minimax uses OpenAI-compatible v1 API
    let client = LlmClient::builder()
        .openai_compatible(&api_key, "minimax")
        .base_url(endpoint.base_url)
        .build()?;

    // Define a dummy tool
    let weather_tool = ToolDefinition::new(
        "get_weather",
        "Get the current weather in a given location",
        json!({
            "type": "object",
            "properties": {
                "location": {
                    "type": "string",
                    "description": "The city and state, e.g. San Francisco, CA"
                },
                "unit": {
                    "type": "string",
                    "enum": ["celsius", "fahrenheit"]
                }
            },
            "required": ["location"]
        }),
    );

    // 1. Tool Calling
    println!("--- Step 1: User asks a question requiring a tool ---");
    let request = ChatRequest::new(&model)
        .add_message(Message::user("What's the weather like in San Francisco?"))
        .add_tool(weather_tool)
        .with_tool_choice(ToolChoice::Auto);

    let response = client.chat(&request).await?;
    
    if let Some(tool_calls) = response.tool_calls() {
        println!("🛠️ Model requested {} tool call(s):", tool_calls.len());
        
        let mut messages = vec![
            Message::user("What's the weather like in San Francisco?"),
            response.message.clone(),
        ];

        for tool_call in tool_calls {
            println!("  - Function: {}, Args: {}", tool_call.function.name, tool_call.function.arguments);
            
            // Mock execution
            let mock_result = json!({
                "location": "San Francisco",
                "temperature": "18",
                "unit": "celsius",
                "description": "Partly cloudy"
            });
            
            messages.push(Message::tool(
                &tool_call.id,
                &tool_call.function.name,
                &mock_result.to_string(),
            ));
        }

        println!("--- Step 2: Sending tool result back to model ---");
        let follow_up_request = ChatRequest::new(&model)
            .with_messages(messages);
            
        let final_response = client.chat(&follow_up_request).await?;
        println!("🏁 Final Answer:\n\n{}", final_response.content);
    } else {
        println!("❌ No tool calls were generated by the model.");
        println!("Response: {}", response.content);
    }

    Ok(())
}
