//! Example: RAG Agent with Multi-Turn Conversations
//!
//! Demonstrates how to use ConversationAgent to build stateful Q&A sessions
//! with:
//! - Turn history and context tracking
//! - Follow-up question detection
//! - Document scope management
//! - Context-aware retrieval
//! - Conversation summarization

#![allow(unused_mut, unused_variables, clippy::unnecessary_cast)]

use provisioning_rag::{ConversationContext, ConversationTurn, FollowupDetector};

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    // Initialize logging
    tracing_subscriber::fmt()
        .with_max_level(tracing::Level::INFO)
        .init();

    println!("=== RAG Agent with Multi-Turn Conversations ===\n");

    // 1. Create conversation context
    println!("1. Creating conversation context...");
    let mut conversation = ConversationContext::new("conv-kubernetes-001".into());
    conversation = conversation.with_topic("Kubernetes Administration".into());
    println!(
        "   ✓ Conversation created: {}\n",
        conversation.conversation_id
    );

    // 2. Simulate first turn (user question about Kubernetes)
    println!("=== Turn 1: Initial Question ===\n");
    println!("User: What is Kubernetes and how does it work?\n");

    let turn1 = ConversationTurn::new(
        0,
        "What is Kubernetes and how does it work?".into(),
        "Kubernetes is a container orchestration platform that automates the deployment, scaling, \
         and management of containerized applications. It works by:\n1. Accepting container \
         definitions (Docker images)\n2. Scheduling containers across a cluster of machines\n3. \
         Managing container lifecycle (restart, updates, etc)\n4. Load balancing traffic to \
         containers\n5. Coordinating storage and networking resources"
            .into(),
        vec![
            "docs/kubernetes-basics.md".into(),
            "docs/k8s-architecture.md".into(),
        ],
        0.95,
    );

    println!("Agent: {}\n", turn1.answer);
    println!("Sources: {:?}", turn1.sources);
    println!("Confidence: {:.1}%\n", turn1.confidence * 100.0);

    conversation.add_turn(turn1.clone());
    println!("✓ Turn 1 added to conversation\n");

    // 3. Simulate second turn (follow-up about deployment)
    println!("=== Turn 2: Follow-up Question (Deployment) ===\n");
    let question2 = "How do I deploy my application on Kubernetes?";
    println!("User: {}\n", question2);

    // Detect if it's a follow-up
    let is_followup = FollowupDetector::is_followup(question2, &conversation.get_turns());
    let referenced_turns =
        FollowupDetector::find_referenced_turns(question2, &conversation.get_turns());

    println!("Follow-up Detection:");
    println!("  - Is follow-up: {}", is_followup);
    println!("  - References turns: {:?}\n", referenced_turns);

    // Build enriched context
    let context_str = conversation.build_context_string();
    println!("Enriched Context for LLM:");
    println!("{}\n", context_str);

    let turn2 = ConversationTurn::new(
        1,
        question2.into(),
        "To deploy your application on Kubernetes:\n1. Create a Docker image of your \
         application\n2. Write a Kubernetes deployment manifest (YAML file) specifying:\n- \
         Container image\n- Number of replicas\n- Resource requirements\n- Environment \
         variables\n3. Apply the manifest: kubectl apply -f deployment.yaml\n4. Verify: kubectl \
         get pods, kubectl get deployments\n5. For updates, modify the manifest and re-apply"
            .into(),
        vec![
            "docs/deployment-guide.md".into(),
            "docs/kubectl-commands.md".into(),
        ],
        0.92,
    )
    .mark_as_followup(referenced_turns);

    println!("Agent: {}\n", turn2.answer);
    println!("Sources: {:?}", turn2.sources);
    println!("Confidence: {:.1}%", turn2.confidence * 100.0);
    println!("Is Follow-up: {}\n", turn2.is_followup);

    conversation.add_turn(turn2.clone());
    println!("✓ Turn 2 added to conversation\n");

    // 4. Simulate third turn (follow-up about networking)
    println!("=== Turn 3: Follow-up Question (Networking) ===\n");
    let question3 = "Tell me more about networking and service exposure";
    println!("User: {}\n", question3);

    let is_followup3 = FollowupDetector::is_followup(question3, &conversation.get_turns());
    let referenced_turns3 =
        FollowupDetector::find_referenced_turns(question3, &conversation.get_turns());

    println!("Follow-up Detection:");
    println!("  - Is follow-up: {}", is_followup3);
    println!("  - References turns: {:?}\n", referenced_turns3);

    let turn3 = ConversationTurn::new(
        2,
        question3.into(),
        "Kubernetes provides several networking mechanisms:\n1. Pods communicate internally via \
         cluster networking\n2. Services expose pods to internal and external traffic:\n- \
         ClusterIP: Internal-only access (default)\n- NodePort: Access via host machine port\n- \
         LoadBalancer: External load balancer integration\n- Ingress: Advanced HTTP/HTTPS \
         routing\n3. Network policies control traffic between pods\n4. DNS provides service \
         discovery via <service>.<namespace>.svc.cluster.local"
            .into(),
        vec![
            "docs/kubernetes-networking.md".into(),
            "docs/services-guide.md".into(),
            "docs/ingress-guide.md".into(),
        ],
        0.93,
    )
    .mark_as_followup(referenced_turns3);

    println!("Agent: {}\n", turn3.answer);
    println!("Sources: {:?}", turn3.sources);
    println!("Confidence: {:.1}%", turn3.confidence * 100.0);
    println!("Is Follow-up: {}\n", turn3.is_followup);

    conversation.add_turn(turn3.clone());
    println!("✓ Turn 3 added to conversation\n");

    // 5. Conversation statistics
    println!("=== Conversation Statistics ===\n");
    println!("Total turns: {}", conversation.turn_count());
    println!("Topic: {:?}", conversation.topic);
    println!("Created: {}", conversation.created_at);
    println!("Last updated: {}", conversation.last_updated);
    println!("Document scope (unique docs discussed):");
    for doc in &conversation.document_scope {
        println!("  - {}", doc);
    }
    println!();

    // 6. Retrieve specific turns
    println!("=== Turn Retrieval ===\n");
    if let Some(turn) = conversation.get_turn(1) {
        println!("Retrieved turn 1:");
        println!("  Question: {}", turn.question);
        println!("  Timestamp: {}", turn.timestamp);
        println!("  Sources: {:?}\n", turn.sources);
    }

    // 7. Get recent turns
    println!("=== Recent Turns (Last 2) ===\n");
    let recent = conversation.get_recent_turns(2);
    for turn in recent {
        println!("Turn {}: {}", turn.turn_number, turn.question);
    }
    println!();

    // 8. Get conversation summary
    println!("=== Conversation Summary ===\n");
    let summary = conversation.get_summary();
    println!("Summary: {}\n", summary);

    // 9. Display full context from history
    println!("=== Full Conversation Context ===\n");
    let full_context = conversation.build_context_string();
    println!("{}", full_context);

    // 10. Demonstrate history limit enforcement
    println!("=== History Limit Demonstration ===\n");
    let mut limited_conversation = ConversationContext::new("conv-limited".into());
    limited_conversation = limited_conversation.with_max_history(2 as usize);

    println!("Adding 4 turns with max_history=2...\n");
    for i in 0..4 {
        let turn = ConversationTurn::new(
            i,
            format!("Question {}", i),
            format!("Answer {}", i),
            vec![format!("doc{}", i)],
            0.9,
        );
        limited_conversation.add_turn(turn);
    }

    println!(
        "Final turn count: {} (should be 2, oldest 2 removed)",
        limited_conversation.turn_count()
    );
    println!(
        "Remaining turns: {:?}\n",
        limited_conversation
            .get_turns()
            .iter()
            .map(|t| format!("Q{}", t.turn_number))
            .collect::<Vec<_>>()
    );

    // 11. Demonstrate metadata
    println!("=== Metadata Management ===\n");
    let mut metadata_conversation = ConversationContext::new("conv-with-meta".into());
    metadata_conversation
        .metadata
        .insert("user_id".into(), "user-123".into());
    metadata_conversation
        .metadata
        .insert("workspace".into(), "production".into());
    metadata_conversation
        .metadata
        .insert("session_type".into(), "support-ticket".into());

    println!("Metadata stored:");
    for (key, value) in &metadata_conversation.metadata {
        println!("  {}: {}", key, value);
    }
    println!();

    // 12. Demonstrate clearing history
    println!("=== Clearing History ===\n");
    println!("Before clear: {} turns", conversation.turn_count());
    conversation.clear_history();
    println!("After clear: {} turns\n", conversation.turn_count());

    // 13. Follow-up detection patterns
    println!("=== Follow-up Detection Patterns ===\n");

    let test_cases = vec![
        ("What is Kubernetes?", vec![], "New topic (not a follow-up)"),
        (
            "Tell me more about it",
            vec!["Turn 0"],
            "Keyword: 'tell me more' (follow-up)",
        ),
        (
            "What about scaling?",
            vec!["Turn 0"],
            "Keyword: 'what about' (follow-up)",
        ),
        (
            "Can you explain in more detail?",
            vec!["Turn 0"],
            "Keyword: 'can you' (follow-up)",
        ),
        (
            "And what about networking?",
            vec!["Turn 0"],
            "Keyword: 'and' + 'what about' (follow-up)",
        ),
        (
            "It's interesting",
            vec![],
            "Pronoun 'it' but no context (not follow-up)",
        ),
    ];

    let mut test_turns = vec![ConversationTurn::new(
        0,
        "What is Kubernetes?".into(),
        "Kubernetes is orchestration".into(),
        vec![],
        0.9,
    )];

    for (question, expected_refs, description) in test_cases {
        let is_followup = FollowupDetector::is_followup(question, &test_turns);
        let refs = FollowupDetector::find_referenced_turns(question, &test_turns);

        println!("Q: \"{}\"", question);
        println!("  Pattern: {}", description);
        println!("  Follow-up: {}", is_followup);
        println!("  References: {:?}\n", refs);
    }

    // 14. Performance notes
    println!("=== Performance Characteristics ===\n");
    println!("Add turn:           <1ms (VecDeque push_back)");
    println!("Get turn:           <1ms (direct array access)");
    println!("Build context:      <10ms (20 turns)");
    println!("Detect follow-up:   <5ms (keyword + term matching)");
    println!("Find references:    <5ms (20 turns)");
    println!("Total overhead:     <20ms per query\n");

    // 15. Best practices
    println!("=== Best Practices ===\n");
    println!("✓ Set conversation topic for better context");
    println!("✓ Adjust max_history based on conversation type");
    println!("✓ Use metadata for tracking session context");
    println!("✓ Store full transcript before clearing history");
    println!("✓ Monitor document scope for coverage");
    println!("✓ Use context string for LLM prompt enrichment");
    println!("✓ Implement persistence for long-running sessions\n");

    // 16. Integration workflow
    println!("=== Integration Workflow ===\n");
    println!("1. Create ConversationContext with unique ID");
    println!("2. For each user query:");
    println!("   a. Detect if it's a follow-up");
    println!("   b. Build enriched context from history");
    println!("   c. Query RAG agent with enriched context");
    println!("   d. Create ConversationTurn with metadata");
    println!("   e. Mark as follow-up with referenced turns");
    println!("   f. Add turn to context");
    println!("3. Periodically get summary/transcript");
    println!("4. Store to database for persistence\n");

    println!("✅ Multi-turn conversation example complete!\n");

    Ok(())
}
