use chrs_graph::DoltGraph;
use chrs_mail::{Mailbox, Message};
use chrono::Utc;
use std::path::Path;
use std::time::Duration;
use tokio::time::sleep;
use uuid::Uuid;

struct CHORUSAgent {
    id: String,
    mailbox: Mailbox,
    graph: DoltGraph,
}

impl CHORUSAgent {
    async fn init(id: &str, base_path: &Path) -> Result<Self, Box<dyn std::error::Error>> {
        let mail_path = base_path.join("mail.sqlite");
        let graph_path = base_path.join("state_graph");
        
        std::fs::create_dir_all(&graph_path)?;
        
        let mailbox = Mailbox::open(mail_path)?;
        let graph = DoltGraph::init(&graph_path)?;
        
        // Ensure table exists
        let _ = graph.create_table("task_log", "id TEXT PRIMARY KEY, topic TEXT, payload TEXT, received_at TEXT");
        
        Ok(Self {
            id: id.to_string(),
            mailbox,
            graph,
        })
    }

    async fn run_loop(&self) {
        println!("Agent {} starting run loop...", self.id);
        loop {
            match self.mailbox.receive_pending(&self.id) {
                Ok(messages) => {
                    for msg in messages {
                        println!("Received message: {:?}", msg.topic);
                        let log_entry = serde_json::json!({
                            "id": msg.id.to_string(),
                            "topic": msg.topic,
                            "payload": msg.payload.to_string(),
                            "received_at": Utc::now().to_rfc3339()
                        });
                        if let Err(e) = self.graph.insert_node("task_log", log_entry) {
                            eprintln!("Failed to log task to graph: {}", e);
                        } else {
                            let _ = self.graph.commit(&format!("Logged task: {}", msg.id));
                            let _ = self.mailbox.mark_read(msg.id);
                        }
                    }
                }
                Err(e) => eprintln!("Mailbox error: {}", e),
            }
            sleep(Duration::from_secs(5)).await;
        }
    }
}

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let agent_id = "agent-001";
    let base_path = Path::new("/home/Tony/rust/projects/reset/CHORUS/data/agent-001");
    std::fs::create_dir_all(base_path)?;
    
    let agent = CHORUSAgent::init(agent_id, base_path).await?;
    agent.run_loop().await;
    
    Ok(())
}
