use uuid::Uuid;

use crate::agent::llm::ChatMessage;
use crate::db::Database;

/// 记忆管理器
pub struct MemoryStore {
    db: &'static Database,
    project_id: Uuid,
    run_id: String,
}

impl MemoryStore {
    pub fn new(db: &'static Database, project_id: Uuid) -> Self {
        Self {
            db,
            project_id,
            run_id: Uuid::new_v4().to_string(),
        }
    }

    /// 保存一轮对话
    pub fn save_turn(&self, messages: &[ChatMessage]) -> Result<(), String> {
        for msg in messages {
            let tool_calls_json = msg
                .tool_calls
                .as_ref()
                .map(|calls| serde_json::to_string(calls).unwrap_or_default());
            self.db
                .save_memory(
                    self.project_id,
                    &msg.role,
                    msg.content.as_deref().unwrap_or(""),
                    tool_calls_json.as_deref(),
                    &self.run_id,
                )
                .map_err(|e| e.to_string())?;
        }
        Ok(())
    }

    /// 加载最近的记忆（转换为 ChatMessage）
    pub fn load_recent(&self, limit: u32) -> Result<Vec<ChatMessage>, String> {
        let messages = self
            .db
            .load_recent_memory(self.project_id, limit)
            .map_err(|e| e.to_string())?;

        Ok(messages
            .into_iter()
            .map(|m| {
                let tool_calls = m.tool_calls.and_then(|s| serde_json::from_str(&s).ok());
                ChatMessage {
                    role: m.role,
                    content: Some(m.content),
                    tool_calls,
                    tool_call_id: None,
                }
            })
            .collect())
    }

    /// 清理旧记忆
    pub fn prune(&self, keep: u32) -> Result<(), String> {
        self.db
            .prune_memory(self.project_id, keep)
            .map_err(|e| e.to_string())
    }
}
