use thiserror::Error;

#[derive(Error, Debug, Clone)]
pub enum AppError {
    #[error("Authentication failed: {0}")]
    AuthError(String),

    #[error("Configuration error: {0}")]
    ConfigError(String),

    #[error("Database error: {0}")]
    DatabaseError(String),

    #[error("Provider error: {0}")]
    ProviderError(String),

    #[error("Validation error: {0}")]
    ValidationError(String),

    #[error("Multimodal processing error: {0}")]
    MultimodalError(String),

    #[error("Rate limit exceeded: {0}")]
    RateLimitError(String),

    #[error("Internal server error: {0}")]
    InternalError(String),
}

impl From<sqlx::Error> for AppError {
    fn from(err: sqlx::Error) -> Self {
        AppError::DatabaseError(err.to_string())
    }
}

impl From<anyhow::Error> for AppError {
    fn from(err: anyhow::Error) -> Self {
        AppError::InternalError(err.to_string())
    }
}

impl axum::response::IntoResponse for AppError {
    fn into_response(self) -> axum::response::Response {
        let status = match self {
            AppError::AuthError(_) => axum::http::StatusCode::UNAUTHORIZED,
            AppError::RateLimitError(_) => axum::http::StatusCode::TOO_MANY_REQUESTS,
            AppError::ValidationError(_) => axum::http::StatusCode::BAD_REQUEST,
            _ => axum::http::StatusCode::INTERNAL_SERVER_ERROR,
        };

        let body = axum::Json(serde_json::json!({
            "error": self.to_string(),
            "type": format!("{:?}", self)
        }));

        (status, body).into_response()
    }
}
