//! Content search utilities

use std::collections::HashMap;

/// Search result
#[derive(Debug, Clone)]
pub struct SearchResult {
    /// Content ID
    pub id: String,
    /// Title
    pub title: String,
    /// Content excerpt
    pub excerpt: String,
    /// Relevance score
    pub score: f32,
}

/// Search index
pub struct SearchIndex {
    /// Content index
    content: HashMap<String, String>,
}

impl SearchIndex {
    /// Create a new search index
    pub fn new() -> Self {
        Self {
            content: HashMap::new(),
        }
    }

    /// Add content to index
    pub fn add_content(&mut self, id: String, content: String) {
        self.content.insert(id, content);
    }

    /// Search content
    pub fn search(&self, query: &str) -> Vec<SearchResult> {
        let query = query.to_lowercase();
        let mut results = Vec::new();

        for (id, content) in &self.content {
            let content_lower = content.to_lowercase();
            if content_lower.contains(&query) {
                let score = calculate_score(content, &query);
                results.push(SearchResult {
                    id: id.clone(),
                    title: id.replace('-', " "),
                    excerpt: create_excerpt(content, &query),
                    score,
                });
            }
        }

        results.sort_by(|a, b| {
            b.score
                .partial_cmp(&a.score)
                .unwrap_or(std::cmp::Ordering::Equal)
        });
        results
    }
}

fn calculate_score(content: &str, query: &str) -> f32 {
    let content_lower = content.to_lowercase();
    let query_lower = query.to_lowercase();

    let matches = content_lower.matches(&query_lower).count();
    matches as f32 / content.len() as f32 * 1000.0
}

fn create_excerpt(content: &str, query: &str) -> String {
    let content_lower = content.to_lowercase();
    let query_lower = query.to_lowercase();

    if let Some(pos) = content_lower.find(&query_lower) {
        let start = pos.saturating_sub(50);
        let end = std::cmp::min(pos + query.len() + 50, content.len());
        content[start..end].to_string()
    } else {
        content.chars().take(100).collect()
    }
}

impl Default for SearchIndex {
    fn default() -> Self {
        Self::new()
    }
}
