use crate::types::SearchResult;

use super::types::KBQueryResult;

/// Convert KB query results into standard SearchResult items.
///
/// The `file_path` is set to `kb://{source}/{collection}/{id}` to distinguish
/// KB results from local file results.
pub fn kb_results_to_search_results(results: &[KBQueryResult]) -> Vec<SearchResult> {
    let mut search_results = Vec::new();

    for qr in results {
        for entry in &qr.entries {
            search_results.push(SearchResult {
                file_path: format!("kb://{}/{}/{}", entry.source, entry.collection, entry.id),
                content: if entry.title.is_empty() {
                    entry.content.clone()
                } else {
                    format!("[{}] {}", entry.title, entry.content)
                },
                relevance_score: entry.relevance_score,
                line_number: None,
            });
        }
    }

    search_results
}

// ===========================================================================
// Tests
// ===========================================================================

#[cfg(test)]
mod tests {
    use std::collections::HashMap;

    use super::*;
    use crate::knowledge::types::{KBQueryResult, KnowledgeEntry};

    #[test]
    fn test_convert_kb_results() {
        let results = vec![KBQueryResult {
            entries: vec![
                KnowledgeEntry {
                    id: "id-1".into(),
                    source: "ChromaDB".into(),
                    collection: "docs".into(),
                    title: "Auth Design".into(),
                    content: "Use JWT tokens".into(),
                    metadata: HashMap::new(),
                    relevance_score: 0.9,
                    retrieved_at: 0,
                },
                KnowledgeEntry {
                    id: "id-2".into(),
                    source: "ChromaDB".into(),
                    collection: "docs".into(),
                    title: "".into(),
                    content: "Raw content here".into(),
                    metadata: HashMap::new(),
                    relevance_score: 0.7,
                    retrieved_at: 0,
                },
            ],
            source: "ChromaDB".into(),
            collection: "docs".into(),
            query: "auth".into(),
            total_results: 2,
        }];

        let search_results = kb_results_to_search_results(&results);
        assert_eq!(search_results.len(), 2);

        assert_eq!(search_results[0].file_path, "kb://ChromaDB/docs/id-1");
        assert!(search_results[0].content.contains("[Auth Design]"));
        assert_eq!(search_results[0].relevance_score, 0.9);
        assert!(search_results[0].line_number.is_none());

        // Entry with empty title should use content directly.
        assert_eq!(search_results[1].file_path, "kb://ChromaDB/docs/id-2");
        assert_eq!(search_results[1].content, "Raw content here");
    }

    #[test]
    fn test_empty_results() {
        let search_results = kb_results_to_search_results(&[]);
        assert!(search_results.is_empty());
    }

    #[test]
    fn test_multiple_sources() {
        let results = vec![
            KBQueryResult {
                entries: vec![KnowledgeEntry {
                    id: "a1".into(),
                    source: "ChromaDB".into(),
                    collection: "col-a".into(),
                    title: "Title A".into(),
                    content: "Content A".into(),
                    metadata: HashMap::new(),
                    relevance_score: 0.8,
                    retrieved_at: 0,
                }],
                source: "ChromaDB".into(),
                collection: "col-a".into(),
                query: "test".into(),
                total_results: 1,
            },
            KBQueryResult {
                entries: vec![KnowledgeEntry {
                    id: "b1".into(),
                    source: "Pinecone".into(),
                    collection: "col-b".into(),
                    title: "Title B".into(),
                    content: "Content B".into(),
                    metadata: HashMap::new(),
                    relevance_score: 0.6,
                    retrieved_at: 0,
                }],
                source: "Pinecone".into(),
                collection: "col-b".into(),
                query: "test".into(),
                total_results: 1,
            },
        ];

        let search_results = kb_results_to_search_results(&results);
        assert_eq!(search_results.len(), 2);
        assert_eq!(search_results[0].file_path, "kb://ChromaDB/col-a/a1");
        assert_eq!(search_results[1].file_path, "kb://Pinecone/col-b/b1");
    }
}
