use rustelo_core_lib::{
    resolve_unified_route, generate_ssr_render_component,
    discover_available_languages, get_available_content_types,
    get_content_type_display_name, resolve_content_type_from_route,
    load_content_by_type, RouteComponent, RouteResolution,
};
use std::collections::HashMap;

// Generated from your TOML configuration files
// Mock generated code for example purposes
// In a real application, these would be generated by build.rs

pub fn get_all_routes() -> HashMap<String, String> {
    let mut routes = HashMap::new();
    routes.insert("/".to_string(), "HomePage".to_string());
    routes.insert("/blog".to_string(), "BlogListPage".to_string());
    routes
}

pub fn get_all_content_types() -> Vec<String> {
    vec!["blog".to_string(), "page".to_string()]
}

/// Example demonstrating Rustelo's Configuration-Driven Page Generation
///
/// Shows how TOML files generate Leptos components automatically,
/// following PAP: Configure, don't code.
#[tokio::main]
fn main() -> Result<(), Box<dyn std::error::Error>> {
    println!("🏗️ Rustelo Configuration-Driven Page Generation");
    println!("===============================================");
    println!();
    println!("This example shows how to add pages by editing TOML files");
    println!("instead of writing Rust component code manually.");
    println!();

    // 1. Show what gets discovered automatically
    demonstrate_automatic_discovery().await?;

    // 2. Show generated route resolution
    demonstrate_generated_routing()?;

    // 3. Show component generation from config
    demonstrate_component_generation()?;

    // 4. Show how to extend when needed
    demonstrate_extension_patterns()?;

    println!("\n✅ Configuration-driven architecture demonstration complete!");
    println!("💡 To add new pages: Edit site/config/routes/*.toml, run cargo build");
    Ok(())
}

async fn demonstrate_automatic_discovery() -> Result<(), Box<dyn std::error::Error>> {
    println!("📊 Automatic Discovery (No Manual Configuration)");
    println!("===============================================");

    // Languages discovered from content/locales/ directory structure
    let languages = discover_available_languages();
    println!("🌍 Languages auto-discovered:");
    for lang in languages {
        println!("   ✅ {} (from content/locales/{})", lang, lang);
    }

    // Content types discovered from content-kinds.toml
    let content_types = get_available_content_types();
    println!("\n📂 Content types from content-kinds.toml:");
    for content_type in &content_types {
        let display_name = get_content_type_display_name(content_type);
        println!("   ✅ {}: {}", content_type, display_name);
    }

    println!("\n💡 All discovered automatically - no manual registration needed!");
    Ok(())
}

fn demonstrate_generated_routing() -> Result<(), Box<dyn std::error::Error>> {
    println!("\n🧭 Generated Route Resolution");
    println!("=============================");

    // Test routes that would be resolved by generated RouteComponent enum
    let test_routes = vec![
        "/",
        "/about",
        "/services",
        "/en/contact",
        "/es/servicios",
        "/fr/a-propos",
        "/blog/my-first-post",
        "/services/web-development",
    ];

    println!("Route resolution using generated components:");
    for route in test_routes {
        let resolution = resolve_unified_route(route);
        if resolution.exists {
            if let Some(component) = &resolution.component {
                println!("   🔗 {} → {:?} (Page)", route, component);

                if let Some(title) = &resolution.metadata.title {
                    println!("      Title: {}", title);
                }
                if let Some(desc) = &resolution.metadata.description {
                    if !desc.is_empty() {
                        println!("      Description: {}", desc);
                    }
                }

                // Show that component HTML is generated automatically
                let rendered = generate_ssr_render_component(component, route, "en", &HashMap::new());
                println!("      Generated HTML: {} characters", rendered.len());
            } else {
                println!("   📄 {} → Dynamic Content", route);
            }
        } else {
            println!("   ❌ {} → Not Found", route);
        }
    }

    println!("\n💡 RouteComponent enum and resolution logic generated from TOML!");
    Ok(())
}

fn demonstrate_component_generation() -> Result<(), Box<dyn std::error::Error>> {
    println!("\n🏗️ Component Generation Process");
    println!("==============================");

    println!("How TOML configuration becomes Leptos components:");
    println!();

    println!("📝 Step 1: Edit site/config/routes/en.toml");
    println!("   [[routes]]");
    println!("   path = \"/about\"");
    println!("   component = \"About\"");
    println!("   title_key = \"about-title\"");
    println!("   description_key = \"about-description\"");
    println!("   menu_group = \"main\"");
    println!();

    println!("⚙️  Step 2: Build system generates Rust code");
    println!("   - RouteComponent::About variant added to enum");
    println!("   - AboutPage component generated with i18n");
    println!("   - Route resolution logic updated");
    println!();

    println!("🦀 Step 3: Generated Leptos component (in OUT_DIR)");
    println!("   #[component]");
    println!("   pub fn AboutPage(");
    println!("       #[prop(optional)] lang: String,");
    println!("       #[prop(optional)] params: HashMap<String, String>,");
    println!("   ) -> impl IntoView {{");
    println!("       let title = t_for_language(\"about-title\", &lang);");
    println!("       let description = t_for_language(\"about-description\", &lang);");
    println!("       ");
    println!("       view! {{");
    println!("           <div class=\"page-container about-page\">");
    println!("               <PageHeader title=title description=description />");
    println!("               <PageContent sections=generated_sections />");
    println!("           </div>");
    println!("       }}");
    println!("   }}");
    println!();

    println!("🔄 Step 4: Your app includes generated code");
    println!("   include!(concat!(env!(\"OUT_DIR\"), \"/generated_routes.rs\"));");
    println!("   include!(concat!(env!(\"OUT_DIR\"), \"/generated_components.rs\"));");
    println!();

    println!("💡 Result: New page available without writing Rust code!");

    Ok(())
}

fn demonstrate_extension_patterns() -> Result<(), Box<dyn std::error::Error>> {
    println!("\n🔧 Extension Patterns (When Configuration Isn't Enough)");
    println!("=====================================================");

    println!("🎯 The 90/10 Rule:");
    println!("   📋 90%: Configure in TOML → Generated automatically");
    println!("   🛠️  10%: Custom code → Manual generation in build.rs");
    println!();

    println!("❌ When you might need custom code:");
    println!("   • Complex interactive widgets");
    println!("   • Third-party API integrations");
    println!("   • Advanced state management");
    println!("   • Custom business logic");
    println!();

    println!("✅ How to extend (in build.rs):");
    println!("   ```rust");
    println!("   // build.rs");
    println!("   use rustelo_core_lib::build::{{generate_shared_resources, CustomTemplate}};");
    println!("   ");
    println!("   fn main() -> Result<(), Box<dyn std::error::Error>> {{");
    println!("       // Foundation generates 90% from TOML config");
    println!("       generate_shared_resources()?;");
    println!("       ");
    println!("       // Add 10% custom logic when config can't express needs");
    println!("       generate_custom_dashboard_component()?;");
    println!("       generate_payment_integration()?;");
    println!("       Ok(())");
    println!("   }}");
    println!("   ");
    println!("   fn generate_custom_dashboard_component() -> Result<(), std::io::Error> {{");
    println!("       let custom_component = r#\"");
    println!("           #[component]");
    println!("           pub fn CustomDashboard() -> impl IntoView {{");
    println!("               // Complex business logic that can't be configured");
    println!("               let (metrics, set_metrics) = create_signal(Vec::new());");
    println!("               ");
    println!("               create_effect(move |_| {{");
    println!("                   spawn_local(async move {{");
    println!("                       let data = fetch_complex_metrics().await;");
    println!("                       set_metrics.set(data);");
    println!("                   }});");
    println!("               }});");
    println!("               ");
    println!("               view! {{");
    println!("                   <div class=\\\"custom-dashboard\\\">");
    println!("                       <ComplexChart metrics=metrics />");
    println!("                       <RealTimeUpdates />");
    println!("                   </div>");
    println!("               }}");
    println!("           }}");
    println!("       \"#;");
    println!("       ");
    println!("       std::fs::write(");
    println!("           concat!(env!(\\\"OUT_DIR\\\"), \\\"/custom_dashboard.rs\\\"),");
    println!("           custom_component");
    println!("       )?;");
    println!("       Ok(())");
    println!("   }}");
    println!("   ```");
    println!();

    println!("🎊 Best Practices:");
    println!("   1. Start with TOML configuration");
    println!("   2. Only add custom code when configuration can't express your needs");
    println!("   3. Generate custom components in build.rs, don't write them directly");
    println!("   4. Include custom generated code alongside foundation generated code");
    println!("   5. Document why custom code was necessary");

    Ok(())
}

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

    #[test]
    fn test_automatic_discovery() {
        let languages = discover_available_languages();
        assert!(!languages.is_empty(), "Should discover at least one language");

        let content_types = get_available_content_types();
        // Content types might be empty in test environment, but function should work
        assert!(content_types.len() >= 0, "Content types discovery should work");
    }

    #[test]
    fn test_route_resolution_pattern() {
        // Test that route resolution follows the expected pattern
        let test_routes = vec!["/", "/about"];

        for route in test_routes {
            let result = resolve_unified_route(route, "en");
            // Should return Ok or Err, not panic
            assert!(result.is_ok() || result.is_err(), "Route resolution should handle all inputs gracefully");
        }
    }

    #[tokio::test]
    async fn test_content_type_resolution() {
        let test_routes = vec!["/blog/post", "/services/item"];

        for route in test_routes {
            let resolved = resolve_content_type_from_route(route);
            // Should return Some or None, not panic
            if let Some(content_type) = resolved {
                assert!(!content_type.is_empty(), "Content type should not be empty");
            }
        }
    }
}
