// API error handling - Convert VaporaError to HTTP responses

use axum::{
    http::StatusCode,
    response::{IntoResponse, Response},
    Json,
};
use serde_json::json;
use vapora_shared::VaporaError;

/// API Result type that implements IntoResponse
pub type ApiResult<T> = Result<T, ApiError>;

/// Convert VaporaError into an HTTP response
pub fn error_response(error: VaporaError) -> Response {
    let (status, message) = match error {
        VaporaError::NotFound(msg) => (StatusCode::NOT_FOUND, msg),
        VaporaError::InvalidInput(msg) => (StatusCode::BAD_REQUEST, msg),
        VaporaError::Unauthorized(msg) => (StatusCode::UNAUTHORIZED, msg),
        VaporaError::ConfigError(msg) => (
            StatusCode::INTERNAL_SERVER_ERROR,
            format!("Configuration error: {}", msg),
        ),
        VaporaError::DatabaseError(msg) => (
            StatusCode::INTERNAL_SERVER_ERROR,
            format!("Database error: {}", msg),
        ),
        VaporaError::AgentError(msg) => (
            StatusCode::INTERNAL_SERVER_ERROR,
            format!("Agent error: {}", msg),
        ),
        VaporaError::LLMRouterError(msg) => (
            StatusCode::INTERNAL_SERVER_ERROR,
            format!("LLM router error: {}", msg),
        ),
        VaporaError::WorkflowError(msg) => (
            StatusCode::INTERNAL_SERVER_ERROR,
            format!("Workflow error: {}", msg),
        ),
        VaporaError::NatsError(msg) => (
            StatusCode::INTERNAL_SERVER_ERROR,
            format!("NATS error: {}", msg),
        ),
        VaporaError::IoError(err) => (
            StatusCode::INTERNAL_SERVER_ERROR,
            format!("IO error: {}", err),
        ),
        VaporaError::SerializationError(err) => (
            StatusCode::BAD_REQUEST,
            format!("Serialization error: {}", err),
        ),
        VaporaError::TomlError(msg) => (
            StatusCode::INTERNAL_SERVER_ERROR,
            format!("TOML error: {}", msg),
        ),
        VaporaError::InternalError(msg) => (StatusCode::INTERNAL_SERVER_ERROR, msg),
    };

    let body = Json(json!({
        "error": message,
        "status": status.as_u16(),
    }));

    (status, body).into_response()
}

/// Wrapper type to implement IntoResponse for VaporaError
#[derive(Debug)]
pub struct ApiError(pub VaporaError);

impl IntoResponse for ApiError {
    fn into_response(self) -> Response {
        error_response(self.0)
    }
}

impl From<VaporaError> for ApiError {
    fn from(err: VaporaError) -> Self {
        ApiError(err)
    }
}

impl From<serde_json::Error> for ApiError {
    fn from(err: serde_json::Error) -> Self {
        ApiError(VaporaError::SerializationError(err))
    }
}
