//! Custom Extensions Example
//!
//! Demonstrates the 10% extension pattern - when TOML configuration isn't
//! sufficient and you need custom client-side behavior beyond what
//! configuration can express.
#![allow(dead_code, unused_variables, unexpected_cfgs)]

use leptos::prelude::*;
use leptos::task::spawn_local;
use serde_json::json;
use wasm_bindgen::prelude::*;
use web_sys::{console, window};

/// Custom client hydration with extensions
///
/// This demonstrates extending the foundation's 90% configuration-driven
/// approach with 10% custom client functionality for complex use cases.
#[wasm_bindgen]
pub fn hydrate_with_custom_extensions() {
    console::log_1(&"🚀 CUSTOM EXTENSIONS EXAMPLE".into());
    console::log_1(&"============================".into());

    // Foundation provides 90% through TOML configuration
    let base_config = ClientConfig::from_generated_routes();

    // Add 10% custom extensions when configuration isn't sufficient
    let extended_config = base_config
        .with_custom_hydration_hooks(setup_custom_hydration_hooks())
        .with_realtime_features(setup_websocket_connections())
        .with_advanced_analytics(setup_client_analytics())
        .with_service_worker(setup_offline_capabilities());

    // Hydrate with both generated + custom functionality
    hydrate_with_config(extended_config);

    console::log_1(&"✨ Extended hydration complete with custom features!".into());
}

/// Custom hydration hooks for special client behavior
///
/// These hooks extend the normal hydration process with custom logic
/// that can't be expressed in TOML configuration.
fn setup_custom_hydration_hooks() -> HydrationOptions {
    HydrationOptions::builder()
        .with_pre_hydration_hook(|| {
            console::log_1(&"🔧 Pre-hydration: Setting up custom client state".into());

            // Custom client initialization that runs before hydration
            initialize_custom_client_storage();
            setup_performance_monitoring();
            register_custom_error_handlers();
        })
        .with_post_hydration_hook(|| {
            console::log_1(&"🎉 Post-hydration: Activating custom features".into());

            // Custom features that activate after hydration completes
            start_background_sync();
            initialize_keyboard_shortcuts();
            setup_client_side_caching();
        })
        .with_component_hydration_hook(|component_name: &str, element: &web_sys::Element| {
            console::log_1(&format!("💧 Hydrating component: {}", component_name).into());

            // Custom per-component hydration logic
            match component_name {
                "Dashboard" => enhance_dashboard_component(element),
                "Chart" => setup_realtime_chart_updates(element),
                "Form" => add_advanced_form_validation(element),
                _ => {} // Default hydration for other components
            }
        })
        .build()
}

/// WebSocket connections for real-time features
///
/// Example of extending the client with real-time capabilities
/// that go beyond what TOML configuration can express.
fn setup_websocket_connections() -> RealtimeConfig {
    RealtimeConfig::builder()
        .with_endpoint("wss://api.example.com/dashboard")
        .with_reconnection_policy(ReconnectionPolicy::ExponentialBackoff)
        .with_message_handler(|message: &str| {
            // Handle real-time messages from server
            console::log_1(&format!("📡 Realtime message: {}", message).into());

            // Update reactive signals based on server messages
            if let Ok(data) = serde_json::from_str::<RealtimeData>(message) {
                update_dashboard_metrics(data.metrics);
                update_notification_badge(data.notifications);
                update_user_presence(data.users_online);
            }
        })
        .with_connection_handler(|status: ConnectionStatus| match status {
            ConnectionStatus::Connected => {
                console::log_1(&"🟢 WebSocket connected".into());
                show_connection_status("Connected", "success");
            }
            ConnectionStatus::Disconnected => {
                console::log_1(&"🔴 WebSocket disconnected".into());
                show_connection_status("Disconnected", "error");
            }
            ConnectionStatus::Reconnecting => {
                console::log_1(&"🟡 WebSocket reconnecting...".into());
                show_connection_status("Reconnecting...", "warning");
            }
        })
        .build()
}

/// Advanced client-side analytics
///
/// Custom analytics that track user behavior beyond basic page views,
/// providing insights that standard configuration can't capture.
fn setup_client_analytics() -> AnalyticsConfig {
    AnalyticsConfig::builder()
        .with_user_journey_tracking(true)
        .with_performance_monitoring(true)
        .with_error_tracking(true)
        .with_custom_events(vec![
            // Track custom business events
            CustomEvent::new("dashboard_interaction").with_properties(
                |interaction: &Interaction| {
                    json!({
                        "component": interaction.component_name,
                        "action": interaction.action_type,
                        "timestamp": js_sys::Date::now(),
                        "user_session": get_session_id()
                    })
                },
            ),
            CustomEvent::new("feature_usage").with_properties(|usage: &FeatureUsage| {
                json!({
                    "feature_name": usage.feature,
                    "usage_duration": usage.duration_ms,
                    "success": usage.completed_successfully,
                    "browser": get_browser_info()
                })
            }),
        ])
        .with_heatmap_tracking(HeatmapConfig {
            track_clicks: true,
            track_scrolling: true,
            track_form_interactions: true,
            sample_rate: 0.1, // 10% of users
        })
        .build()
}

/// Service Worker setup for offline capabilities
///
/// Extends the client with Progressive Web App features
/// that provide offline functionality and background sync.
fn setup_offline_capabilities() -> ServiceWorkerConfig {
    ServiceWorkerConfig::builder()
        .with_cache_strategy(CacheStrategy::NetworkFirst)
        .with_offline_pages(vec![
            "/dashboard".to_string(),
            "/profile".to_string(),
            "/settings".to_string(),
        ])
        .with_background_sync(BackgroundSyncConfig {
            queue_name: "rustelo-sync".to_string(),
            retry_policy: RetryPolicy::ExponentialBackoff {
                initial_delay: 1000,
                max_delay: 30000,
                max_retries: 5,
            },
        })
        .with_push_notifications(PushNotificationConfig {
            vapid_public_key: get_vapid_public_key(),
            notification_handler: |notification| {
                // Handle push notifications when app is not active
                show_system_notification(&notification.title, &notification.body);
            },
        })
        .build()
}

/// Enhanced Dashboard Component
///
/// Example of extending a generated component with custom client-side features
/// that go beyond what the TOML configuration can provide.
#[component]
pub fn EnhancedDashboard() -> impl IntoView {
    console::log_1(&"🎨 Rendering Enhanced Dashboard with custom extensions".into());

    // Get the base component generated from TOML configuration (90%)
    let base_dashboard = get_generated_component("Dashboard");

    // Add custom client-side state for extensions (10%)
    // RwSignal uses SyncStorage — Send + Sync — required by IntoClass for class:
    // conditionals.
    let realtime_metrics: RwSignal<Vec<_>> = RwSignal::new(Vec::new());
    let notification_count = RwSignal::new(0i32);
    let is_offline = RwSignal::new(false);

    // Custom WebSocket effect for real-time data
    Effect::new(move |_| {
        spawn_local(async move {
            match establish_websocket_connection().await {
                Ok(mut ws_stream) => {
                    console::log_1(&"📡 Real-time connection established".into());

                    // Listen for real-time updates
                    while let Some(message) = ws_stream.next().await {
                        if let Ok(metrics) = parse_metrics_message(&message) {
                            realtime_metrics.set(metrics);
                        }
                    }
                }
                Err(e) => {
                    console::log_1(&format!("❌ WebSocket error: {}", e).into());
                }
            }
        });
    });

    // Custom offline detection
    Effect::new(move |_| {
        if let Some(win) = window() {
            let navigator = win.navigator();
            let is_online = navigator.on_line();
            is_offline.set(!is_online);
            if !is_online {
                console::log_1(&"🔌 Application is now offline - enabling offline features".into());
            }
        }
    });

    // Keyboard shortcuts for power users
    Effect::new(move |_| {
        let Some(win) = window() else { return };
        let Some(document) = win.document() else {
            return;
        };

        let closure = Closure::wrap(Box::new(move |event: web_sys::KeyboardEvent| {
            if event.ctrl_key() {
                match event.key().as_str() {
                    "d" => {
                        event.prevent_default();
                        console::log_1(&"⌨️ Keyboard shortcut: Focus dashboard".into());
                    }
                    "n" => {
                        event.prevent_default();
                        console::log_1(&"⌨️ Keyboard shortcut: New item".into());
                    }
                    "?" => {
                        event.prevent_default();
                        show_keyboard_shortcuts_modal();
                    }
                    _ => {}
                }
            }
        }) as Box<dyn FnMut(_)>);

        let _ =
            document.add_event_listener_with_callback("keydown", closure.as_ref().unchecked_ref());

        closure.forget();
    });

    view! {
        <div class="enhanced-dashboard">
            // Status indicators for custom features
            <div class="extension-status-bar">
                <div class="realtime-indicator" class:connected={move || !realtime_metrics.get().is_empty()}>
                    "📡 " {move || if realtime_metrics.get().is_empty() { "Connecting..." } else { "Live" }}
                </div>

                <div class="notification-badge" class:has-notifications={move || notification_count.get() > 0}>
                    "🔔 " {move || notification_count.get().to_string()}
                </div>

                <div class="offline-indicator" class:offline={is_offline}>
                    {move || if is_offline.get() { "🔌 Offline Mode" } else { "🌐 Online" }}
                </div>
            </div>

            // Base component from TOML configuration (90%)
            {base_dashboard}

            // Custom extensions (10%)
            <div class="custom-extensions">
                <RealtimeMetricsPanel metrics=realtime_metrics />
                <AdvancedCharting />
                <CustomNotificationCenter />
                <OfflineQueueStatus />
            </div>

            // Custom overlay features
            <KeyboardShortcutsModal />
            <OfflineDataSyncIndicator />
        </div>
    }
}

/// Real-time Metrics Panel
///
/// Custom component that displays live data from WebSocket connections
#[component]
fn RealtimeMetricsPanel(metrics: RwSignal<Vec<Metric>>) -> impl IntoView {
    view! {
        <div class="realtime-metrics-panel">
            <h3>"📊 Live Metrics"</h3>
            <div class="metrics-grid">
                {move || {
                    metrics.get().into_iter().map(|metric| {
                        let trend = metric.trend;
                        view! {
                            <div class="metric-card" data-metric-type=metric.metric_type>
                                <div class="metric-value">{metric.value}</div>
                                <div class="metric-label">{metric.label}</div>
                                <div class="metric-trend" class:positive={trend > 0.0} class:negative={trend < 0.0}>
                                    {format!("{:+.1}%", trend)}
                                </div>
                            </div>
                        }
                    }).collect_view()
                }}
            </div>
        </div>
    }
}

/// Advanced Charting Component
///
/// Custom charting with advanced interactivity
#[component]
fn AdvancedCharting() -> impl IntoView {
    let chart_data = RwSignal::new(Vec::<serde_json::Value>::new());
    let chart_type = RwSignal::new(ChartType::Line);

    // Custom chart initialization
    Effect::new(move |_| {
        spawn_local(async move {
            match load_advanced_chart_data().await {
                Ok(data) => chart_data.set(data),
                Err(e) => console::log_1(&format!("Chart loading error: {}", e).into()),
            }
        });
    });

    view! {
        <div class="advanced-chart-container">
            <div class="chart-controls">
                <select on:change=move |ev| {
                    let value = event_target_value(&ev);
                    chart_type.set(ChartType::from_str(&value));
                }>
                    <option value="line">"Line Chart"</option>
                    <option value="bar">"Bar Chart"</option>
                    <option value="scatter">"Scatter Plot"</option>
                    <option value="heatmap">"Heatmap"</option>
                </select>

                <button on:click=move |_| export_chart_data()>
                    "📊 Export Data"
                </button>

                <button on:click=move |_| toggle_chart_animation()>
                    "🎬 Toggle Animation"
                </button>
            </div>

            <canvas id="advanced-chart" class="chart-canvas"></canvas>

            // Custom chart interactions
            <div class="chart-interactions">
                <div class="zoom-controls">
                    <button on:click=move |_| zoom_in()>"🔍 +"</button>
                    <button on:click=move |_| zoom_out()>"🔍 -"</button>
                    <button on:click=move |_| reset_zoom()>"🔄 Reset"</button>
                </div>

                <div class="data-range-selector">
                    // Custom date range picker implementation
                </div>
            </div>
        </div>
    }
}

/// Custom build-time extension
///
/// Example of extending the build system to generate custom client code
/// beyond what the standard TOML configuration can express.
#[cfg(feature = "build-extensions")]
pub mod build_extensions {
    use rustelo_client::build::{BuildContext, ClientBuildExtension};

    pub struct DashboardExtension;

    impl ClientBuildExtension for DashboardExtension {
        fn name(&self) -> &str {
            "dashboard-realtime-extension"
        }

        fn generate_code(&self, context: &BuildContext) -> Result<String, String> {
            // Generate custom client code based on build context
            let custom_code = format!(
                r#"
                // Generated custom dashboard extensions
                #[wasm_bindgen]
                pub fn initialize_dashboard_extensions() {{
                    setup_websocket_connection("{}");
                    register_keyboard_shortcuts();
                    initialize_offline_storage();
                }}

                #[wasm_bindgen]
                pub fn get_dashboard_config() -> JsValue {{
                    let config = DashboardConfig {{
                        realtime_endpoint: "{}".to_string(),
                        analytics_enabled: true,
                        offline_capable: true,
                        keyboard_shortcuts: true,
                    }};

                    serde_wasm_bindgen::to_value(&config).unwrap()
                }}
            "#,
                context
                    .get_env("WEBSOCKET_ENDPOINT")
                    .unwrap_or("ws://localhost:8080"),
                context
                    .get_env("WEBSOCKET_ENDPOINT")
                    .unwrap_or("ws://localhost:8080")
            );

            Ok(custom_code)
        }

        fn dependencies(&self) -> Vec<String> {
            vec![
                "serde-wasm-bindgen".to_string(),
                "web-sys".to_string(),
                "wasm-bindgen-futures".to_string(),
            ]
        }

        fn features(&self) -> Vec<String> {
            vec![
                "realtime".to_string(),
                "offline".to_string(),
                "analytics".to_string(),
            ]
        }
    }

    pub struct CustomAnalyticsExtension;

    impl ClientBuildExtension for CustomAnalyticsExtension {
        fn name(&self) -> &str {
            "custom-analytics-extension"
        }

        fn generate_code(&self, context: &BuildContext) -> Result<String, String> {
            let analytics_config = context.get_config("analytics.toml")?;

            let custom_code = format!(
                r#"
                // Generated analytics integration
                #[wasm_bindgen]
                pub fn track_custom_event(event_name: &str, properties: JsValue) {{
                    let props: serde_json::Value = serde_wasm_bindgen::from_value(properties).unwrap();

                    // Send to custom analytics endpoint
                    spawn_local(async move {{
                        let _ = send_analytics_event("{}".to_string(), event_name, props).await;
                    }});
                }}

                #[wasm_bindgen]
                pub fn initialize_user_journey_tracking() {{
                    setup_page_view_tracking();
                    setup_user_interaction_tracking();
                    setup_performance_monitoring();
                }}
            "#,
                analytics_config
                    .get("endpoint")
                    .unwrap_or("https://analytics.example.com")
            );

            Ok(custom_code)
        }

        fn dependencies(&self) -> Vec<String> {
            vec!["serde_json".to_string(), "reqwasm".to_string()]
        }
    }
}

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

    use super::*;

    wasm_bindgen_test_configure!(run_in_browser);

    #[wasm_bindgen_test]
    async fn test_custom_hydration_extensions() {
        // Test that custom extensions work correctly
        let config = setup_custom_hydration_hooks();
        assert!(config.has_pre_hydration_hook());
        assert!(config.has_post_hydration_hook());
    }

    #[wasm_bindgen_test]
    async fn test_realtime_connection() {
        // Test WebSocket connection setup
        let realtime_config = setup_websocket_connections();
        assert_eq!(
            realtime_config.endpoint(),
            "wss://api.example.com/dashboard"
        );
    }

    #[wasm_bindgen_test]
    async fn test_enhanced_dashboard_rendering() {
        // Test that enhanced dashboard renders correctly
        let dashboard = EnhancedDashboard();
        // Add assertions for custom features
    }
}

/// Main function for demonstration
fn main() {
    println!("🎯 RUSTELO CLIENT CUSTOM EXTENSIONS EXAMPLE");
    println!("============================================");
    println!();

    println!("This example demonstrates extending Rustelo's configuration-driven approach");
    println!("with custom client functionality for the 10% of use cases that require it.");
    println!();

    println!("📋 Extension Patterns Demonstrated:");
    println!("   • Custom hydration hooks for special initialization");
    println!("   • Real-time features with WebSocket connections");
    println!("   • Advanced analytics beyond basic page tracking");
    println!("   • Offline capabilities with service workers");
    println!("   • Enhanced components with custom interactions");
    println!("   • Build-time extensions for code generation");
    println!();

    println!("🏗️ Architecture Balance:");
    println!("   • 90%: TOML configuration → generated client code");
    println!("   • 10%: Custom extensions for complex requirements");
    println!();

    println!("💡 Key Extension Points:");
    println!("   • Hydration hooks (pre/post hydration custom logic)");
    println!("   • Component enhancement (extend generated components)");
    println!("   • Build-time generation (custom code generation)");
    println!("   • State management (custom reactive patterns)");
    println!("   • Browser API integration (advanced web features)");
    println!();

    println!("⚖️ When to Use Extensions:");
    println!("   ✅ Real-time features (WebSockets, Server-Sent Events)");
    println!("   ✅ Complex client-side business logic");
    println!("   ✅ Advanced browser API integration");
    println!("   ✅ Custom performance optimization");
    println!("   ✅ Third-party service integration");
    println!();

    println!("❌ When NOT to Use Extensions:");
    println!("   ❌ Basic routing (use TOML configuration)");
    println!("   ❌ Standard components (use generated components)");
    println!("   ❌ Simple state management (use configuration)");
    println!("   ❌ Basic theming (use TOML theme configuration)");
    println!("   ❌ Standard i18n (use fluent files)");

    // Note: In real WASM environment, would call:
    // hydrate_with_custom_extensions();
}

// Supporting types and functions for the example
#[derive(Clone, Debug, serde::Deserialize)]
struct RealtimeData {
    metrics: Vec<Metric>,
    notifications: u32,
    users_online: u32,
}

#[derive(Clone, Debug, serde::Deserialize)]
struct Metric {
    metric_type: String,
    value: String,
    label: String,
    trend: f64,
}

#[derive(Clone, Debug)]
enum ChartType {
    Line,
    Bar,
    Scatter,
    Heatmap,
}

#[derive(Clone, Debug)]
enum ConnectionStatus {
    Connected,
    Disconnected,
    Reconnecting,
}

// Mock implementations for example purposes
impl ChartType {
    fn from_str(s: &str) -> Self {
        match s {
            "line" => ChartType::Line,
            "bar" => ChartType::Bar,
            "scatter" => ChartType::Scatter,
            "heatmap" => ChartType::Heatmap,
            _ => ChartType::Line,
        }
    }
}

// Mock function implementations
fn initialize_custom_client_storage() {}
fn setup_performance_monitoring() {}
fn register_custom_error_handlers() {}
fn start_background_sync() {}
fn initialize_keyboard_shortcuts() {}
fn setup_client_side_caching() {}
fn enhance_dashboard_component(_element: &web_sys::Element) {}
fn setup_realtime_chart_updates(_element: &web_sys::Element) {}
fn add_advanced_form_validation(_element: &web_sys::Element) {}
fn update_dashboard_metrics(_metrics: Vec<Metric>) {}
fn update_notification_badge(_count: u32) {}
fn update_user_presence(_count: u32) {}
fn show_connection_status(_status: &str, _level: &str) {}
fn get_session_id() -> String {
    "session_123".to_string()
}
fn get_browser_info() -> String {
    "Chrome".to_string()
}
fn get_vapid_public_key() -> String {
    "vapid_key".to_string()
}
fn show_system_notification(_title: &str, _body: &str) {}
async fn establish_websocket_connection() -> Result<MockWsStream, String> {
    Ok(MockWsStream)
}

struct MockWsStream;

impl MockWsStream {
    async fn next(&mut self) -> Option<String> {
        None
    }
}
fn parse_metrics_message(_message: &str) -> Result<Vec<Metric>, String> {
    Ok(vec![])
}
fn show_keyboard_shortcuts_modal() {}
async fn load_advanced_chart_data() -> Result<Vec<serde_json::Value>, String> {
    Ok(vec![])
}
fn export_chart_data() {}
fn toggle_chart_animation() {}
fn zoom_in() {}
fn zoom_out() {}
fn reset_zoom() {}
async fn send_analytics_event(
    _endpoint: String,
    _event: &str,
    _props: serde_json::Value,
) -> Result<(), String> {
    Ok(())
}
fn setup_page_view_tracking() {}
fn setup_user_interaction_tracking() {}

// Mock configuration builders
struct HydrationOptions;
struct RealtimeConfig;
struct AnalyticsConfig;
struct ServiceWorkerConfig;

impl HydrationOptions {
    fn builder() -> HydrationOptionsBuilder {
        HydrationOptionsBuilder
    }
}

impl RealtimeConfig {
    fn builder() -> RealtimeConfigBuilder {
        RealtimeConfigBuilder
    }
}

impl AnalyticsConfig {
    fn builder() -> AnalyticsConfigBuilder {
        AnalyticsConfigBuilder
    }
}

impl ServiceWorkerConfig {
    fn builder() -> ServiceWorkerConfigBuilder {
        ServiceWorkerConfigBuilder
    }
}

struct HydrationOptionsBuilder;
struct RealtimeConfigBuilder;
struct AnalyticsConfigBuilder;
struct ServiceWorkerConfigBuilder;

impl HydrationOptionsBuilder {
    fn with_pre_hydration_hook<F>(self, _f: F) -> Self
    where
        F: FnOnce(),
    {
        self
    }
    fn with_post_hydration_hook<F>(self, _f: F) -> Self
    where
        F: FnOnce(),
    {
        self
    }
    fn with_component_hydration_hook<F>(self, _f: F) -> Self
    where
        F: Fn(&str, &web_sys::Element),
    {
        self
    }
    fn build(self) -> HydrationOptions {
        HydrationOptions
    }
}

impl HydrationOptions {
    fn has_pre_hydration_hook(&self) -> bool {
        true
    }
    fn has_post_hydration_hook(&self) -> bool {
        true
    }
}

impl RealtimeConfigBuilder {
    fn with_endpoint(self, _endpoint: &str) -> Self {
        self
    }
    fn with_reconnection_policy(self, _policy: ReconnectionPolicy) -> Self {
        self
    }
    fn with_message_handler<F>(self, _f: F) -> Self
    where
        F: Fn(&str),
    {
        self
    }
    fn with_connection_handler<F>(self, _f: F) -> Self
    where
        F: Fn(ConnectionStatus),
    {
        self
    }
    fn build(self) -> RealtimeConfig {
        RealtimeConfig
    }
}

impl RealtimeConfig {
    fn endpoint(&self) -> &str {
        "wss://api.example.com/dashboard"
    }
}

#[derive(Clone)]
enum ReconnectionPolicy {
    ExponentialBackoff,
}

impl AnalyticsConfigBuilder {
    fn with_user_journey_tracking(self, _enabled: bool) -> Self {
        self
    }
    fn with_performance_monitoring(self, _enabled: bool) -> Self {
        self
    }
    fn with_error_tracking(self, _enabled: bool) -> Self {
        self
    }
    fn with_custom_events(self, _events: Vec<CustomEvent>) -> Self {
        self
    }
    fn with_heatmap_tracking(self, _config: HeatmapConfig) -> Self {
        self
    }
    fn build(self) -> AnalyticsConfig {
        AnalyticsConfig
    }
}

impl ServiceWorkerConfigBuilder {
    fn with_cache_strategy(self, _strategy: CacheStrategy) -> Self {
        self
    }
    fn with_offline_pages(self, _pages: Vec<String>) -> Self {
        self
    }
    fn with_background_sync(self, _config: BackgroundSyncConfig) -> Self {
        self
    }
    fn with_push_notifications(self, _config: PushNotificationConfig) -> Self {
        self
    }
    fn build(self) -> ServiceWorkerConfig {
        ServiceWorkerConfig
    }
}

struct CustomEvent {
    name: String,
}

impl CustomEvent {
    fn new(name: &str) -> Self {
        Self {
            name: name.to_string(),
        }
    }
    fn with_properties<T, F>(self, _f: F) -> Self
    where
        F: Fn(&T) -> serde_json::Value,
    {
        self
    }
}

struct FeatureUsage {
    feature: String,
    duration_ms: u64,
    completed_successfully: bool,
}

struct HeatmapConfig {
    track_clicks: bool,
    track_scrolling: bool,
    track_form_interactions: bool,
    sample_rate: f64,
}

enum CacheStrategy {
    NetworkFirst,
}

struct BackgroundSyncConfig {
    queue_name: String,
    retry_policy: RetryPolicy,
}

enum RetryPolicy {
    ExponentialBackoff {
        initial_delay: u64,
        max_delay: u64,
        max_retries: u32,
    },
}

struct PushNotificationConfig {
    vapid_public_key: String,
    notification_handler: fn(&Notification),
}

struct Interaction {
    component_name: String,
    action_type: String,
}

struct Notification {
    title: String,
    body: String,
}

// ── Example API stubs
// ────────────────────────────────────────────────────────── These represent
// the future 90/10 extension API surface for rustelo_client. Defined here
// locally so the example compiles without modifications to the crate.

struct ClientConfig;

impl ClientConfig {
    fn from_generated_routes() -> Self {
        Self
    }

    fn with_custom_hydration_hooks(self, _opts: HydrationOptions) -> Self {
        self
    }

    fn with_realtime_features(self, _cfg: RealtimeConfig) -> Self {
        self
    }

    fn with_advanced_analytics(self, _cfg: AnalyticsConfig) -> Self {
        self
    }

    fn with_service_worker(self, _cfg: ServiceWorkerConfig) -> Self {
        self
    }
}

fn hydrate_with_config(_config: ClientConfig) {}

fn get_generated_component(_name: &str) -> impl IntoView {
    view! { <div class="generated-component-placeholder"></div> }
}

// ── Missing component stubs
// ────────────────────────────────────────────────────

#[component]
fn CustomNotificationCenter() -> impl IntoView {
    view! { <div class="notification-center"></div> }
}

#[component]
fn OfflineQueueStatus() -> impl IntoView {
    view! { <div class="offline-queue-status"></div> }
}

#[component]
fn KeyboardShortcutsModal() -> impl IntoView {
    view! { <div class="keyboard-shortcuts-modal"></div> }
}

#[component]
fn OfflineDataSyncIndicator() -> impl IntoView {
    view! { <div class="offline-sync-indicator"></div> }
}
