//! Protocol Translation Layer for Trading Service
//!
//! Translates between TLI proto (foxhunt.tli) and Trading Service proto (trading).
//! Acts as API Gateway's adapter to bridge client-facing and backend interfaces.
//!
//! Architecture:
//! - Receives TLI proto requests from clients
//! - Translates to Trading Service proto
//! - Forwards to backend Trading Service
//! - Translates responses back to TLI proto
//!
//! Features:
//! - Zero-allocation translations where possible
//! - Circuit breaker with atomic health state
//! - Connection pooling with tonic::Channel
//! - Metadata extraction and forwarding
//! - Target: <10μs translation overhead

use futures::Stream;
use std::collections::HashMap;
use std::pin::Pin;
use std::sync::atomic::{AtomicBool, AtomicU64, Ordering};
use std::sync::Arc;
use std::time::Instant;
use tokio::sync::watch;
use tonic::transport::Channel;
use tonic::{Request, Response, Status};
use tracing::{debug, error, warn, instrument};

// Import TLI proto (client-facing interface)
use crate::foxhunt::tli::trading_service_server::TradingService as TliTradingService;

// Import Trading Service backend proto
use crate::trading_backend::trading_service_client::TradingServiceClient as BackendTradingClient;

// Import Risk Service backend proto
use crate::risk::risk_service_client::RiskServiceClient as BackendRiskClient;

// Import Config Service backend proto
use crate::config_backend::config_service_client::ConfigServiceClient as BackendConfigClient;

/// Health checker for backend trading service
///
/// Uses atomic operations for lock-free health state management.
///
/// Minimal overhead: ~1-2ns per health check (single atomic load).
#[derive(Debug)]
pub struct HealthChecker {
    /// Last successful health check timestamp (nanoseconds since epoch)
    last_check: Arc<AtomicU64>,
    /// Current health state (true = healthy, false = unhealthy)
    is_healthy: Arc<AtomicBool>,
    /// Health check interval in seconds
    check_interval_secs: u64,
}

impl HealthChecker {
    /// Create new health checker with specified check interval
    pub fn new(check_interval_secs: u64) -> Self {
        Self {
            last_check: Arc::new(AtomicU64::new(0)),
            is_healthy: Arc::new(AtomicBool::new(true)), // Optimistically start healthy
            check_interval_secs,
        }
    }

    /// Check if backend is healthy (lock-free atomic read)
    ///
    /// Latency: ~1-2ns (single atomic load)
    #[inline(always)]
    pub fn is_healthy(&self) -> bool {
        self.is_healthy.load(Ordering::Relaxed)
    }

    /// Check if health check is needed based on interval
    fn should_check(&self) -> bool {
        let now = std::time::SystemTime::now()
            .duration_since(std::time::UNIX_EPOCH)
            .map(|d| d.as_secs())
            .unwrap_or(0);

        let last = self.last_check.load(Ordering::Relaxed);
        now.saturating_sub(last) >= self.check_interval_secs
    }

    /// Perform health check against backend service
    pub async fn check_health(&self, client: &mut BackendTradingClient<Channel>) {
        if !self.should_check() {
            return;
        }

        let start = Instant::now();

        // Simple health check with GetPositions
        let health_result = tokio::time::timeout(
            std::time::Duration::from_millis(100),
            client.get_positions(Request::new(crate::trading_backend::GetPositionsRequest {
                account_id: Some("health_check".to_string()),
                symbol: None,
            })),
        )
        .await;

        let is_healthy = health_result.is_ok();
        self.is_healthy.store(is_healthy, Ordering::Relaxed);

        let now_secs = std::time::SystemTime::now()
            .duration_since(std::time::UNIX_EPOCH)
            .map(|d| d.as_secs())
            .unwrap_or(0);
        self.last_check.store(now_secs, Ordering::Relaxed);

        let elapsed = start.elapsed();
        if is_healthy {
            debug!("Health check passed in {:?}", elapsed);
        } else {
            warn!("Health check failed in {:?}", elapsed);
        }
    }

    /// Mark backend as unhealthy (used by circuit breaker)
    pub fn mark_unhealthy(&self) {
        self.is_healthy.store(false, Ordering::Relaxed);
    }
}

/// Per-service health entry streamed to clients via SubscribeSystemStatus.
#[derive(Debug, Clone)]
pub struct ServiceHealthEntry {
    pub name: String,
    pub healthy: bool,
    pub message: String,
}

/// Shared health snapshot updated by a background task and consumed by
/// `subscribe_system_status`. Uses a `watch` channel for efficient broadcast.
#[derive(Clone)]
pub struct BackendHealthState {
    rx: watch::Receiver<Vec<ServiceHealthEntry>>,
}

impl BackendHealthState {
    /// Create a new health state and its update sender.
    pub fn new() -> (watch::Sender<Vec<ServiceHealthEntry>>, Self) {
        let (tx, rx) = watch::channel(Vec::new());
        (tx, Self { rx })
    }
}

/// Protocol translation proxy for Trading Service
///
/// Bridges TLI proto (client interface) and Trading Service proto (backend).
pub struct TradingServiceProxy {
    /// Backend trading service client
    backend_client: BackendTradingClient<Channel>,
    /// Backend risk service client
    risk_client: BackendRiskClient<Channel>,
    /// Backend config service client
    config_client: BackendConfigClient<Channel>,
    /// Health checker with circuit breaker
    health_checker: Arc<HealthChecker>,
    /// Shared backend health state for SubscribeSystemStatus
    health_state: Option<BackendHealthState>,
}

impl TradingServiceProxy {
    /// Create new trading service proxy with protocol translation
    pub async fn new(backend_url: &str) -> Result<Self, Box<dyn std::error::Error>> {
        let channel = Channel::from_shared(backend_url.to_string())?
            .connect()
            .await?;

        let backend_client = BackendTradingClient::new(channel.clone());
        let risk_client = BackendRiskClient::new(channel.clone());
        let config_client = BackendConfigClient::new(channel);

        Ok(Self {
            backend_client,
            risk_client,
            config_client,
            health_checker: Arc::new(HealthChecker::new(30)),
            health_state: None,
        })
    }

    /// Create proxy with lazy connection
    pub fn new_lazy(backend_url: &str) -> Result<Self, Box<dyn std::error::Error>> {
        let channel = Channel::from_shared(backend_url.to_string())?.connect_lazy();

        let backend_client = BackendTradingClient::new(channel.clone());
        let risk_client = BackendRiskClient::new(channel.clone());
        let config_client = BackendConfigClient::new(channel);

        Ok(Self {
            backend_client,
            risk_client,
            config_client,
            health_checker: Arc::new(HealthChecker::new(30)),
            health_state: None,
        })
    }

    /// Inject shared backend health state for SubscribeSystemStatus streaming.
    pub fn set_health_state(&mut self, state: BackendHealthState) {
        self.health_state = Some(state);
    }

    /// Check circuit breaker before forwarding request
    #[inline(always)]
    fn check_circuit_breaker(&self) -> Result<(), Status> {
        if !self.health_checker.is_healthy() {
            return Err(Status::unavailable(
                "Trading service is unavailable (circuit breaker open)",
            ));
        }
        Ok(())
    }

    /// Extract user_id from metadata (injected by upstream AuthInterceptor)
    #[inline(always)]
    fn extract_user_id<T>(request: &Request<T>) -> Result<String, Status> {
        request
            .metadata()
            .get("x-user-id")
            .ok_or_else(|| Status::internal("Missing user context (x-user-id)"))?
            .to_str()
            .map(|s| s.to_string())
            .map_err(|_| Status::internal("Invalid user_id encoding"))
    }

    /// Background health check
    pub async fn background_health_check(&mut self) {
        self.health_checker
            .check_health(&mut self.backend_client)
            .await;
    }

    // ========================================================================
    // Translation Helper Functions
    // ========================================================================

    /// Translate TLI OrderSide to Backend OrderSide (enum values match, just pass through)
    #[inline]
    fn translate_order_side(tli_side: i32) -> i32 {
        tli_side // Enum values are identical between TLI and backend proto
    }

    /// Translate Backend OrderSide to TLI OrderSide (enum values match, just pass through)
    #[inline]
    fn translate_order_side_back(backend_side: i32) -> i32 {
        backend_side // Enum values are identical between TLI and backend proto
    }

    /// Translate TLI OrderType to Backend OrderType (enum values match, just pass through)
    #[inline]
    fn translate_order_type(tli_type: i32) -> i32 {
        tli_type // Enum values are identical between TLI and backend proto
    }

    /// Translate Backend OrderType to TLI OrderType (enum values match, just pass through)
    #[inline]
    fn translate_order_type_back(backend_type: i32) -> i32 {
        backend_type // Enum values are identical between TLI and backend proto
    }

    /// Translate Backend OrderStatus to TLI OrderStatus (enum values match, just pass through)
    #[inline]
    fn translate_order_status(backend_status: i32) -> i32 {
        backend_status // Enum values are identical between TLI and backend proto
    }

    /// Translate Backend `Position` to TLI Position
    fn translate_position(
        backend_pos: crate::trading_backend::Position,
    ) -> crate::foxhunt::tli::Position {
        // Calculate market_price from market_value and quantity
        let market_price = if backend_pos.quantity != 0.0 {
            backend_pos.market_value / backend_pos.quantity
        } else {
            0.0
        };

        crate::foxhunt::tli::Position {
            symbol: backend_pos.symbol,
            quantity: backend_pos.quantity,
            market_price,
            market_value: backend_pos.market_value,
            average_cost: backend_pos.average_price,
            unrealized_pnl: backend_pos.unrealized_pnl,
            realized_pnl: backend_pos.realized_pnl,
        }
    }

    /// Translate Backend MarketDataEvent to TLI MarketDataEvent
    fn translate_market_data_event(
        backend_event: crate::trading_backend::MarketDataEvent,
    ) -> crate::foxhunt::tli::MarketDataEvent {
        use crate::trading_backend::market_data_event::Data as BackendData;

        // Extract the event data based on backend oneof type
        let tli_event = match backend_event.data {
            Some(BackendData::Trade(backend_trade)) => {
                // Backend Trade → TLI TradeData
                crate::foxhunt::tli::market_data_event::Event::Trade(
                    crate::foxhunt::tli::TradeData {
                        symbol: backend_event.symbol.clone(),
                        timestamp_unix_nanos: backend_trade.timestamp,
                        price: backend_trade.price,
                        size: backend_trade.volume as u64,
                        trade_id: format!("{}", backend_trade.timestamp), // Generate trade_id from timestamp
                        exchange: "".to_string(), // Backend doesn't have exchange field
                    },
                )
            },
            Some(BackendData::Quote(backend_quote)) => {
                // Backend Quote → TLI QuoteData
                crate::foxhunt::tli::market_data_event::Event::Quote(
                    crate::foxhunt::tli::QuoteData {
                        symbol: backend_event.symbol.clone(),
                        timestamp_unix_nanos: backend_quote.timestamp,
                        bid_price: backend_quote.bid_price,
                        bid_size: backend_quote.bid_size as u64,
                        ask_price: backend_quote.ask_price,
                        ask_size: backend_quote.ask_size as u64,
                        exchange: "".to_string(), // Backend doesn't have exchange field
                    },
                )
            },
            Some(BackendData::OrderBook(backend_book)) => {
                // Backend OrderBook → TLI TickData (use last trade from order book)
                // Note: TLI doesn't have OrderBook, so we convert to a tick with mid price
                let mid_price = if let (Some(bid), Some(ask)) =
                    (backend_book.bids.first(), backend_book.asks.first())
                {
                    (bid.price + ask.price) / 2.0
                } else if let Some(bid) = backend_book.bids.first() {
                    bid.price
                } else if let Some(ask) = backend_book.asks.first() {
                    ask.price
                } else {
                    0.0
                };

                let size = if let Some(bid) = backend_book.bids.first() {
                    bid.quantity as u64
                } else if let Some(ask) = backend_book.asks.first() {
                    ask.quantity as u64
                } else {
                    0_u64
                };

                crate::foxhunt::tli::market_data_event::Event::Tick(crate::foxhunt::tli::TickData {
                    symbol: backend_event.symbol.clone(),
                    timestamp_unix_nanos: backend_book.timestamp,
                    price: mid_price,
                    size,
                    exchange: "".to_string(),
                })
            },
            None => {
                // No data available, create empty tick
                warn!("Backend MarketDataEvent has no data, creating empty tick");
                crate::foxhunt::tli::market_data_event::Event::Tick(crate::foxhunt::tli::TickData {
                    symbol: backend_event.symbol.clone(),
                    timestamp_unix_nanos: backend_event.timestamp,
                    price: 0.0,
                    size: 0_u64,
                    exchange: "".to_string(),
                })
            },
        };

        crate::foxhunt::tli::MarketDataEvent {
            event: Some(tli_event),
        }
    }

    /// Translate Backend OrderEvent to TLI OrderUpdateEvent
    fn translate_order_event(
        backend_event: crate::trading_backend::OrderEvent,
    ) -> crate::foxhunt::tli::OrderUpdateEvent {
        // Extract order from backend event
        let backend_order = backend_event.order.unwrap_or_else(|| {
            warn!("Backend OrderEvent missing order details");
            crate::trading_backend::Order {
                order_id: backend_event.order_id.clone(),
                symbol: "".to_string(),
                side: 0,
                order_type: 0,
                quantity: 0.0,
                filled_quantity: 0.0,
                price: None,
                stop_price: None,
                status: 0,
                created_at: backend_event.timestamp,
                updated_at: Some(backend_event.timestamp),
                account_id: "".to_string(),
                metadata: Default::default(),
            }
        });

        crate::foxhunt::tli::OrderUpdateEvent {
            order_id: backend_order.order_id,
            symbol: backend_order.symbol,
            status: backend_order.status, // Enum values match
            filled_quantity: backend_order.filled_quantity,
            remaining_quantity: backend_order.quantity - backend_order.filled_quantity,
            last_fill_price: backend_order.price.unwrap_or(0.0),
            last_fill_quantity: 0_u64, // Backend doesn't have last_fill_quantity
            timestamp_unix_nanos: backend_event.timestamp,
            message: backend_event.message,
        }
    }
}

// ============================================================================
// TradingService trait implementation with protocol translation
// ============================================================================

#[tonic::async_trait]
impl TliTradingService for TradingServiceProxy {
    // Streaming response types
    type SubscribeMarketDataStream =
        Pin<Box<dyn Stream<Item = Result<crate::foxhunt::tli::MarketDataEvent, Status>> + Send>>;
    type SubscribeOrderUpdatesStream =
        Pin<Box<dyn Stream<Item = Result<crate::foxhunt::tli::OrderUpdateEvent, Status>> + Send>>;
    type SubscribeRiskAlertsStream =
        Pin<Box<dyn Stream<Item = Result<crate::foxhunt::tli::RiskAlertEvent, Status>> + Send>>;
    type SubscribeMetricsStream =
        Pin<Box<dyn Stream<Item = Result<crate::foxhunt::tli::MetricsEvent, Status>> + Send>>;
    type SubscribeConfigStream =
        Pin<Box<dyn Stream<Item = Result<crate::foxhunt::tli::ConfigEvent, Status>> + Send>>;
    type SubscribeSystemStatusStream =
        Pin<Box<dyn Stream<Item = Result<crate::foxhunt::tli::SystemStatusEvent, Status>> + Send>>;

    /// Submit order with protocol translation
    #[instrument(skip_all)]
    async fn submit_order(
        &self,
        request: Request<crate::foxhunt::tli::SubmitOrderRequest>,
    ) -> Result<Response<crate::foxhunt::tli::SubmitOrderResponse>, Status> {
        self.check_circuit_breaker()?;

        let user_id = Self::extract_user_id(&request)?;
        debug!("Translating submit_order for user: {}", user_id);

        // Extract metadata BEFORE into_inner() consumes the request
        let client_metadata = request.metadata().clone();
        debug!("Client metadata count: {}", client_metadata.keys().count());
        debug!("Checking for authorization header...");
        if let Some(auth) = client_metadata.get("authorization") {
            debug!("  authorization: present (value: {:?})", auth);
        } else {
            error!("  authorization: MISSING");
        }
        if let Some(user_id) = client_metadata.get("x-user-id") {
            debug!("  x-user-id: {:?}", user_id);
        } else {
            error!("  x-user-id: MISSING");
        }
        let tli_req = request.into_inner();

        // Translate TLI proto → Trading proto
        let backend_req = crate::trading_backend::SubmitOrderRequest {
            symbol: tli_req.symbol,
            side: Self::translate_order_side(tli_req.side),
            quantity: tli_req.quantity,
            order_type: Self::translate_order_type(tli_req.order_type),
            price: tli_req.price,
            stop_price: tli_req.stop_price,
            account_id: user_id,
            metadata: vec![
                ("client_order_id".to_string(), tli_req.client_order_id),
                ("time_in_force".to_string(), tli_req.time_in_force),
            ]
            .into_iter()
            .collect(),
        };

        // Forward to backend with auth metadata
        let mut client = self.backend_client.clone();
        let mut backend_request = Request::new(backend_req);

        // Forward authorization and user context from client metadata
        let backend_metadata = backend_request.metadata_mut();
        if let Some(auth_token) = client_metadata.get("authorization") {
            debug!("Forwarding authorization header to backend");
            backend_metadata.insert("authorization", auth_token.clone());
        } else {
            error!("No authorization header in client metadata!");
        }
        if let Some(user_id_meta) = client_metadata.get("x-user-id") {
            debug!("Forwarding x-user-id header to backend");
            backend_metadata.insert("x-user-id", user_id_meta.clone());
        } else {
            error!("No x-user-id header in client metadata!");
        }

        let backend_resp = match client.submit_order(backend_request).await {
            Ok(resp) => resp.into_inner(),
            Err(e) => {
                error!("Backend error in submit_order: {}", e);
                if matches!(
                    e.code(),
                    tonic::Code::Unavailable | tonic::Code::DeadlineExceeded
                ) {
                    self.health_checker.mark_unhealthy();
                }
                return Err(e);
            },
        };

        // Translate Trading proto → TLI proto
        let tli_resp = crate::foxhunt::tli::SubmitOrderResponse {
            success: backend_resp.status == 2, // OrderStatusSubmitted = 2
            order_id: backend_resp.order_id,
            message: backend_resp.message,
            timestamp_unix_nanos: backend_resp.timestamp,
        };

        Ok(Response::new(tli_resp))
    }

    /// Cancel order with protocol translation
    #[instrument(skip_all)]
    async fn cancel_order(
        &self,
        request: Request<crate::foxhunt::tli::CancelOrderRequest>,
    ) -> Result<Response<crate::foxhunt::tli::CancelOrderResponse>, Status> {
        self.check_circuit_breaker()?;

        let user_id = Self::extract_user_id(&request)?;
        debug!("Translating cancel_order for user: {}", user_id);

        // Extract metadata BEFORE into_inner() consumes the request
        let client_metadata = request.metadata().clone();
        let tli_req = request.into_inner();

        // Translate request
        let backend_req = crate::trading_backend::CancelOrderRequest {
            order_id: tli_req.order_id,
            account_id: user_id,
        };

        // Forward to backend with auth metadata
        let mut client = self.backend_client.clone();
        let mut backend_request = Request::new(backend_req);

        // Forward authorization and user context from client metadata
        let backend_metadata = backend_request.metadata_mut();
        if let Some(auth_token) = client_metadata.get("authorization") {
            backend_metadata.insert("authorization", auth_token.clone());
        }
        if let Some(user_id_meta) = client_metadata.get("x-user-id") {
            backend_metadata.insert("x-user-id", user_id_meta.clone());
        }

        let backend_resp = match client.cancel_order(backend_request).await {
            Ok(resp) => resp.into_inner(),
            Err(e) => {
                error!("Backend error in cancel_order: {}", e);
                if matches!(
                    e.code(),
                    tonic::Code::Unavailable | tonic::Code::DeadlineExceeded
                ) {
                    self.health_checker.mark_unhealthy();
                }
                return Err(e);
            },
        };

        // Translate response
        let tli_resp = crate::foxhunt::tli::CancelOrderResponse {
            success: backend_resp.success,
            message: backend_resp.message,
            timestamp_unix_nanos: backend_resp.timestamp,
        };

        Ok(Response::new(tli_resp))
    }

    /// Get order status with protocol translation
    #[instrument(skip_all)]
    async fn get_order_status(
        &self,
        request: Request<crate::foxhunt::tli::GetOrderStatusRequest>,
    ) -> Result<Response<crate::foxhunt::tli::GetOrderStatusResponse>, Status> {
        self.check_circuit_breaker()?;

        // Extract metadata BEFORE into_inner() consumes the request
        let client_metadata = request.metadata().clone();
        let tli_req = request.into_inner();

        // Translate request
        let backend_req = crate::trading_backend::GetOrderStatusRequest {
            order_id: tli_req.order_id.clone(),
        };

        // Forward to backend with auth metadata
        let mut client = self.backend_client.clone();
        let mut backend_request = Request::new(backend_req);

        // Forward authorization and user context from client metadata
        let backend_metadata = backend_request.metadata_mut();
        if let Some(auth_token) = client_metadata.get("authorization") {
            backend_metadata.insert("authorization", auth_token.clone());
        }
        if let Some(user_id_meta) = client_metadata.get("x-user-id") {
            backend_metadata.insert("x-user-id", user_id_meta.clone());
        }

        let backend_resp = match client.get_order_status(backend_request).await {
            Ok(resp) => resp.into_inner(),
            Err(e) => {
                error!("Backend error in get_order_status: {}", e);
                if matches!(
                    e.code(),
                    tonic::Code::Unavailable | tonic::Code::DeadlineExceeded
                ) {
                    self.health_checker.mark_unhealthy();
                }
                return Err(e);
            },
        };

        // Extract order from backend response
        let backend_order = backend_resp
            .order
            .ok_or_else(|| Status::internal("Backend returned empty order"))?;

        // Translate response
        let tli_resp = crate::foxhunt::tli::GetOrderStatusResponse {
            order_id: backend_order.order_id,
            symbol: backend_order.symbol,
            side: Self::translate_order_side_back(backend_order.side),
            order_type: Self::translate_order_type_back(backend_order.order_type),
            quantity: backend_order.quantity,
            filled_quantity: backend_order.filled_quantity,
            remaining_quantity: backend_order.quantity - backend_order.filled_quantity,
            average_price: backend_order.price.unwrap_or(0.0),
            status: Self::translate_order_status(backend_order.status),
            created_at_unix_nanos: backend_order.created_at,
            updated_at_unix_nanos: backend_order.updated_at.unwrap_or(backend_order.created_at),
        };

        Ok(Response::new(tli_resp))
    }

    /// Get account info with protocol translation
    #[instrument(skip_all)]
    async fn get_account_info(
        &self,
        request: Request<crate::foxhunt::tli::GetAccountInfoRequest>,
    ) -> Result<Response<crate::foxhunt::tli::GetAccountInfoResponse>, Status> {
        self.check_circuit_breaker()?;

        let _user_id = Self::extract_user_id(&request)?;

        // Extract metadata BEFORE into_inner() consumes the request
        let client_metadata = request.metadata().clone();
        let tli_req = request.into_inner();

        // TLI GetAccountInfo maps to Backend GetPortfolioSummary
        let backend_req = crate::trading_backend::GetPortfolioSummaryRequest {
            account_id: tli_req.account_id.clone(),
        };

        // Forward to backend with auth metadata
        let mut client = self.backend_client.clone();
        let mut backend_request = Request::new(backend_req);

        // Forward authorization and user context from client metadata
        let backend_metadata = backend_request.metadata_mut();
        if let Some(auth_token) = client_metadata.get("authorization") {
            backend_metadata.insert("authorization", auth_token.clone());
        }
        if let Some(user_id_meta) = client_metadata.get("x-user-id") {
            backend_metadata.insert("x-user-id", user_id_meta.clone());
        }

        let backend_resp = match client.get_portfolio_summary(backend_request).await {
            Ok(resp) => resp.into_inner(),
            Err(e) => {
                error!("Backend error in get_portfolio_summary: {}", e);
                if matches!(
                    e.code(),
                    tonic::Code::Unavailable | tonic::Code::DeadlineExceeded
                ) {
                    self.health_checker.mark_unhealthy();
                }
                return Err(e);
            },
        };

        // Translate response
        let tli_resp = crate::foxhunt::tli::GetAccountInfoResponse {
            account_id: tli_req.account_id,
            total_value: backend_resp.total_value,
            cash_balance: backend_resp.buying_power, // Map buying_power to cash_balance
            buying_power: backend_resp.buying_power,
            maintenance_margin: backend_resp.margin_used,
            day_trading_buying_power: backend_resp.buying_power, // Approximation
        };

        Ok(Response::new(tli_resp))
    }

    /// Get positions with protocol translation
    #[instrument(skip_all)]
    async fn get_positions(
        &self,
        request: Request<crate::foxhunt::tli::GetPositionsRequest>,
    ) -> Result<Response<crate::foxhunt::tli::GetPositionsResponse>, Status> {
        self.check_circuit_breaker()?;

        let user_id = Self::extract_user_id(&request)?;
        debug!("Translating get_positions for user: {}", user_id);

        // Extract metadata BEFORE into_inner() consumes the request
        let client_metadata = request.metadata().clone();
        let tli_req = request.into_inner();

        // Translate request
        let backend_req = crate::trading_backend::GetPositionsRequest {
            account_id: Some(user_id),
            symbol: tli_req.symbol,
        };

        // Forward to backend with auth metadata
        let mut client = self.backend_client.clone();
        let mut backend_request = Request::new(backend_req);

        // Forward authorization and user context from client metadata
        let backend_metadata = backend_request.metadata_mut();
        if let Some(auth_token) = client_metadata.get("authorization") {
            backend_metadata.insert("authorization", auth_token.clone());
        }
        if let Some(user_id_meta) = client_metadata.get("x-user-id") {
            backend_metadata.insert("x-user-id", user_id_meta.clone());
        }

        let backend_resp = match client.get_positions(backend_request).await {
            Ok(resp) => resp.into_inner(),
            Err(e) => {
                error!("Backend error in get_positions: {}", e);
                if matches!(
                    e.code(),
                    tonic::Code::Unavailable | tonic::Code::DeadlineExceeded
                ) {
                    self.health_checker.mark_unhealthy();
                }
                return Err(e);
            },
        };

        // Translate positions
        let tli_positions = backend_resp
            .positions
            .into_iter()
            .map(Self::translate_position)
            .collect();

        let tli_resp = crate::foxhunt::tli::GetPositionsResponse {
            positions: tli_positions,
        };

        Ok(Response::new(tli_resp))
    }

    // ========================================================================
    // Streaming Methods (Phase 4 implementation)
    // ========================================================================

    /// Subscribe to market data stream with protocol translation
    #[instrument(skip_all)]
    async fn subscribe_market_data(
        &self,
        request: Request<crate::foxhunt::tli::SubscribeMarketDataRequest>,
    ) -> Result<Response<Self::SubscribeMarketDataStream>, Status> {
        self.check_circuit_breaker()?;

        let _user_id = Self::extract_user_id(&request)?;

        // Extract metadata BEFORE into_inner() consumes the request
        let client_metadata = request.metadata().clone();
        let tli_req = request.into_inner();

        debug!(
            "Translating subscribe_market_data for symbols: {:?}, data_types: {:?}",
            tli_req.symbols, tli_req.data_types
        );

        // Translate TLI proto → Trading proto
        let backend_req = crate::trading_backend::StreamMarketDataRequest {
            symbols: tli_req.symbols,
            data_types: tli_req.data_types, // Enum values match between protos
        };

        // Connect to backend stream with auth metadata
        let mut client = self.backend_client.clone();
        let mut backend_request = Request::new(backend_req);

        // Forward authorization and user context from client metadata
        let backend_metadata = backend_request.metadata_mut();
        if let Some(auth_token) = client_metadata.get("authorization") {
            backend_metadata.insert("authorization", auth_token.clone());
        }
        if let Some(user_id_meta) = client_metadata.get("x-user-id") {
            backend_metadata.insert("x-user-id", user_id_meta.clone());
        }

        let backend_stream = match client.stream_market_data(backend_request).await {
            Ok(resp) => resp.into_inner(),
            Err(e) => {
                error!("Backend error in subscribe_market_data: {}", e);
                if matches!(
                    e.code(),
                    tonic::Code::Unavailable | tonic::Code::DeadlineExceeded
                ) {
                    self.health_checker.mark_unhealthy();
                }
                return Err(e);
            },
        };

        // Create translation stream: Backend MarketDataEvent → TLI MarketDataEvent
        let tli_stream = futures::stream::unfold(backend_stream, |mut stream| async move {
            match stream.message().await {
                Ok(Some(backend_event)) => {
                    let tli_event = Self::translate_market_data_event(backend_event);
                    Some((Ok(tli_event), stream))
                },
                Ok(None) => None, // Stream ended
                Err(e) => {
                    error!("Error in market data stream: {}", e);
                    Some((Err(e), stream))
                },
            }
        });

        Ok(Response::new(Box::pin(tli_stream)))
    }

    /// Subscribe to order updates stream with protocol translation
    #[instrument(skip_all)]
    async fn subscribe_order_updates(
        &self,
        request: Request<crate::foxhunt::tli::SubscribeOrderUpdatesRequest>,
    ) -> Result<Response<Self::SubscribeOrderUpdatesStream>, Status> {
        self.check_circuit_breaker()?;

        let user_id = Self::extract_user_id(&request)?;

        // Extract metadata BEFORE into_inner() consumes the request
        let client_metadata = request.metadata().clone();
        let tli_req = request.into_inner();

        debug!(
            "Translating subscribe_order_updates for account: {:?}",
            tli_req.account_id
        );

        // Translate TLI proto → Trading proto
        let backend_req = crate::trading_backend::StreamOrdersRequest {
            account_id: tli_req.account_id.or(Some(user_id)),
            symbol: None, // TLI doesn't have symbol filter for order updates
        };

        // Connect to backend stream with auth metadata
        let mut client = self.backend_client.clone();
        let mut backend_request = Request::new(backend_req);

        // Forward authorization and user context from client metadata
        let backend_metadata = backend_request.metadata_mut();
        if let Some(auth_token) = client_metadata.get("authorization") {
            backend_metadata.insert("authorization", auth_token.clone());
        }
        if let Some(user_id_meta) = client_metadata.get("x-user-id") {
            backend_metadata.insert("x-user-id", user_id_meta.clone());
        }

        let backend_stream = match client.stream_orders(backend_request).await {
            Ok(resp) => resp.into_inner(),
            Err(e) => {
                error!("Backend error in subscribe_order_updates: {}", e);
                if matches!(
                    e.code(),
                    tonic::Code::Unavailable | tonic::Code::DeadlineExceeded
                ) {
                    self.health_checker.mark_unhealthy();
                }
                return Err(e);
            },
        };

        // Create translation stream: Backend OrderEvent → TLI OrderUpdateEvent
        let tli_stream = futures::stream::unfold(backend_stream, |mut stream| async move {
            match stream.message().await {
                Ok(Some(backend_event)) => {
                    let tli_event = Self::translate_order_event(backend_event);
                    Some((Ok(tli_event), stream))
                },
                Ok(None) => None, // Stream ended
                Err(e) => {
                    error!("Error in order updates stream: {}", e);
                    Some((Err(e), stream))
                },
            }
        });

        Ok(Response::new(Box::pin(tli_stream)))
    }

    // ========================================================================
    // Risk Management Methods (connect to Risk Service backend)
    // ========================================================================

    #[instrument(skip_all)]
    async fn get_va_r(
        &self,
        request: Request<crate::foxhunt::tli::GetVaRRequest>,
    ) -> Result<Response<crate::foxhunt::tli::GetVaRResponse>, Status> {
        self.check_circuit_breaker()?;

        // Extract metadata BEFORE into_inner() consumes the request
        let client_metadata = request.metadata().clone();
        let tli_req = request.into_inner();

        // Translate TLI proto → Risk proto
        let backend_req = crate::risk::GetVaRRequest {
            symbols: tli_req.symbols,
            confidence_level: tli_req.confidence_level,
            lookback_days: i32::try_from(tli_req.lookback_days).map_err(|_| {
                Status::invalid_argument(format!(
                    "lookback_days {} exceeds i32 range",
                    tli_req.lookback_days
                ))
            })?,
            method: tli_req.methodology, // TLI uses 'methodology', backend uses 'method'
        };

        // Forward to Risk backend with auth metadata
        let mut client = self.risk_client.clone();
        let mut backend_request = Request::new(backend_req);

        // Forward authorization and user context from client metadata
        let backend_metadata = backend_request.metadata_mut();
        if let Some(auth_token) = client_metadata.get("authorization") {
            backend_metadata.insert("authorization", auth_token.clone());
        }
        if let Some(user_id_meta) = client_metadata.get("x-user-id") {
            backend_metadata.insert("x-user-id", user_id_meta.clone());
        }

        let backend_resp = match client.get_va_r(backend_request).await {
            Ok(resp) => resp.into_inner(),
            Err(e) => {
                error!("Backend error in get_va_r: {}", e);
                if matches!(
                    e.code(),
                    tonic::Code::Unavailable | tonic::Code::DeadlineExceeded
                ) {
                    self.health_checker.mark_unhealthy();
                }
                return Err(e);
            },
        };

        // Translate response - Backend uses different field names than TLI
        let tli_resp = crate::foxhunt::tli::GetVaRResponse {
            portfolio_var: backend_resp.portfolio_var,
            symbol_vars: backend_resp
                .symbol_vars
                .into_iter()
                .map(|sv| {
                    crate::foxhunt::tli::SymbolVaR {
                        symbol: sv.symbol,
                        var_amount: sv.var_value, // Backend: var_value → TLI: var_amount
                        contribution_percent: sv.contribution_pct, // Backend: contribution_pct → TLI: contribution_percent
                    }
                })
                .collect(),
            timestamp_unix_nanos: backend_resp.calculated_at, // Backend: calculated_at (i64) → TLI: timestamp_unix_nanos (i64)
            methodology_used: format!("{:?}", backend_resp.method), // Backend: method (enum) → TLI: methodology_used (string)
                                                                    // Note: TLI doesn't have confidence_level or lookback_days in response
                                                                    // These are request parameters that TLI clients already know
        };

        Ok(Response::new(tli_resp))
    }

    #[instrument(skip_all)]
    async fn get_position_risk(
        &self,
        request: Request<crate::foxhunt::tli::GetPositionRiskRequest>,
    ) -> Result<Response<crate::foxhunt::tli::GetPositionRiskResponse>, Status> {
        self.check_circuit_breaker()?;

        // Extract metadata BEFORE into_inner() consumes the request
        let client_metadata = request.metadata().clone();
        let tli_req = request.into_inner();

        // Translate TLI proto → Risk proto
        // Note: TLI doesn't have account_id in GetPositionRiskRequest
        let backend_req = crate::risk::GetPositionRiskRequest {
            symbol: tli_req.symbol,
            account_id: None, // TLI proto doesn't include account_id
        };

        // Forward to Risk backend with auth metadata
        let mut client = self.risk_client.clone();
        let mut backend_request = Request::new(backend_req);

        // Forward authorization and user context from client metadata
        let backend_metadata = backend_request.metadata_mut();
        if let Some(auth_token) = client_metadata.get("authorization") {
            backend_metadata.insert("authorization", auth_token.clone());
        }
        if let Some(user_id_meta) = client_metadata.get("x-user-id") {
            backend_metadata.insert("x-user-id", user_id_meta.clone());
        }

        let backend_resp = match client.get_position_risk(backend_request).await {
            Ok(resp) => resp.into_inner(),
            Err(e) => {
                error!("Backend error in get_position_risk: {}", e);
                if matches!(
                    e.code(),
                    tonic::Code::Unavailable | tonic::Code::DeadlineExceeded
                ) {
                    self.health_checker.mark_unhealthy();
                }
                return Err(e);
            },
        };

        // Translate response: Backend has more fields than TLI
        // Backend PositionRisk → TLI PositionRisk field mappings:
        //   concentration_risk (f64) → concentration_percent (f64)
        //   overall_score.risk_level (enum) → risk_level (enum)
        //   liquidity_risk, metrics → discarded (TLI doesn't have these fields)

        let positions: Vec<_> = backend_resp
            .position_risks
            .into_iter()
            .map(|pr| {
                crate::foxhunt::tli::PositionRisk {
                    symbol: pr.symbol,
                    position_size: pr.position_size,
                    market_value: pr.market_value,
                    var_contribution: pr.var_contribution,
                    concentration_percent: pr.concentration_risk, // Backend concentration_risk → TLI concentration_percent
                    risk_level: pr.overall_score.map(|rs| rs.risk_level).unwrap_or(0), // Extract risk_level from overall_score
                }
            })
            .collect();

        // Calculate total_exposure and concentration_risk for TLI response
        let total_exposure: f64 = positions.iter().map(|p| p.market_value.abs()).sum();
        let max_concentration: f64 = positions
            .iter()
            .map(|p| p.concentration_percent)
            .fold(0.0, f64::max);

        let tli_resp = crate::foxhunt::tli::GetPositionRiskResponse {
            positions, // Backend position_risks → TLI positions
            total_exposure,
            concentration_risk: max_concentration,
            timestamp_unix_nanos: std::time::SystemTime::now()
                .duration_since(std::time::UNIX_EPOCH)
                .unwrap_or_default()
                .as_nanos()
                .try_into()
                .unwrap_or_else(|_| {
                    warn!("Timestamp exceeds i64::MAX nanoseconds");
                    i64::MAX
                }),
        };

        Ok(Response::new(tli_resp))
    }

    #[instrument(skip_all)]
    async fn validate_order(
        &self,
        request: Request<crate::foxhunt::tli::ValidateOrderRequest>,
    ) -> Result<Response<crate::foxhunt::tli::ValidateOrderResponse>, Status> {
        self.check_circuit_breaker()?;

        // Extract metadata BEFORE into_inner() consumes the request
        let client_metadata = request.metadata().clone();
        let tli_req = request.into_inner();

        // Convert TLI OrderSide enum to string for backend
        let side_str = match tli_req.side {
            1 => "buy",  // ORDER_SIDE_BUY
            2 => "sell", // ORDER_SIDE_SELL
            _ => "unknown",
        }
        .to_string();

        // Translate TLI proto → Risk proto
        let backend_req = crate::risk::ValidateOrderRequest {
            symbol: tli_req.symbol,
            quantity: tli_req.quantity,
            price: tli_req.price,
            side: side_str,
            account_id: tli_req.account_id,
        };

        // Forward to Risk backend with auth metadata
        let mut client = self.risk_client.clone();
        let mut backend_request = Request::new(backend_req);

        // Forward authorization and user context from client metadata
        let backend_metadata = backend_request.metadata_mut();
        if let Some(auth_token) = client_metadata.get("authorization") {
            backend_metadata.insert("authorization", auth_token.clone());
        }
        if let Some(user_id_meta) = client_metadata.get("x-user-id") {
            backend_metadata.insert("x-user-id", user_id_meta.clone());
        }

        let backend_resp = match client.validate_order(backend_request).await {
            Ok(resp) => resp.into_inner(),
            Err(e) => {
                error!("Backend error in validate_order: {}", e);
                if matches!(
                    e.code(),
                    tonic::Code::Unavailable | tonic::Code::DeadlineExceeded
                ) {
                    self.health_checker.mark_unhealthy();
                }
                return Err(e);
            },
        };

        // Translate response
        // Backend has: is_valid, violations, risk_score, message
        // TLI has: approved, reason, violations, projected_exposure, margin_impact
        let tli_resp = crate::foxhunt::tli::ValidateOrderResponse {
            approved: backend_resp.is_valid,
            reason: backend_resp.message,
            violations: backend_resp
                .violations
                .into_iter()
                .map(|v| {
                    // Backend RiskViolation has: violation_type, description, current_value, limit_value, severity
                    // TLI RiskViolation has: type, description, limit_value, current_value, severity
                    crate::foxhunt::tli::RiskViolation {
                        r#type: v.violation_type,
                        description: v.description,
                        limit_value: v.limit_value,
                        current_value: v.current_value,
                        severity: v.severity,
                    }
                })
                .collect(),
            projected_exposure: 0.0, // Backend doesn't provide this, use placeholder
            margin_impact: 0.0,      // Backend doesn't provide this, use placeholder
        };

        Ok(Response::new(tli_resp))
    }

    #[instrument(skip_all)]
    async fn get_risk_metrics(
        &self,
        request: Request<crate::foxhunt::tli::GetRiskMetricsRequest>,
    ) -> Result<Response<crate::foxhunt::tli::GetRiskMetricsResponse>, Status> {
        self.check_circuit_breaker()?;

        // Extract metadata BEFORE into_inner() consumes the request
        let client_metadata = request.metadata().clone();
        let tli_req = request.into_inner();

        // Translate TLI proto → Risk proto
        let backend_req = crate::risk::GetRiskMetricsRequest {
            portfolio_id: tli_req.portfolio_id,
        };

        // Forward to Risk backend with auth metadata
        let mut client = self.risk_client.clone();
        let mut backend_request = Request::new(backend_req);

        // Forward authorization and user context from client metadata
        let backend_metadata = backend_request.metadata_mut();
        if let Some(auth_token) = client_metadata.get("authorization") {
            backend_metadata.insert("authorization", auth_token.clone());
        }
        if let Some(user_id_meta) = client_metadata.get("x-user-id") {
            backend_metadata.insert("x-user-id", user_id_meta.clone());
        }

        let backend_resp = match client.get_risk_metrics(backend_request).await {
            Ok(resp) => resp.into_inner(),
            Err(e) => {
                error!("Backend error in get_risk_metrics: {}", e);
                if matches!(
                    e.code(),
                    tonic::Code::Unavailable | tonic::Code::DeadlineExceeded
                ) {
                    self.health_checker.mark_unhealthy();
                }
                return Err(e);
            },
        };

        // Translate response - backend has nested RiskMetrics, TLI has flat fields
        let tli_resp = crate::foxhunt::tli::GetRiskMetricsResponse {
            // Extract fields from nested metrics
            sharpe_ratio: backend_resp
                .metrics
                .as_ref()
                .map(|m| m.sharpe_ratio)
                .unwrap_or(0.0),
            max_drawdown: backend_resp
                .metrics
                .as_ref()
                .map(|m| m.max_drawdown)
                .unwrap_or(0.0),
            current_drawdown: backend_resp
                .metrics
                .as_ref()
                .map(|m| m.current_drawdown)
                .unwrap_or(0.0),
            volatility: backend_resp
                .metrics
                .as_ref()
                .map(|m| m.volatility)
                .unwrap_or(0.0),
            beta: backend_resp.metrics.as_ref().map(|m| m.beta).unwrap_or(0.0),
            alpha: backend_resp
                .metrics
                .as_ref()
                .map(|m| m.alpha)
                .unwrap_or(0.0),
            value_at_risk: backend_resp
                .metrics
                .as_ref()
                .map(|m| m.portfolio_var_1d)
                .unwrap_or(0.0),
            expected_shortfall: backend_resp
                .metrics
                .as_ref()
                .map(|m| {
                    // Calculate expected shortfall as average of VaR values (approximation)
                    (m.portfolio_var_1d + m.portfolio_var_5d + m.portfolio_var_30d) / 3.0
                })
                .unwrap_or(0.0),
            timestamp_unix_nanos: backend_resp.calculated_at,
        };

        Ok(Response::new(tli_resp))
    }

    #[instrument(skip_all)]
    async fn subscribe_risk_alerts(
        &self,
        request: Request<crate::foxhunt::tli::SubscribeRiskAlertsRequest>,
    ) -> Result<Response<Self::SubscribeRiskAlertsStream>, Status> {
        self.check_circuit_breaker()?;

        // Extract metadata BEFORE into_inner() consumes the request
        let client_metadata = request.metadata().clone();
        let tli_req = request.into_inner();

        // Translate TLI proto → Risk proto
        let backend_req = crate::risk::StreamRiskAlertsRequest {
            min_severity: tli_req.min_severity.first().copied().unwrap_or(0),
            alert_types: Vec::new(), // TLI doesn't expose alert_types, backend requires it
        };
        // Connect to Risk backend stream with auth metadata
        let mut client = self.risk_client.clone();
        let mut backend_request = Request::new(backend_req);

        // Forward authorization and user context from client metadata
        let backend_metadata = backend_request.metadata_mut();
        if let Some(auth_token) = client_metadata.get("authorization") {
            backend_metadata.insert("authorization", auth_token.clone());
        }
        if let Some(user_id_meta) = client_metadata.get("x-user-id") {
            backend_metadata.insert("x-user-id", user_id_meta.clone());
        }

        let backend_stream = match client.stream_risk_alerts(backend_request).await {
            Ok(resp) => resp.into_inner(),
            Err(e) => {
                error!("Backend error in subscribe_risk_alerts: {}", e);
                if matches!(
                    e.code(),
                    tonic::Code::Unavailable | tonic::Code::DeadlineExceeded
                ) {
                    self.health_checker.mark_unhealthy();
                }
                return Err(e);
            },
        };

        // Create translation stream
        let tli_stream = futures::stream::unfold(backend_stream, |mut stream| async move {
            match stream.message().await {
                Ok(Some(backend_event)) => {
                    let tli_event = crate::foxhunt::tli::RiskAlertEvent {
                        alert_id: backend_event.alert_id,
                        // Map backend RiskAlertSeverity to TLI RiskSeverity (enum values may differ)
                        severity: backend_event.severity, // Pass through, assuming compatible
                        message: backend_event.message,
                        symbol: backend_event.symbol.unwrap_or_default(), // TLI requires string
                        // TLI doesn't have threshold_value, current_value - set to 0.0
                        threshold_value: 0.0,
                        current_value: 0.0,
                        timestamp_unix_nanos: backend_event.timestamp,
                        // TLI doesn't have account_id, metadata, alert_type
                        // Map severity to requires_action (critical/emergency = true)
                        requires_action: backend_event.severity >= 3, // CRITICAL or EMERGENCY
                    };
                    Some((Ok(tli_event), stream))
                },
                Ok(None) => None,
                Err(e) => {
                    error!("Error in risk alerts stream: {}", e);
                    Some((Err(e), stream))
                },
            }
        });

        Ok(Response::new(Box::pin(tli_stream)))
    }

    #[instrument(skip_all)]
    async fn emergency_stop(
        &self,
        request: Request<crate::foxhunt::tli::EmergencyStopRequest>,
    ) -> Result<Response<crate::foxhunt::tli::EmergencyStopResponse>, Status> {
        self.check_circuit_breaker()?;

        // Extract metadata BEFORE into_inner() consumes the request
        let client_metadata = request.metadata().clone();
        let tli_req = request.into_inner();

        // Translate TLI proto → Risk proto
        // TLI has repeated symbols, backend takes single optional symbol (use first if provided)
        let backend_req = crate::risk::EmergencyStopRequest {
            stop_type: tli_req.stop_type,
            reason: tli_req.reason,
            symbol: tli_req.symbols.first().cloned(),
            account_id: None, // TLI doesn't provide account_id in request
        };

        // Forward to Risk backend with auth metadata
        let mut client = self.risk_client.clone();
        let mut backend_request = Request::new(backend_req);

        // Forward authorization and user context from client metadata
        let backend_metadata = backend_request.metadata_mut();
        if let Some(auth_token) = client_metadata.get("authorization") {
            backend_metadata.insert("authorization", auth_token.clone());
        }
        if let Some(user_id_meta) = client_metadata.get("x-user-id") {
            backend_metadata.insert("x-user-id", user_id_meta.clone());
        }

        let backend_resp = match client.emergency_stop(backend_request).await {
            Ok(resp) => resp.into_inner(),
            Err(e) => {
                error!("Backend error in emergency_stop: {}", e);
                if matches!(
                    e.code(),
                    tonic::Code::Unavailable | tonic::Code::DeadlineExceeded
                ) {
                    self.health_checker.mark_unhealthy();
                }
                return Err(e);
            },
        };

        // Translate response
        // Backend provides affected_orders list, TLI expects counts
        let orders_cancelled =
            u32::try_from(backend_resp.affected_orders.len()).unwrap_or_else(|_| {
                warn!(
                    "Number of affected orders {} exceeds u32::MAX",
                    backend_resp.affected_orders.len()
                );
                u32::MAX
            });

        let tli_resp = crate::foxhunt::tli::EmergencyStopResponse {
            success: backend_resp.success,
            message: backend_resp.message,
            orders_cancelled,
            positions_closed: 0_u32, // Backend doesn't track positions_closed
            timestamp_unix_nanos: backend_resp.timestamp,
        };

        Ok(Response::new(tli_resp))
    }

    // ========================================================================
    // Monitoring Methods — DEPRECATED: Use MonitoringService directly
    // These TLI monitoring RPCs targeted the stale trading_service monitoring
    // proto (10 RPCs, never implemented). The real MonitoringService (2 RPCs:
    // GetLiveTrainingMetrics, StreamTrainingMetrics) is now served directly
    // by the API gateway via MonitoringServiceHandler.
    // ========================================================================

    #[instrument(skip_all)]
    async fn get_metrics(
        &self,
        _request: Request<crate::foxhunt::tli::GetMetricsRequest>,
    ) -> Result<Response<crate::foxhunt::tli::GetMetricsResponse>, Status> {
        Err(Status::unimplemented("Use MonitoringService directly"))
    }

    #[instrument(skip_all)]
    async fn get_latency(
        &self,
        _request: Request<crate::foxhunt::tli::GetLatencyRequest>,
    ) -> Result<Response<crate::foxhunt::tli::GetLatencyResponse>, Status> {
        Err(Status::unimplemented("Use MonitoringService directly"))
    }

    #[instrument(skip_all)]
    async fn get_throughput(
        &self,
        _request: Request<crate::foxhunt::tli::GetThroughputRequest>,
    ) -> Result<Response<crate::foxhunt::tli::GetThroughputResponse>, Status> {
        Err(Status::unimplemented("Use MonitoringService directly"))
    }

    #[instrument(skip_all)]
    async fn subscribe_metrics(
        &self,
        _request: Request<crate::foxhunt::tli::SubscribeMetricsRequest>,
    ) -> Result<Response<Self::SubscribeMetricsStream>, Status> {
        Err(Status::unimplemented("Use MonitoringService directly"))
    }

    // ========================================================================
    // Configuration Methods (connect to Config Service backend)
    // ========================================================================

    #[instrument(skip_all)]
    async fn update_parameters(
        &self,
        request: Request<crate::foxhunt::tli::UpdateParametersRequest>,
    ) -> Result<Response<crate::foxhunt::tli::UpdateParametersResponse>, Status> {
        self.check_circuit_breaker()?;

        // Extract metadata BEFORE into_inner() consumes the request
        let client_metadata = request.metadata().clone();
        let tli_req = request.into_inner();

        // Extract user_id for changed_by field
        let user_id = client_metadata
            .get("x-user-id")
            .and_then(|v| v.to_str().ok())
            .unwrap_or("unknown")
            .to_string();

        // Translate TLI proto → Config proto
        // TLI has map<string, string> parameters
        // Backend expects individual UpdateConfigurationRequest per parameter
        // For simplicity, we'll update each parameter individually
        // Note: TLI UpdateParametersRequest has:
        //   - parameters: map<string, string>
        //   - persist: bool
        // Backend UpdateConfigurationRequest has:
        //   - category, key, value, changed_by, change_reason, environment

        // Since TLI doesn't specify category/key structure, we'll parse keys as "category.key"
        // For now, treat the first parameter (if multiple, use first one only for single backend call)
        let (key, value) = tli_req
            .parameters
            .iter()
            .next()
            .ok_or_else(|| Status::invalid_argument("No parameters provided"))?;

        let backend_req = crate::config_backend::UpdateConfigurationRequest {
            category: "runtime".to_string(), // Default category since TLI doesn't specify
            key: key.clone(),
            value: value.clone(),
            changed_by: user_id.clone(),
            change_reason: Some(format!("Updated via TLI (persist={})", tli_req.persist)),
            environment: None,
        };

        // Forward to Config backend with auth metadata
        let mut client = self.config_client.clone();
        let mut backend_request = Request::new(backend_req);

        // Forward authorization and user context from client metadata
        let backend_metadata = backend_request.metadata_mut();
        if let Some(auth_token) = client_metadata.get("authorization") {
            backend_metadata.insert("authorization", auth_token.clone());
        }
        if let Some(user_id_meta) = client_metadata.get("x-user-id") {
            backend_metadata.insert("x-user-id", user_id_meta.clone());
        }

        let backend_resp = match client.update_configuration(backend_request).await {
            Ok(resp) => resp.into_inner(),
            Err(e) => {
                error!("Backend error in update_parameters: {}", e);
                if matches!(
                    e.code(),
                    tonic::Code::Unavailable | tonic::Code::DeadlineExceeded
                ) {
                    self.health_checker.mark_unhealthy();
                }
                return Err(e);
            },
        };

        // Translate response
        let tli_resp = crate::foxhunt::tli::UpdateParametersResponse {
            success: backend_resp.success,
            message: backend_resp.message,
            updated_keys: vec![key.clone()], // Return the updated key
        };

        Ok(Response::new(tli_resp))
    }

    #[instrument(skip_all)]
    async fn get_config(
        &self,
        request: Request<crate::foxhunt::tli::GetConfigRequest>,
    ) -> Result<Response<crate::foxhunt::tli::GetConfigResponse>, Status> {
        self.check_circuit_breaker()?;

        // Extract metadata BEFORE into_inner() consumes the request
        let client_metadata = request.metadata().clone();
        let tli_req = request.into_inner();

        // Translate TLI proto → Config proto
        // TLI has: repeated string keys
        // Backend expects: optional category, optional key, optional environment
        // Strategy: If keys is empty, get all configs (category=None, key=None)
        //           If keys has values, we need to query each key individually
        // For simplicity, we'll get all configs and filter by keys if provided
        let backend_req = crate::config_backend::GetConfigurationRequest {
            category: None,
            key: None,
            environment: None,
        };

        // Forward to Config backend with auth metadata
        let mut client = self.config_client.clone();
        let mut backend_request = Request::new(backend_req);

        // Forward authorization and user context from client metadata
        let backend_metadata = backend_request.metadata_mut();
        if let Some(auth_token) = client_metadata.get("authorization") {
            backend_metadata.insert("authorization", auth_token.clone());
        }
        if let Some(user_id_meta) = client_metadata.get("x-user-id") {
            backend_metadata.insert("x-user-id", user_id_meta.clone());
        }

        let backend_resp = match client.get_configuration(backend_request).await {
            Ok(resp) => resp.into_inner(),
            Err(e) => {
                error!("Backend error in get_config: {}", e);
                if matches!(
                    e.code(),
                    tonic::Code::Unavailable | tonic::Code::DeadlineExceeded
                ) {
                    self.health_checker.mark_unhealthy();
                }
                return Err(e);
            },
        };

        // Translate response: Backend ConfigurationSetting → TLI map<string, string>
        // TLI expects: map<string, string> config, version, last_updated_unix_nanos
        // Backend provides: repeated ConfigurationSetting with many fields

        // Build map from settings, filtering by requested keys if provided
        let mut config_map = std::collections::HashMap::new();
        let mut max_modified_at = 0i64;

        for setting in backend_resp.settings {
            // If keys filter provided, only include matching keys
            if !tli_req.keys.is_empty() && !tli_req.keys.contains(&setting.key) {
                continue;
            }

            // Use "category.key" as the map key for uniqueness
            let full_key = format!("{}.{}", setting.category, setting.key);
            config_map.insert(full_key, setting.value);

            // Track latest modification time
            if setting.modified_at > max_modified_at {
                max_modified_at = setting.modified_at;
            }
        }

        let tli_resp = crate::foxhunt::tli::GetConfigResponse {
            config: config_map,
            version: 1_i64, // Backend doesn't provide version, use 1 as default
            last_updated_unix_nanos: max_modified_at,
        };

        Ok(Response::new(tli_resp))
    }

    #[instrument(skip_all)]
    async fn subscribe_config(
        &self,
        request: Request<crate::foxhunt::tli::SubscribeConfigRequest>,
    ) -> Result<Response<Self::SubscribeConfigStream>, Status> {
        self.check_circuit_breaker()?;

        // Extract metadata BEFORE into_inner() consumes the request
        let client_metadata = request.metadata().clone();
        let tli_req = request.into_inner();

        // Translate TLI proto → Config proto (StreamConfigChanges)
        let backend_req = crate::config_backend::StreamConfigChangesRequest {
            categories: Vec::new(), // TLI doesn't have categories, backend requires it
            keys: tli_req.keys,
        };

        // Connect to Config backend stream with auth metadata
        let mut client = self.config_client.clone();
        let mut backend_request = Request::new(backend_req);

        // Forward authorization and user context from client metadata
        let backend_metadata = backend_request.metadata_mut();
        if let Some(auth_token) = client_metadata.get("authorization") {
            backend_metadata.insert("authorization", auth_token.clone());
        }
        if let Some(user_id_meta) = client_metadata.get("x-user-id") {
            backend_metadata.insert("x-user-id", user_id_meta.clone());
        }

        let backend_stream = match client.stream_config_changes(backend_request).await {
            Ok(resp) => resp.into_inner(),
            Err(e) => {
                error!("Backend error in subscribe_config: {}", e);
                if matches!(
                    e.code(),
                    tonic::Code::Unavailable | tonic::Code::DeadlineExceeded
                ) {
                    self.health_checker.mark_unhealthy();
                }
                return Err(e);
            },
        };

        // Create translation stream
        let tli_stream = futures::stream::unfold(backend_stream, |mut stream| async move {
            match stream.message().await {
                Ok(Some(backend_event)) => {
                    // Translate Backend ConfigChangeEvent → TLI ConfigEvent (simplified structure)
                    let tli_event = crate::foxhunt::tli::ConfigEvent {
                        key: backend_event.key,
                        value: backend_event.new_value,
                        old_value: backend_event.old_value,
                        timestamp_unix_nanos: backend_event.timestamp,
                    };
                    Some((Ok(tli_event), stream))
                },
                Ok(None) => None,
                Err(e) => {
                    error!("Error in config stream: {}", e);
                    Some((Err(e), stream))
                },
            }
        });

        Ok(Response::new(Box::pin(tli_stream)))
    }

    #[instrument(skip_all)]
    async fn get_system_status(
        &self,
        _request: Request<crate::foxhunt::tli::GetSystemStatusRequest>,
    ) -> Result<Response<crate::foxhunt::tli::GetSystemStatusResponse>, Status> {
        let health_state = self
            .health_state
            .as_ref()
            .ok_or_else(|| Status::unavailable("System health monitoring not configured"))?;

        let entries = health_state.rx.borrow().clone();
        let all_healthy = entries.iter().all(|e| e.healthy);
        let overall = if all_healthy { 1 } else { 2 }; // HEALTHY=1, DEGRADED=2

        let services: Vec<crate::foxhunt::tli::ServiceStatus> = entries
            .iter()
            .map(|e| crate::foxhunt::tli::ServiceStatus {
                name: e.name.clone(),
                status: if e.healthy { 1 } else { 3 },
                message: e.message.clone(),
                last_check_unix_nanos: 0,
                details: HashMap::new(),
            })
            .collect();

        Ok(Response::new(
            crate::foxhunt::tli::GetSystemStatusResponse {
                overall_status: overall,
                services,
                timestamp_unix_nanos: std::time::SystemTime::now()
                    .duration_since(std::time::UNIX_EPOCH)
                    .map(|d| d.as_nanos() as i64)
                    .unwrap_or(0),
            },
        ))
    }

    #[instrument(skip_all)]
    async fn subscribe_system_status(
        &self,
        _request: Request<crate::foxhunt::tli::SubscribeSystemStatusRequest>,
    ) -> Result<Response<Self::SubscribeSystemStatusStream>, Status> {
        let health_state = self
            .health_state
            .as_ref()
            .ok_or_else(|| Status::unavailable("System health monitoring not configured"))?
            .clone();

        let stream = async_stream::stream! {
            let mut rx = health_state.rx.clone();
            // Emit initial snapshot immediately.
            {
                let entries = rx.borrow().clone();
                let now = std::time::SystemTime::now()
                    .duration_since(std::time::UNIX_EPOCH)
                    .map(|d| d.as_nanos() as i64)
                    .unwrap_or(0);
                for entry in &entries {
                    let status = if entry.healthy { 1 } else { 3 }; // HEALTHY=1, UNHEALTHY=3
                    yield Ok(crate::foxhunt::tli::SystemStatusEvent {
                        service_name: entry.name.clone(),
                        status,
                        previous_status: 0,
                        message: entry.message.clone(),
                        timestamp_unix_nanos: now,
                    });
                }
            }
            // Then emit updates whenever the health snapshot changes.
            loop {
                if rx.changed().await.is_err() {
                    break; // Sender dropped — gateway shutting down.
                }
                let entries = rx.borrow_and_update().clone();
                let now = std::time::SystemTime::now()
                    .duration_since(std::time::UNIX_EPOCH)
                    .map(|d| d.as_nanos() as i64)
                    .unwrap_or(0);
                for entry in &entries {
                    let status = if entry.healthy { 1 } else { 3 };
                    yield Ok(crate::foxhunt::tli::SystemStatusEvent {
                        service_name: entry.name.clone(),
                        status,
                        previous_status: 0,
                        message: entry.message.clone(),
                        timestamp_unix_nanos: now,
                    });
                }
            }
        };

        Ok(Response::new(Box::pin(stream)))
    }

    // ========================================================================
    // ML Trading Operations
    // ========================================================================

    /// Submit ML-powered trading order with ensemble predictions
    #[instrument(skip_all)]
    async fn submit_ml_order(
        &self,
        request: Request<crate::foxhunt::tli::SubmitMlOrderRequest>,
    ) -> Result<Response<crate::foxhunt::tli::SubmitMlOrderResponse>, Status> {
        self.check_circuit_breaker()?;

        let user_id = Self::extract_user_id(&request)?;
        debug!("Translating submit_ml_order for user: {}", user_id);

        // Extract metadata BEFORE into_inner() consumes the request
        let client_metadata = request.metadata().clone();
        let tli_req = request.into_inner();

        // Translate TLI proto → Trading proto
        let backend_req = crate::trading_backend::MlOrderRequest {
            symbol: tli_req.symbol.clone(),
            account_id: user_id,
            use_ensemble: tli_req.model_filter.is_none(),
            model_name: tli_req.model_filter.clone(),
            features: vec![], // Features are extracted in the trading service
        };

        // Forward to backend with auth metadata
        let mut client = self.backend_client.clone();
        let mut backend_request = Request::new(backend_req);

        // Forward authorization and user context from client metadata
        let backend_metadata = backend_request.metadata_mut();
        if let Some(auth_token) = client_metadata.get("authorization") {
            backend_metadata.insert("authorization", auth_token.clone());
        }
        if let Some(user_id_meta) = client_metadata.get("x-user-id") {
            backend_metadata.insert("x-user-id", user_id_meta.clone());
        }

        let backend_resp = match client.submit_ml_order(backend_request).await {
            Ok(resp) => resp.into_inner(),
            Err(e) => {
                error!("Backend error in submit_ml_order: {}", e);
                if matches!(
                    e.code(),
                    tonic::Code::Unavailable | tonic::Code::DeadlineExceeded
                ) {
                    self.health_checker.mark_unhealthy();
                }
                return Err(e);
            },
        };

        // Translate Trading proto → TLI proto
        let tli_resp = crate::foxhunt::tli::SubmitMlOrderResponse {
            order_id: backend_resp.order_id,
            symbol: tli_req.symbol,
            model_used: if backend_resp.executed {
                if tli_req.model_filter.is_some() {
                    tli_req
                        .model_filter
                        .unwrap_or_else(|| "Ensemble".to_string())
                } else {
                    "Ensemble".to_string()
                }
            } else {
                "None".to_string()
            },
            predicted_action: backend_resp.action,
            confidence: backend_resp.confidence,
            // BLOCKER: The Trading-service MlOrderResponse proto does not include a
            // quantity field — it only returns order_id, prediction_id, action,
            // confidence, message, and executed. To expose real order quantity here,
            // either:
            //   1. Add an `int32 quantity` field to MlOrderResponse in trading.proto
            //      and populate it from the SubmitOrderResponse in the trading service, or
            //   2. Perform a follow-up GetOrderStatus RPC using the returned order_id
            //      to fetch the filled quantity (adds latency).
            // Until then, we report 1 (executed) or 0 (not executed) as a boolean proxy.
            quantity: if backend_resp.executed { 1 } else { 0 },
            executed: backend_resp.executed,
            message: backend_resp.message,
        };

        Ok(Response::new(tli_resp))
    }

    /// Get ML prediction history with outcomes
    #[instrument(skip_all)]
    async fn get_ml_predictions(
        &self,
        request: Request<crate::foxhunt::tli::GetMlPredictionsRequest>,
    ) -> Result<Response<crate::foxhunt::tli::GetMlPredictionsResponse>, Status> {
        self.check_circuit_breaker()?;

        debug!("Translating get_ml_predictions");

        // Extract metadata BEFORE into_inner() consumes the request
        let client_metadata = request.metadata().clone();
        let tli_req = request.into_inner();

        // Translate TLI proto → Trading proto
        let backend_req = crate::trading_backend::MlPredictionsRequest {
            symbol: tli_req.symbol,
            model_name: tli_req.model_filter,
            limit: tli_req.limit.unwrap_or(10),
            start_time: None,
            end_time: None,
        };

        // Forward to backend with auth metadata
        let mut client = self.backend_client.clone();
        let mut backend_request = Request::new(backend_req);

        // Forward authorization and user context from client metadata
        let backend_metadata = backend_request.metadata_mut();
        if let Some(auth_token) = client_metadata.get("authorization") {
            backend_metadata.insert("authorization", auth_token.clone());
        }
        if let Some(user_id_meta) = client_metadata.get("x-user-id") {
            backend_metadata.insert("x-user-id", user_id_meta.clone());
        }

        let backend_resp = match client.get_ml_predictions(backend_request).await {
            Ok(resp) => resp.into_inner(),
            Err(e) => {
                error!("Backend error in get_ml_predictions: {}", e);
                if matches!(
                    e.code(),
                    tonic::Code::Unavailable | tonic::Code::DeadlineExceeded
                ) {
                    self.health_checker.mark_unhealthy();
                }
                return Err(e);
            },
        };

        // Translate Trading proto → TLI proto
        let predictions = backend_resp
            .predictions
            .into_iter()
            .map(|pred| crate::foxhunt::tli::MlPrediction {
                timestamp: format!("{}", pred.timestamp), // Convert nanos to ISO 8601 if needed
                model_id: pred.ensemble_action.clone(),   // Use action as model_id for simplicity
                symbol: pred.symbol,
                predicted_action: pred.ensemble_action,
                confidence: pred.ensemble_confidence,
                actual_return: pred.actual_pnl,
            })
            .collect();

        let tli_resp = crate::foxhunt::tli::GetMlPredictionsResponse { predictions };

        Ok(Response::new(tli_resp))
    }

    /// Get ML model performance metrics
    #[instrument(skip_all)]
    async fn get_ml_performance(
        &self,
        request: Request<crate::foxhunt::tli::GetMlPerformanceRequest>,
    ) -> Result<Response<crate::foxhunt::tli::GetMlPerformanceResponse>, Status> {
        self.check_circuit_breaker()?;

        debug!("Translating get_ml_performance");

        // Extract metadata BEFORE into_inner() consumes the request
        let client_metadata = request.metadata().clone();
        let tli_req = request.into_inner();

        // Translate TLI proto → Trading proto
        let backend_req = crate::trading_backend::MlPerformanceRequest {
            model_name: tli_req.model_filter,
            start_time: None,
            end_time: None,
        };

        // Forward to backend with auth metadata
        let mut client = self.backend_client.clone();
        let mut backend_request = Request::new(backend_req);

        // Forward authorization and user context from client metadata
        let backend_metadata = backend_request.metadata_mut();
        if let Some(auth_token) = client_metadata.get("authorization") {
            backend_metadata.insert("authorization", auth_token.clone());
        }
        if let Some(user_id_meta) = client_metadata.get("x-user-id") {
            backend_metadata.insert("x-user-id", user_id_meta.clone());
        }

        let backend_resp = match client.get_ml_performance(backend_request).await {
            Ok(resp) => resp.into_inner(),
            Err(e) => {
                error!("Backend error in get_ml_performance: {}", e);
                if matches!(
                    e.code(),
                    tonic::Code::Unavailable | tonic::Code::DeadlineExceeded
                ) {
                    self.health_checker.mark_unhealthy();
                }
                return Err(e);
            },
        };

        // Translate Trading proto → TLI proto
        let active_models = backend_resp.models.len() as i32;
        let models = backend_resp
            .models
            .into_iter()
            .map(|model| crate::foxhunt::tli::ModelPerformance {
                model_id: model.model_name,
                accuracy: model.accuracy,
                total_predictions: model.total_predictions,
                sharpe_ratio: model.sharpe_ratio,
                avg_return: model.avg_pnl,
                max_drawdown: 0.0, // Backend doesn't provide this field
            })
            .collect();

        let tli_resp = crate::foxhunt::tli::GetMlPerformanceResponse {
            models,
            ensemble_threshold: 0.6, // Default threshold, should come from config
            active_models,
            total_models: 4, // DQN, MAMBA2, PPO, TFT
        };

        Ok(Response::new(tli_resp))
    }

    /// Get current regime state for a symbol (Wave D)
    #[instrument(skip_all)]
    async fn get_regime_state(
        &self,
        request: Request<crate::foxhunt::tli::GetRegimeStateRequest>,
    ) -> Result<Response<crate::foxhunt::tli::GetRegimeStateResponse>, Status> {
        self.check_circuit_breaker()?;

        debug!("Translating get_regime_state");

        // Extract metadata BEFORE into_inner() consumes the request
        let client_metadata = request.metadata().clone();
        let tli_req = request.into_inner();

        // Translate TLI proto → Trading proto
        let backend_req = crate::trading_backend::GetRegimeStateRequest {
            symbol: tli_req.symbol,
        };

        // Forward to backend with auth metadata
        let mut client = self.backend_client.clone();
        let mut backend_request = Request::new(backend_req);

        // Forward authorization and user context from client metadata
        let backend_metadata = backend_request.metadata_mut();
        if let Some(auth_token) = client_metadata.get("authorization") {
            backend_metadata.insert("authorization", auth_token.clone());
        }
        if let Some(user_id_meta) = client_metadata.get("x-user-id") {
            backend_metadata.insert("x-user-id", user_id_meta.clone());
        }

        let backend_resp = match client.get_regime_state(backend_request).await {
            Ok(resp) => resp.into_inner(),
            Err(e) => {
                error!("Backend error in get_regime_state: {}", e);
                if matches!(
                    e.code(),
                    tonic::Code::Unavailable | tonic::Code::DeadlineExceeded
                ) {
                    self.health_checker.mark_unhealthy();
                }
                return Err(e);
            },
        };

        // Translate Trading proto → TLI proto
        let tli_resp = crate::foxhunt::tli::GetRegimeStateResponse {
            symbol: backend_resp.symbol,
            current_regime: backend_resp.current_regime,
            confidence: backend_resp.confidence,
            cusum_s_plus: backend_resp.cusum_s_plus,
            cusum_s_minus: backend_resp.cusum_s_minus,
            adx: backend_resp.adx,
            stability: backend_resp.stability,
            entropy: backend_resp.entropy,
            updated_at_unix_nanos: backend_resp.updated_at,
        };

        Ok(Response::new(tli_resp))
    }

    /// Get regime transition history for a symbol (Wave D)
    #[instrument(skip_all)]
    async fn get_regime_transitions(
        &self,
        request: Request<crate::foxhunt::tli::GetRegimeTransitionsRequest>,
    ) -> Result<Response<crate::foxhunt::tli::GetRegimeTransitionsResponse>, Status> {
        self.check_circuit_breaker()?;

        debug!("Translating get_regime_transitions");

        // Extract metadata BEFORE into_inner() consumes the request
        let client_metadata = request.metadata().clone();
        let tli_req = request.into_inner();

        // Translate TLI proto → Trading proto
        let backend_req = crate::trading_backend::GetRegimeTransitionsRequest {
            symbol: tli_req.symbol,
            limit: tli_req.limit,
        };

        // Forward to backend with auth metadata
        let mut client = self.backend_client.clone();
        let mut backend_request = Request::new(backend_req);

        // Forward authorization and user context from client metadata
        let backend_metadata = backend_request.metadata_mut();
        if let Some(auth_token) = client_metadata.get("authorization") {
            backend_metadata.insert("authorization", auth_token.clone());
        }
        if let Some(user_id_meta) = client_metadata.get("x-user-id") {
            backend_metadata.insert("x-user-id", user_id_meta.clone());
        }

        let backend_resp = match client.get_regime_transitions(backend_request).await {
            Ok(resp) => resp.into_inner(),
            Err(e) => {
                error!("Backend error in get_regime_transitions: {}", e);
                if matches!(
                    e.code(),
                    tonic::Code::Unavailable | tonic::Code::DeadlineExceeded
                ) {
                    self.health_checker.mark_unhealthy();
                }
                return Err(e);
            },
        };

        // Translate Trading proto → TLI proto
        let transitions = backend_resp
            .transitions
            .into_iter()
            .map(|trans| crate::foxhunt::tli::RegimeTransition {
                from_regime: trans.from_regime,
                to_regime: trans.to_regime,
                duration_bars: trans.duration_bars,
                transition_probability: trans.transition_probability,
                timestamp_unix_nanos: trans.timestamp,
            })
            .collect();

        let tli_resp = crate::foxhunt::tli::GetRegimeTransitionsResponse { transitions };

        Ok(Response::new(tli_resp))
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_health_checker_creation() {
        let checker = HealthChecker::new(30);
        assert!(checker.is_healthy());
    }

    #[test]
    fn test_health_checker_mark_unhealthy() {
        let checker = HealthChecker::new(30);
        checker.mark_unhealthy();
        assert!(!checker.is_healthy());
    }

    #[test]
    fn test_order_side_translation() {
        assert_eq!(TradingServiceProxy::translate_order_side(1), 1); // Buy
        assert_eq!(TradingServiceProxy::translate_order_side(2), 2); // Sell
    }

    #[test]
    fn test_order_type_translation() {
        assert_eq!(TradingServiceProxy::translate_order_type(1), 1); // Market
        assert_eq!(TradingServiceProxy::translate_order_type(2), 2); // Limit
    }
}
