use serde::{Deserialize, Serialize};
use serde_json::Value;
use thiserror::Error;

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct ChatMessage {
    pub role: String,
    pub content: String,
}

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct ToolDefinition {
    pub name: String,
    pub description: String,
    pub parameters: Value,
}

#[derive(Debug, Clone, PartialEq)]
pub struct ToolFunctionCall {
    pub id: String,
    pub name: String,
    pub arguments: Value,
}

pub trait LlmProvider {
    fn chat(
        &self,
        messages: &[ChatMessage],
        tools: &[ToolDefinition],
    ) -> Result<Vec<ToolFunctionCall>, LlmError>;
}

#[derive(Debug, Error)]
pub enum LlmError {
    #[error(transparent)]
    Config(#[from] crate::config::ConfigError),
    #[error(transparent)]
    Http(#[from] reqwest::Error),
    #[error(transparent)]
    Json(#[from] serde_json::Error),
    #[error("llm returned no tool calls")]
    NoToolCalls,
    #[error("llm returned malformed tool arguments: {0}")]
    InvalidToolArguments(String),
}
