#![allow(unexpected_cfgs)]
#![cfg(feature = "__trading_service_integration")]
//! End-to-End Integration Tests for Trading Service
//!
//! Comprehensive E2E test scenarios covering:
//! - Order placement -> Risk check -> Execution (complete flow)
//! - Position tracking across multiple orders
//! - PnL calculation with partial and full fills
//! - Stop-loss triggers and automatic liquidation
//! - Market order execution
//! - Limit order matching
//! - Order cancellation flows
//! - Position close-out scenarios
//!
//! These tests use real PostgreSQL connections (not mocks) to validate
//! complete integration between all service components.

use anyhow::Result;
use common::{OrderSide, OrderStatus, OrderType};
use sqlx::PgPool;
use std::sync::Arc;
use tonic::Request;
use trading_service::proto::trading::{
    trading_service_server::TradingService, CancelOrderRequest, GetOrderStatusRequest,
    GetPortfolioSummaryRequest, GetPositionsRequest, SubmitOrderRequest,
};
use trading_service::repositories::*;
use trading_service::repository_impls::*;
use trading_service::services::trading::TradingServiceImpl;
use trading_service::state::TradingServiceState;

/// Setup test database connection pool
async fn setup_test_db() -> Result<PgPool> {
    let database_url = std::env::var("DATABASE_URL").unwrap_or_else(|_| {
        "postgresql://foxhunt:foxhunt_dev_password@localhost:5432/foxhunt".to_string()
    });

    let pool = PgPool::connect(&database_url).await?;
    Ok(pool)
}

/// Setup complete trading service with real database repositories
async fn setup_trading_service_with_db() -> Result<TradingServiceImpl> {
    let pool = setup_test_db().await?;

    // Create repository implementations
    let trading_repo = Arc::new(PostgresTradingRepository::new(pool.clone()));
    let market_data_repo = Arc::new(PostgresMarketDataRepository::new(pool.clone()));
    let risk_repo = Arc::new(PostgresRiskRepository::new(pool.clone()));
    let config_repo = Arc::new(PostgresConfigRepository::new(pool.clone()));

    // Create event persistence for audit trail
    let event_persistence = Arc::new(trading_service::event_persistence::EventPersistence::new(
        pool.clone(),
        "trading_service_test".to_string(),
        std::process::id(),
    ));

    // Create state with repositories
    let state = Arc::new(
        TradingServiceState::new_with_repositories(
            trading_repo,
            market_data_repo,
            risk_repo,
            config_repo,
            event_persistence,
            None, // kill_switch
            None, // model_cache
        )
        .await?,
    );

    Ok(TradingServiceImpl::new(state))
}

/// Clean up test orders for a specific account
async fn cleanup_test_orders(pool: &PgPool, account_id: &str) -> Result<()> {
    sqlx::query("DELETE FROM orders WHERE account_id = $1")
        .bind(account_id)
        .execute(pool)
        .await?;

    sqlx::query("DELETE FROM positions WHERE account_id = $1")
        .bind(account_id)
        .execute(pool)
        .await?;

    sqlx::query("DELETE FROM executions WHERE account_id = $1")
        .bind(account_id)
        .execute(pool)
        .await?;

    Ok(())
}

// ============================================================================
// E2E Test: Order Placement → Risk Check → Execution
// ============================================================================

#[tokio::test]
async fn test_e2e_order_placement_to_execution() -> Result<()> {
    println!("\n=== E2E Test: Order Placement → Risk Check → Execution ===");

    let service = setup_trading_service_with_db().await?;
    let pool = setup_test_db().await?;
    let account_id = "e2e_account_001";

    cleanup_test_orders(&pool, account_id).await?;

    // 1. Place market order
    let request = Request::new(SubmitOrderRequest {
        account_id: account_id.to_string(),
        symbol: "AAPL".to_string(),
        side: OrderSide::Buy as i32,
        order_type: OrderType::Market as i32,
        quantity: 100.0,
        price: None,
        stop_price: None,
        metadata: std::collections::HashMap::new(),
    });

    let response = service.submit_order(request).await?;
    let order_result = response.into_inner();

    println!("  1. Order placed: {}", order_result.order_id);
    assert_eq!(order_result.status, OrderStatus::Submitted as i32);

    // 2. Verify risk check passed (implicit in successful submission)
    assert!(!order_result.order_id.is_empty());
    println!("  2. Risk check passed");

    // 3. Verify order status
    let status_req = Request::new(GetOrderStatusRequest {
        order_id: order_result.order_id.clone(),
    });

    let status_response = service.get_order_status(status_req).await?;
    let order_status = status_response.into_inner();

    assert!(order_status.order.is_some());
    println!(
        "  3. Order status verified: {:?}",
        order_status.order.unwrap().status
    );

    cleanup_test_orders(&pool, account_id).await?;
    Ok(())
}

#[tokio::test]
async fn test_e2e_limit_order_placement_and_matching() -> Result<()> {
    println!("\n=== E2E Test: Limit Order Placement and Matching ===");

    let service = setup_trading_service_with_db().await?;
    let pool = setup_test_db().await?;
    let account_id = "e2e_account_002";

    cleanup_test_orders(&pool, account_id).await?;

    // Place limit order
    let request = Request::new(SubmitOrderRequest {
        account_id: account_id.to_string(),
        symbol: "GOOGL".to_string(),
        side: OrderSide::Buy as i32,
        order_type: OrderType::Limit as i32,
        quantity: 50.0,
        price: Some(150.50),
        stop_price: None,
        metadata: std::collections::HashMap::new(),
    });

    let response = service.submit_order(request).await?;
    let order = response.into_inner();

    println!("  Limit order placed at $150.50: {}", order.order_id);
    assert_eq!(order.status, OrderStatus::Submitted as i32);

    cleanup_test_orders(&pool, account_id).await?;
    Ok(())
}

// ============================================================================
// E2E Test: Position Tracking Across Multiple Orders
// ============================================================================

#[tokio::test]
async fn test_e2e_position_tracking_multiple_orders() -> Result<()> {
    println!("\n=== E2E Test: Position Tracking Across Multiple Orders ===");

    let service = setup_trading_service_with_db().await?;
    let pool = setup_test_db().await?;
    let account_id = "e2e_account_003";

    cleanup_test_orders(&pool, account_id).await?;

    // Place multiple orders for same symbol
    for i in 1..=3 {
        let request = Request::new(SubmitOrderRequest {
            account_id: account_id.to_string(),
            symbol: "NVDA".to_string(),
            side: OrderSide::Buy as i32,
            order_type: OrderType::Market as i32,
            quantity: 10.0 * i as f64,
            price: None,
            stop_price: None,
            metadata: std::collections::HashMap::new(),
        });

        let response = service.submit_order(request).await?;
        println!("  Order {} placed: {}", i, response.into_inner().order_id);
    }

    // Get positions
    let pos_request = Request::new(GetPositionsRequest {
        account_id: Some(account_id.to_string()),
        symbol: Some("NVDA".to_string()),
    });

    let positions = service.get_positions(pos_request).await?;
    println!(
        "  Total positions: {}",
        positions.into_inner().positions.len()
    );

    cleanup_test_orders(&pool, account_id).await?;
    Ok(())
}

#[tokio::test]
async fn test_e2e_position_updates_with_fills() -> Result<()> {
    println!("\n=== E2E Test: Position Updates with Fills ===");

    let service = setup_trading_service_with_db().await?;
    let pool = setup_test_db().await?;
    let account_id = "e2e_account_004";

    cleanup_test_orders(&pool, account_id).await?;

    // Buy order
    let buy_request = Request::new(SubmitOrderRequest {
        account_id: account_id.to_string(),
        symbol: "TSLA".to_string(),
        side: OrderSide::Buy as i32,
        order_type: OrderType::Market as i32,
        quantity: 100.0,
        price: None,
        stop_price: None,
        metadata: std::collections::HashMap::new(),
    });

    let buy_response = service.submit_order(buy_request).await?;
    let buy_order_id = buy_response.into_inner().order_id;
    println!("  Buy order placed: {}", buy_order_id);

    // Sell order (reduce position)
    let sell_request = Request::new(SubmitOrderRequest {
        account_id: account_id.to_string(),
        symbol: "TSLA".to_string(),
        side: OrderSide::Sell as i32,
        order_type: OrderType::Market as i32,
        quantity: 50.0,
        price: None,
        stop_price: None,
        metadata: std::collections::HashMap::new(),
    });

    let sell_response = service.submit_order(sell_request).await?;
    println!(
        "  Sell order placed: {}",
        sell_response.into_inner().order_id
    );

    // Verify position
    let pos_request = Request::new(GetPositionsRequest {
        account_id: Some(account_id.to_string()),
        symbol: Some("TSLA".to_string()),
    });

    let positions = service.get_positions(pos_request).await?;
    let position_count = positions.into_inner().positions.len();
    println!("  Net position count: {}", position_count);

    cleanup_test_orders(&pool, account_id).await?;
    Ok(())
}

// ============================================================================
// E2E Test: PnL Calculation with Partial/Full Fills
// ============================================================================

#[tokio::test]
async fn test_e2e_pnl_calculation_full_fill() -> Result<()> {
    println!("\n=== E2E Test: PnL Calculation with Full Fill ===");

    let service = setup_trading_service_with_db().await?;
    let pool = setup_test_db().await?;
    let account_id = "e2e_account_005";

    cleanup_test_orders(&pool, account_id).await?;

    // Buy at lower price
    let buy_request = Request::new(SubmitOrderRequest {
        account_id: account_id.to_string(),
        symbol: "AMD".to_string(),
        side: OrderSide::Buy as i32,
        order_type: OrderType::Limit as i32,
        quantity: 100.0,
        price: Some(100.0),
        stop_price: None,
        metadata: std::collections::HashMap::new(),
    });

    let buy_response = service.submit_order(buy_request).await?;
    println!(
        "  Buy order placed at $100: {}",
        buy_response.into_inner().order_id
    );

    // Sell at higher price
    let sell_request = Request::new(SubmitOrderRequest {
        account_id: account_id.to_string(),
        symbol: "AMD".to_string(),
        side: OrderSide::Sell as i32,
        order_type: OrderType::Limit as i32,
        quantity: 100.0,
        price: Some(110.0),
        stop_price: None,
        metadata: std::collections::HashMap::new(),
    });

    let sell_response = service.submit_order(sell_request).await?;
    println!(
        "  Sell order placed at $110: {}",
        sell_response.into_inner().order_id
    );

    // Get portfolio summary (includes PnL)
    let summary_request = Request::new(GetPortfolioSummaryRequest {
        account_id: account_id.to_string(),
    });

    let summary = service.get_portfolio_summary(summary_request).await?;
    let portfolio = summary.into_inner();
    println!("  Expected PnL: $1000 (100 shares × $10 profit)");
    println!("  Realized PnL: ${}", portfolio.realized_pnl);

    cleanup_test_orders(&pool, account_id).await?;
    Ok(())
}

#[tokio::test]
async fn test_e2e_pnl_calculation_partial_fill() -> Result<()> {
    println!("\n=== E2E Test: PnL Calculation with Partial Fill ===");

    let service = setup_trading_service_with_db().await?;
    let pool = setup_test_db().await?;
    let account_id = "e2e_account_006";

    cleanup_test_orders(&pool, account_id).await?;

    // Place large limit order (may partially fill)
    let request = Request::new(SubmitOrderRequest {
        account_id: account_id.to_string(),
        symbol: "SPY".to_string(),
        side: OrderSide::Buy as i32,
        order_type: OrderType::Limit as i32,
        quantity: 1000.0,
        price: Some(450.0),
        stop_price: None,
        metadata: std::collections::HashMap::new(),
    });

    let response = service.submit_order(request).await?;
    let order_id = response.into_inner().order_id;
    println!("  Large limit order placed: {}", order_id);

    // Check order status for partial fill
    let status_req = Request::new(GetOrderStatusRequest {
        order_id: order_id.clone(),
    });

    let status = service.get_order_status(status_req).await?;
    if let Some(order) = status.into_inner().order {
        println!(
            "  Order quantity: {}, Filled: {}",
            order.quantity, order.filled_quantity
        );
    }

    cleanup_test_orders(&pool, account_id).await?;
    Ok(())
}

// ============================================================================
// E2E Test: Stop-Loss Trigger and Automatic Liquidation
// ============================================================================

#[tokio::test]
async fn test_e2e_stop_loss_trigger() -> Result<()> {
    println!("\n=== E2E Test: Stop-Loss Trigger ===");

    let service = setup_trading_service_with_db().await?;
    let pool = setup_test_db().await?;
    let account_id = "e2e_account_007";

    cleanup_test_orders(&pool, account_id).await?;

    // Place stop-loss order
    let request = Request::new(SubmitOrderRequest {
        account_id: account_id.to_string(),
        symbol: "META".to_string(),
        side: OrderSide::Sell as i32,
        order_type: OrderType::Stop as i32,
        quantity: 50.0,
        price: None,
        stop_price: Some(350.0), // Trigger if price drops to 350
        metadata: std::collections::HashMap::new(),
    });

    let response = service.submit_order(request).await?;
    let order_id = response.into_inner().order_id;
    println!(
        "  Stop-loss order placed at trigger price $350: {}",
        order_id
    );

    // Verify order exists
    let status_req = Request::new(GetOrderStatusRequest {
        order_id: order_id.clone(),
    });

    let status = service.get_order_status(status_req).await?;
    assert!(status.into_inner().order.is_some());
    println!("  Stop-loss order verified and active");

    cleanup_test_orders(&pool, account_id).await?;
    Ok(())
}

#[tokio::test]
async fn test_e2e_automatic_liquidation() -> Result<()> {
    println!("\n=== E2E Test: Automatic Liquidation ===");

    let service = setup_trading_service_with_db().await?;
    let pool = setup_test_db().await?;
    let account_id = "e2e_account_008";

    cleanup_test_orders(&pool, account_id).await?;

    // Build position
    let buy_request = Request::new(SubmitOrderRequest {
        account_id: account_id.to_string(),
        symbol: "NFLX".to_string(),
        side: OrderSide::Buy as i32,
        order_type: OrderType::Market as i32,
        quantity: 100.0,
        price: None,
        stop_price: None,
        metadata: std::collections::HashMap::new(),
    });

    let buy_response = service.submit_order(buy_request).await?;
    println!("  Position opened: {}", buy_response.into_inner().order_id);

    // Liquidation order (close entire position)
    let liquidation_request = Request::new(SubmitOrderRequest {
        account_id: account_id.to_string(),
        symbol: "NFLX".to_string(),
        side: OrderSide::Sell as i32,
        order_type: OrderType::Market as i32,
        quantity: 100.0, // Close entire position
        price: None,
        stop_price: None,
        metadata: std::collections::HashMap::new(),
    });

    let liq_response = service.submit_order(liquidation_request).await?;
    println!(
        "  Liquidation order submitted: {}",
        liq_response.into_inner().order_id
    );

    // Verify position closed
    let pos_request = Request::new(GetPositionsRequest {
        account_id: Some(account_id.to_string()),
        symbol: Some("NFLX".to_string()),
    });

    let positions = service.get_positions(pos_request).await?;
    let position_count = positions.into_inner().positions.len();
    println!("  Position count after liquidation: {}", position_count);

    cleanup_test_orders(&pool, account_id).await?;
    Ok(())
}

// ============================================================================
// E2E Test: Market Order Execution
// ============================================================================

#[tokio::test]
async fn test_e2e_market_order_immediate_execution() -> Result<()> {
    println!("\n=== E2E Test: Market Order Immediate Execution ===");

    let service = setup_trading_service_with_db().await?;
    let pool = setup_test_db().await?;
    let account_id = "e2e_account_009";

    cleanup_test_orders(&pool, account_id).await?;

    let request = Request::new(SubmitOrderRequest {
        account_id: account_id.to_string(),
        symbol: "QQQ".to_string(),
        side: OrderSide::Buy as i32,
        order_type: OrderType::Market as i32,
        quantity: 50.0,
        price: None,
        stop_price: None,
        metadata: std::collections::HashMap::new(),
    });

    let start = std::time::Instant::now();
    let response = service.submit_order(request).await?;
    let elapsed = start.elapsed();

    let order = response.into_inner();
    println!("  Market order executed in {:?}", elapsed);
    println!("  Order ID: {}", order.order_id);
    assert_eq!(order.status, OrderStatus::Submitted as i32);

    cleanup_test_orders(&pool, account_id).await?;
    Ok(())
}

#[tokio::test]
async fn test_e2e_market_order_with_slippage() -> Result<()> {
    println!("\n=== E2E Test: Market Order with Slippage ===");

    let service = setup_trading_service_with_db().await?;
    let pool = setup_test_db().await?;
    let account_id = "e2e_account_010";

    cleanup_test_orders(&pool, account_id).await?;

    // Large market order (may experience slippage)
    let request = Request::new(SubmitOrderRequest {
        account_id: account_id.to_string(),
        symbol: "SPY".to_string(),
        side: OrderSide::Buy as i32,
        order_type: OrderType::Market as i32,
        quantity: 5000.0,
        price: None,
        stop_price: None,
        metadata: std::collections::HashMap::new(),
    });

    let response = service.submit_order(request).await?;
    let order_id = response.into_inner().order_id;
    println!("  Large market order placed: {}", order_id);

    // Check execution details
    let status_req = Request::new(GetOrderStatusRequest { order_id });
    let status = service.get_order_status(status_req).await?;

    if let Some(order) = status.into_inner().order {
        println!("  Order status: {:?}", order.status);
        if let Some(price) = order.price {
            println!("  Execution price: ${}", price);
        }
    }

    cleanup_test_orders(&pool, account_id).await?;
    Ok(())
}

// ============================================================================
// E2E Test: Limit Order Matching
// ============================================================================

#[tokio::test]
async fn test_e2e_limit_order_price_matching() -> Result<()> {
    println!("\n=== E2E Test: Limit Order Price Matching ===");

    let service = setup_trading_service_with_db().await?;
    let pool = setup_test_db().await?;
    let account_id = "e2e_account_011";

    cleanup_test_orders(&pool, account_id).await?;

    // Buy limit at specific price
    let buy_limit = Request::new(SubmitOrderRequest {
        account_id: account_id.to_string(),
        symbol: "AAPL".to_string(),
        side: OrderSide::Buy as i32,
        order_type: OrderType::Limit as i32,
        quantity: 100.0,
        price: Some(180.0),
        stop_price: None,
        metadata: std::collections::HashMap::new(),
    });

    let buy_response = service.submit_order(buy_limit).await?;
    let buy_order_id = buy_response.into_inner().order_id;
    println!("  Buy limit order at $180: {}", buy_order_id);

    // Sell limit at higher price
    let sell_limit = Request::new(SubmitOrderRequest {
        account_id: account_id.to_string(),
        symbol: "AAPL".to_string(),
        side: OrderSide::Sell as i32,
        order_type: OrderType::Limit as i32,
        quantity: 100.0,
        price: Some(185.0),
        stop_price: None,
        metadata: std::collections::HashMap::new(),
    });

    let sell_response = service.submit_order(sell_limit).await?;
    let sell_order_id = sell_response.into_inner().order_id;
    println!("  Sell limit order at $185: {}", sell_order_id);

    cleanup_test_orders(&pool, account_id).await?;
    Ok(())
}

#[tokio::test]
async fn test_e2e_limit_order_queue_priority() -> Result<()> {
    println!("\n=== E2E Test: Limit Order Queue Priority ===");

    let service = setup_trading_service_with_db().await?;
    let pool = setup_test_db().await?;
    let account_id = "e2e_account_012";

    cleanup_test_orders(&pool, account_id).await?;

    // Place multiple limit orders at same price (FIFO queue)
    for i in 1..=3 {
        let request = Request::new(SubmitOrderRequest {
            account_id: account_id.to_string(),
            symbol: "MSFT".to_string(),
            side: OrderSide::Buy as i32,
            order_type: OrderType::Limit as i32,
            quantity: 50.0,
            price: Some(400.0),
            stop_price: None,
            metadata: {
                let mut map = std::collections::HashMap::new();
                map.insert("queue_position".to_string(), i.to_string());
                map
            },
        });

        let response = service.submit_order(request).await?;
        println!(
            "  Limit order {} placed at $400: {}",
            i,
            response.into_inner().order_id
        );
    }

    cleanup_test_orders(&pool, account_id).await?;
    Ok(())
}

// ============================================================================
// E2E Test: Order Cancellation
// ============================================================================

#[tokio::test]
async fn test_e2e_order_cancellation_before_fill() -> Result<()> {
    println!("\n=== E2E Test: Order Cancellation Before Fill ===");

    let service = setup_trading_service_with_db().await?;
    let pool = setup_test_db().await?;
    let account_id = "e2e_account_013";

    cleanup_test_orders(&pool, account_id).await?;

    // Place limit order
    let submit_req = Request::new(SubmitOrderRequest {
        account_id: account_id.to_string(),
        symbol: "GOOGL".to_string(),
        side: OrderSide::Buy as i32,
        order_type: OrderType::Limit as i32,
        quantity: 25.0,
        price: Some(140.0),
        stop_price: None,
        metadata: std::collections::HashMap::new(),
    });

    let submit_response = service.submit_order(submit_req).await?;
    let order_id = submit_response.into_inner().order_id;
    println!("  Order placed: {}", order_id);

    // Cancel immediately
    let cancel_req = Request::new(CancelOrderRequest {
        order_id: order_id.clone(),
        account_id: account_id.to_string(),
    });

    let cancel_response = service.cancel_order(cancel_req).await?;
    assert!(cancel_response.into_inner().success);
    println!("  Order cancelled successfully");

    // Verify cancellation
    let status_req = Request::new(GetOrderStatusRequest { order_id });
    let status = service.get_order_status(status_req).await?;

    if let Some(order) = status.into_inner().order {
        println!("  Final status: {:?}", order.status);
    }

    cleanup_test_orders(&pool, account_id).await?;
    Ok(())
}

#[tokio::test]
async fn test_e2e_bulk_order_cancellation() -> Result<()> {
    println!("\n=== E2E Test: Bulk Order Cancellation ===");

    let service = setup_trading_service_with_db().await?;
    let pool = setup_test_db().await?;
    let account_id = "e2e_account_014";

    cleanup_test_orders(&pool, account_id).await?;

    let mut order_ids = Vec::new();

    // Place multiple orders
    for i in 1..=5 {
        let request = Request::new(SubmitOrderRequest {
            account_id: account_id.to_string(),
            symbol: "TSLA".to_string(),
            side: OrderSide::Buy as i32,
            order_type: OrderType::Limit as i32,
            quantity: 10.0,
            price: Some(250.0 + i as f64),
            stop_price: None,
            metadata: std::collections::HashMap::new(),
        });

        let response = service.submit_order(request).await?;
        let order_id = response.into_inner().order_id;
        order_ids.push(order_id.clone());
        println!("  Order {} placed: {}", i, order_id);
    }

    // Cancel all orders
    for (i, order_id) in order_ids.into_iter().enumerate() {
        let cancel_req = Request::new(CancelOrderRequest {
            order_id: order_id.clone(),
            account_id: account_id.to_string(),
        });

        let cancel_response = service.cancel_order(cancel_req).await?;
        assert!(cancel_response.into_inner().success);
        println!("  Order {} cancelled", i + 1);
    }

    cleanup_test_orders(&pool, account_id).await?;
    Ok(())
}

// ============================================================================
// E2E Test: Position Close-Out
// ============================================================================

#[tokio::test]
async fn test_e2e_position_closeout_market_order() -> Result<()> {
    println!("\n=== E2E Test: Position Close-Out with Market Order ===");

    let service = setup_trading_service_with_db().await?;
    let pool = setup_test_db().await?;
    let account_id = "e2e_account_015";

    cleanup_test_orders(&pool, account_id).await?;

    // Open position
    let open_req = Request::new(SubmitOrderRequest {
        account_id: account_id.to_string(),
        symbol: "NVDA".to_string(),
        side: OrderSide::Buy as i32,
        order_type: OrderType::Market as i32,
        quantity: 200.0,
        price: None,
        stop_price: None,
        metadata: std::collections::HashMap::new(),
    });

    let open_response = service.submit_order(open_req).await?;
    println!("  Position opened: {}", open_response.into_inner().order_id);

    // Close position with market order
    let close_req = Request::new(SubmitOrderRequest {
        account_id: account_id.to_string(),
        symbol: "NVDA".to_string(),
        side: OrderSide::Sell as i32,
        order_type: OrderType::Market as i32,
        quantity: 200.0,
        price: None,
        stop_price: None,
        metadata: std::collections::HashMap::new(),
    });

    let close_response = service.submit_order(close_req).await?;
    println!(
        "  Position closed: {}",
        close_response.into_inner().order_id
    );

    // Verify no open positions
    let pos_req = Request::new(GetPositionsRequest {
        account_id: Some(account_id.to_string()),
        symbol: Some("NVDA".to_string()),
    });

    let positions = service.get_positions(pos_req).await?;
    println!(
        "  Open positions: {}",
        positions.into_inner().positions.len()
    );

    cleanup_test_orders(&pool, account_id).await?;
    Ok(())
}

#[tokio::test]
async fn test_e2e_position_closeout_limit_order() -> Result<()> {
    println!("\n=== E2E Test: Position Close-Out with Limit Order ===");

    let service = setup_trading_service_with_db().await?;
    let pool = setup_test_db().await?;
    let account_id = "e2e_account_016";

    cleanup_test_orders(&pool, account_id).await?;

    // Open position
    let open_req = Request::new(SubmitOrderRequest {
        account_id: account_id.to_string(),
        symbol: "AMD".to_string(),
        side: OrderSide::Buy as i32,
        order_type: OrderType::Market as i32,
        quantity: 150.0,
        price: None,
        stop_price: None,
        metadata: std::collections::HashMap::new(),
    });

    let open_response = service.submit_order(open_req).await?;
    println!("  Position opened: {}", open_response.into_inner().order_id);

    // Close with limit order at target price
    let close_req = Request::new(SubmitOrderRequest {
        account_id: account_id.to_string(),
        symbol: "AMD".to_string(),
        side: OrderSide::Sell as i32,
        order_type: OrderType::Limit as i32,
        quantity: 150.0,
        price: Some(120.0), // Target exit price
        stop_price: None,
        metadata: std::collections::HashMap::new(),
    });

    let close_response = service.submit_order(close_req).await?;
    println!(
        "  Close order placed at $120: {}",
        close_response.into_inner().order_id
    );

    cleanup_test_orders(&pool, account_id).await?;
    Ok(())
}

// ============================================================================
// E2E Test: Complex Multi-Leg Scenarios
// ============================================================================

#[tokio::test]
async fn test_e2e_multi_symbol_portfolio_management() -> Result<()> {
    println!("\n=== E2E Test: Multi-Symbol Portfolio Management ===");

    let service = setup_trading_service_with_db().await?;
    let pool = setup_test_db().await?;
    let account_id = "e2e_account_017";

    cleanup_test_orders(&pool, account_id).await?;

    let symbols = vec!["AAPL", "GOOGL", "MSFT", "NVDA"];

    // Build diversified portfolio
    for symbol in &symbols {
        let request = Request::new(SubmitOrderRequest {
            account_id: account_id.to_string(),
            symbol: symbol.to_string(),
            side: OrderSide::Buy as i32,
            order_type: OrderType::Market as i32,
            quantity: 50.0,
            price: None,
            stop_price: None,
            metadata: std::collections::HashMap::new(),
        });

        let response = service.submit_order(request).await?;
        println!(
            "  {} position opened: {}",
            symbol,
            response.into_inner().order_id
        );
    }

    // Get portfolio summary
    let summary_req = Request::new(GetPortfolioSummaryRequest {
        account_id: account_id.to_string(),
    });

    let summary = service.get_portfolio_summary(summary_req).await?;
    let portfolio = summary.into_inner();
    println!("  Portfolio value: ${}", portfolio.total_value);
    println!("  Number of positions: {}", symbols.len());

    cleanup_test_orders(&pool, account_id).await?;
    Ok(())
}

#[tokio::test]
async fn test_e2e_hedging_strategy() -> Result<()> {
    println!("\n=== E2E Test: Hedging Strategy ===");

    let service = setup_trading_service_with_db().await?;
    let pool = setup_test_db().await?;
    let account_id = "e2e_account_018";

    cleanup_test_orders(&pool, account_id).await?;

    // Long position
    let long_req = Request::new(SubmitOrderRequest {
        account_id: account_id.to_string(),
        symbol: "SPY".to_string(),
        side: OrderSide::Buy as i32,
        order_type: OrderType::Market as i32,
        quantity: 100.0,
        price: None,
        stop_price: None,
        metadata: std::collections::HashMap::new(),
    });

    let long_response = service.submit_order(long_req).await?;
    println!(
        "  Long SPY position: {}",
        long_response.into_inner().order_id
    );

    // Hedge with short position
    let hedge_req = Request::new(SubmitOrderRequest {
        account_id: account_id.to_string(),
        symbol: "SPY".to_string(),
        side: OrderSide::Sell as i32,
        order_type: OrderType::Limit as i32,
        quantity: 50.0, // Partial hedge
        price: Some(455.0),
        stop_price: None,
        metadata: std::collections::HashMap::new(),
    });

    let hedge_response = service.submit_order(hedge_req).await?;
    println!(
        "  Hedge order placed: {}",
        hedge_response.into_inner().order_id
    );

    // Verify net position
    let pos_req = Request::new(GetPositionsRequest {
        account_id: Some(account_id.to_string()),
        symbol: Some("SPY".to_string()),
    });

    let positions = service.get_positions(pos_req).await?;
    println!(
        "  Net positions: {}",
        positions.into_inner().positions.len()
    );

    cleanup_test_orders(&pool, account_id).await?;
    Ok(())
}

// ============================================================================
// E2E Test: Concurrent Trading Operations
// ============================================================================

#[tokio::test]
async fn test_e2e_concurrent_multi_account_trading() -> Result<()> {
    println!("\n=== E2E Test: Concurrent Multi-Account Trading ===");

    let service = Arc::new(setup_trading_service_with_db().await?);
    let pool = setup_test_db().await?;

    let accounts = vec![
        "concurrent_account_1",
        "concurrent_account_2",
        "concurrent_account_3",
    ];

    // Cleanup all accounts
    for account in &accounts {
        cleanup_test_orders(&pool, account).await?;
    }

    let mut handles = Vec::new();

    // Concurrent trading from multiple accounts
    for account in accounts.clone() {
        let svc = service.clone();
        let handle = tokio::spawn(async move {
            let request = Request::new(SubmitOrderRequest {
                account_id: account.to_string(),
                symbol: "QQQ".to_string(),
                side: OrderSide::Buy as i32,
                order_type: OrderType::Market as i32,
                quantity: 100.0,
                price: None,
                stop_price: None,
                metadata: std::collections::HashMap::new(),
            });

            svc.submit_order(request).await
        });
        handles.push(handle);
    }

    // Wait for all orders
    let mut success_count = 0;
    for handle in handles {
        if let Ok(Ok(response)) = handle.await {
            println!("  Order placed: {}", response.into_inner().order_id);
            success_count += 1;
        }
    }

    println!(
        "  {}/{} concurrent orders succeeded",
        success_count,
        accounts.len()
    );
    assert_eq!(success_count, accounts.len());

    // Cleanup
    for account in &accounts {
        cleanup_test_orders(&pool, account).await?;
    }

    Ok(())
}

#[tokio::test]
async fn test_e2e_high_frequency_order_flow() -> Result<()> {
    println!("\n=== E2E Test: High-Frequency Order Flow ===");

    let service = setup_trading_service_with_db().await?;
    let pool = setup_test_db().await?;
    let account_id = "hft_account_001";

    cleanup_test_orders(&pool, account_id).await?;

    let mut latencies = Vec::new();

    // Simulate high-frequency order flow
    for i in 1..=50 {
        let request = Request::new(SubmitOrderRequest {
            account_id: account_id.to_string(),
            symbol: "SPY".to_string(),
            side: if i % 2 == 0 {
                OrderSide::Buy as i32
            } else {
                OrderSide::Sell as i32
            },
            order_type: OrderType::Market as i32,
            quantity: 1.0,
            price: None,
            stop_price: None,
            metadata: std::collections::HashMap::new(),
        });

        let start = std::time::Instant::now();
        let _ = service.submit_order(request).await;
        let elapsed = start.elapsed();
        latencies.push(elapsed);
    }

    // Calculate latency metrics
    latencies.sort();
    let p50 = latencies[24];
    let p95 = latencies[47];
    let p99 = latencies[49];

    println!("  HFT Latency Metrics (50 orders):");
    println!("  ├─ P50:  {:?}", p50);
    println!("  ├─ P95:  {:?}", p95);
    println!("  └─ P99:  {:?}", p99);

    cleanup_test_orders(&pool, account_id).await?;
    Ok(())
}

// ============================================================================
// E2E Test: Error Recovery and Edge Cases
// ============================================================================

#[tokio::test]
async fn test_e2e_duplicate_order_handling() -> Result<()> {
    println!("\n=== E2E Test: Duplicate Order Handling ===");

    let service = setup_trading_service_with_db().await?;
    let pool = setup_test_db().await?;
    let account_id = "e2e_account_019";

    cleanup_test_orders(&pool, account_id).await?;

    let mut metadata = std::collections::HashMap::new();
    metadata.insert(
        "client_order_id".to_string(),
        "duplicate_test_123".to_string(),
    );

    // Submit first order
    let request1 = Request::new(SubmitOrderRequest {
        account_id: account_id.to_string(),
        symbol: "AAPL".to_string(),
        side: OrderSide::Buy as i32,
        order_type: OrderType::Market as i32,
        quantity: 50.0,
        price: None,
        stop_price: None,
        metadata: metadata.clone(),
    });

    let response1 = service.submit_order(request1).await?;
    println!("  First order: {}", response1.into_inner().order_id);

    // Submit duplicate (same client_order_id)
    let request2 = Request::new(SubmitOrderRequest {
        account_id: account_id.to_string(),
        symbol: "AAPL".to_string(),
        side: OrderSide::Buy as i32,
        order_type: OrderType::Market as i32,
        quantity: 50.0,
        price: None,
        stop_price: None,
        metadata: metadata.clone(),
    });

    let response2 = service.submit_order(request2).await?;
    println!("  Second order: {}", response2.into_inner().order_id);

    cleanup_test_orders(&pool, account_id).await?;
    Ok(())
}

#[tokio::test]
async fn test_e2e_order_rejection_insufficient_margin() -> Result<()> {
    println!("\n=== E2E Test: Order Rejection - Insufficient Margin ===");

    let service = setup_trading_service_with_db().await?;
    let pool = setup_test_db().await?;
    let account_id = "e2e_account_020";

    cleanup_test_orders(&pool, account_id).await?;

    // Attempt very large order (should fail margin check)
    let request = Request::new(SubmitOrderRequest {
        account_id: account_id.to_string(),
        symbol: "SPY".to_string(),
        side: OrderSide::Buy as i32,
        order_type: OrderType::Market as i32,
        quantity: 1_000_000.0,
        price: None,
        stop_price: None,
        metadata: std::collections::HashMap::new(),
    });

    let result = service.submit_order(request).await;

    match result {
        Ok(_) => println!("  Order was accepted (unexpected)"),
        Err(status) => {
            println!("  Order rejected: {}", status.message());
            assert!(
                status.message().contains("Risk violation")
                    || status.message().contains("exceeds maximum")
            );
        },
    }

    cleanup_test_orders(&pool, account_id).await?;
    Ok(())
}

// ============================================================================
// E2E Test: Advanced Order Types
// ============================================================================

#[tokio::test]
async fn test_e2e_iceberg_order_execution() -> Result<()> {
    println!("\n=== E2E Test: Iceberg Order Execution ===");

    let service = setup_trading_service_with_db().await?;
    let pool = setup_test_db().await?;
    let account_id = "e2e_account_021";

    cleanup_test_orders(&pool, account_id).await?;

    // Iceberg order - large order with hidden quantity
    let request = Request::new(SubmitOrderRequest {
        account_id: account_id.to_string(),
        symbol: "AAPL".to_string(),
        side: OrderSide::Buy as i32,
        order_type: OrderType::Iceberg as i32,
        quantity: 10000.0, // Total quantity
        price: Some(180.0),
        stop_price: None,
        metadata: {
            let mut map = std::collections::HashMap::new();
            map.insert("visible_quantity".to_string(), "100".to_string());
            map
        },
    });

    let response = service.submit_order(request).await?;
    let order_id = response.into_inner().order_id;
    println!(
        "  Iceberg order placed: total 10000, visible 100: {}",
        order_id
    );

    // Verify order
    let status_req = Request::new(GetOrderStatusRequest { order_id });
    let status = service.get_order_status(status_req).await?;
    assert!(status.into_inner().order.is_some());

    cleanup_test_orders(&pool, account_id).await?;
    Ok(())
}

#[tokio::test]
async fn test_e2e_trailing_stop_order() -> Result<()> {
    println!("\n=== E2E Test: Trailing Stop Order ===");

    let service = setup_trading_service_with_db().await?;
    let pool = setup_test_db().await?;
    let account_id = "e2e_account_022";

    cleanup_test_orders(&pool, account_id).await?;

    // Trailing stop order
    let request = Request::new(SubmitOrderRequest {
        account_id: account_id.to_string(),
        symbol: "NVDA".to_string(),
        side: OrderSide::Sell as i32,
        order_type: OrderType::TrailingStop as i32,
        quantity: 100.0,
        price: None,
        stop_price: Some(5.0), // Trail by $5
        metadata: std::collections::HashMap::new(),
    });

    let response = service.submit_order(request).await?;
    let order_id = response.into_inner().order_id;
    println!("  Trailing stop order placed (trail: $5): {}", order_id);

    // Verify order exists
    let status_req = Request::new(GetOrderStatusRequest { order_id });
    let status = service.get_order_status(status_req).await?;
    assert!(status.into_inner().order.is_some());
    println!("  Trailing stop order active and monitoring");

    cleanup_test_orders(&pool, account_id).await?;
    Ok(())
}

#[tokio::test]
async fn test_e2e_order_execution_with_fees() -> Result<()> {
    println!("\n=== E2E Test: Order Execution with Fees ===");

    let service = setup_trading_service_with_db().await?;
    let pool = setup_test_db().await?;
    let account_id = "e2e_account_023";

    cleanup_test_orders(&pool, account_id).await?;

    // Place order with fee metadata
    let request = Request::new(SubmitOrderRequest {
        account_id: account_id.to_string(),
        symbol: "SPY".to_string(),
        side: OrderSide::Buy as i32,
        order_type: OrderType::Market as i32,
        quantity: 100.0,
        price: None,
        stop_price: None,
        metadata: {
            let mut map = std::collections::HashMap::new();
            map.insert("commission_rate".to_string(), "0.0001".to_string());
            map
        },
    });

    let response = service.submit_order(request).await?;
    let order_id = response.into_inner().order_id;
    println!("  Order with fees placed: {}", order_id);

    // Calculate expected fees
    let expected_fee = 100.0 * 450.0 * 0.0001; // qty * price * rate
    println!("  Expected commission: ${:.2}", expected_fee);

    // Verify order
    let status_req = Request::new(GetOrderStatusRequest { order_id });
    let status = service.get_order_status(status_req).await?;
    assert!(status.into_inner().order.is_some());

    cleanup_test_orders(&pool, account_id).await?;
    Ok(())
}
