//! # Gemini SDK
//!
//! A simple Rust SDK for Google Gemini AI services.
//!
//! ## Features
//!
//! - **Simple Interface**: Send text + attachments to Gemini AI
//! - **Type Safety**: Strong typing with compile-time error checking
//! - **Easy Integration**: Minimal external dependencies
//!
//! ## Quick Start
//!
//! ```rust,no_run
//! use gemini_sdk::{GeminiSDK, MessageRequest, Attachment, Agent};
//!
//! #[tokio::main]
//! async fn main() -> Result<(), Box<dyn std::error::Error>> {
//!     // Initialize SDK
//!     let mut sdk = GeminiSDK::new()?;
//!
//!     // Create an agent (optional)
//!     let agent = Agent::new("assistant", "Assistant", "You are a helpful assistant");
//!     sdk.add_agent(agent);
//!
//!     // Send a message with attachment
//!     let request = MessageRequest {
//!         text: "Analyze this image".to_string(),
//!         attachments: vec![Attachment::new("./image.jpg")],
//!         agent_id: Some("assistant".to_string()),
//!     };
//!
//!     let response = sdk.send_message(request).await?;
//!     println!("Response: {}", response.content);
//!
//!     Ok(())
//! }
//! ```

pub mod sdk;
pub mod agent;
pub mod attachment;
pub mod error;

// Re-export main types for convenience
pub use sdk::{GeminiSDK, MessageRequest, MessageResponse};
pub use agent::Agent;
pub use attachment::Attachment;
pub use error::{SDKError, Result};

/// SDK version
pub const VERSION: &str = env!("CARGO_PKG_VERSION");

/// Default configuration for the SDK
#[derive(Debug, Clone)]
pub struct GeminiConfig {
    pub base_url: String,
    pub bearer_token: String,
    pub timeout: u64,
    pub model_name: String,
    pub max_retries: u32,
    pub retry_delay: u64,
    pub temperature: f32,
    pub max_tokens: u32,
    pub cloudflare_project_id: String,
    pub cloudflare_gateway_id: String,
    pub google_project_id: String,
    pub regions: Vec<String>,
}

impl Default for GeminiConfig {
    fn default() -> Self {
        Self {
            base_url: "https://bowongai-dev--bowong-ai-video-gemini-fastapi-webapp.modal.run".to_string(),
            bearer_token: "bowong7777".to_string(),
            timeout: 120,
            model_name: "gemini-2.5-pro".to_string(),
            max_retries: 3,
            retry_delay: 2,
            temperature: 0.7,
            max_tokens: 64000,
            cloudflare_project_id: "67720b647ff2b55cf37ba3ef9e677083".to_string(),
            cloudflare_gateway_id: "bowong-dev".to_string(),
            google_project_id: "gen-lang-client-0413414134".to_string(),
            regions: vec![
                "us-central1".to_string(),
                "us-east1".to_string(),
                "europe-west1".to_string(),
            ],
        }
    }
}

impl GeminiConfig {
    /// Create configuration from environment variables
    pub fn from_env() -> Self {
        Self {
            base_url: std::env::var("GEMINI_BASE_URL")
                .unwrap_or_else(|_| Self::default().base_url),
            bearer_token: std::env::var("GEMINI_BEARER_TOKEN")
                .unwrap_or_else(|_| Self::default().bearer_token),
            timeout: std::env::var("GEMINI_TIMEOUT")
                .ok()
                .and_then(|s| s.parse().ok())
                .unwrap_or(Self::default().timeout),
            model_name: std::env::var("GEMINI_MODEL_NAME")
                .unwrap_or_else(|_| Self::default().model_name),
            max_retries: std::env::var("GEMINI_MAX_RETRIES")
                .ok()
                .and_then(|s| s.parse().ok())
                .unwrap_or(Self::default().max_retries),
            retry_delay: std::env::var("GEMINI_RETRY_DELAY")
                .ok()
                .and_then(|s| s.parse().ok())
                .unwrap_or(Self::default().retry_delay),
            temperature: std::env::var("GEMINI_TEMPERATURE")
                .ok()
                .and_then(|s| s.parse().ok())
                .unwrap_or(Self::default().temperature),
            max_tokens: std::env::var("GEMINI_MAX_TOKENS")
                .ok()
                .and_then(|s| s.parse().ok())
                .unwrap_or(Self::default().max_tokens),
            cloudflare_project_id: std::env::var("GEMINI_CLOUDFLARE_PROJECT_ID")
                .unwrap_or_else(|_| Self::default().cloudflare_project_id),
            cloudflare_gateway_id: std::env::var("GEMINI_CLOUDFLARE_GATEWAY_ID")
                .unwrap_or_else(|_| Self::default().cloudflare_gateway_id),
            google_project_id: std::env::var("GEMINI_GOOGLE_PROJECT_ID")
                .unwrap_or_else(|_| Self::default().google_project_id),
            regions: std::env::var("GEMINI_REGIONS")
                .ok()
                .map(|s| s.split(',').map(|s| s.trim().to_string()).collect())
                .unwrap_or_else(|| Self::default().regions),
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_config_default() {
        let config = GeminiConfig::default();
        assert!(!config.base_url.is_empty());
        assert!(!config.bearer_token.is_empty());
        assert!(config.timeout > 0);
        assert!(!config.model_name.is_empty());
        assert!(config.max_retries > 0);
        assert!(config.temperature >= 0.0 && config.temperature <= 2.0);
        assert!(config.max_tokens > 0);
        assert!(!config.regions.is_empty());
    }

    #[test]
    fn test_config_from_env() {
        // Test that from_env doesn't panic and returns valid config
        let config = GeminiConfig::from_env();
        assert!(!config.base_url.is_empty());
        assert!(!config.bearer_token.is_empty());
    }

    #[test]
    fn test_version() {
        assert!(!VERSION.is_empty());
    }
}
