#![allow(
    clippy::expect_used,
    clippy::unwrap_used,
    clippy::panic,
    clippy::uninlined_format_args,
    clippy::collapsible_if,
    clippy::redundant_clone,
    clippy::needless_raw_string_hashes,
    clippy::single_match,
    clippy::redundant_closure_for_method_calls,
    clippy::redundant_pattern_matching,
    clippy::ignored_unit_patterns,
    clippy::clone_on_copy,
    clippy::manual_assert,
    clippy::unwrap_in_result,
    clippy::useless_vec
)]
use std::sync::Arc;
use std::time::Duration;

use futures::StreamExt;
use meerkat::{AgentEvent, AgentFactory, Config, build_ephemeral_service};
use meerkat_mob::{MeerkatId, MobBuilder, MobStorage, Prefab, ProfileName};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let _ = std::env::var("OPENAI_API_KEY")
        .map_err(|_| "Set OPENAI_API_KEY to run real_mob_llm_smoke")?;

    let model = std::env::var("RKAT_SMOKE_MODEL").unwrap_or_else(|_| "gpt-4.1-mini".to_string());
    println!("REAL_SMOKE: using model={model}");

    let temp_dir = tempfile::tempdir()?;
    let store_path = temp_dir.path().join("sessions");
    std::fs::create_dir_all(&store_path)?;

    let factory = AgentFactory::new(&store_path).comms(true);
    let config = Config::default();
    let session_service = Arc::new(build_ephemeral_service(factory, config, 16));

    let mut definition = Prefab::CodingSwarm.definition();
    for profile in definition.profiles.values_mut() {
        profile.model = model.clone();
    }

    let handle = MobBuilder::new(definition, MobStorage::in_memory())
        .with_session_service(session_service)
        .allow_ephemeral_sessions(true)
        .create()
        .await?;

    println!(
        "REAL_SMOKE: mob created id={} status={:?}",
        handle.mob_id(),
        handle.status()
    );

    handle
        .spawn(
            ProfileName::from("lead"),
            MeerkatId::from("lead-1"),
            Some("You are the lead. Keep responses brief and direct.".to_string()),
        )
        .await?;
    handle
        .spawn(
            ProfileName::from("worker"),
            MeerkatId::from("worker-1"),
            Some("You are a worker. Help the lead when asked.".to_string()),
        )
        .await?;
    handle
        .wire(MeerkatId::from("lead-1"), MeerkatId::from("worker-1"))
        .await?;
    println!("REAL_SMOKE: spawned lead-1 + worker-1 and wired them");

    let mut agent_stream = handle
        .subscribe_agent_events(&MeerkatId::from("lead-1"))
        .await?;
    handle
        .send_message(
            MeerkatId::from("lead-1"),
            "Give a 2-sentence plan to implement a Rust CLI smoke test and mention one task to delegate to worker-1.".to_string(),
        )
        .await?;
    println!("REAL_SMOKE: message sent to lead-1");

    let mut final_result: Option<String> = None;
    let deadline = tokio::time::Instant::now() + Duration::from_secs(120);

    while tokio::time::Instant::now() < deadline {
        let remaining = deadline.saturating_duration_since(tokio::time::Instant::now());
        let evt = tokio::time::timeout(remaining.min(Duration::from_secs(5)), agent_stream.next())
            .await
            .ok()
            .flatten()
            .map(|envelope| envelope.payload);

        let Some(evt) = evt else {
            continue;
        };

        match evt {
            AgentEvent::TextDelta { delta } => {
                print!("{delta}");
            }
            AgentEvent::TextComplete { content } => {
                println!("\nREAL_SMOKE: text_complete={content}");
            }
            AgentEvent::ToolCallRequested { name, .. } => {
                println!("\nREAL_SMOKE: tool_call_requested={name}");
            }
            AgentEvent::ToolResultReceived { name, is_error, .. } => {
                println!("\nREAL_SMOKE: tool_result name={name} is_error={is_error}");
            }
            AgentEvent::InteractionComplete { result, .. } => {
                final_result = Some(result);
                println!("\nREAL_SMOKE: interaction_complete");
                break;
            }
            AgentEvent::InteractionFailed { error, .. } => {
                println!("\nREAL_SMOKE: interaction_failed error={error}");
                break;
            }
            _ => {}
        }
    }

    if final_result.is_none() {
        println!("REAL_SMOKE: no terminal result before timeout");
    } else if let Some(result) = final_result {
        println!("REAL_SMOKE: final_result={result}");
    }

    let members = handle.list_members().await;
    println!("REAL_SMOKE: members={}", members.len());
    for member in members {
        println!(
            "  - {} profile={} wired_to={:?}",
            member.meerkat_id, member.profile, member.wired_to
        );
    }

    handle.retire_all().await?;
    println!("REAL_SMOKE: retired all members");

    Ok(())
}
