//! # Swarm Task Assignment Example
//!
//! Demonstrates how tasks are assigned to agents with load balancing.
//!
//! ## What This Example Shows
//! - Submitting tasks for swarm bidding
//! - Load-aware agent selection
//! - Task assignment with capability filtering
//! - Viewing assignment decisions
//!
//! ## Run
//! ```bash
//! cargo run --example 02-task-assignment -p vapora-swarm
//! ```

use vapora_swarm::{AgentProfile, SwarmCoordinator};

fn main() {
    println!("=== Swarm Task Assignment Example ===\n");

    // Step 1: Create coordinator and register agents
    let coordinator = SwarmCoordinator::new();

    let agents = vec![
        AgentProfile {
            id: "agent-1".to_string(),
            roles: vec!["developer".to_string()],
            capabilities: vec!["coding".to_string(), "testing".to_string()],
            current_load: 0.20,
            success_rate: 0.92,
            availability: true,
        },
        AgentProfile {
            id: "agent-2".to_string(),
            roles: vec!["developer".to_string()],
            capabilities: vec!["coding".to_string(), "documentation".to_string()],
            current_load: 0.10,
            success_rate: 0.85,
            availability: true,
        },
        AgentProfile {
            id: "agent-3".to_string(),
            roles: vec!["reviewer".to_string()],
            capabilities: vec!["code_review".to_string()],
            current_load: 0.00,
            success_rate: 0.98,
            availability: true,
        },
    ];

    println!("Registering agents:");
    for agent in &agents {
        coordinator.register_agent(agent.clone()).ok();
        println!(
            "  ✓ {} (load: {:.0}%, success: {:.0}%)",
            agent.id,
            agent.current_load * 100.0,
            agent.success_rate * 100.0
        );
    }

    // Step 2: Submit tasks for assignment
    println!("\n=== Task Submissions ===\n");

    let tasks = vec![
        ("task-001", "coding", vec!["coding".to_string()]),
        ("task-002", "code_review", vec!["code_review".to_string()]),
        ("task-003", "coding", vec!["coding".to_string()]),
        (
            "task-004",
            "documentation",
            vec!["documentation".to_string()],
        ),
    ];

    for (task_id, description, required_capabilities) in &tasks {
        println!("Task: {} ({})", task_id, description);
        println!("  Required capabilities: {:?}", required_capabilities);

        // In real scenario, this would call coordinator.submit_task_for_bidding
        // For now, show the assignment logic

        // Filter eligible agents
        let eligible: Vec<_> = agents
            .iter()
            .filter(|a| {
                required_capabilities
                    .iter()
                    .any(|cap| a.capabilities.contains(cap))
            })
            .collect();

        println!("  Eligible agents: {}", eligible.len());

        // Score agents
        let mut scored: Vec<_> = eligible
            .iter()
            .map(|a| {
                let score = a.success_rate / (1.0 + a.current_load);
                (a, score)
            })
            .collect();

        scored.sort_by(|a, b| b.1.partial_cmp(&a.1).unwrap_or(std::cmp::Ordering::Equal));

        if let Some((best, score)) = scored.first() {
            println!("  ✓ Assigned to: {} (score: {:.3})", best.id, score);
        }
        println!();
    }

    // Step 3: Show swarm statistics
    println!("=== Swarm Statistics ===");
    let stats = coordinator.get_swarm_stats();
    println!("Total agents: {}", stats.total_agents);
    println!("Available agents: {}", stats.available_agents);
    println!("Average load: {:.2}%", stats.avg_load * 100.0);
    println!("Active tasks: {}", stats.active_tasks);

    // Step 4: Load distribution
    println!("\n=== Load Distribution ===");
    for agent in &agents {
        let bar_length = (agent.current_load * 20.0) as usize;
        let bar = "█".repeat(bar_length) + &"░".repeat(20 - bar_length);
        println!("  {}: {} {:.0}%", agent.id, bar, agent.current_load * 100.0);
    }
}
