//! Comprehensive Prometheus Metrics for Broker Gateway Service
//!
//! This module provides production-grade metrics tracking for broker order routing,
//! FIX protocol communication, and position management with AMP Futures (CQG).
//!
//! ## Metric Categories
//!
//! 1. **Order Metrics**: Track order submission, fills, rejections, cancellations
//! 2. **Latency Metrics**: Monitor order routing and FIX message latency
//! 3. **Position Metrics**: Track position values and exposure
//! 4. **FIX Session Metrics**: Monitor FIX connection status and health
//! 5. **Error Metrics**: Track failures by type and severity
//!
//! ## Integration
//!
//! These metrics are exposed on port 9096 for Prometheus scraping and complement
//! the Trading Service and Trading Agent Service metrics.

#![deny(warnings)]

use once_cell::sync::Lazy;
use prometheus::{
    register_counter_vec, register_gauge, register_gauge_vec, register_histogram_vec,
    register_int_gauge_vec, CounterVec, Gauge, GaugeVec, HistogramVec, IntGaugeVec,
};

// ============================================================================
// Order Metrics
// ============================================================================

/// Counter for orders submitted to broker by symbol and order type
///
/// Labels:
/// - symbol: ES.FUT, NQ.FUT, ZN.FUT, 6E.FUT, etc.
/// - order_type: MARKET, LIMIT, STOP, STOP_LIMIT
/// - side: BUY, SELL
///
/// Use this to track order submission volume and distribution
pub static BROKER_GATEWAY_ORDERS_SUBMITTED_TOTAL: Lazy<CounterVec> = Lazy::new(|| {
    register_counter_vec!(
        "broker_gateway_orders_submitted_total",
        "Total number of orders submitted to broker by symbol, type, and side",
        &["symbol", "order_type", "side"]
    )
    .unwrap_or_else(|e| {
        eprintln!("FATAL: Failed to register broker_gateway_orders_submitted_total: {e}");
        std::process::abort()
    })
});

/// Counter for orders successfully filled by broker
///
/// Labels:
/// - symbol: Trading symbol
/// - order_type: MARKET, LIMIT, STOP, STOP_LIMIT
/// - side: BUY, SELL
///
/// Fill rate = filled_total / submitted_total
pub static BROKER_GATEWAY_ORDERS_FILLED_TOTAL: Lazy<CounterVec> = Lazy::new(|| {
    register_counter_vec!(
        "broker_gateway_orders_filled_total",
        "Total number of orders successfully filled by broker",
        &["symbol", "order_type", "side"]
    )
    .unwrap_or_else(|e| {
        eprintln!("FATAL: Failed to register broker_gateway_orders_filled_total: {e}");
        std::process::abort()
    })
});

/// Counter for orders rejected by broker or risk system
///
/// Labels:
/// - symbol: Trading symbol
/// - order_type: MARKET, LIMIT, STOP, STOP_LIMIT
/// - reason: RISK_LIMIT, INSUFFICIENT_MARGIN, INVALID_PRICE, MARKET_CLOSED, etc.
///
/// High rejection rate may indicate:
/// - Risk limits too tight
/// - Invalid order parameters
/// - Market microstructure issues
pub static BROKER_GATEWAY_ORDERS_REJECTED_TOTAL: Lazy<CounterVec> = Lazy::new(|| {
    register_counter_vec!(
        "broker_gateway_orders_rejected_total",
        "Total number of orders rejected with reason",
        &["symbol", "order_type", "reason"]
    )
    .unwrap_or_else(|e| {
        eprintln!("FATAL: Failed to register broker_gateway_orders_rejected_total: {e}");
        std::process::abort()
    })
});

/// Counter for order cancellations by symbol
///
/// Labels:
/// - symbol: Trading symbol
/// - status: CANCEL_SUCCESS, CANCEL_REJECTED, CANCEL_TOO_LATE
///
/// Tracks order cancellation volume and success rate
pub static BROKER_GATEWAY_ORDERS_CANCELLED_TOTAL: Lazy<CounterVec> = Lazy::new(|| {
    register_counter_vec!(
        "broker_gateway_orders_cancelled_total",
        "Total number of order cancellation requests by status",
        &["symbol", "status"]
    )
    .unwrap_or_else(|e| {
        eprintln!("FATAL: Failed to register broker_gateway_orders_cancelled_total: {e}");
        std::process::abort()
    })
});

/// Counter for partial fills (orders filled in multiple lots)
///
/// Labels:
/// - symbol: Trading symbol
///
/// High partial fill rate may indicate:
/// - Insufficient liquidity
/// - Large order sizes
/// - Aggressive limit prices
pub static BROKER_GATEWAY_ORDERS_PARTIAL_FILLS_TOTAL: Lazy<CounterVec> = Lazy::new(|| {
    register_counter_vec!(
        "broker_gateway_orders_partial_fills_total",
        "Total number of partial fills by symbol",
        &["symbol"]
    )
    .unwrap_or_else(|e| {
        eprintln!("FATAL: Failed to register broker_gateway_orders_partial_fills_total: {e}");
        std::process::abort()
    })
});

// ============================================================================
// Latency Metrics
// ============================================================================

/// Histogram for order routing latency (seconds)
///
/// Measures time from gRPC request to order acknowledgment
///
/// Buckets: 0.001, 0.005, 0.01, 0.05, 0.1, 0.5, 1.0 seconds
/// Target: P99 < 100ms for production trading
pub static BROKER_GATEWAY_ORDER_LATENCY_SECONDS: Lazy<HistogramVec> = Lazy::new(|| {
    register_histogram_vec!(
        "broker_gateway_order_latency_seconds",
        "Order routing latency from gRPC to broker acknowledgment in seconds",
        &["order_type"],
        vec![0.001, 0.005, 0.01, 0.05, 0.1, 0.5, 1.0]
    )
    .unwrap_or_else(|e| {
        eprintln!("FATAL: Failed to register broker_gateway_order_latency_seconds: {e}");
        std::process::abort()
    })
});

/// Histogram for FIX message processing latency (milliseconds)
///
/// Measures time to encode, send, and acknowledge FIX messages
///
/// Buckets: 0.1, 0.5, 1.0, 5.0, 10.0, 50.0, 100.0 ms
/// Target: P99 < 10ms for HFT trading
pub static BROKER_GATEWAY_FIX_MESSAGE_LATENCY_MS: Lazy<HistogramVec> = Lazy::new(|| {
    register_histogram_vec!(
        "broker_gateway_fix_message_latency_ms",
        "FIX message processing latency in milliseconds",
        &["message_type"],
        vec![0.1, 0.5, 1.0, 5.0, 10.0, 50.0, 100.0]
    )
    .unwrap_or_else(|e| {
        eprintln!("FATAL: Failed to register broker_gateway_fix_message_latency_ms: {e}");
        std::process::abort()
    })
});

/// Histogram for order fill latency (seconds)
///
/// Measures time from order submission to first fill
///
/// Buckets: 0.01, 0.1, 0.5, 1.0, 5.0, 10.0, 60.0 seconds
pub static BROKER_GATEWAY_ORDER_FILL_LATENCY_SECONDS: Lazy<HistogramVec> = Lazy::new(|| {
    register_histogram_vec!(
        "broker_gateway_order_fill_latency_seconds",
        "Time from order submission to first fill in seconds",
        &["symbol", "order_type"],
        vec![0.01, 0.1, 0.5, 1.0, 5.0, 10.0, 60.0]
    )
    .unwrap_or_else(|e| {
        eprintln!("FATAL: Failed to register broker_gateway_order_fill_latency_seconds: {e}");
        std::process::abort()
    })
});

// ============================================================================
// Position Metrics
// ============================================================================

/// Gauge for current position value in USD
///
/// Labels:
/// - symbol: Trading symbol
/// - account_id: Trading account identifier
///
/// Tracks total position value (quantity * current_price)
pub static BROKER_GATEWAY_POSITION_VALUE_USD: Lazy<GaugeVec> = Lazy::new(|| {
    register_gauge_vec!(
        "broker_gateway_position_value_usd",
        "Current position value in USD by symbol and account",
        &["symbol", "account_id"]
    )
    .unwrap_or_else(|e| {
        eprintln!("FATAL: Failed to register broker_gateway_position_value_usd: {e}");
        std::process::abort()
    })
});

/// Gauge for current position quantity
///
/// Labels:
/// - symbol: Trading symbol
/// - account_id: Trading account identifier
///
/// Positive = long position, Negative = short position
pub static BROKER_GATEWAY_POSITION_QUANTITY: Lazy<GaugeVec> = Lazy::new(|| {
    register_gauge_vec!(
        "broker_gateway_position_quantity",
        "Current position quantity by symbol and account (positive=long, negative=short)",
        &["symbol", "account_id"]
    )
    .unwrap_or_else(|e| {
        eprintln!("FATAL: Failed to register broker_gateway_position_quantity: {e}");
        std::process::abort()
    })
});

/// Gauge for unrealized PnL in USD
///
/// Labels:
/// - symbol: Trading symbol
/// - account_id: Trading account identifier
///
/// Tracks mark-to-market profit/loss on open positions
pub static BROKER_GATEWAY_UNREALIZED_PNL_USD: Lazy<GaugeVec> = Lazy::new(|| {
    register_gauge_vec!(
        "broker_gateway_unrealized_pnl_usd",
        "Unrealized profit/loss in USD by symbol and account",
        &["symbol", "account_id"]
    )
    .unwrap_or_else(|e| {
        eprintln!("FATAL: Failed to register broker_gateway_unrealized_pnl_usd: {e}");
        std::process::abort()
    })
});

/// Gauge for account cash balance in USD
///
/// Labels:
/// - account_id: Trading account identifier
///
/// Tracks available cash balance
pub static BROKER_GATEWAY_CASH_BALANCE_USD: Lazy<GaugeVec> = Lazy::new(|| {
    register_gauge_vec!(
        "broker_gateway_cash_balance_usd",
        "Account cash balance in USD",
        &["account_id"]
    )
    .unwrap_or_else(|e| {
        eprintln!("FATAL: Failed to register broker_gateway_cash_balance_usd: {e}");
        std::process::abort()
    })
});

/// Gauge for account margin used in USD
///
/// Labels:
/// - account_id: Trading account identifier
///
/// Tracks margin utilized for open positions
pub static BROKER_GATEWAY_MARGIN_USED_USD: Lazy<GaugeVec> = Lazy::new(|| {
    register_gauge_vec!(
        "broker_gateway_margin_used_usd",
        "Margin used in USD by account",
        &["account_id"]
    )
    .unwrap_or_else(|e| {
        eprintln!("FATAL: Failed to register broker_gateway_margin_used_usd: {e}");
        std::process::abort()
    })
});

// ============================================================================
// FIX Session Metrics
// ============================================================================

/// Gauge for FIX session connection status
///
/// Labels:
/// - session_id: FIX session identifier (e.g., "FOXHUNT-CQG")
///
/// Values:
/// - 0 = DISCONNECTED
/// - 1 = CONNECTED
/// - 2 = RECONNECTING
///
/// Alert when status = 0 for > 60 seconds
pub static BROKER_GATEWAY_FIX_SESSION_STATUS: Lazy<GaugeVec> = Lazy::new(|| {
    register_gauge_vec!(
        "broker_gateway_fix_session_status",
        "FIX session connection status (0=disconnected, 1=connected, 2=reconnecting)",
        &["session_id"]
    )
    .unwrap_or_else(|e| {
        eprintln!("FATAL: Failed to register broker_gateway_fix_session_status: {e}");
        std::process::abort()
    })
});

/// Counter for FIX sequence number gaps detected
///
/// Labels:
/// - session_id: FIX session identifier
///
/// Sequence gaps indicate:
/// - Message loss
/// - Network issues
/// - Session desynchronization
pub static BROKER_GATEWAY_SEQUENCE_NUMBER_GAP_TOTAL: Lazy<CounterVec> = Lazy::new(|| {
    register_counter_vec!(
        "broker_gateway_sequence_number_gap_total",
        "Total FIX sequence number gaps detected",
        &["session_id"]
    )
    .unwrap_or_else(|e| {
        eprintln!("FATAL: Failed to register broker_gateway_sequence_number_gap_total: {e}");
        std::process::abort()
    })
});

/// Gauge for FIX heartbeat round-trip time (milliseconds)
///
/// Labels:
/// - session_id: FIX session identifier
///
/// Tracks network latency via heartbeat messages
/// High RTT may indicate network congestion
pub static BROKER_GATEWAY_FIX_HEARTBEAT_RTT_MS: Lazy<GaugeVec> = Lazy::new(|| {
    register_gauge_vec!(
        "broker_gateway_fix_heartbeat_rtt_ms",
        "FIX heartbeat round-trip time in milliseconds",
        &["session_id"]
    )
    .unwrap_or_else(|e| {
        eprintln!("FATAL: Failed to register broker_gateway_fix_heartbeat_rtt_ms: {e}");
        std::process::abort()
    })
});

/// Gauge for FIX sender sequence number
///
/// Labels:
/// - session_id: FIX session identifier
///
/// Tracks outbound message sequence
pub static BROKER_GATEWAY_FIX_SENDER_SEQ_NUM: Lazy<IntGaugeVec> = Lazy::new(|| {
    register_int_gauge_vec!(
        "broker_gateway_fix_sender_seq_num",
        "FIX sender sequence number",
        &["session_id"]
    )
    .unwrap_or_else(|e| {
        eprintln!("FATAL: Failed to register broker_gateway_fix_sender_seq_num: {e}");
        std::process::abort()
    })
});

/// Gauge for FIX target sequence number
///
/// Labels:
/// - session_id: FIX session identifier
///
/// Tracks inbound message sequence
pub static BROKER_GATEWAY_FIX_TARGET_SEQ_NUM: Lazy<IntGaugeVec> = Lazy::new(|| {
    register_int_gauge_vec!(
        "broker_gateway_fix_target_seq_num",
        "FIX target sequence number",
        &["session_id"]
    )
    .unwrap_or_else(|e| {
        eprintln!("FATAL: Failed to register broker_gateway_fix_target_seq_num: {e}");
        std::process::abort()
    })
});

/// Counter for FIX messages sent by type
///
/// Labels:
/// - session_id: FIX session identifier
/// - message_type: NewOrderSingle, OrderCancelRequest, Heartbeat, etc.
pub static BROKER_GATEWAY_FIX_MESSAGES_SENT_TOTAL: Lazy<CounterVec> = Lazy::new(|| {
    register_counter_vec!(
        "broker_gateway_fix_messages_sent_total",
        "Total FIX messages sent by type",
        &["session_id", "message_type"]
    )
    .unwrap_or_else(|e| {
        eprintln!("FATAL: Failed to register broker_gateway_fix_messages_sent_total: {e}");
        std::process::abort()
    })
});

/// Counter for FIX messages received by type
///
/// Labels:
/// - session_id: FIX session identifier
/// - message_type: ExecutionReport, OrderCancelReject, Heartbeat, etc.
pub static BROKER_GATEWAY_FIX_MESSAGES_RECEIVED_TOTAL: Lazy<CounterVec> = Lazy::new(|| {
    register_counter_vec!(
        "broker_gateway_fix_messages_received_total",
        "Total FIX messages received by type",
        &["session_id", "message_type"]
    )
    .unwrap_or_else(|e| {
        eprintln!("FATAL: Failed to register broker_gateway_fix_messages_received_total: {e}");
        std::process::abort()
    })
});

// ============================================================================
// Error Metrics
// ============================================================================

/// Counter for errors by type
///
/// Labels:
/// - error_type: DATABASE_ERROR, FIX_ERROR, VALIDATION_ERROR, NETWORK_ERROR, etc.
/// - severity: CRITICAL, ERROR, WARNING
///
/// Tracks error volume by type and severity
pub static BROKER_GATEWAY_ERROR_TOTAL: Lazy<CounterVec> = Lazy::new(|| {
    register_counter_vec!(
        "broker_gateway_error_total",
        "Total errors by type and severity",
        &["error_type", "severity"]
    )
    .unwrap_or_else(|e| {
        eprintln!("FATAL: Failed to register broker_gateway_error_total: {e}");
        std::process::abort()
    })
});

/// Counter for database operation failures
///
/// Labels:
/// - operation: INSERT, UPDATE, SELECT, DELETE
///
/// Tracks database error rate
pub static BROKER_GATEWAY_DB_ERRORS_TOTAL: Lazy<CounterVec> = Lazy::new(|| {
    register_counter_vec!(
        "broker_gateway_db_errors_total",
        "Total database operation failures",
        &["operation"]
    )
    .unwrap_or_else(|e| {
        eprintln!("FATAL: Failed to register broker_gateway_db_errors_total: {e}");
        std::process::abort()
    })
});

/// Gauge for timestamp of last successful order (Unix epoch seconds)
///
/// Use for activity detection: `time() - last_order_time > 600` during market hours
pub static BROKER_GATEWAY_LAST_ORDER_TIME: Lazy<Gauge> = Lazy::new(|| {
    register_gauge!(
        "broker_gateway_last_order_time",
        "Unix timestamp of last successful order submission"
    )
    .unwrap_or_else(|e| {
        eprintln!("FATAL: Failed to register broker_gateway_last_order_time: {e}");
        std::process::abort()
    })
});

/// Gauge for active order count
///
/// Labels:
/// - status: PENDING_SUBMIT, SUBMITTED, PARTIALLY_FILLED, CANCEL_PENDING
///
/// Tracks number of active orders by status
pub static BROKER_GATEWAY_ACTIVE_ORDERS: Lazy<GaugeVec> = Lazy::new(|| {
    register_gauge_vec!(
        "broker_gateway_active_orders",
        "Number of active orders by status",
        &["status"]
    )
    .unwrap_or_else(|e| {
        eprintln!("FATAL: Failed to register broker_gateway_active_orders: {e}");
        std::process::abort()
    })
});

// ============================================================================
// Helper Functions for Recording Metrics
// ============================================================================

/// Record an order submission
///
/// # Arguments
/// * `symbol` - Trading symbol (e.g., "ES.FUT")
/// * `order_type` - Order type (MARKET, LIMIT, STOP, STOP_LIMIT)
/// * `side` - Order side (BUY, SELL)
pub fn record_order_submitted(symbol: &str, order_type: &str, side: &str) {
    BROKER_GATEWAY_ORDERS_SUBMITTED_TOTAL
        .with_label_values(&[symbol, order_type, side])
        .inc();

    // Update last order timestamp
    let now = std::time::SystemTime::now()
        .duration_since(std::time::UNIX_EPOCH)
        .map(|d| d.as_secs() as f64)
        .unwrap_or(0.0);
    BROKER_GATEWAY_LAST_ORDER_TIME.set(now);
}

/// Record an order fill
///
/// # Arguments
/// * `symbol` - Trading symbol
/// * `order_type` - Order type
/// * `side` - Order side
/// * `fill_latency_seconds` - Time from submission to fill
pub fn record_order_filled(
    symbol: &str,
    order_type: &str,
    side: &str,
    fill_latency_seconds: f64,
) {
    BROKER_GATEWAY_ORDERS_FILLED_TOTAL
        .with_label_values(&[symbol, order_type, side])
        .inc();

    BROKER_GATEWAY_ORDER_FILL_LATENCY_SECONDS
        .with_label_values(&[symbol, order_type])
        .observe(fill_latency_seconds);
}

/// Record an order rejection
///
/// # Arguments
/// * `symbol` - Trading symbol
/// * `order_type` - Order type
/// * `reason` - Rejection reason
pub fn record_order_rejected(symbol: &str, order_type: &str, reason: &str) {
    BROKER_GATEWAY_ORDERS_REJECTED_TOTAL
        .with_label_values(&[symbol, order_type, reason])
        .inc();

    record_error("ORDER_REJECTED", "WARNING");
}

/// Record an order cancellation
///
/// # Arguments
/// * `symbol` - Trading symbol
/// * `status` - Cancellation status (CANCEL_SUCCESS, CANCEL_REJECTED, CANCEL_TOO_LATE)
pub fn record_order_cancelled(symbol: &str, status: &str) {
    BROKER_GATEWAY_ORDERS_CANCELLED_TOTAL
        .with_label_values(&[symbol, status])
        .inc();
}

/// Record a partial fill
///
/// # Arguments
/// * `symbol` - Trading symbol
pub fn record_partial_fill(symbol: &str) {
    BROKER_GATEWAY_ORDERS_PARTIAL_FILLS_TOTAL
        .with_label_values(&[symbol])
        .inc();
}

/// Record order routing latency
///
/// # Arguments
/// * `order_type` - Order type
/// * `latency_seconds` - Latency in seconds
pub fn record_order_latency(order_type: &str, latency_seconds: f64) {
    BROKER_GATEWAY_ORDER_LATENCY_SECONDS
        .with_label_values(&[order_type])
        .observe(latency_seconds);
}

/// Update position metrics
///
/// # Arguments
/// * `symbol` - Trading symbol
/// * `account_id` - Account identifier
/// * `quantity` - Position quantity
/// * `value_usd` - Position value in USD
/// * `unrealized_pnl` - Unrealized PnL in USD
pub fn update_position(
    symbol: &str,
    account_id: &str,
    quantity: f64,
    value_usd: f64,
    unrealized_pnl: f64,
) {
    BROKER_GATEWAY_POSITION_QUANTITY
        .with_label_values(&[symbol, account_id])
        .set(quantity);

    BROKER_GATEWAY_POSITION_VALUE_USD
        .with_label_values(&[symbol, account_id])
        .set(value_usd);

    BROKER_GATEWAY_UNREALIZED_PNL_USD
        .with_label_values(&[symbol, account_id])
        .set(unrealized_pnl);
}

/// Update account metrics
///
/// # Arguments
/// * `account_id` - Account identifier
/// * `cash_balance` - Cash balance in USD
/// * `margin_used` - Margin used in USD
pub fn update_account(account_id: &str, cash_balance: f64, margin_used: f64) {
    BROKER_GATEWAY_CASH_BALANCE_USD
        .with_label_values(&[account_id])
        .set(cash_balance);

    BROKER_GATEWAY_MARGIN_USED_USD
        .with_label_values(&[account_id])
        .set(margin_used);
}

/// Update FIX session status
///
/// # Arguments
/// * `session_id` - FIX session identifier
/// * `status` - Connection status (0=disconnected, 1=connected, 2=reconnecting)
pub fn update_fix_session_status(session_id: &str, status: f64) {
    BROKER_GATEWAY_FIX_SESSION_STATUS
        .with_label_values(&[session_id])
        .set(status);
}

/// Record FIX sequence number gap
///
/// # Arguments
/// * `session_id` - FIX session identifier
pub fn record_sequence_gap(session_id: &str) {
    BROKER_GATEWAY_SEQUENCE_NUMBER_GAP_TOTAL
        .with_label_values(&[session_id])
        .inc();

    record_error("SEQUENCE_GAP", "WARNING");
}

/// Update FIX heartbeat RTT
///
/// # Arguments
/// * `session_id` - FIX session identifier
/// * `rtt_ms` - Round-trip time in milliseconds
pub fn update_heartbeat_rtt(session_id: &str, rtt_ms: f64) {
    BROKER_GATEWAY_FIX_HEARTBEAT_RTT_MS
        .with_label_values(&[session_id])
        .set(rtt_ms);
}

/// Update FIX sequence numbers
///
/// # Arguments
/// * `session_id` - FIX session identifier
/// * `sender_seq` - Sender sequence number
/// * `target_seq` - Target sequence number
pub fn update_sequence_numbers(session_id: &str, sender_seq: i64, target_seq: i64) {
    BROKER_GATEWAY_FIX_SENDER_SEQ_NUM
        .with_label_values(&[session_id])
        .set(sender_seq);

    BROKER_GATEWAY_FIX_TARGET_SEQ_NUM
        .with_label_values(&[session_id])
        .set(target_seq);
}

/// Record FIX message sent
///
/// # Arguments
/// * `session_id` - FIX session identifier
/// * `message_type` - Message type
/// * `latency_ms` - Processing latency in milliseconds
pub fn record_fix_message_sent(session_id: &str, message_type: &str, latency_ms: f64) {
    BROKER_GATEWAY_FIX_MESSAGES_SENT_TOTAL
        .with_label_values(&[session_id, message_type])
        .inc();

    BROKER_GATEWAY_FIX_MESSAGE_LATENCY_MS
        .with_label_values(&[message_type])
        .observe(latency_ms);
}

/// Record FIX message received
///
/// # Arguments
/// * `session_id` - FIX session identifier
/// * `message_type` - Message type
pub fn record_fix_message_received(session_id: &str, message_type: &str) {
    BROKER_GATEWAY_FIX_MESSAGES_RECEIVED_TOTAL
        .with_label_values(&[session_id, message_type])
        .inc();
}

/// Record an error
///
/// # Arguments
/// * `error_type` - Error type
/// * `severity` - Error severity (CRITICAL, ERROR, WARNING)
pub fn record_error(error_type: &str, severity: &str) {
    BROKER_GATEWAY_ERROR_TOTAL
        .with_label_values(&[error_type, severity])
        .inc();
}

/// Record a database error
///
/// # Arguments
/// * `operation` - Database operation (INSERT, UPDATE, SELECT, DELETE)
pub fn record_db_error(operation: &str) {
    BROKER_GATEWAY_DB_ERRORS_TOTAL
        .with_label_values(&[operation])
        .inc();

    record_error("DATABASE_ERROR", "ERROR");
}

/// Update active order count
///
/// # Arguments
/// * `status` - Order status
/// * `count` - Number of active orders
pub fn update_active_orders(status: &str, count: f64) {
    BROKER_GATEWAY_ACTIVE_ORDERS
        .with_label_values(&[status])
        .set(count);
}
