use genai::Client;
use genai::chat::{ChatMessage, ChatRequest, Tool, ToolCall, ToolResponse};
use serde_json::json;

const MODEL: &str = "gemini-3-flash-preview";

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
	let client = Client::default();

	let weather_tool = Tool::new("get_weather")
		.with_description("Get the current weather for a location")
		.with_schema(json!({
			"type": "object",
			"properties": {
				"city": { "type": "string" },
				"unit": { "type": "string", "enum": ["C", "F"] }
			},
			"required": ["city", "unit"]
		}));

	// Create a synthetic conversation history. These tool calls were not generated by
	// Gemini 3 (or any LLM) and do not have a thought signature. This is useful for e.g.
	// pre-seeding a conversation with tool calls and responses, or executing deterministic
	// logic "in-band" with the LLM conversation. genai will correctly inject the required
	// string "skip_thought_signature_validator" in place of a valid signature. Otherwise,
	// the call would error out on Gemini 3 models.
	let messages = vec![
		ChatMessage::user("What's the weather like in Paris?"),
		ChatMessage::assistant(vec![ToolCall {
			call_id: "call_123".to_string(),
			fn_name: "get_weather".to_string(),
			fn_arguments: json!({"city": "Paris", "unit": "C"}),
			thought_signatures: None,
		}]),
		ChatMessage::from(ToolResponse::new(
			"call_123".to_string(),
			json!({"temperature": 15, "condition": "Cloudy"}).to_string(),
		)),
	];

	let chat_req = ChatRequest::new(messages).with_tools(vec![weather_tool]);

	println!("--- Model: {MODEL}");
	println!("--- Sending deterministic history (synthetic tool call)...");

	match client.exec_chat(MODEL, chat_req, None).await {
		Ok(chat_res) => {
			println!("\n--- Response received successfully:");
			if let Some(text) = chat_res.first_text() {
				println!("{}", text);
			}
		}
		Err(e) => {
			eprintln!("\n--- Error: Request failed!");
			eprintln!("{}", e);
			return Err(e.into());
		}
	}

	Ok(())
}
