//! Page scaffolding system for Rustelo
//!
//! This module implements safe page auto-scaffolding that:
//! - Only runs in development mode
//! - Never overwrites existing pages
//! - Automatically updates route configurations
//! - Generates initial boilerplate and FTL files for new pages

use std::env;
use std::path::Path;

use chrono::Utc;

/// Main entry point for page scaffolding
pub fn run_page_scaffolding(project_root: &Path) -> Result<usize, Box<dyn std::error::Error>> {
    // Only run scaffolding in development mode for safety
    if !is_development_mode() {
        println!("cargo:warning=Page scaffolding skipped - not in development mode");
        return Ok(0);
    }

    println!("cargo:warning=Running page scaffolding in development mode");

    // Use environment variables for paths with fallbacks
    let site_config_path =
        std::env::var("SITE_CONFIG_PATH").unwrap_or_else(|_| "site/config".to_string());
    let site_i18n_path =
        std::env::var("SITE_I18N_PATH").unwrap_or_else(|_| "site/i18n".to_string());

    let routes_dir = project_root.join(format!("{}/routes", site_config_path));
    let pages_src_dir = project_root.join("crates/pages/src");
    let locales_dir = project_root.join(format!("{}/locales", site_i18n_path));

    if !routes_dir.exists() {
        return Ok(0); // No routes to process
    }

    let mut total_changes = 0;

    // Process all .toml files in routes directory
    for entry in std::fs::read_dir(&routes_dir)? {
        let entry = entry?;
        let path = entry.path();

        if path.extension().and_then(|s| s.to_str()) == Some("toml") {
            let changes = process_route_file(&path, &pages_src_dir, &locales_dir)?;
            total_changes += changes;
        }
    }

    Ok(total_changes)
}

/// Check if we're running in development mode
fn is_development_mode() -> bool {
    // Multiple checks for safety - we only want to scaffold in development
    let env_check = env::var("ENVIRONMENT")
        .map(|e| e == "development" || e == "dev")
        .unwrap_or(false);

    let profile_check = env::var("PROFILE").map(|p| p == "debug").unwrap_or(false);

    // Check if we're in a debug build
    let cargo_check = cfg!(debug_assertions);

    // Also check for common development indicators
    let has_env_file = Path::new(".env").exists() || Path::new("../../.env").exists();

    env_check || profile_check || cargo_check || has_env_file
}

/// Process a single route configuration file
fn process_route_file(
    route_file: &Path,
    pages_src_dir: &Path,
    locales_dir: &Path,
) -> Result<usize, Box<dyn std::error::Error>> {
    use std::fs;

    let content = fs::read_to_string(route_file)?;
    let mut config: toml::Value = toml::from_str(&content)?;
    let mut changes = 0;
    let mut config_changed = false;

    if let Some(routes) = config.get_mut("routes").and_then(|v| v.as_array_mut()) {
        for route_value in routes {
            if let Some(route) = route_value.as_table_mut() {
                let component = route
                    .get("component")
                    .and_then(|v| v.as_str())
                    .unwrap_or_default()
                    .to_string(); // Clone the string to avoid borrowing issues

                if component.is_empty() {
                    continue;
                }

                let module_name = component_to_module_name(&component);
                let page_exists = check_page_exists(pages_src_dir, &module_name);

                if page_exists {
                    // Page exists - update route configuration to reflect reality
                    if update_existing_page_flags(route) {
                        config_changed = true;
                        println!(
                            "cargo:warning=Page {} exists - disabled generation flags",
                            component
                        );
                    }
                } else {
                    // Page doesn't exist - check if we should scaffold it
                    let should_scaffold = route
                        .get("auto_scaffold")
                        .and_then(|v| v.as_bool())
                        .unwrap_or(false);

                    if should_scaffold {
                        scaffold_new_page(pages_src_dir, locales_dir, route, &module_name)?;

                        // Update route configuration after successful scaffolding
                        route.insert("auto_scaffold".to_string(), toml::Value::Boolean(false));
                        route.insert(
                            "generate_boilerplate_only".to_string(),
                            toml::Value::Boolean(false),
                        );
                        route.insert(
                            "replace_existing_boilerplate".to_string(),
                            toml::Value::Boolean(false),
                        );

                        config_changed = true;
                        changes += 1;
                        println!("cargo:warning=Scaffolded new page: {}", component);
                    }
                }
            }
        }
    }

    // Write back the updated configuration if it changed
    if config_changed {
        let updated_content = format!(
            "# Auto-updated by build system at {}\n# Existing pages have priority over generation \
             flags\n\n{}",
            Utc::now().format("%Y-%m-%d %H:%M:%S UTC"),
            toml::to_string_pretty(&config)?
        );
        fs::write(route_file, updated_content)?;
        println!(
            "cargo:warning=Updated route configuration: {}",
            route_file.display()
        );
    }

    Ok(changes)
}

/// Convert component name to module name (PascalCase -> snake_case)
fn component_to_module_name(component: &str) -> String {
    let mut result = String::new();
    let mut chars = component.chars();

    if let Some(first) = chars.next() {
        result.push(first.to_ascii_lowercase());
    }

    for ch in chars {
        if ch.is_ascii_uppercase() {
            result.push('_');
            result.push(ch.to_ascii_lowercase());
        } else {
            result.push(ch);
        }
    }

    result
}

/// Check if a page exists in the pages source directory
fn check_page_exists(pages_src_dir: &Path, module_name: &str) -> bool {
    let page_path = pages_src_dir.join(module_name).join("mod.rs");
    page_path.exists()
}

/// Update flags for existing pages to prevent overwriting
fn update_existing_page_flags(route: &mut toml::value::Table) -> bool {
    let mut changed = false;

    // Disable auto-scaffolding for existing pages
    if route
        .get("auto_scaffold")
        .and_then(|v| v.as_bool())
        .unwrap_or(false)
    {
        route.insert("auto_scaffold".to_string(), toml::Value::Boolean(false));
        changed = true;
    }

    // Disable boilerplate generation for existing pages
    if route
        .get("generate_boilerplate_only")
        .and_then(|v| v.as_bool())
        .unwrap_or(false)
    {
        route.insert(
            "generate_boilerplate_only".to_string(),
            toml::Value::Boolean(false),
        );
        changed = true;
    }

    // Disable replacement for existing pages
    if route
        .get("replace_existing_boilerplate")
        .and_then(|v| v.as_bool())
        .unwrap_or(false)
    {
        route.insert(
            "replace_existing_boilerplate".to_string(),
            toml::Value::Boolean(false),
        );
        changed = true;
    }

    changed
}

/// Scaffold a new page with boilerplate code
fn scaffold_new_page(
    pages_src_dir: &Path,
    locales_dir: &Path,
    route: &toml::value::Table,
    module_name: &str,
) -> Result<(), Box<dyn std::error::Error>> {
    use std::fs;

    let component = route
        .get("component")
        .and_then(|v| v.as_str())
        .ok_or("Missing component name")?;

    let template_type = route
        .get("scaffold_template")
        .and_then(|v| v.as_str())
        .unwrap_or("basic_page");

    let i18n_patterns = route
        .get("i18n_patterns")
        .and_then(|v| v.as_array())
        .map(|arr| {
            arr.iter()
                .filter_map(|v| v.as_str())
                .map(|s| s.to_string())
                .collect::<Vec<_>>()
        })
        .unwrap_or_else(|| vec![format!("{}-", module_name.replace('_', "-"))]);

    // Create page directory
    let page_dir = pages_src_dir.join(module_name);
    fs::create_dir_all(&page_dir)?;

    // Generate mod.rs
    let mod_content = generate_mod_rs(component, &i18n_patterns);
    fs::write(page_dir.join("mod.rs"), mod_content)?;

    // Generate unified.rs
    let unified_content =
        generate_unified_rs(component, module_name, template_type, &i18n_patterns);
    fs::write(page_dir.join("unified.rs"), unified_content)?;

    // Generate FTL files for all supported languages
    generate_ftl_files(locales_dir, module_name, &i18n_patterns, template_type)?;

    Ok(())
}

/// Generate mod.rs content for scaffolded page
fn generate_mod_rs(component: &str, patterns: &[String]) -> String {
    let patterns_str = patterns
        .iter()
        .map(|p| format!("\"{}\"", p))
        .collect::<Vec<_>>()
        .join(", ");

    format!(
        r#"//! Auto-generated scaffold for {} page
//! Generated at: {}
//! TODO: Customize this implementation as needed

use rustelo_core_lib::generate_page;

pub mod unified;
pub use unified::*;

generate_page! {{
    name: {},
    patterns: [{}],
}}
"#,
        component,
        Utc::now().format("%Y-%m-%d %H:%M:%S UTC"),
        component,
        patterns_str
    )
}

/// Generate unified.rs content for scaffolded page
fn generate_unified_rs(
    component: &str,
    module_name: &str,
    template_type: &str,
    patterns: &[String],
) -> String {
    let primary_pattern = patterns
        .first()
        .map(|p| p.trim_end_matches('-'))
        .unwrap_or(module_name);

    let content = match template_type {
        "hero_page" => generate_hero_page_content(primary_pattern),
        "form_page" => generate_form_page_content(primary_pattern),
        "content_list" => generate_content_list_content(primary_pattern),
        _ => generate_basic_page_content(primary_pattern),
    };

    format!(
        r#"//! Auto-generated scaffold for {} page
//! Generated at: {}
//! TODO: Replace this implementation with your actual page logic

use leptos::prelude::*;
use rustelo_core_types::i18n::create_content_provider;

#[component]
pub fn Unified{}Page(
    #[prop(optional)] lang_content: Option<std::collections::HashMap<String, String>>,
) -> impl IntoView {{
    let content = create_content_provider(lang_content);

{}
}}
"#,
        component,
        Utc::now().format("%Y-%m-%d %H:%M:%S UTC"),
        component,
        content
    )
}

/// Generate basic page content template
fn generate_basic_page_content(prefix: &str) -> String {
    format!(
        r#"    view! {{
        <div class="ds-bg-page">
            <section class="relative py-ds-4 ds-container ds-rounded-lg ds-shadow-lg">
                <div class="mx-auto max-w-4xl text-center">
                    <h1 class="text-balance text-4xl font-bold tracking-tight ds-text sm:text-6xl mb-ds-4">
                        {{content.t("{}-title")}}
                    </h1>
                    <rustelo_components_leptos::HtmlContent
                        content={{content.t("{}-description")}}
                        class="mt-ds-6 ds-body ds-text-secondary max-w-2xl mx-auto".to_string()
                    />
                </div>

                <div class="mt-8 p-4 border-2 border-dashed border-yellow-500 bg-yellow-50 dark:bg-yellow-900/20 rounded">
                    <p class="text-yellow-700 dark:text-yellow-400 text-center">
                        "⚠️ This is an auto-generated scaffold. Please implement your actual page content."
                    </p>
                </div>
            </section>
        </div>
    }}"#,
        prefix, prefix
    )
}

/// Generate hero page content template
fn generate_hero_page_content(prefix: &str) -> String {
    format!(
        r#"    view! {{
        <div class="ds-bg-page">
            <section class="relative py-ds-4 ds-container ds-rounded-lg ds-shadow-lg">
                <div class="mx-auto max-w-4xl text-center">
                    <h1 class="text-balance text-4xl font-bold tracking-tight ds-text sm:text-6xl mb-ds-4">
                        {{content.t("{}-hero-title")}}
                    </h1>
                    <rustelo_components_leptos::HtmlContent
                        content={{content.t("{}-hero-subtitle")}}
                        class="mt-ds-6 ds-body ds-text-secondary max-w-2xl mx-auto".to_string()
                    />

                    <div class="flex flex-col sm:flex-row gap-4 justify-center mt-8">
                        <a href={{content.t("{}-cta-primary-url")}} class="no-underline ds-btn-primary">
                            {{content.t("{}-cta-primary-text")}}
                        </a>
                        <a href={{content.t("{}-cta-secondary-url")}} class="no-underline ds-btn-secondary">
                            {{content.t("{}-cta-secondary-text")}}
                        </a>
                    </div>
                </div>

                <div class="mt-8 p-4 border-2 border-dashed border-yellow-500 bg-yellow-50 dark:bg-yellow-900/20 rounded">
                    <p class="text-yellow-700 dark:text-yellow-400 text-center">
                        "⚠️ This is an auto-generated hero page scaffold. Please implement your actual content."
                    </p>
                </div>
            </section>
        </div>
    }}"#,
        prefix, prefix, prefix, prefix, prefix, prefix
    )
}

/// Generate form page content template
fn generate_form_page_content(prefix: &str) -> String {
    format!(
        r#"    view! {{
        <div class="ds-bg-page">
            <section class="relative py-ds-4 ds-container ds-rounded-lg ds-shadow-lg">
                <div class="mx-auto max-w-2xl">
                    <div class="text-center mb-8">
                        <h1 class="text-3xl font-bold ds-text mb-4">
                            {{content.t("{}-title")}}
                        </h1>
                        <rustelo_components_leptos::HtmlContent
                            content={{content.t("{}-description")}}
                            class="ds-text-secondary".to_string()
                        />
                    </div>

                    <div class="ds-bg p-6 ds-rounded-lg ds-shadow-sm">
                        <form class="space-y-6">
                            <div class="p-4 border-2 border-dashed border-blue-500 bg-blue-50 dark:bg-blue-900/20 rounded">
                                <p class="text-blue-700 dark:text-blue-400 text-center">
                                    "📝 TODO: Implement your form fields here"
                                </p>
                            </div>
                        </form>
                    </div>
                </div>
            </section>
        </div>
    }}"#,
        prefix, prefix
    )
}

/// Generate content list page template
fn generate_content_list_content(prefix: &str) -> String {
    format!(
        r#"    view! {{
        <div class="ds-bg-page">
            <section class="relative py-ds-4 ds-container">
                <div class="text-center mb-8">
                    <h1 class="text-3xl font-bold ds-text mb-4">
                        {{content.t("{}-title")}}
                    </h1>
                    <rustelo_components_leptos::HtmlContent
                        content={{content.t("{}-description")}}
                        class="ds-text-secondary max-w-2xl mx-auto".to_string()
                    />
                </div>

                <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
                    <div class="ds-bg p-6 ds-rounded-lg ds-shadow-sm">
                        <div class="p-4 border-2 border-dashed border-green-500 bg-green-50 dark:bg-green-900/20 rounded">
                            <p class="text-green-700 dark:text-green-400 text-center">
                                "📋 TODO: Implement your content list here"
                            </p>
                        </div>
                    </div>
                </div>
            </section>
        </div>
    }}"#,
        prefix, prefix
    )
}

/// Generate FTL files for all supported languages
fn generate_ftl_files(
    locales_dir: &Path,
    module_name: &str,
    patterns: &[String],
    template_type: &str,
) -> Result<(), Box<dyn std::error::Error>> {
    use std::fs;

    // Get supported languages by scanning locale directories
    let languages = if locales_dir.exists() {
        std::fs::read_dir(locales_dir)?
            .filter_map(|entry| {
                let entry = entry.ok()?;
                let path = entry.path();
                if path.is_dir() {
                    path.file_name()?.to_str().map(|s| s.to_string())
                } else {
                    None
                }
            })
            .collect::<Vec<_>>()
    } else {
        vec!["en".to_string(), "es".to_string()] // Default languages
    };

    let file_name = module_name.replace('_', "-");
    let primary_pattern = patterns
        .first()
        .map(|p| p.trim_end_matches('-'))
        .unwrap_or(&file_name);

    for lang in &languages {
        let pages_dir = locales_dir.join(lang).join("pages");
        fs::create_dir_all(&pages_dir)?;

        let ftl_content = generate_ftl_content(primary_pattern, template_type, lang);
        let ftl_path = pages_dir.join(format!("{}.ftl", file_name));

        if !ftl_path.exists() {
            fs::write(&ftl_path, ftl_content)?;
            println!("cargo:warning=Created FTL file: {}", ftl_path.display());
        }
    }

    Ok(())
}

/// Generate FTL content based on template type
fn generate_ftl_content(prefix: &str, template_type: &str, language: &str) -> String {
    let lang_suffix = match language {
        "es" => " (ES)",
        "en" => "",
        _ => &format!(" ({})", language.to_uppercase()),
    };

    let timestamp = Utc::now().format("%Y-%m-%d %H:%M:%S UTC");

    let title_case = prefix
        .split('-')
        .map(|word| {
            let mut chars = word.chars();
            match chars.next() {
                None => String::new(),
                Some(first) => first.to_uppercase().collect::<String>() + chars.as_str(),
            }
        })
        .collect::<Vec<_>>()
        .join(" ");

    match template_type {
        "hero_page" => format!(
            r#"# Auto-generated scaffold for {} page - {}
# TODO: Replace with actual content
# Generated: {}

{}-hero-title = {}{}
{}-hero-subtitle = This hero page was auto-scaffolded. Please add your content here.
{}-cta-primary-text = Get Started
{}-cta-primary-url = #
{}-cta-secondary-text = Learn More
{}-cta-secondary-url = #

# TODO: Add more translation keys as needed
"#,
            title_case,
            language,
            timestamp,
            prefix,
            title_case,
            lang_suffix,
            prefix,
            prefix,
            prefix,
            prefix,
            prefix
        ),

        "form_page" => format!(
            r#"# Auto-generated scaffold for {} page - {}
# TODO: Replace with actual content
# Generated: {}

{}-title = {} Form{}
{}-description = This form page was auto-scaffolded. Please add your form implementation here.

# TODO: Add form field labels and validation messages
# {}-field-name = Name
# {}-field-email = Email
# {}-field-message = Message
# {}-button-submit = Submit
# {}-success-message = Thank you for your submission!
# {}-error-message = Please correct the errors below.
"#,
            title_case,
            language,
            timestamp,
            prefix,
            title_case,
            lang_suffix,
            prefix,
            prefix,
            prefix,
            prefix,
            prefix,
            prefix,
            prefix
        ),

        "content_list" => format!(
            r#"# Auto-generated scaffold for {} page - {}
# TODO: Replace with actual content
# Generated: {}

{}-title = {}{}
{}-description = This content list page was auto-scaffolded. Please add your content listing here.
{}-no-items-message = No items found.
{}-load-more = Load More
{}-showing-items = Showing {{$count}} of {{$total}} items

# TODO: Add more translation keys as needed
"#,
            title_case,
            language,
            timestamp,
            prefix,
            title_case,
            lang_suffix,
            prefix,
            prefix,
            prefix,
            prefix
        ),

        _ => format!(
            r#"# Auto-generated scaffold for {} page - {}
# TODO: Replace with actual content
# Generated: {}

{}-title = {}{}
{}-description = This page was auto-scaffolded. Please add your content here.

# TODO: Add more translation keys as needed
# {}-content-title =
# {}-content-description =
"#,
            title_case,
            language,
            timestamp,
            prefix,
            title_case,
            lang_suffix,
            prefix,
            prefix,
            prefix
        ),
    }
}
