//! PostgreSQL repository implementations
//!
//! This module provides concrete implementations of the repository traits using PostgreSQL
//! as the underlying data store. These implementations handle all database operations
//! and provide the data access layer for the Trading Service.

use crate::error::{TradingServiceError, TradingServiceResult};
use crate::proto::trading::*;
use crate::repositories::*;
use async_trait::async_trait;
use common::PriceLevel;
use sqlx::{PgPool, Row};

/// Helper function to safely convert Unix timestamp to DateTime
///
/// Returns TimestampConversion error if timestamp is out of valid range
#[inline]
fn safe_timestamp_to_datetime(
    timestamp: i64,
) -> TradingServiceResult<chrono::DateTime<chrono::Utc>> {
    chrono::DateTime::from_timestamp(timestamp, 0)
        .ok_or(TradingServiceError::TimestampConversion { timestamp })
}

/// Postgre`SQL` implementation of TradingRepository
#[derive(Debug, Clone)]
pub struct PostgresTradingRepository {
    pool: PgPool,
}

impl PostgresTradingRepository {
    /// Create new Postgre`SQL` trading repository
    pub fn new(pool: PgPool) -> Self {
        Self { pool }
    }

    /// Get reference to database pool (for direct queries in service layer)
    pub fn pool(&self) -> &PgPool {
        &self.pool
    }
}

#[async_trait]
impl TradingRepository for PostgresTradingRepository {
    async fn store_order(&self, order: &TradingOrder) -> TradingServiceResult<String> {
        let order_id = uuid::Uuid::new_v4();

        // Use direct sqlx query binding instead of trait objects
        // Convert float prices to BIGINT (cents) - multiply by 100 for cent precision
        // Market orders must have NULL limit_price per database constraint
        let limit_price_cents = if order.order_type == common::OrderType::Market {
            None
        } else {
            let price_cents = order.price * 100.0;
            if !price_cents.is_finite()
                || price_cents < i64::MIN as f64
                || price_cents > i64::MAX as f64
            {
                return Err(TradingServiceError::ValidationError {
                    message: format!(
                        "Price overflow: {} cannot be safely converted to i64",
                        order.price
                    ),
                });
            }
            Some(price_cents as i64)
        };
        let stop_price_cents = order.stop_price.map(|p| {
            let price_cents = p * 100.0;
            if !price_cents.is_finite()
                || price_cents < i64::MIN as f64
                || price_cents > i64::MAX as f64
            {
                i64::MAX // Clamp to max value if overflow
            } else {
                price_cents as i64
            }
        });

        // Convert quantity to BIGINT (base units)
        let quantity_cents = order.quantity * 100.0;
        if !quantity_cents.is_finite() || quantity_cents < 0.0 || quantity_cents > i64::MAX as f64 {
            return Err(TradingServiceError::ValidationError {
                message: format!(
                    "Quantity overflow: {} cannot be safely converted to i64",
                    order.quantity
                ),
            });
        }
        let quantity_bigint = quantity_cents as i64;

        // Use nanosecond timestamp directly
        let timestamp_ns = order.timestamp * 1_000_000_000; // Convert seconds to nanoseconds

        // Convert enums to PostgreSQL enum strings
        let side_str = match order.side {
            common::OrderSide::Buy => "buy",
            common::OrderSide::Sell => "sell",
        };

        let order_type_str = match order.order_type {
            common::OrderType::Market => "market",
            common::OrderType::Limit => "limit",
            common::OrderType::Stop => "stop",
            common::OrderType::StopLimit => "stop_limit",
            _ => "market", // Default fallback
        };

        let status_str = match order.status {
            common::OrderStatus::Pending => "pending",
            common::OrderStatus::New => "accepted",
            common::OrderStatus::Rejected => "rejected",
            common::OrderStatus::PartiallyFilled => "partial",
            common::OrderStatus::Filled => "filled",
            common::OrderStatus::Cancelled => "cancelled",
            common::OrderStatus::Expired => "expired",
            common::OrderStatus::Submitted => "submitted",
            common::OrderStatus::Created => "created",
            common::OrderStatus::Working => "working",
            common::OrderStatus::Unknown => "unknown",
            common::OrderStatus::Suspended => "suspended",
            common::OrderStatus::PendingCancel => "pending_cancel",
            common::OrderStatus::PendingReplace => "pending_replace",
            _ => "unknown", // Catch-all for non-exhaustive enum
        };

        let query = r#"
            INSERT INTO orders (id, account_id, symbol, side, order_type, quantity, limit_price, stop_price, status, created_at, updated_at, venue)
            VALUES ($1, $2, $3, $4::order_side, $5::order_type, $6, $7, $8, $9::order_status, $10, $10, $11)
        "#;

        sqlx::query(query)
            .bind(order_id)
            .bind(&order.account_id)
            .bind(&order.symbol)
            .bind(side_str)
            .bind(order_type_str)
            .bind(quantity_bigint)
            .bind(limit_price_cents)
            .bind(stop_price_cents)
            .bind(status_str)
            .bind(timestamp_ns)
            .bind("SIMULATED") // venue - required field
            .execute(&self.pool)
            .await
            .map_err(|e| TradingServiceError::DatabaseError {
                source: Box::new(e),
            })?;

        Ok(order_id.to_string())
    }

    async fn update_order_status(
        &self,
        order_id: &str,
        status: common::types::OrderStatus,
    ) -> TradingServiceResult<()> {
        let status_str = match status {
            common::OrderStatus::Pending => "pending",
            common::OrderStatus::New => "accepted",
            common::OrderStatus::Rejected => "rejected",
            common::OrderStatus::PartiallyFilled => "partial",
            common::OrderStatus::Filled => "filled",
            common::OrderStatus::Cancelled => "cancelled",
            common::OrderStatus::Expired => "expired",
            common::OrderStatus::Submitted => "submitted",
            common::OrderStatus::Created => "created",
            common::OrderStatus::Working => "working",
            common::OrderStatus::Unknown => "unknown",
            common::OrderStatus::Suspended => "suspended",
            common::OrderStatus::PendingCancel => "pending_cancel",
            common::OrderStatus::PendingReplace => "pending_replace",
            _ => "unknown", // Catch-all for non-exhaustive enum
        };

        let timestamp_ns = chrono::Utc::now().timestamp() * 1_000_000_000;
        let query =
            "UPDATE orders SET status = $1::order_status, updated_at = $2 WHERE id = $3::uuid";

        sqlx::query(query)
            .bind(status_str)
            .bind(timestamp_ns)
            .bind(order_id)
            .execute(&self.pool)
            .await
            .map_err(|e| TradingServiceError::DatabaseError {
                source: Box::new(e),
            })?;

        Ok(())
    }

    async fn get_order(&self, order_id: &str) -> TradingServiceResult<Option<TradingOrder>> {
        let query = "SELECT id::uuid::text as id, account_id, symbol, side::text, order_type::text, quantity, limit_price, stop_price, filled_quantity, status::text, created_at FROM orders WHERE id = $1::uuid";

        let row = sqlx::query(query)
            .bind(order_id)
            .fetch_optional(&self.pool)
            .await
            .map_err(|e| TradingServiceError::DatabaseError {
                source: Box::new(e),
            })?;

        if let Some(row) = row {
            // Convert BIGINT back to f64
            let quantity_bigint: i64 = row.get("quantity");
            let limit_price_bigint: Option<i64> = row.get("limit_price");
            let stop_price_bigint: Option<i64> = row.get("stop_price");
            let filled_quantity_bigint: i64 = row.get("filled_quantity");
            let created_at_ns: i64 = row.get("created_at");

            // Parse enum strings from PostgreSQL
            let side_str: String = row.get("side");
            let order_type_str: String = row.get("order_type");
            let status_str: String = row.get("status");

            let side = match side_str.as_str() {
                "buy" => common::OrderSide::Buy,
                "sell" => common::OrderSide::Sell,
                _ => common::OrderSide::Buy,
            };

            let order_type = match order_type_str.as_str() {
                "market" => common::OrderType::Market,
                "limit" => common::OrderType::Limit,
                "stop" => common::OrderType::Stop,
                "stop_limit" => common::OrderType::StopLimit,
                _ => common::OrderType::Market,
            };

            let status = match status_str.as_str() {
                "pending" => common::OrderStatus::Pending,
                "accepted" => common::OrderStatus::New,
                "rejected" => common::OrderStatus::Rejected,
                "partial" => common::OrderStatus::PartiallyFilled,
                "filled" => common::OrderStatus::Filled,
                "cancelled" => common::OrderStatus::Cancelled,
                "expired" => common::OrderStatus::Expired,
                "submitted" => common::OrderStatus::Submitted,
                "created" => common::OrderStatus::Created,
                "working" => common::OrderStatus::Working,
                "unknown" => common::OrderStatus::Unknown,
                "suspended" => common::OrderStatus::Suspended,
                "pending_cancel" => common::OrderStatus::PendingCancel,
                "pending_replace" => common::OrderStatus::PendingReplace,
                _ => common::OrderStatus::Pending,
            };

            Ok(Some(TradingOrder {
                id: row.get("id"),
                account_id: row.get("account_id"),
                symbol: row.get("symbol"),
                side,
                order_type,
                quantity: quantity_bigint as f64 / 100.0,
                filled_quantity: filled_quantity_bigint as f64 / 100.0,
                price: limit_price_bigint.map(|p| p as f64 / 100.0).unwrap_or(0.0),
                stop_price: stop_price_bigint.map(|p| p as f64 / 100.0),
                status,
                timestamp: created_at_ns / 1_000_000_000, // Convert nanoseconds to seconds
            }))
        } else {
            Ok(None)
        }
    }

    async fn get_orders_for_account(
        &self,
        account_id: &str,
    ) -> TradingServiceResult<Vec<TradingOrder>> {
        let rows = sqlx::query(
            "SELECT id::uuid::text as id, account_id, symbol, side::text, order_type::text, quantity, limit_price, stop_price, filled_quantity, status::text, created_at FROM orders WHERE account_id = $1 ORDER BY created_at DESC"
        )
        .bind(account_id)
        .fetch_all(&self.pool)
        .await
        .map_err(|e| TradingServiceError::DatabaseError { source: Box::new(e) })?;

        let orders = rows
            .into_iter()
            .map(|row| {
                // Convert BIGINT back to f64
                let quantity_bigint: i64 = row.get("quantity");
                let limit_price_bigint: Option<i64> = row.get("limit_price");
                let stop_price_bigint: Option<i64> = row.get("stop_price");
                let filled_quantity_bigint: i64 = row.get("filled_quantity");
                let created_at_ns: i64 = row.get("created_at");

                // Parse enum strings from PostgreSQL
                let side_str: String = row.get("side");
                let order_type_str: String = row.get("order_type");
                let status_str: String = row.get("status");

                let side = match side_str.as_str() {
                    "buy" => common::OrderSide::Buy,
                    "sell" => common::OrderSide::Sell,
                    _ => common::OrderSide::Buy,
                };

                let order_type = match order_type_str.as_str() {
                    "market" => common::OrderType::Market,
                    "limit" => common::OrderType::Limit,
                    "stop" => common::OrderType::Stop,
                    "stop_limit" => common::OrderType::StopLimit,
                    _ => common::OrderType::Market,
                };

                let status = match status_str.as_str() {
                    "pending" => common::OrderStatus::Pending,
                    "accepted" => common::OrderStatus::New,
                    "rejected" => common::OrderStatus::Rejected,
                    "partial" => common::OrderStatus::PartiallyFilled,
                    "filled" => common::OrderStatus::Filled,
                    "cancelled" => common::OrderStatus::Cancelled,
                    "expired" => common::OrderStatus::Expired,
                    "submitted" => common::OrderStatus::Submitted,
                    "created" => common::OrderStatus::Created,
                    "working" => common::OrderStatus::Working,
                    "unknown" => common::OrderStatus::Unknown,
                    "suspended" => common::OrderStatus::Suspended,
                    "pending_cancel" => common::OrderStatus::PendingCancel,
                    "pending_replace" => common::OrderStatus::PendingReplace,
                    _ => common::OrderStatus::Pending,
                };

                TradingOrder {
                    id: row.get("id"),
                    account_id: row.get("account_id"),
                    symbol: row.get("symbol"),
                    side,
                    order_type,
                    quantity: quantity_bigint as f64 / 100.0,
                    filled_quantity: filled_quantity_bigint as f64 / 100.0,
                    price: limit_price_bigint.map(|p| p as f64 / 100.0).unwrap_or(0.0),
                    stop_price: stop_price_bigint.map(|p| p as f64 / 100.0),
                    status,
                    timestamp: created_at_ns / 1_000_000_000,
                }
            })
            .collect();

        Ok(orders)
    }

    async fn store_execution(
        &self,
        execution: &crate::repositories::ExecutionEvent,
    ) -> TradingServiceResult<()> {
        sqlx::query(
            r#"
            INSERT INTO executions (id, order_id, account_id, symbol, side, quantity, price, timestamp)
            VALUES ($1, $2, $3, $4, $5, $6, $7, $8)
            "#
        )
        .bind(&execution.id)
        .bind(&execution.order_id)
        .bind(&execution.account_id)
        .bind(&execution.symbol)
        .bind(match execution.side { common::OrderSide::Buy => 0, common::OrderSide::Sell => 1 })
        .bind(execution.quantity)
        .bind(execution.price)
        .bind(safe_timestamp_to_datetime(execution.timestamp)?)
        .execute(&self.pool)
        .await
        .map_err(|e| TradingServiceError::DatabaseError { source: Box::new(e) })?;

        Ok(())
    }

    async fn get_execution_history(
        &self,
        request: &GetExecutionHistoryRequest,
    ) -> TradingServiceResult<Vec<crate::repositories::ExecutionEvent>> {
        let rows = sqlx::query(
            "SELECT id::uuid::text as id, order_id::uuid::text as order_id, account_id, symbol, side, quantity, price, EXTRACT(EPOCH FROM timestamp)::bigint as timestamp FROM executions WHERE account_id = $1 ORDER BY timestamp DESC LIMIT 1000"
        )
        .bind(request.account_id.as_deref().unwrap_or(""))
        .fetch_all(&self.pool)
        .await
        .map_err(|e| TradingServiceError::DatabaseError { source: Box::new(e) })?;

        let executions = rows
            .into_iter()
            .map(|row| crate::repositories::ExecutionEvent {
                id: row.get("id"),
                order_id: row.get("order_id"),
                account_id: row.get("account_id"),
                symbol: row.get("symbol"),
                side: common::OrderSide::try_from(row.get::<i32, _>("side"))
                    .unwrap_or(common::OrderSide::Buy),
                quantity: row.get("quantity"),
                price: row.get("price"),
                timestamp: row.get::<Option<i64>, _>("timestamp").unwrap_or(0),
            })
            .collect();

        Ok(executions)
    }

    async fn store_position(&self, position: &TradingPosition) -> TradingServiceResult<()> {
        sqlx::query(
            r#"
            INSERT INTO positions (account_id, symbol, quantity, average_price, market_value, unrealized_pnl, timestamp)
            VALUES ($1, $2, $3, $4, $5, $6, $7)
            ON CONFLICT (account_id, symbol) DO UPDATE SET
                quantity = EXCLUDED.quantity,
                average_price = EXCLUDED.average_price,
                market_value = EXCLUDED.market_value,
                unrealized_pnl = EXCLUDED.unrealized_pnl,
                timestamp = EXCLUDED.timestamp
            "#
        )
        .bind(&position.account_id)
        .bind(&position.symbol)
        .bind(position.quantity)
        .bind(position.average_price)
        .bind(position.market_value)
        .bind(position.unrealized_pnl)
        .bind(safe_timestamp_to_datetime(position.timestamp)?)
        .execute(&self.pool)
        .await
        .map_err(|e| TradingServiceError::DatabaseError { source: Box::new(e) })?;

        Ok(())
    }

    async fn get_positions(
        &self,
        account_id: Option<&str>,
        symbol: Option<&str>,
    ) -> TradingServiceResult<Vec<TradingPosition>> {
        let mut query = "SELECT account_id, symbol, quantity, avg_cost as average_price, market_value, unrealized_pnl, (last_updated / 1000000000)::bigint as timestamp FROM positions WHERE 1=1".to_string();
        let mut params = Vec::new();
        let mut param_count = 1;

        if let Some(account) = account_id {
            query.push_str(&format!(" AND account_id = ${}", param_count));
            params.push(account);
            param_count += 1;
        }

        if let Some(sym) = symbol {
            query.push_str(&format!(" AND symbol = ${}", param_count));
            params.push(sym);
        }

        query.push_str(" ORDER BY last_updated DESC");

        // For simplicity, using a basic query - in production would use proper parameter binding
        let rows = if let (Some(account), Some(sym)) = (account_id, symbol) {
            sqlx::query(
                "SELECT account_id, symbol, quantity, avg_cost as average_price, market_value, unrealized_pnl, (last_updated / 1000000000)::bigint as timestamp FROM positions WHERE account_id = $1 AND symbol = $2 ORDER BY last_updated DESC"
            )
            .bind(account)
            .bind(sym)
            .fetch_all(&self.pool)
            .await
        } else if let Some(account) = account_id {
            sqlx::query(
                "SELECT account_id, symbol, quantity, avg_cost as average_price, market_value, unrealized_pnl, (last_updated / 1000000000)::bigint as timestamp FROM positions WHERE account_id = $1 ORDER BY last_updated DESC"
            )
            .bind(account)
            .fetch_all(&self.pool)
            .await
        } else {
            sqlx::query(
                "SELECT account_id, symbol, quantity, avg_cost as average_price, market_value, unrealized_pnl, (last_updated / 1000000000)::bigint as timestamp FROM positions ORDER BY last_updated DESC"
            )
            .fetch_all(&self.pool)
            .await
        }
        .map_err(|e| TradingServiceError::DatabaseError { source: Box::new(e) })?;

        let positions = rows
            .into_iter()
            .map(|row| TradingPosition {
                account_id: row.get("account_id"),
                symbol: row.get("symbol"),
                quantity: row.get("quantity"),
                average_price: row.get("average_price"),
                market_value: row.get("market_value"),
                unrealized_pnl: row.get("unrealized_pnl"),
                timestamp: row.get::<Option<i64>, _>("timestamp").unwrap_or(0),
            })
            .collect();

        Ok(positions)
    }

    async fn get_portfolio_summary(
        &self,
        account_id: &str,
    ) -> TradingServiceResult<PortfolioSummary> {
        let row = sqlx::query(
            r#"
            SELECT
                COALESCE(SUM(market_value), 0.0)::DOUBLE PRECISION as total_value,
                COALESCE(SUM(unrealized_pnl), 0.0)::DOUBLE PRECISION as unrealized_pnl,
                COALESCE(SUM(CASE WHEN quantity > 0 THEN market_value ELSE 0 END), 0.0)::DOUBLE PRECISION as positions_value
            FROM positions
            WHERE account_id = $1
            "#
        )
        .bind(account_id)
        .fetch_one(&self.pool)
        .await
        .map_err(|e| TradingServiceError::DatabaseError { source: Box::new(e) })?;

        // Get realized PnL from executions (simplified calculation)
        let realized_pnl_row = sqlx::query(
            "SELECT COALESCE(SUM(quantity * price), 0.0)::DOUBLE PRECISION as realized_pnl FROM executions WHERE account_id = $1"
        )
        .bind(account_id)
        .fetch_one(&self.pool)
        .await
        .map_err(|e| TradingServiceError::DatabaseError { source: Box::new(e) })?;

        // CRITICAL: Get actual cash balance from database - NO HARDCODED DEFAULTS
        let cash_balance = sqlx::query_scalar::<_, f64>(
            "SELECT COALESCE(cash_balance, 0.0) FROM account_balances WHERE account_id = $1"
        )
        .bind(account_id)
        .fetch_optional(&self.pool)
        .await
        .map_err(|e| TradingServiceError::DatabaseError { source: Box::new(e) })?
        .ok_or_else(|| TradingServiceError::ConfigurationError {
            message: format!("CRITICAL: No cash balance found for account {} - cannot create portfolio summary with hardcoded defaults", account_id)
        })?;

        Ok(PortfolioSummary {
            account_id: account_id.to_string(),
            total_value: row.get::<Option<f64>, _>("total_value").unwrap_or(0.0),
            cash_balance,
            positions_value: row.get::<Option<f64>, _>("positions_value").unwrap_or(0.0),
            unrealized_pnl: row.get::<Option<f64>, _>("unrealized_pnl").unwrap_or(0.0),
            realized_pnl: realized_pnl_row
                .get::<Option<f64>, _>("realized_pnl")
                .unwrap_or(0.0),
        })
    }

    async fn get_realized_pnl(
        &self,
        account_id: &str,
        symbol: Option<&str>,
    ) -> TradingServiceResult<f64> {
        let query = if let Some(sym) = symbol {
            sqlx::query_scalar::<_, Option<f64>>(
                "SELECT SUM(quantity * price) FROM executions WHERE account_id = $1 AND symbol = $2"
            )
            .bind(account_id)
            .bind(sym)
        } else {
            sqlx::query_scalar::<_, Option<f64>>(
                "SELECT SUM(quantity * price) FROM executions WHERE account_id = $1",
            )
            .bind(account_id)
        };

        let result = query.fetch_optional(&self.pool).await.map_err(|e| {
            TradingServiceError::DatabaseError {
                source: Box::new(e),
            }
        })?;

        Ok(result.flatten().unwrap_or(0.0))
    }

    async fn get_day_pnl(&self, account_id: &str) -> TradingServiceResult<f64> {
        let result = sqlx::query_scalar::<_, Option<f64>>(
            r#"
            SELECT SUM(quantity * price)
            FROM executions
            WHERE account_id = $1
              AND DATE(timestamp) = CURRENT_DATE
            "#,
        )
        .bind(account_id)
        .fetch_optional(&self.pool)
        .await
        .map_err(|e| TradingServiceError::DatabaseError {
            source: Box::new(e),
        })?;

        Ok(result.flatten().unwrap_or(0.0))
    }
}

/// Postgre`SQL` implementation of MarketDataRepository
#[derive(Debug, Clone)]
pub struct PostgresMarketDataRepository {
    pool: PgPool,
}

impl PostgresMarketDataRepository {
    pub fn new(pool: PgPool) -> Self {
        Self { pool }
    }
}

#[async_trait]
impl MarketDataRepository for PostgresMarketDataRepository {
    async fn store_market_tick(
        &self,
        tick: &crate::repositories::MarketTick,
    ) -> TradingServiceResult<()> {
        sqlx::query(
            r#"
            INSERT INTO market_ticks (symbol, price, quantity, side, timestamp)
            VALUES ($1, $2, $3, $4, $5)
            "#,
        )
        .bind(&tick.symbol)
        .bind(tick.price)
        .bind(tick.quantity)
        .bind(tick.side.map(|s| match s {
            common::OrderSide::Buy => 0,
            common::OrderSide::Sell => 1,
        }))
        .bind(safe_timestamp_to_datetime(tick.timestamp)?)
        .execute(&self.pool)
        .await
        .map_err(|e| TradingServiceError::DatabaseError {
            source: Box::new(e),
        })?;

        Ok(())
    }

    async fn get_order_book(
        &self,
        symbol: &str,
        depth: i32,
    ) -> TradingServiceResult<crate::repositories::OrderBook> {
        // Simplified order book retrieval - in production would aggregate from order book table
        let rows = sqlx::query(
            r#"
            SELECT price, quantity, side, EXTRACT(EPOCH FROM timestamp)::bigint as timestamp
            FROM market_ticks
            WHERE symbol = $1
            ORDER BY timestamp DESC
            LIMIT $2
            "#,
        )
        .bind(symbol)
        .bind(
            i64::try_from(depth).map_err(|_| TradingServiceError::ValidationError {
                message: format!("Depth {} out of range for i64", depth),
            })?,
        )
        .fetch_all(&self.pool)
        .await
        .map_err(|e| TradingServiceError::DatabaseError {
            source: Box::new(e),
        })?;

        let mut bids = Vec::new();
        let mut asks = Vec::new();

        for row in rows {
            let price_level = PriceLevel {
                price: row.get("price"),
                size: row.get("quantity"),
            };

            let side: i32 = row.get("side");
            if side == common::OrderSide::Buy as i32 {
                bids.push(price_level);
            } else {
                asks.push(price_level);
            }
        }

        Ok(crate::repositories::OrderBook {
            symbol: symbol.to_string(),
            bids,
            asks,
            timestamp: chrono::Utc::now().timestamp(),
        })
    }

    async fn store_order_book(
        &self,
        symbol: &str,
        order_book: &crate::repositories::OrderBook,
    ) -> TradingServiceResult<()> {
        // In production, this would store to a dedicated order book table
        // For now, store as individual price levels
        for bid in &order_book.bids {
            sqlx::query(
                r#"
                INSERT INTO order_book_levels (symbol, side, price, quantity, timestamp)
                VALUES ($1, $2, $3, $4, $5)
                "#,
            )
            .bind(symbol)
            .bind(0)
            .bind(bid.price)
            .bind(bid.size)
            .bind(safe_timestamp_to_datetime(order_book.timestamp)?)
            .execute(&self.pool)
            .await
            .map_err(|e| TradingServiceError::DatabaseError {
                source: Box::new(e),
            })?;
        }

        for ask in &order_book.asks {
            sqlx::query(
                r#"
                INSERT INTO order_book_levels (symbol, side, price, quantity, timestamp)
                VALUES ($1, $2, $3, $4, $5)
                "#,
            )
            .bind(symbol)
            .bind(1)
            .bind(ask.price)
            .bind(ask.size)
            .bind(safe_timestamp_to_datetime(order_book.timestamp)?)
            .execute(&self.pool)
            .await
            .map_err(|e| TradingServiceError::DatabaseError {
                source: Box::new(e),
            })?;
        }

        Ok(())
    }

    async fn get_latest_prices(
        &self,
        symbols: &[String],
    ) -> TradingServiceResult<Vec<crate::repositories::MarketTick>> {
        let symbol_list = symbols.join("','");
        let query = format!(
            r#"
            SELECT DISTINCT ON (symbol) symbol, price, quantity, side, EXTRACT(EPOCH FROM timestamp)::bigint as timestamp
            FROM market_ticks 
            WHERE symbol IN ('{}') 
            ORDER BY symbol, timestamp DESC
            "#,
            symbol_list
        );

        let rows = sqlx::query_as::<_, (String, f64, f64, Option<i32>, Option<i64>)>(&query)
            .fetch_all(&self.pool)
            .await
            .map_err(|e| TradingServiceError::DatabaseError {
                source: Box::new(e),
            })?;

        let ticks = rows
            .into_iter()
            .map(
                |(symbol, price, quantity, side, timestamp)| crate::repositories::MarketTick {
                    symbol,
                    price,
                    quantity,
                    side: side.map(|s| match s {
                        0 => common::OrderSide::Buy,
                        _ => common::OrderSide::Sell,
                    }),
                    timestamp: timestamp.unwrap_or(0),
                },
            )
            .collect();

        Ok(ticks)
    }

    async fn store_market_event(
        &self,
        event: &common::MarketDataEvent,
    ) -> TradingServiceResult<()> {
        sqlx::query(
            r#"
            INSERT INTO market_events (symbol, event_type, data, timestamp)
            VALUES ($1, $2, $3, $4)
            "#
        )
        .bind(event.symbol())
        .bind(format!("{:?}", event)) // Store the enum variant as string
        .bind(serde_json::to_string(event).unwrap_or_default())
        .bind(event.timestamp().unwrap_or_else(chrono::Utc::now))
        .execute(&self.pool)
        .await
        .map_err(|e| TradingServiceError::DatabaseError { source: Box::new(e) })?;

        Ok(())
    }

    async fn get_historical_data(
        &self,
        symbol: &str,
        from: i64,
        to: i64,
    ) -> TradingServiceResult<Vec<crate::repositories::MarketTick>> {
        let rows = sqlx::query(
            r#"
            SELECT symbol, price, quantity, side, EXTRACT(EPOCH FROM timestamp)::bigint as timestamp
            FROM market_ticks
            WHERE symbol = $1
                AND timestamp >= $2
                AND timestamp <= $3
            ORDER BY timestamp DESC
            LIMIT 10000
            "#,
        )
        .bind(symbol)
        .bind(safe_timestamp_to_datetime(from)?)
        .bind(safe_timestamp_to_datetime(to)?)
        .fetch_all(&self.pool)
        .await
        .map_err(|e| TradingServiceError::DatabaseError {
            source: Box::new(e),
        })?;

        let ticks = rows
            .into_iter()
            .map(|row| crate::repositories::MarketTick {
                symbol: row.get("symbol"),
                price: row.get("price"),
                quantity: row.get("quantity"),
                side: row.get::<Option<i32>, _>("side").map(|s| match s {
                    0 => common::OrderSide::Buy,
                    _ => common::OrderSide::Sell,
                }),
                timestamp: row.get::<Option<i64>, _>("timestamp").unwrap_or(0),
            })
            .collect();

        Ok(ticks)
    }

    async fn get_order_book_level_count(
        &self,
        symbol: &str,
        price: f64,
        side: common::OrderSide,
    ) -> TradingServiceResult<i32> {
        let side_str = match side {
            common::OrderSide::Buy => "bid",
            common::OrderSide::Sell => "ask",
        };

        let result = sqlx::query_scalar::<_, Option<i32>>(
            "SELECT order_count FROM order_book_levels WHERE symbol = $1 AND price = $2 AND side = $3"
        )
        .bind(symbol)
        .bind(price)
        .bind(side_str)
        .fetch_optional(&self.pool)
        .await
        .map_err(|e| TradingServiceError::DatabaseError { source: Box::new(e) })?;

        // Default to 1 if order count not available
        Ok(result.flatten().unwrap_or(1))
    }
}

/// Postgre`SQL` implementation of RiskRepository
#[derive(Debug, Clone)]
pub struct PostgresRiskRepository {
    pool: PgPool,
}

impl PostgresRiskRepository {
    pub fn new(pool: PgPool) -> Self {
        Self { pool }
    }
}

#[async_trait]
impl RiskRepository for PostgresRiskRepository {
    async fn store_var_calculation(
        &self,
        calculation: &VarCalculation,
    ) -> TradingServiceResult<()> {
        sqlx::query(
            r#"
            INSERT INTO var_calculations (account_id, var_value, confidence, time_horizon_days, timestamp)
            VALUES ($1, $2, $3, $4, $5)
            "#
        )
        .bind(&calculation.account_id)
        .bind(calculation.var_value)
        .bind(calculation.confidence)
        .bind(calculation.time_horizon_days)
        .bind(safe_timestamp_to_datetime(calculation.timestamp)?)
        .execute(&self.pool)
        .await
        .map_err(|e| TradingServiceError::DatabaseError { source: Box::new(e) })?;

        Ok(())
    }

    async fn get_risk_limits(&self, account_id: &str) -> TradingServiceResult<RiskLimits> {
        let row = sqlx::query(
            "SELECT account_id, max_order_size, max_position_limit, max_drawdown_limit, daily_loss_limit FROM risk_limits WHERE account_id = $1"
        )
        .bind(account_id)
        .fetch_optional(&self.pool)
        .await
        .map_err(|e| TradingServiceError::DatabaseError { source: Box::new(e) })?;

        if let Some(row) = row {
            Ok(RiskLimits {
                account_id: row.get("account_id"),
                max_order_size: row.get("max_order_size"),
                max_position_limit: row.get("max_position_limit"),
                max_drawdown_limit: row.get("max_drawdown_limit"),
                daily_loss_limit: row.get("daily_loss_limit"),
            })
        } else {
            // CRITICAL: NO DEFAULT RISK LIMITS - Must be explicitly configured
            return Err(TradingServiceError::ConfigurationError {
                message: format!(
                    "CRITICAL: No risk limits found for account {} - cannot use dangerous hardcoded defaults. Risk limits must be explicitly configured in database.", 
                    account_id
                )
            });
        }
    }

    async fn update_risk_limits(
        &self,
        account_id: &str,
        limits: &RiskLimits,
    ) -> TradingServiceResult<()> {
        sqlx::query(
            r#"
            INSERT INTO risk_limits (account_id, max_order_size, max_position_limit, max_drawdown_limit, daily_loss_limit)
            VALUES ($1, $2, $3, $4, $5)
            ON CONFLICT (account_id) DO UPDATE SET
                max_order_size = EXCLUDED.max_order_size,
                max_position_limit = EXCLUDED.max_position_limit,
                max_drawdown_limit = EXCLUDED.max_drawdown_limit,
                daily_loss_limit = EXCLUDED.daily_loss_limit,
                updated_at = NOW()
            "#
        )
        .bind(account_id)
        .bind(limits.max_order_size)
        .bind(limits.max_position_limit)
        .bind(limits.max_drawdown_limit)
        .bind(limits.daily_loss_limit)
        .execute(&self.pool)
        .await
        .map_err(|e| TradingServiceError::DatabaseError { source: Box::new(e) })?;

        Ok(())
    }

    async fn store_risk_alert(&self, alert: &RiskAlert) -> TradingServiceResult<()> {
        sqlx::query(
            r#"
            INSERT INTO risk_alerts (account_id, alert_type, message, severity, timestamp)
            VALUES ($1, $2, $3, $4, $5)
            "#,
        )
        .bind(&alert.account_id)
        .bind(&alert.alert_type)
        .bind(&alert.message)
        .bind(&alert.severity)
        .bind(safe_timestamp_to_datetime(alert.timestamp)?)
        .execute(&self.pool)
        .await
        .map_err(|e| TradingServiceError::DatabaseError {
            source: Box::new(e),
        })?;

        Ok(())
    }

    async fn get_risk_metrics(&self, account_id: &str) -> TradingServiceResult<RiskMetrics> {
        // Fetch total absolute position value
        let position_value: f64 = sqlx::query_scalar::<_, f64>(
            "SELECT COALESCE(SUM(ABS(market_value)), 0.0) FROM positions WHERE account_id = $1",
        )
        .bind(account_id)
        .fetch_one(&self.pool)
        .await
        .map_err(|e| TradingServiceError::DatabaseError {
            source: Box::new(e),
        })?;

        let latest_var: f64 = sqlx::query_scalar(
            "SELECT COALESCE(var_value, 0.0) FROM var_calculations WHERE account_id = $1 ORDER BY timestamp DESC LIMIT 1"
        )
        .bind(account_id)
        .fetch_optional(&self.pool)
        .await
        .map_err(|e| TradingServiceError::DatabaseError { source: Box::new(e) })?
        .unwrap_or(0.0);

        // Calculate current drawdown from position PnL.
        // drawdown = max(0, -total_unrealized_pnl / total_market_value)
        let current_drawdown: f64 = if position_value > 0.0 {
            let total_unrealized_pnl: f64 = sqlx::query_scalar::<_, f64>(
                "SELECT COALESCE(SUM(unrealized_pnl), 0.0) FROM positions WHERE account_id = $1",
            )
            .bind(account_id)
            .fetch_one(&self.pool)
            .await
            .map_err(|e| TradingServiceError::DatabaseError {
                source: Box::new(e),
            })?;
            if total_unrealized_pnl < 0.0 {
                (-total_unrealized_pnl) / position_value
            } else {
                0.0
            }
        } else {
            tracing::warn!(
                account_id = account_id,
                "No position data for drawdown calculation, returning 0.0"
            );
            0.0
        };

        // Calculate leverage ratio = total_notional / account_equity.
        // Account equity = account balance + unrealized PnL.
        let account_equity: f64 = sqlx::query_scalar::<_, f64>(
            "SELECT COALESCE(balance, 0.0) + COALESCE((SELECT SUM(unrealized_pnl) FROM positions WHERE account_id = $1), 0.0) FROM accounts WHERE account_id = $1",
        )
        .bind(account_id)
        .fetch_optional(&self.pool)
        .await
        .map_err(|e| TradingServiceError::DatabaseError { source: Box::new(e) })?
        .unwrap_or(0.0);

        let leverage_ratio = if account_equity > 0.0 {
            position_value / account_equity
        } else if position_value > 0.0 {
            // No account equity record but positions exist: use position_value as denominator
            // (leverage >= 1.0 since notional / notional = 1.0)
            tracing::warn!(
                account_id = account_id,
                "No account equity data, approximating leverage from position value"
            );
            1.0
        } else {
            0.0
        };

        // Calculate position concentration = largest single position / total portfolio value.
        // Uses sum of all positions as total capital (real portfolio).
        let max_single_position: f64 = sqlx::query_scalar::<_, f64>(
            "SELECT COALESCE(MAX(ABS(market_value)), 0.0) FROM positions WHERE account_id = $1",
        )
        .bind(account_id)
        .fetch_one(&self.pool)
        .await
        .map_err(|e| TradingServiceError::DatabaseError {
            source: Box::new(e),
        })?;

        let position_concentration = if position_value > 0.0 {
            max_single_position / position_value
        } else {
            0.0
        };

        Ok(RiskMetrics {
            account_id: account_id.to_string(),
            current_var: latest_var,
            current_drawdown,
            position_concentration,
            leverage_ratio,
        })
    }

    async fn store_position_risk(
        &self,
        account_id: &str,
        symbol: &str,
        risk: &PositionRisk,
    ) -> TradingServiceResult<()> {
        sqlx::query(
            r#"
            INSERT INTO position_risks (account_id, symbol, position_var, concentration_risk, liquidity_risk, timestamp)
            VALUES ($1, $2, $3, $4, $5, NOW())
            ON CONFLICT (account_id, symbol) DO UPDATE SET
                position_var = EXCLUDED.position_var,
                concentration_risk = EXCLUDED.concentration_risk,
                liquidity_risk = EXCLUDED.liquidity_risk,
                timestamp = EXCLUDED.timestamp
            "#
        )
        .bind(account_id)
        .bind(symbol)
        .bind(risk.position_var)
        .bind(risk.concentration_risk)
        .bind(risk.liquidity_risk)
        .execute(&self.pool)
        .await
        .map_err(|e| TradingServiceError::DatabaseError { source: Box::new(e) })?;

        Ok(())
    }

    async fn validate_order_risk(
        &self,
        account_id: &str,
        order: &OrderRequest,
    ) -> TradingServiceResult<bool> {
        // Get risk limits
        let limits = self.get_risk_limits(account_id).await?;

        // CRITICAL: Order price must be provided - NO DANGEROUS FALLBACKS
        let order_price = order.price.ok_or_else(|| TradingServiceError::ConfigurationError {
            message: "CRITICAL: Order price must be specified - cannot use fallback price for risk validation".to_string()
        })?;

        // Check order size limit with overflow protection
        let order_notional = order.quantity * order_price;
        if !order_notional.is_finite() {
            return Err(TradingServiceError::ValidationError {
                message: format!(
                    "Order notional overflow: {} * {}",
                    order.quantity, order_price
                ),
            });
        }
        if order_notional > limits.max_order_size {
            return Ok(false);
        }

        // Get current position value
        let current_position_value: f64 = sqlx::query_scalar::<_, f64>(
            "SELECT COALESCE(SUM(ABS(market_value)), 0.0) FROM positions WHERE account_id = $1",
        )
        .bind(account_id)
        .fetch_one(&self.pool)
        .await
        .map_err(|e| TradingServiceError::DatabaseError {
            source: Box::new(e),
        })?;

        // Check position limit with overflow protection
        let order_value = order.quantity * order_price;
        if !order_value.is_finite() {
            return Err(TradingServiceError::ValidationError {
                message: format!("Order value overflow: {} * {}", order.quantity, order_price),
            });
        }
        let new_position_value = current_position_value + order_value;
        if !new_position_value.is_finite() {
            return Err(TradingServiceError::ValidationError {
                message: format!(
                    "Position value overflow: {} + {}",
                    current_position_value, order_value
                ),
            });
        }
        if new_position_value > limits.max_position_limit {
            return Ok(false);
        }

        Ok(true)
    }

    async fn calculate_margin_used(&self, account_id: &str) -> TradingServiceResult<f64> {
        let result = sqlx::query_scalar::<_, Option<f64>>(
            r#"
            SELECT SUM(ABS(quantity * average_price) * 0.5)
            FROM positions
            WHERE account_id = $1
            "#,
        )
        .bind(account_id)
        .fetch_optional(&self.pool)
        .await
        .map_err(|e| TradingServiceError::DatabaseError {
            source: Box::new(e),
        })?;

        // Default margin calculation: 50% of position value
        // In production, this would use asset-specific margin requirements
        // from the risk configuration or asset classification system
        Ok(result.flatten().unwrap_or(0.0))
    }
}

/// Postgre`SQL` implementation of ConfigRepository
#[derive(Debug, Clone)]
pub struct PostgresConfigRepository {
    pool: PgPool,
}

impl PostgresConfigRepository {
    pub fn new(pool: PgPool) -> Self {
        Self { pool }
    }
}

#[async_trait]
impl ConfigRepository for PostgresConfigRepository {
    async fn get_config_f64(&self, category: &str, key: &str) -> TradingServiceResult<Option<f64>> {
        let row = sqlx::query("SELECT value FROM configuration WHERE category = $1 AND key = $2")
            .bind(category)
            .bind(key)
            .fetch_optional(&self.pool)
            .await
            .map_err(|e| TradingServiceError::DatabaseError {
                source: Box::new(e),
            })?;

        if let Some(row) = row {
            let value_str: String = row.get("value");
            let value: f64 = serde_json::from_str(&value_str).map_err(|e| {
                TradingServiceError::ConfigurationError {
                    message: format!("Failed to deserialize config value: {}", e),
                }
            })?;
            Ok(Some(value))
        } else {
            Ok(None)
        }
    }

    async fn get_config_u64(&self, category: &str, key: &str) -> TradingServiceResult<Option<u64>> {
        let row = sqlx::query("SELECT value FROM configuration WHERE category = $1 AND key = $2")
            .bind(category)
            .bind(key)
            .fetch_optional(&self.pool)
            .await
            .map_err(|e| TradingServiceError::DatabaseError {
                source: Box::new(e),
            })?;

        if let Some(row) = row {
            let value_str: String = row.get("value");
            let value: u64 = serde_json::from_str(&value_str).map_err(|e| {
                TradingServiceError::ConfigurationError {
                    message: format!("Failed to deserialize config value: {}", e),
                }
            })?;
            Ok(Some(value))
        } else {
            Ok(None)
        }
    }

    async fn get_config_string(
        &self,
        category: &str,
        key: &str,
    ) -> TradingServiceResult<Option<String>> {
        let row = sqlx::query("SELECT value FROM configuration WHERE category = $1 AND key = $2")
            .bind(category)
            .bind(key)
            .fetch_optional(&self.pool)
            .await
            .map_err(|e| TradingServiceError::DatabaseError {
                source: Box::new(e),
            })?;

        if let Some(row) = row {
            let value_str: String = row.get("value");
            let value: String = serde_json::from_str(&value_str).map_err(|e| {
                TradingServiceError::ConfigurationError {
                    message: format!("Failed to deserialize config value: {}", e),
                }
            })?;
            Ok(Some(value))
        } else {
            Ok(None)
        }
    }

    async fn set_config<T>(&self, category: &str, key: &str, value: &T) -> TradingServiceResult<()>
    where
        T: serde::Serialize + Send + Sync,
    {
        let value_json =
            serde_json::to_string(value).map_err(|e| TradingServiceError::ConfigurationError {
                message: format!("Failed to serialize config value: {}", e),
            })?;

        sqlx::query(
            r#"
                INSERT INTO configuration (category, key, value, updated_at)
                VALUES ($1, $2, $3, NOW())
                ON CONFLICT (category, key) DO UPDATE SET
                    value = EXCLUDED.value,
                    updated_at = EXCLUDED.updated_at
                "#,
        )
        .bind(category)
        .bind(key)
        .bind(value_json)
        .execute(&self.pool)
        .await
        .map_err(|e| TradingServiceError::DatabaseError {
            source: Box::new(e),
        })?;

        Ok(())
    }
    async fn get_secret(&self, key: &str) -> TradingServiceResult<Option<String>> {
        let row = sqlx::query("SELECT value FROM secrets WHERE key = $1")
            .bind(key)
            .fetch_optional(&self.pool)
            .await
            .map_err(|e| TradingServiceError::DatabaseError {
                source: Box::new(e),
            })?;

        Ok(row.map(|r| r.get("value")))
    }

    async fn set_secret(&self, key: &str, value: &str) -> TradingServiceResult<()> {
        sqlx::query(
            r#"
            INSERT INTO secrets (key, value, updated_at)
            VALUES ($1, $2, NOW())
            ON CONFLICT (key) DO UPDATE SET
                value = EXCLUDED.value,
                updated_at = EXCLUDED.updated_at
            "#,
        )
        .bind(key)
        .bind(value)
        .execute(&self.pool)
        .await
        .map_err(|e| TradingServiceError::DatabaseError {
            source: Box::new(e),
        })?;

        Ok(())
    }

    async fn subscribe_to_changes(&self) -> TradingServiceResult<ConfigChangeReceiver> {
        let (_tx, rx) = tokio::sync::broadcast::channel(1000);

        // In production, this would use PostgreSQL LISTEN/NOTIFY
        // For now, return a channel that can be used for config change notifications
        tokio::spawn(async move {
            // Placeholder - would implement PostgreSQL LISTEN here
        });

        Ok(rx)
    }
}

// =============================================================================
// Mock Implementations for Testing
// =============================================================================

#[cfg(test)]
#[allow(dead_code)]
mod mock_repositories {
    use super::*;

    /// Mock implementation of TradingRepository for testing
    #[derive(Debug, Clone, Default)]
    pub struct MockTradingRepository;

    impl MockTradingRepository {
        pub fn new() -> Self {
            Self
        }
    }

    #[async_trait]
    impl TradingRepository for MockTradingRepository {
        async fn store_order(&self, _order: &TradingOrder) -> TradingServiceResult<String> {
            Ok(uuid::Uuid::new_v4().to_string())
        }

        async fn update_order_status(
            &self,
            _order_id: &str,
            _status: common::types::OrderStatus,
        ) -> TradingServiceResult<()> {
            Ok(())
        }

        async fn get_order(&self, _order_id: &str) -> TradingServiceResult<Option<TradingOrder>> {
            Ok(None)
        }

        async fn get_orders_for_account(
            &self,
            _account_id: &str,
        ) -> TradingServiceResult<Vec<TradingOrder>> {
            Ok(Vec::new())
        }

        async fn store_execution(
            &self,
            _execution: &crate::repositories::ExecutionEvent,
        ) -> TradingServiceResult<()> {
            Ok(())
        }

        async fn get_execution_history(
            &self,
            _request: &GetExecutionHistoryRequest,
        ) -> TradingServiceResult<Vec<crate::repositories::ExecutionEvent>> {
            Ok(Vec::new())
        }
        async fn store_position(&self, _position: &TradingPosition) -> TradingServiceResult<()> {
            Ok(())
        }

        async fn get_positions(
            &self,
            _account_id: Option<&str>,
            _symbol: Option<&str>,
        ) -> TradingServiceResult<Vec<TradingPosition>> {
            Ok(Vec::new())
        }

        async fn get_portfolio_summary(
            &self,
            account_id: &str,
        ) -> TradingServiceResult<PortfolioSummary> {
            Ok(PortfolioSummary {
                account_id: account_id.to_string(),
                total_value: 0.0,
                cash_balance: 0.0,
                positions_value: 0.0,
                unrealized_pnl: 0.0,
                realized_pnl: 0.0,
            })
        }

        async fn get_realized_pnl(
            &self,
            _account_id: &str,
            _symbol: Option<&str>,
        ) -> TradingServiceResult<f64> {
            Ok(0.0)
        }

        async fn get_day_pnl(&self, _account_id: &str) -> TradingServiceResult<f64> {
            Ok(0.0)
        }
    }

    /// Mock implementation of MarketDataRepository for testing
    #[derive(Debug, Clone, Default)]
    pub struct MockMarketDataRepository;

    impl MockMarketDataRepository {
        pub fn new() -> Self {
            Self
        }
    }

    #[async_trait]
    impl MarketDataRepository for MockMarketDataRepository {
        async fn store_market_tick(&self, _tick: &MarketTick) -> TradingServiceResult<()> {
            Ok(())
        }

        async fn get_order_book(
            &self,
            symbol: &str,
            _depth: i32,
        ) -> TradingServiceResult<crate::repositories::OrderBook> {
            Ok(crate::repositories::OrderBook {
                symbol: symbol.to_string(),
                bids: Vec::new(),
                asks: Vec::new(),
                timestamp: chrono::Utc::now().timestamp(),
            })
        }

        async fn store_order_book(
            &self,
            _symbol: &str,
            _order_book: &crate::repositories::OrderBook,
        ) -> TradingServiceResult<()> {
            Ok(())
        }
        async fn get_latest_prices(
            &self,
            _symbols: &[String],
        ) -> TradingServiceResult<Vec<MarketTick>> {
            Ok(Vec::new())
        }

        async fn store_market_event(
            &self,
            _event: &common::MarketDataEvent,
        ) -> TradingServiceResult<()> {
            Ok(())
        }

        async fn get_historical_data(
            &self,
            _symbol: &str,
            _from: i64,
            _to: i64,
        ) -> TradingServiceResult<Vec<MarketTick>> {
            Ok(Vec::new())
        }

        async fn get_order_book_level_count(
            &self,
            _symbol: &str,
            _price: f64,
            _side: common::OrderSide,
        ) -> TradingServiceResult<i32> {
            Ok(1)
        }
    }

    /// Mock implementation of RiskRepository for testing
    #[derive(Debug, Clone, Default)]
    pub struct MockRiskRepository;

    impl MockRiskRepository {
        pub fn new() -> Self {
            Self
        }
    }

    #[async_trait]
    impl RiskRepository for MockRiskRepository {
        async fn store_var_calculation(
            &self,
            _calculation: &VarCalculation,
        ) -> TradingServiceResult<()> {
            Ok(())
        }

        async fn get_risk_limits(&self, account_id: &str) -> TradingServiceResult<RiskLimits> {
            Ok(RiskLimits {
                account_id: account_id.to_string(),
                max_order_size: 1000000.0,
                max_position_limit: 10000000.0,
                max_drawdown_limit: 0.10,
                daily_loss_limit: Some(50000.0),
            })
        }

        async fn update_risk_limits(
            &self,
            _account_id: &str,
            _limits: &RiskLimits,
        ) -> TradingServiceResult<()> {
            Ok(())
        }

        async fn store_risk_alert(&self, _alert: &RiskAlert) -> TradingServiceResult<()> {
            Ok(())
        }

        async fn get_risk_metrics(&self, account_id: &str) -> TradingServiceResult<RiskMetrics> {
            Ok(RiskMetrics {
                account_id: account_id.to_string(),
                current_var: 0.0,
                current_drawdown: 0.0,
                position_concentration: 0.0,
                leverage_ratio: 1.0,
            })
        }

        async fn store_position_risk(
            &self,
            _account_id: &str,
            _symbol: &str,
            _risk: &PositionRisk,
        ) -> TradingServiceResult<()> {
            Ok(())
        }

        async fn validate_order_risk(
            &self,
            _account_id: &str,
            _order: &OrderRequest,
        ) -> TradingServiceResult<bool> {
            Ok(true)
        }

        async fn calculate_margin_used(&self, _account_id: &str) -> TradingServiceResult<f64> {
            Ok(0.0)
        }
    }
}
