//! Complete example showing all cfgmatic features.
//!
//! Run with:
//! ```bash
//! export MYAPP__APP_NAME="My Application"
//! export MYAPP__VERSION="1.0.0"
//! export MYAPP__SERVER_PORT=8080
//! export MYAPP__SERVER_TLS=true
//! export MYAPP__DATABASE_URL=postgres://localhost/mydb
//! export MYAPP__FEATURES_ENABLE_CACHE=true
//! cargo run --example complete
//! ```

use cfgmatic::{Config, ConfigLoader};
use serde::Deserialize;
use validator::Validate;

#[derive(Debug, Default, Deserialize, Config, Validate)]
#[config(prefix = "MYAPP")]
struct ApplicationConfig {
    #[config(default = "MyApp")]
    app_name: String,

    #[config(default = "0.1.0")]
    version: String,

    // Server settings
    #[validate(range(min = 1, max = 65535))]
    #[config(default = "8080")]
    server_port: u16,

    #[config(default = "127.0.0.1")]
    server_host: String,

    #[config(default = "false")]
    server_tls: bool,

    #[config(default = "30")]
    server_timeout_seconds: u64,

    // Database settings
    #[validate(url)]
    #[config(default = "postgres://localhost/postgres")]
    database_url: String,

    #[validate(range(min = 1, max = 100))]
    #[config(default = "10")]
    database_pool_size: u32,

    // Feature flags
    #[config(default = "true")]
    features_enable_cache: bool,

    #[config(default = "10485760")] // 10MB
    features_max_upload_size: usize,
}

fn main() {
    println!("Complete Configuration Example");
    println!();

    // Load configuration
    println!("Loading configuration from environment...");
    println!();

    let config = match ApplicationConfig::from_env() {
        Ok(cfg) => {
            println!("Configuration loaded successfully!");
            println!();
            cfg
        }
        Err(e) => {
            eprintln!("Failed to load configuration: {e}");
            std::process::exit(1);
        }
    };

    // Validate
    if let Err(e) = config.validate() {
        eprintln!("Validation failed:");
        for (field, errors) in &e.field_errors() {
            eprintln!("  - {field}: {errors:?}");
        }
        std::process::exit(1);
    }
    println!("Configuration validated!");
    println!();

    // Display configuration
    println!("Application Settings");
    println!();
    println!("  Name:    {}", config.app_name);
    println!("  Version: {}", config.version);
    println!();

    println!("Server Settings");
    println!();
    println!("  Port:    {}", config.server_port);
    println!("  Host:    {}", config.server_host);
    println!(
        "  TLS:     {}",
        if config.server_tls {
            "enabled"
        } else {
            "disabled"
        }
    );
    println!("  Timeout: {}s", config.server_timeout_seconds);
    println!();

    println!("Database Settings");
    println!();
    println!("  URL:       {}", config.database_url);
    println!("  Pool Size: {}", config.database_pool_size);
    println!();

    println!("Feature Flags");
    println!();
    println!(
        "  Cache:         {}",
        if config.features_enable_cache {
            "enabled"
        } else {
            "disabled"
        }
    );
    println!(
        "  Max Upload:    {} bytes ({} MB)",
        config.features_max_upload_size,
        config.features_max_upload_size / 1024 / 1024
    );
    println!();

    // Simulate application startup
    println!("Startup Simulation");
    println!();
    println!("Starting {} v{}...", config.app_name, config.version);
    println!();

    if config.server_tls {
        println!("  - TLS enabled");
        println!(
            "  - Listening on https://{}:{}",
            config.server_host, config.server_port
        );
    } else {
        println!("  - TLS disabled (not recommended for production)");
        println!(
            "  - Listening on http://{}:{}",
            config.server_host, config.server_port
        );
    }

    println!();
    println!("  - Connected to database");
    println!(
        "  - Connection pool: {} connections",
        config.database_pool_size
    );

    if config.features_enable_cache {
        println!("  - Cache enabled");
    }

    println!();
    println!("Application ready!");
}
