//! Error types for the AI client.
//!
//! This module defines custom error types for AI operations.

use thiserror::Error;

use crate::provider::Provider;

/// Errors that can occur during AI operations.
#[derive(Debug, Error)]
pub enum AiError {
    /// No API key configured for any provider.
    #[error("No API key configured for any available provider")]
    NoApiKey,

    /// API key not found for specific provider.
    #[error("API key not found for provider {0}")]
    ApiKeyNotFound(Provider),

    /// HTTP request failed.
    #[error("HTTP request failed: {0}")]
    HttpError(String),

    /// Failed to parse response.
    #[error("Failed to parse response: {0}")]
    ParseError(String),

    /// API returned an error.
    #[error("API error from {provider}: {message}")]
    ApiError {
        /// The provider that returned the error.
        provider: Provider,
        /// Error message from the API.
        message: String,
        /// HTTP status code if available.
        status_code: Option<u16>,
    },

    /// All providers failed.
    #[error("All providers failed: {0:?}")]
    AllProvidersFailed(Vec<(Provider, String)>),

    /// Model not available on any configured provider.
    #[error("Model {0} not available on any configured provider")]
    ModelNotAvailable(String),

    /// Verification failed after max retries.
    #[error("Verification failed after {retries} retries: {message}")]
    VerificationFailed {
        /// Number of retries attempted.
        retries: usize,
        /// Last verification error message.
        message: String,
    },

    /// Request timeout.
    #[error("Request timed out after {0} seconds")]
    Timeout(u64),

    /// Rate limit exceeded.
    #[error("Rate limit exceeded for provider {0}")]
    RateLimitExceeded(Provider),

    /// Invalid request.
    #[error("Invalid request: {0}")]
    InvalidRequest(String),
}

/// Result type alias for AI operations.
pub type AiResult<T> = Result<T, AiError>;
