//! Slug normalization utilities
//!
//! Provides functions to convert strings to URL-safe slugs following the pattern:
//! - All lowercase
//! - Spaces replaced with dashes
//! - No accents or special characters
//! - Safe for URL usage

use std::collections::HashMap;
use unicode_normalization::UnicodeNormalization;

/// Normalize a string to a URL-safe slug
///
/// Rules:
/// - Convert to lowercase
/// - Replace spaces with dashes
/// - Remove accents and diacritics using Unicode normalization
/// - Remove non-alphanumeric characters except dashes
/// - Collapse multiple consecutive dashes
/// - Trim leading/trailing dashes
pub fn to_slug(input: &str) -> String {
    // Normalize to NFD (decomposed form) and filter out combining marks (accents)
    let no_accents: String = input
        .nfd()
        .filter(|c| !unicode_normalization::char::is_combining_mark(*c))
        .collect();

    no_accents
        .to_lowercase()
        .chars()
        .map(|c| {
            if c.is_ascii_alphanumeric() {
                c
            } else if c.is_whitespace() || c == '_' || c == '/' {
                '-'
            } else if c.is_ascii_punctuation() && c != '-' {
                // Remove other punctuation
                '\0' // Will be filtered out
            } else {
                c
            }
        })
        .filter(|&c| c != '\0')
        .collect::<String>()
        .split('-')
        .filter(|s| !s.is_empty())
        .collect::<Vec<&str>>()
        .join("-")
}

/// Normalize a category name to slug format
pub fn normalize_category(category: &str) -> String {
    to_slug(category)
}

/// Normalize a tag name to slug format
pub fn normalize_tag(tag: &str) -> String {
    to_slug(tag)
}

/// Generate a URL slug from a title
/// More aggressive normalization for titles that will be used in URLs
pub fn title_to_slug(title: &str) -> String {
    // Remove common words that don't add SEO value
    let stop_words = [
        "the",
        "a",
        "an",
        "and",
        "or",
        "but",
        "in",
        "on",
        "at",
        "to",
        "for",
        "of",
        "with",
        "by",
        "from",
        "up",
        "about",
        "into",
        "through",
        "during",
        "before",
        "after",
        "above",
        "below",
        "between",
        "among",
        "throughout",
        "within",
        "without",
        "against",
        "across",
        "behind",
        "beyond",
        "during",
        "except",
        "under",
        "over",
    ];

    let base_slug = to_slug(title);

    // Don't remove stop words if the result would be too short
    let words: Vec<&str> = base_slug.split('-').collect();
    if words.len() <= 3 {
        return base_slug;
    }

    words
        .into_iter()
        .filter(|word| !stop_words.contains(word) || word.len() > 3)
        .collect::<Vec<&str>>()
        .join("-")
}

/// Create a mapping of old category names to new normalized slugs
// pub fn create_category_slug_mapping() -> HashMap<String, String> {
//     let mut mapping = HashMap::new();

//     // Common categories found in the content
//     let categories = [

//     ];

//     for category in categories {
//         mapping.insert(category.to_string(), normalize_category(category));
//     }

//     mapping
// }

// /// Create a mapping of old tag names to new normalized slugs
// pub fn create_tag_slug_mapping() -> HashMap<String, String> {
//     let mut mapping = HashMap::new();

//     // Common tags found in the content
//     let tags = [

//     ];

//     for tag in tags {
//         mapping.insert(tag.to_string(), normalize_tag(tag));
//     }

//     mapping
// }

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

    #[test]
    fn test_to_slug() {
        assert_eq!(to_slug("Rust Programming"), "rust-programming");
        assert_eq!(to_slug("Docker Multi-Stage"), "docker-multi-stage");
        assert_eq!(to_slug("CI/CD Pipeline"), "ci-cd-pipeline");
        assert_eq!(to_slug("Async Error Handling"), "async-error-handling");
        assert_eq!(to_slug("Web3 & Blockchain"), "web3-blockchain");
        assert_eq!(to_slug("España Programación"), "espana-programacion");
        assert_eq!(to_slug("  Multiple   Spaces  "), "multiple-spaces");
        assert_eq!(to_slug("Testing__123"), "testing-123");
    }

    #[test]
    fn test_normalize_category() {
        assert_eq!(normalize_category("Rust Programming"), "rust-programming");
        assert_eq!(normalize_category("Docker"), "docker");
        assert_eq!(normalize_category("CI/CD"), "ci-cd");
    }

    #[test]
    fn test_title_to_slug() {
        assert_eq!(
            title_to_slug("Modern Rust Web Development in 2024"),
            "modern-rust-web-development-2024"
        );
        assert_eq!(title_to_slug("A Guide to Docker"), "guide-docker");
        // Short titles should keep all words
        assert_eq!(title_to_slug("The Test"), "the-test");
    }

    #[test]
    fn test_accents_removal() {
        assert_eq!(to_slug("Configuración Avanzada"), "configuracion-avanzada");
        assert_eq!(to_slug("Programación Rust"), "programacion-rust");
        assert_eq!(to_slug("Español"), "espanol");
    }
}
