//! Integration with RAG system for LLM context formatting
//!
//! This module provides helpers to format RAG retrieval results as useful
//! context for LLM prompts in the configuration assistant.

/// RAG retrieval result (mirrors typedialog_core::ai::rag::RetrievalResult)
#[derive(Clone)]
pub struct RetrievalResult {
    /// Document ID/source identifier
    pub doc_id: String,
    /// Document content
    pub content: String,
    /// Combined relevance score (0-1)
    pub combined_score: f32,
}

/// Format RAG results as contextual examples for LLM
///
/// Converts a list of RAG retrieval results into a formatted context
/// that can be included in LLM prompts to provide relevant examples.
///
/// # Example
///
/// ```
/// use typedialog_ai::llm::rag_integration::{format_rag_context, RetrievalResult};
///
/// let results = vec![
///     RetrievalResult {
///         doc_id: "example1".to_string(),
///         content: "port = 8080".to_string(),
///         combined_score: 0.92,
///     },
/// ];
///
/// let context = format_rag_context(&results);
/// println!("Context:\n{}", context);
/// ```
pub fn format_rag_context(results: &[RetrievalResult]) -> String {
    if results.is_empty() {
        return "No relevant examples found.".to_string();
    }

    let mut context = String::from("Here are relevant examples from similar configurations:\n\n");

    for (idx, result) in results.iter().enumerate() {
        context.push_str(&format!(
            "Example {} (from {}): [Relevance: {:.1}%]\n{}\n\n",
            idx + 1,
            result.doc_id,
            result.combined_score * 100.0,
            result.content
        ));
    }

    context
}

/// Extract field value suggestions from RAG results
///
/// Analyzes RAG results to extract common values for a specific field name.
///
/// # Example
///
/// ```
/// use typedialog_ai::llm::rag_integration::{extract_field_values, RetrievalResult};
///
/// let results = vec![
///     RetrievalResult {
///         doc_id: "config1".to_string(),
///         content: "port = 8080\nhost = localhost".to_string(),
///         combined_score: 0.90,
///     },
/// ];
///
/// let values = extract_field_values(&results, "port");
/// // Would extract "8080" from the results
/// ```
pub fn extract_field_values(results: &[RetrievalResult], field_name: &str) -> Vec<String> {
    let mut values = Vec::new();

    for result in results {
        // Simple pattern matching for field values
        // Looks for patterns like "field_name = value" or "field_name: value"
        let lines = result.content.lines();

        for line in lines {
            let trimmed = line.trim();

            // Check for TOML/Nickel style: field = value
            if let Some(idx) = trimmed.find('=') {
                let key_part = trimmed[..idx].trim();
                if key_part == field_name {
                    let value_part = trimmed[idx + 1..].trim();
                    let value = clean_value(value_part);
                    if !value.is_empty() && !values.contains(&value) {
                        values.push(value);
                    }
                }
            }

            // Check for JSON/YAML style: field: value or "field": value
            if let Some(idx) = trimmed.find(':') {
                let key_part = trimmed[..idx].trim().trim_matches('"');
                if key_part == field_name {
                    let value_part = trimmed[idx + 1..].trim();
                    let value = clean_value(value_part);
                    if !value.is_empty() && !values.contains(&value) {
                        values.push(value);
                    }
                }
            }
        }
    }

    values
}

/// Clean extracted field values
fn clean_value(value: &str) -> String {
    let value = value.trim();

    // Remove trailing comma (TOML syntax)
    let value = value.strip_suffix(',').unwrap_or(value);

    // Remove quotes
    let value = value.trim_matches(|c| c == '"' || c == '\'');

    // Remove comments
    if let Some(idx) = value.find('#') {
        value[..idx].trim().to_string()
    } else {
        value.to_string()
    }
}

/// Format RAG results with field-specific recommendations
///
/// Creates a structured recommendation list for a specific field
/// based on RAG retrieval results.
pub fn format_field_recommendations(
    field_name: &str,
    field_description: &str,
    results: &[RetrievalResult],
) -> String {
    let values = extract_field_values(results, field_name);

    if values.is_empty() {
        return format!(
            "No direct examples found for '{}', but {} is an important configuration setting.",
            field_name, field_description
        );
    }

    let mut rec = format!(
        "For the '{}' field ({}):\nCommon values from similar configurations:\n",
        field_name, field_description
    );

    for (idx, value) in values.iter().enumerate() {
        rec.push_str(&format!("  {}. {}\n", idx + 1, value));
    }

    rec
}

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

    #[test]
    fn test_format_rag_context_empty() {
        let results = vec![];
        let context = format_rag_context(&results);
        assert_eq!(context, "No relevant examples found.");
    }

    #[test]
    fn test_format_rag_context() {
        let results = vec![RetrievalResult {
            doc_id: "example1".to_string(),
            content: "port = 8080".to_string(),
            combined_score: 0.95,
        }];

        let context = format_rag_context(&results);
        assert!(context.contains("Example 1"));
        assert!(context.contains("example1"));
        assert!(context.contains("port = 8080"));
        assert!(context.contains("95.0%"));
    }

    #[test]
    fn test_extract_field_values_toml() {
        let results = vec![RetrievalResult {
            doc_id: "config.toml".to_string(),
            content: "port = 8080\nhost = localhost".to_string(),
            combined_score: 0.90,
        }];

        let values = extract_field_values(&results, "port");
        assert!(values.contains(&"8080".to_string()));

        let hosts = extract_field_values(&results, "host");
        assert!(hosts.contains(&"localhost".to_string()));
    }

    #[test]
    fn test_extract_field_values_json() {
        let results = vec![RetrievalResult {
            doc_id: "config.json".to_string(),
            content: r#"  "port": 8080,
  "host": "localhost""#
                .to_string(),
            combined_score: 0.90,
        }];

        let values = extract_field_values(&results, "host");
        assert!(values.contains(&"localhost".to_string()));
    }

    #[test]
    fn test_clean_value() {
        assert_eq!(clean_value("8080"), "8080");
        assert_eq!(clean_value("\"localhost\""), "localhost");
        assert_eq!(clean_value("true,"), "true");
        assert_eq!(clean_value("value # comment"), "value");
    }

    #[test]
    fn test_format_field_recommendations() {
        let results = vec![RetrievalResult {
            doc_id: "example".to_string(),
            content: "port = 8080\nport = 3000".to_string(),
            combined_score: 0.90,
        }];

        let rec = format_field_recommendations("port", "Server port number", &results);
        assert!(rec.contains("Common values"));
        assert!(rec.contains("8080") || rec.contains("3000"));
    }
}
