use super::{
    anthropic::messages::AnthropicMessage, open_ai::messages::OpenAIMessage, tools::ToolDefinition,
};
use anyhow::Result;
use serde::{Deserialize, Serialize};

#[derive(Clone, Debug)]
pub enum MessageType {
    Anthropic(AnthropicMessage),
    OpenAI(OpenAIMessage),
}

impl AbstractMessage for MessageType {
    fn get_role(&self) -> Role {
        match self {
            MessageType::Anthropic(m) => m.get_role(),
            MessageType::OpenAI(m) => m.get_role(),
        }
    }

    fn get_content(&self) -> Result<String> {
        match self {
            MessageType::Anthropic(m) => m.get_content(),
            MessageType::OpenAI(m) => m.get_content(),
        }
    }
}

pub trait AbstractMessage: Clone + 'static {
    fn get_role(&self) -> Role;
    fn get_content(&self) -> Result<String>;
}

pub trait ToolMessage: AbstractMessage {
    fn get_tools(&self) -> Result<Vec<Box<dyn ToolDefinition>>>;
    fn add_tool<T: ToolDefinition>(&mut self, tool: T);
}

pub trait Message: AbstractMessage {
    fn new(content: &str, role: Role) -> Self;
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub enum Role {
    System,
    User,
    Assistant,
    Tool,
}
