//! Proxy error types

use axum::{
    http::StatusCode,
    response::{IntoResponse, Response},
    Json,
};
use serde::Serialize;
use thiserror::Error;

/// Proxy errors
#[derive(Debug, Error)]
pub enum ProxyError {
    /// Failed to create HTTP client
    #[error("Failed to create HTTP client: {0}")]
    ClientCreation(String),

    /// Failed to read request body
    #[error("Failed to read request body: {0}")]
    RequestBody(String),

    /// Backend request failed
    #[error("Backend request failed: {0}")]
    BackendRequest(String),

    /// Failed to read response body
    #[error("Failed to read response body: {0}")]
    ResponseBody(String),

    /// Route not found
    #[error("Route not found for: {0}")]
    RouteNotFound(String),

    /// Invalid configuration
    #[error("Invalid configuration: {0}")]
    InvalidConfig(String),
}

impl IntoResponse for ProxyError {
    fn into_response(self) -> Response {
        let (status, error_message) = match &self {
            ProxyError::RouteNotFound(_) => (StatusCode::NOT_FOUND, self.to_string()),
            ProxyError::InvalidConfig(_) => (StatusCode::INTERNAL_SERVER_ERROR, self.to_string()),
            ProxyError::BackendRequest(_) => (StatusCode::BAD_GATEWAY, self.to_string()),
            _ => (StatusCode::INTERNAL_SERVER_ERROR, self.to_string()),
        };

        #[derive(Serialize)]
        struct ErrorResponse {
            error: String,
            message: String,
        }

        let body = Json(ErrorResponse {
            error: "PROXY_ERROR".to_string(),
            message: error_message,
        });

        (status, body).into_response()
    }
}

/// Result type for proxy operations
pub type ProxyResult<T> = Result<T, ProxyError>;
