use actix_web::http::StatusCode;
use actix_web::HttpResponse;
use serde_json::{json, Value};

use crate::api::gateway::contracts::GatewayOperationKind;

pub fn gateway_error_with_details(
    status: StatusCode,
    operation: GatewayOperationKind,
    message: impl Into<String>,
    error: impl Into<String>,
    details: Option<Value>,
) -> HttpResponse {
    let mut data = json!({
        "operation": operation.as_str(),
    });
    if let Some(details) = details {
        data["details"] = details;
    }

    HttpResponse::build(status).json(json!({
        "status": "error",
        "message": message.into(),
        "error": error.into(),
        "data": data,
    }))
}

pub fn gateway_bad_request(
    operation: GatewayOperationKind,
    message: impl Into<String>,
    error: impl Into<String>,
) -> HttpResponse {
    gateway_error_with_details(
        StatusCode::BAD_REQUEST,
        operation,
        message,
        error,
        None,
    )
}

pub fn gateway_internal_error(
    operation: GatewayOperationKind,
    message: impl Into<String>,
    error: impl Into<String>,
) -> HttpResponse {
    gateway_error_with_details(
        StatusCode::INTERNAL_SERVER_ERROR,
        operation,
        message,
        error,
        None,
    )
}

pub fn gateway_service_unavailable(
    operation: GatewayOperationKind,
    message: impl Into<String>,
    error: impl Into<String>,
) -> HttpResponse {
    gateway_error_with_details(
        StatusCode::SERVICE_UNAVAILABLE,
        operation,
        message,
        error,
        None,
    )
}
