//! Profile card example — demonstrates el-ui styling, layout, i18n, config, and secrets.
//!
//! This example shows what building with el-ui looks like:
//!
//! - Styling via semantic tokens and the StyleModifier trait
//! - Responsive layout: VStack/HStack that wrap automatically
//! - Localization via LocaleContext and t()/t_plural()
//! - Configuration from el.toml / env vars
//! - Secrets that never appear in logs

use std::collections::HashMap;

use el_config::prelude::*;
use el_i18n::prelude::*;
use el_layout::prelude::*;
use el_secrets::prelude::*;
use el_style::prelude::*;

// --- Domain model ---

struct UserProfile {
    handle: String,
    display_name: String,
    bio: String,
    follower_count: i64,
    following_count: i64,
    is_verified: bool,
    is_following: bool,
}

// --- Profile card component ---

/// A profile card component.
///
/// In a real el-ui app, this would be a .el component file compiled by
/// el-ui-compiler. Here we show the same patterns in pure Rust so the
/// example is self-contained and runnable.
struct ProfileCard {
    profile: UserProfile,
    theme: Theme,
    style: StyleSet,
    locale: LocaleContext,
}

impl StyleModifier for ProfileCard {
    fn style_mut(&mut self) -> &mut StyleSet {
        &mut self.style
    }
}

impl ProfileCard {
    fn new(profile: UserProfile, theme: Theme, locale: LocaleContext) -> Self {
        Self {
            profile,
            theme,
            style: StyleSet::default(),
            locale,
        }
    }

    /// "Render" the card — in a real app the backend converts this to
    /// native views. Here we produce a human-readable description.
    fn render(&self) -> String {
        let t = &self.locale;
        let theme = &self.theme;

        // --- Header HStack (avatar + name + verified badge) ---
        // HStack wraps automatically if the container is narrow (mobile-first)
        let header = HStack::new()
            .spacing(12)
            .alignment(VAlign::Center)
            .wrap(true);

        // --- Name text: Title style ---
        let name_style = theme.typography.resolve(&TextStyle::Title);

        // --- Body text: Body style ---
        let body_style = theme.typography.resolve(&TextStyle::Body);

        // --- Stats HStack (followers / following) ---
        let _stats_layout = HStack::new().spacing(24).wrap(true);

        // --- Follow button ---
        // VStack wraps children that don't fit, so this works on any screen width
        let _card_layout = VStack::new()
            .spacing(16)
            .alignment(HAlign::Leading)
            .wrap(true);

        // --- Localized strings ---
        let follow_label = if self.profile.is_following {
            t.t("profile.following")
        } else {
            t.t("profile.follow")
        };

        let followers_label =
            t.t_plural("profile.followers", self.profile.follower_count);
        let following_label =
            t.t_plural("profile.following_count", self.profile.following_count);

        // --- Color resolution ---
        let (bg_r, bg_g, bg_b, _) = theme.colors.resolve(&Color::Surface);
        let (text_r, text_g, text_b, _) = theme.colors.resolve(&Color::OnSurface);
        let (primary_r, primary_g, primary_b, _) = theme.colors.resolve(&Color::Primary);

        // --- Shadow ---
        let shadow_css = theme
            .shadows
            .resolve(&Shadow::Md)
            .map(|s| s.to_css())
            .unwrap_or_default();

        // --- Formatted stats (locale-aware numbers) ---
        let follower_count_fmt = format_integer(self.profile.follower_count, &self.locale.locale);
        let following_count_fmt = format_integer(self.profile.following_count, &self.locale.locale);

        // --- RTL layout signal ---
        let layout_direction = if self.locale.is_rtl() { "rtl" } else { "ltr" };

        // --- Build the output ---
        format!(
            r#"
┌─ ProfileCard ─────────────────────────────────────────────
│ Layout direction:  {}
│ Theme mode:        {:?}
│
│ [Card background: rgb({},{},{}), shadow: {}]
│
│ {} {} [Header HStack, spacing=12, wrap=true]
│   Avatar  [44×44pt, radius=Full — meets touch target]
│   {} [font: {}pt weight={}, color: rgb({},{},{})]
│   {} [verified badge]
│
│ {} [Body style, {}pt, color: rgb({},{},{})]
│
│ [Stats HStack, spacing=24, wrap=true]
│   {} {} — follower count (locale-formatted)
│   {} {} — following count
│
│ [Button: Primary variant]
│   {} [color: rgb({},{},{})]
│
│ [Card ends]
└────────────────────────────────────────────────────────────
"#,
            layout_direction,
            theme.mode,
            bg_r, bg_g, bg_b,
            shadow_css,
            header.spacing,
            if header.wrap { "wrap=true" } else { "wrap=false" },
            self.profile.display_name,
            name_style.size,
            name_style.weight.value(),
            text_r, text_g, text_b,
            if self.profile.is_verified { "✓" } else { "" },
            self.profile.bio,
            body_style.size,
            text_r, text_g, text_b,
            follower_count_fmt,
            followers_label,
            following_count_fmt,
            following_label,
            follow_label,
            primary_r, primary_g, primary_b,
        )
    }
}

// --- Application entry point ---

fn main() {
    // 1. Configuration — layered, typed
    let el_toml = r#"
[config]
app.name = "ProfileCard Example"
app.version = "1.0.0"
profile.max_bio_length = "160"

[env.development]
app.debug = "true"
"#;

    let toml_source = load_from_toml(el_toml, &Environment::Development)
        .expect("el.toml should be valid");

    let mut config = Config::new(Environment::Development);
    config.push_source(Box::new(toml_source));

    let app_name = config.get::<String>("app.name").unwrap_or_default();
    let app_version = config.get::<String>("app.version").unwrap_or_default();
    let max_bio: u32 = config.get_or("profile.max_bio_length", 160u32);
    let debug: bool = config.get_or("app.debug", false);

    println!("=== {} v{} ===", app_name, app_version);
    println!("Environment: {}", config.environment);
    println!("Debug mode:  {}", debug);
    println!("Max bio:     {} chars", max_bio);

    // 2. Secrets — loaded at startup, never logged
    let mut secret_src = InMemorySource::new();
    secret_src.insert("analytics.key", "ana_abc123xyz");

    let secrets = SecretsResolver::new()
        .source(Box::new(secret_src))
        .require("analytics.key")
        .resolve()
        .expect("required secrets must be present at startup");

    let analytics_key = secrets.require("analytics.key");
    // This will always print [REDACTED] — never the actual key
    println!("Analytics key: {} (safely [REDACTED] in logs)", analytics_key);
    // To actually use it:
    let _actual_key: &str = analytics_key.expose();

    // 3. Localization — English
    let mut en_bundle = LocaleBundle::new(Locale::en_us());
    en_bundle.insert("profile.follow", "Follow");
    en_bundle.insert("profile.following", "Following");
    let mut forms = HashMap::new();
    forms.insert("one".to_string(), "{n} Follower".to_string());
    forms.insert("other".to_string(), "{n} Followers".to_string());
    en_bundle.insert_plural("profile.followers", forms);
    let mut following_forms = HashMap::new();
    following_forms.insert("one".to_string(), "{n} Following".to_string());
    following_forms.insert("other".to_string(), "{n} Following".to_string());
    en_bundle.insert_plural("profile.following_count", following_forms);

    let en_ctx = LocaleContext::new(Locale::en_us(), en_bundle);

    // 4. Theme — light, system colors
    let light_theme = Theme::default_light();
    let dark_theme = Theme::default_dark();

    // 5. Profile data
    let profile = UserProfile {
        handle: "alice".to_string(),
        display_name: "Alice Chen".to_string(),
        bio: "Building beautiful things with el-ui. Rust enthusiast.".to_string(),
        follower_count: 12_483,
        following_count: 342,
        is_verified: true,
        is_following: false,
    };

    // 6. Render the card (light theme, English)
    println!("\n=== Light Theme, English ===");
    let card = ProfileCard::new(
        UserProfile {
            handle: profile.handle.clone(),
            display_name: profile.display_name.clone(),
            bio: profile.bio.clone(),
            follower_count: profile.follower_count,
            following_count: profile.following_count,
            is_verified: profile.is_verified,
            is_following: profile.is_following,
        },
        light_theme,
        en_ctx.clone(),
    );
    // Apply style modifiers — fluent, zero-cost at compile time
    let styled_card = card
        .padding(16)
        .background(Color::Surface)
        .radius(Radius::Lg)
        .shadow(Shadow::Md)
        .max_width(Dimension::Fixed(480));

    println!("{}", styled_card.render());

    // 7. Render with dark theme
    println!("=== Dark Theme, English ===");
    let card_dark = ProfileCard::new(
        UserProfile {
            handle: profile.handle.clone(),
            display_name: profile.display_name.clone(),
            bio: profile.bio.clone(),
            follower_count: 1, // test singular
            following_count: profile.following_count,
            is_verified: profile.is_verified,
            is_following: true,
        },
        dark_theme,
        en_ctx,
    );
    let styled_dark = card_dark
        .padding(16)
        .background(Color::Surface)
        .radius(Radius::Lg)
        .shadow(Shadow::Lg);

    println!("{}", styled_dark.render());

    // 8. Layout demonstration
    println!("=== Layout Engine Demo ===");

    // Grid: auto columns — picks 1, 2, 3... based on container width
    let grid = GridLayout::new().columns_auto(200.0).gap(16);
    for width in [300.0f32, 600.0, 900.0, 1200.0] {
        println!(
            "  Container {}px → {} columns",
            width,
            grid.active_columns(width)
        );
    }

    // Responsive value
    let cols: Responsive<u32> = Responsive::fixed(1).md(2).lg(3);
    println!("\n  Responsive columns:");
    for bp in [
        Breakpoint::Base,
        Breakpoint::Sm,
        Breakpoint::Md,
        Breakpoint::Lg,
        Breakpoint::Xl,
    ] {
        println!("    {:?}: {} col(s)", bp, cols.resolve(bp));
    }

    // Platform sizing
    let ios_sizing = PlatformSizing::for_platform(PlatformFamily::Ios);
    let android_sizing = PlatformSizing::for_platform(PlatformFamily::Android);
    println!("\n  Min touch targets:");
    println!("    iOS:     {}pt", ios_sizing.min_touch_target);
    println!("    Android: {}dp", android_sizing.min_touch_target);

    // 9. Locale formatting
    println!("\n=== Locale-Aware Formatting ===");
    let number = 1_234_567.89;
    for (tag, locale) in [
        ("en-US", Locale::en_us()),
        ("de-DE", Locale::new("de-DE")),
        ("fr-FR", Locale::fr_fr()),
        ("ja-JP", Locale::ja()),
    ] {
        let formatted = format_number(number, &locale, 2);
        let currency = format_currency(1234.56, &locale, "USD");
        println!("  {}: {}  |  {}", tag, formatted, currency);
    }

    // 10. RTL detection
    println!("\n=== RTL Detection ===");
    for tag in ["en-US", "ar-SA", "he", "fa", "zh-TW"] {
        let locale = Locale::new(tag);
        println!("  {}: {}", tag, if locale.is_rtl() { "RTL" } else { "LTR" });
    }

    println!("\nAll systems operational. el-ui is ready.");
}
