//! Server-side shell implementation with proper routing
//!
//! This module provides the SSR shell that uses the server's routing system
//! and renders actual page components instead of just route information.

use leptos::prelude::*;
use leptos_config::LeptosOptions;
use leptos_meta::provide_meta_context;
use rustelo_core_lib::routing::utils::detect_language_from_path;
use rustelo_core_lib::AssetMode;

/// The SSR shell for Leptos/Axum integration with server-side routing
pub fn shell_with_path(_options: LeptosOptions, path: Option<String>) -> impl IntoView {
    let current_path = path.unwrap_or_default();
    let language = detect_language_from_path(&current_path);

    // Get package name from environment or use default
    let package_name =
        std::env::var("LEPTOS_OUTPUT_NAME").unwrap_or_else(|_| "website".to_string());

    // Get page metadata from shared routing system
    let (mut title, description, keywords) = crate::routing::get_page_metadata(&current_path);

    // Ensure title is properly formatted for Leptos rendering
    if title.is_empty() {
        title = "Rustelo".to_string();
    }

    // Determine asset loading mode (source vs bundled)
    let asset_mode = AssetMode::default_for_environment();

    // Generate CSS includes based on asset mode
    let (css1, css2, css3, css4, css5, css6, css7) = if asset_mode.is_source() {
        // Source mode: individual CSS files for debugging
        (
            "/assets/styles/design-system.css",
            "/assets/styles/theme-default.css",
            "/assets/styles/website.css",
            "/assets/styles/custom.css",
            "/assets/styles/overrides/contact-tailwind-overrides.css",
            "/styles/highlight-github-dark.min.css",
            "/styles/highlightjs-copy.min.css",
        )
    } else {
        // Bundled mode: minified bundles for production
        (
            "/styles/site.min.css",
            "/styles/app.min.css",
            "/styles/enhancements.min.css",
            "/styles/highlightjs-copy.min.css",
            "",
            "",
            "",
        )
    };

    let css_links = view! {
        <link rel="stylesheet" href={css1} />
        <link rel="stylesheet" href={css2} />
        <link rel="stylesheet" href={css3} />
        {(!css4.is_empty()).then(|| view! { <link rel="stylesheet" href={css4} /> })}
        {(!css5.is_empty()).then(|| view! { <link rel="stylesheet" href={css5} /> })}
        {(!css6.is_empty()).then(|| view! { <link rel="stylesheet" href={css6} /> })}
        {(!css7.is_empty()).then(|| view! { <link rel="stylesheet" href={css7} /> })}
    };

    // Generate JS includes based on asset mode
    let (js1, js2, js3, js4) = if asset_mode.is_source() {
        // Source mode: individual JS files for debugging
        (
            "/js/highlight-bundle.min.js",
            "/assets/scripts/theme-init.js",
            "/assets/scripts/highlight-utils.js",
            "/js/tag-filters.js",
        )
    } else {
        // Bundled mode: minified scripts for production
        (
            "/js/highlight-bundle.min.js",
            "/js/theme-init.min.js",
            "/js/highlight-utils.min.js",
            "/js/tag-filters.js",
        )
    };

    let js_scripts = view! {
        <script src={js1}></script>
        <script src={js2}></script>
        <script src={js3}></script>
        <script src={js4}></script>
    };

    // Create the app shell for SSR with meta context inside the component
    let language_clone = language.clone();
    let current_path_clone = current_path.clone();
    let app = move || {
        // Provide meta context within the component context
        provide_meta_context();

        view! {
            <rustelo_components::theme::ThemeProvider>
                <div class="min-h-screen ds-bg-page flex flex-col">
                    <rustelo_components::navigation::navmenu::ssr::NavMenuSSR language=language_clone.clone() />
                    <main class="max-w-7xl mx-auto py-2 sm:ds-container flex-grow page-content fade-out">
                        {
                            // Use the shared routing system directly
                            crate::routing::render_page_content_ssr(&current_path_clone)
                        }
                    </main>
                    <rustelo_components::navigation::footer::ssr::FooterSSR language=language_clone.clone() />
                </div>
            </rustelo_components::theme::ThemeProvider>
        }
    };

    view! {
      <!DOCTYPE html>
      <html lang={language}>
        <head>
          <meta charset="utf-8"/>
          <meta name="viewport" content="width=device-width, initial-scale=1"/>
          <title inner_html={title.replace("<!>", "")}></title>
          <meta name="description" content={description} />
          <meta name="keywords" content={keywords} />
          // CSS includes based on asset mode (source vs bundled)
          {css_links}
          <link rel="modulepreload" href={format!("/pkg/{}.js", package_name)} />
          // JavaScript includes based on asset mode (source vs bundled)
          {js_scripts}
          <leptos_meta::MetaTags />
        </head>
        <body>
          {app()}
          <script id="leptos-hydration">
            {r#"
            // Initialize Leptos hydration resources
            globalThis.__RESOLVED_RESOURCES = {};
            globalThis.__INCOMPLETE_CHUNKS = [];
            window.__RESOLVED_RESOURCES = globalThis.__RESOLVED_RESOURCES;
            window.__INCOMPLETE_CHUNKS = globalThis.__INCOMPLETE_CHUNKS;
            "#}
          </script>
          <script type="module">
            {format!(r#"
            import init, {{ hydrate }} from '/pkg/{}.js';
            async function run() {{
              await init({{ module_or_path: '/pkg/{}.wasm' }});
              hydrate();
            }}
            run();
            "#, package_name, package_name)}
          </script>
        </body>
      </html>
    }
}

/// Legacy compatibility function
#[allow(dead_code)]
pub fn shell(options: LeptosOptions) -> impl IntoView {
    shell_with_path(options, None)
}
