//! Example: Configuration Loading Methods
//!
//! This example demonstrates all the different ways to configure the LastID
//! SDK:
//! - Auto-discovery from standard paths
//! - Loading from a specific TOML file (native only)
//! - Using the builder pattern
//! - Environment variable overrides
//! - Environment variable interpolation in TOML
//!
//! # Running
//!
//! ```bash
//! cargo run --example config_loading
//! ```

#[cfg(not(target_arch = "wasm32"))]
use std::path::Path;

use lastid_sdk::LastIDError;
use lastid_sdk::config::{CacheConfig, PollingConfig, RetryPolicy, SDKConfig};

fn main() -> Result<(), LastIDError> {
    println!("=== LastID SDK Configuration Examples ===\n");

    // Method 1: Auto-discovery
    println!("1. Auto-Discovery");
    println!("   Searches: ./lastid.toml, ~/.config/lastid/config.toml, /etc/lastid/config.toml");
    match SDKConfig::discover() {
        Ok(config) => {
            println!("   Found config with endpoint: {}", config.idp_endpoint);
        }
        Err(e) => {
            println!("   No config found: {}", e);
        }
    }
    println!();

    // Method 2: Load from specific file (native only - filesystem not available in WASM)
    #[cfg(not(target_arch = "wasm32"))]
    {
        println!("2. Load from File");
        let config_path = Path::new("examples/config/development.toml");
        if config_path.exists() {
            let config = SDKConfig::from_file(config_path)?;
            println!("   Loaded from: {}", config_path.display());
            println!("   IDP Endpoint: {}", config.idp_endpoint);
            println!("   Timeout: {}s", config.timeout_seconds);
        } else {
            println!("   File not found: {}", config_path.display());
        }
        println!();
    }
    #[cfg(target_arch = "wasm32")]
    {
        println!("2. Load from File");
        println!("   (Skipped: filesystem not available in WASM)");
        println!();
    }

    // Method 3: Builder pattern
    println!("3. Builder Pattern");
    let config = SDKConfig::builder()
        .idp_endpoint("https://human.lastid.co")
        .timeout_seconds(30)
        .polling_initial_interval_ms(2000)
        .polling_max_interval_ms(30000)
        .polling_max_duration_seconds(300)
        .retry_max_attempts(3)
        .retry_initial_delay_ms(1000)
        .cache_enabled(true)
        .cache_ttl_seconds(60)
        .build()?;

    println!("   Built config:");
    println!("   - IDP Endpoint: {}", config.idp_endpoint);
    println!("   - Timeout: {}s", config.timeout_seconds);
    println!(
        "   - Polling interval: {}ms - {}ms",
        config.polling.initial_interval_ms, config.polling.max_interval_ms
    );
    println!("   - Retry attempts: {}", config.retry.max_attempts);
    println!("   - Cache TTL: {}s", config.cache.ttl_seconds);
    println!();

    // Method 4: TOML string with environment variable interpolation
    println!("4. TOML with Environment Variable Interpolation");
    let toml_content = r#"
        idp_endpoint = "https://example.lastid.co"
        timeout_seconds = 45
    "#;
    let config = SDKConfig::from_toml(toml_content)?;
    println!("   Parsed TOML:");
    println!("   - IDP Endpoint: {}", config.idp_endpoint);
    println!("   - Timeout: {}s", config.timeout_seconds);
    println!();

    // Method 5: Sub-config builders
    println!("5. Sub-Configuration Objects");

    let polling = PollingConfig {
        initial_interval_ms: 1000,
        max_interval_ms: 10000,
        max_duration_seconds: 120,
        backoff_multiplier: 1.5,
    };
    println!("   PollingConfig:");
    println!("   - Initial: {}ms", polling.initial_interval_ms);
    println!("   - Max: {}ms", polling.max_interval_ms);
    println!("   - Duration: {}s", polling.max_duration_seconds);

    let retry = RetryPolicy {
        max_attempts: 5,
        initial_delay_ms: 500,
        max_delay_ms: 15000,
        backoff_base: 2.0,
        jitter_factor: 0.1, // 10% jitter to prevent thundering herd
    };
    println!("   RetryPolicy:");
    println!("   - Max attempts: {}", retry.max_attempts);
    println!("   - Initial delay: {}ms", retry.initial_delay_ms);

    let cache = CacheConfig {
        enabled: true,
        ttl_seconds: 120,
        max_entries: 500,
    };
    println!("   CacheConfig:");
    println!("   - Enabled: {}", cache.enabled);
    println!("   - TTL: {}s", cache.ttl_seconds);
    println!("   - Max entries: {}", cache.max_entries);
    println!();

    // Method 6: Config merging
    println!("6. Configuration Merging");
    let mut base_config = SDKConfig::builder()
        .idp_endpoint("https://base.lastid.co")
        .timeout_seconds(30)
        .build()?;

    let override_config = SDKConfig::builder()
        .idp_endpoint("https://override.lastid.co")
        .timeout_seconds(60)
        .build()?;

    println!(
        "   Base: {} ({}s)",
        base_config.idp_endpoint, base_config.timeout_seconds
    );
    println!(
        "   Override: {} ({}s)",
        override_config.idp_endpoint, override_config.timeout_seconds
    );

    base_config.merge(&override_config);
    println!(
        "   After merge: {} ({}s)",
        base_config.idp_endpoint, base_config.timeout_seconds
    );
    println!();

    // Method 7: Validation
    println!("7. Configuration Validation");
    let invalid_config = SDKConfig::default();
    match invalid_config.validate() {
        Ok(()) => println!("   Config is valid"),
        Err(e) => println!("   Validation error: {}", e),
    }

    let valid_config = SDKConfig::builder()
        .idp_endpoint("https://human.lastid.co")
        .build();
    match valid_config {
        Ok(_) => println!("   Valid config built successfully"),
        Err(e) => println!("   Build error: {}", e),
    }
    println!();

    // Method 8: Effective trust registry endpoint
    println!("8. Effective Trust Registry Endpoint");
    let config_no_registry = SDKConfig::builder()
        .idp_endpoint("https://human.lastid.co")
        .build()?;
    println!(
        "   Without explicit registry: {}",
        config_no_registry.effective_trust_registry_endpoint()
    );

    let config_with_registry = SDKConfig::builder()
        .idp_endpoint("https://human.lastid.co")
        .trust_registry_endpoint("https://custom.registry.co/v1/trust-registry")
        .build()?;
    println!(
        "   With explicit registry: {}",
        config_with_registry.effective_trust_registry_endpoint()
    );

    println!("\n=== Configuration Examples Complete ===");
    Ok(())
}
