pub type AiResult<T> = Result<T, AiError>;

#[derive(Debug, thiserror::Error)]
pub enum AiError {
    #[error("ai config error: {0}")]
    Config(String),

    #[error("ai api error: {0}")]
    Api(String),

    #[error("qdrant error: {0}")]
    Qdrant(Box<qdrant_client::QdrantError>),

    #[error("database error: {0}")]
    Database(#[from] db::sqlx::Error),

    #[error("cache error: {0}")]
    Cache(#[from] cache::CacheError),

    #[error("redis error: {0}")]
    Redis(#[from] redis::RedisError),

    #[error("ai response error: {0}")]
    Response(String),

    #[error("model retries exhausted after {attempts} attempts: {last_error}")]
    ModelRetriesExhausted { attempts: usize, last_error: String },

    #[error("agent timeout after {seconds}s")]
    Timeout { seconds: u64 },

    #[error("tool not found: {tool}")]
    ToolNotFound { tool: String },

    #[error("tool execution failed: {cause}")]
    ToolExecutionFailed { cause: String },

    #[error("invalid input in '{field}': {reason}")]
    InvalidInput { field: String, reason: String },

    #[error("token budget exceeded: used ~{estimated} tokens, limit {limit}")]
    TokenBudgetExceeded { estimated: u64, limit: i64 },
}

impl From<qdrant_client::QdrantError> for AiError {
    fn from(e: qdrant_client::QdrantError) -> Self {
        AiError::Qdrant(Box::new(e))
    }
}
