//! Category and tag validation functionality
//!
//! Validates categories and tags across languages for routing

use std::path::Path;

use crate::categories::cache::META_CACHE;
use crate::categories::filter::{get_all_categories_unfiltered, get_all_tags_unfiltered};

/// Check if a category is valid for a given content type by checking all
/// available languages This is language-agnostic and loads categories
/// dynamically from meta.toml files
pub fn is_valid_category(content_type: &str, category: &str) -> bool {
    #[cfg(not(target_arch = "wasm32"))]
    {
        tracing::debug!(
            "🏷️ CATEGORY: Validating category '{}' for content_type '{}'",
            category,
            content_type
        );

        // Server-side: Use meta.toml files for comprehensive validation
        let supported_languages = crate::config::get_supported_languages();
        let languages: Vec<&str> = supported_languages.iter().map(|s| s.as_str()).collect();

        tracing::debug!("🏷️ CATEGORY: Checking against languages: {:?}", languages);

        for language in &languages {
            let categories = get_all_categories_unfiltered(content_type, language);
            let tags = get_all_tags_unfiltered(content_type, language);

            tracing::debug!(
                "🏷️ CATEGORY: Language '{}' - categories: {:?}, tags: {:?}",
                language,
                categories.keys().collect::<Vec<_>>(),
                tags.keys().collect::<Vec<_>>()
            );

            // Check exact match in categories
            if categories.contains_key(category) {
                tracing::debug!(
                    "✅ CATEGORY: Found exact match in categories for '{}'",
                    category
                );
                return true;
            }

            // Check exact match in tags
            if tags.contains_key(category) {
                tracing::debug!("✅ CATEGORY: Found exact match in tags for '{}'", category);
                return true;
            }

            // Check case-insensitive match in categories
            for category_key in categories.keys() {
                if category_key.to_lowercase() == category.to_lowercase() {
                    tracing::debug!(
                        "✅ CATEGORY: Found case-insensitive match in categories: '{}' matches \
                         '{}'",
                        category_key,
                        category
                    );
                    return true;
                }
            }

            // Check case-insensitive match in tags
            for tag_key in tags.keys() {
                if tag_key.to_lowercase() == category.to_lowercase() {
                    tracing::debug!(
                        "✅ CATEGORY: Found case-insensitive match in tags: '{}' matches '{}'",
                        tag_key,
                        category
                    );
                    return true;
                }
            }
        }

        tracing::debug!(
            "❌ CATEGORY: No match found for category '{}' in content_type '{}'",
            category,
            content_type
        );
        false
    }

    #[cfg(target_arch = "wasm32")]
    {
        // Client-side: Use pre-loaded meta configurations to ensure routing consistency
        // This ensures hydration compatibility by using the same validation as server
        is_valid_category_wasm_sync(content_type, category)
    }
}

/// WASM-compatible synchronous category validation using preloaded meta data
/// This provides the same validation logic as server but without async loading
/// Fully content-agnostic - works with any content type through configuration
#[cfg(target_arch = "wasm32")]
fn is_valid_category_wasm_sync(content_type: &str, category: &str) -> bool {
    use crate::config::get_supported_languages;

    web_sys::console::log_1(
        &format!(
            "🏷️ WASM: Validating category '{}' for content_type '{}'",
            category, content_type
        )
        .into(),
    );

    let supported_languages = get_supported_languages();
    web_sys::console::log_1(
        &format!("🏷️ WASM: Supported languages: {:?}", supported_languages).into(),
    );

    // Check if the content type exists in the generated registry
    let content_registry = crate::create_content_kind_registry();

    // Debug: Show what's actually in the registry
    let registry_keys: Vec<String> = content_registry.kinds.keys().cloned().collect();
    web_sys::console::log_1(
        &format!(
            "🏷️ WASM: Available content types in registry: {:?}",
            registry_keys
        )
        .into(),
    );

    if content_registry.kinds.get(content_type).is_none() {
        web_sys::console::log_1(
            &format!(
                "🏷️ WASM: Content type '{}' not found in registry, using permissive validation",
                content_type
            )
            .into(),
        );
        // Return true anyway to prevent hydration mismatch
        return true;
    }

    web_sys::console::log_1(
        &format!("🏷️ WASM: Content type '{}' found in registry", content_type).into(),
    );

    // Try to use cached meta configurations
    for language in supported_languages.iter() {
        // Check if we have cached meta config (from previous successful loads)
        if let Ok(cache) = META_CACHE.read() {
            let cache_key = format!("{content_type}:{language}");
            if let Some(meta_config) = cache.get(&cache_key) {
                // Check exact match in categories
                if meta_config.categories_emojis.contains_key(category) {
                    tracing::debug!(
                        "WASM: Found exact category match '{}' for {}/{}",
                        category,
                        content_type,
                        language
                    );
                    return true;
                }

                // Check exact match in tags
                if meta_config.tags_emojis.contains_key(category) {
                    tracing::debug!(
                        "WASM: Found exact tag match '{}' for {}/{}",
                        category,
                        content_type,
                        language
                    );
                    return true;
                }

                // Check case-insensitive match in categories
                for category_key in meta_config.categories_emojis.keys() {
                    if category_key.to_lowercase() == category.to_lowercase() {
                        tracing::debug!(
                            "WASM: Found case-insensitive category match '{}' -> '{}' for {}/{}",
                            category,
                            category_key,
                            content_type,
                            language
                        );
                        return true;
                    }
                }

                // Check case-insensitive match in tags
                for tag_key in meta_config.tags_emojis.keys() {
                    if tag_key.to_lowercase() == category.to_lowercase() {
                        tracing::debug!(
                            "WASM: Found case-insensitive tag match '{}' -> '{}' for {}/{}",
                            category,
                            tag_key,
                            content_type,
                            language
                        );
                        return true;
                    }
                }
            } else {
                // Try to trigger async loading for future use but don't block routing
                crate::categories::wasm::initiate_meta_config_loading(
                    content_type,
                    language,
                    cache_key,
                );
            }
        }
    }

    // During hydration or before meta configs are loaded, use permissive validation
    // to prevent hydration mismatches. This is critical for routing consistency.
    web_sys::console::log_1(
        &format!(
            "🏷️ WASM: No cached meta config available for category '{}' in content_type '{}', \
             using permissive validation to prevent hydration mismatch",
            category, content_type
        )
        .into(),
    );

    // Return true for now to prevent hydration mismatches - meta configs will be
    // loaded async This ensures client-side routing matches server-side during
    // hydration
    web_sys::console::log_1(
        &format!(
            "🏷️ WASM: RETURNING TRUE for category '{}' to prevent hydration mismatch",
            category
        )
        .into(),
    );
    true
}

/// Get all available languages for a content type by checking directory
/// structure
#[cfg_attr(target_arch = "wasm32", allow(unused_variables))]
pub fn get_available_languages(content_type: &str) -> Vec<String> {
    #[cfg(not(target_arch = "wasm32"))]
    {
        use std::fs;

        let content_root =
            std::env::var("SITE_CONTENT_PATH").unwrap_or_else(|_| "site/content".to_string());
        let content_dir = Path::new(&content_root).join(content_type);
        match fs::read_dir(&content_dir) {
            Ok(entries) => entries
                .filter_map(|entry| entry.ok())
                .filter_map(|entry| {
                    if entry.file_type().ok()?.is_dir() {
                        entry.file_name().to_str().map(|s| s.to_string())
                    } else {
                        None
                    }
                })
                .collect(),
            Err(e) => {
                tracing::warn!("Failed to read content directory {:?}: {}", content_dir, e);
                // Use dynamic language discovery as fallback instead of hardcoded languages
                crate::i18n::discovery::discover_available_languages().clone()
            }
        }
    }

    #[cfg(target_arch = "wasm32")]
    {
        // Fallback for WASM - use configured supported languages
        crate::config::get_supported_languages().clone()
    }
}
