/**
 * Advanced Risk Management Examples
 * Demonstrates orderbook analytics, portfolio risk, and bet sizing
 */

import { OrderbookAnalyzer, RiskAnalyzer, TradingEngine } from '@stock-bot/engine';
import { getLogger } from '@stock-bot/logger';

const logger = getLogger('AdvancedRiskExample');

// Example 1: Orderbook Analytics
async function orderbookAnalyticsExample() {
  console.log('\n=== Orderbook Analytics Example ===');
  
  const engine = new TradingEngine('paper', { startingCapital: 100000 });
  const obAnalyzer = new OrderbookAnalyzer();
  
  // Update orderbook with some data
  const symbol = 'AAPL';
  engine.updateQuote(symbol, 149.95, 150.05, 1000, 1200);
  engine.updateQuote(symbol, 149.90, 150.10, 800, 900);
  engine.updateQuote(symbol, 149.85, 150.15, 600, 700);
  
  // Get orderbook snapshot
  const snapshotJson = engine.getOrderbookSnapshot(symbol, 10);
  const snapshot = JSON.parse(snapshotJson);
  
  // Analyze orderbook
  const analyticsJson = obAnalyzer.analyzeOrderbook(snapshotJson);
  const analytics = JSON.parse(analyticsJson);
  
  console.log('Orderbook Analytics:');
  console.log(`  Spread: $${analytics.spread.toFixed(2)} (${analytics.spread_bps.toFixed(1)} bps)`);
  console.log(`  Mid Price: $${analytics.mid_price.toFixed(2)}`);
  console.log(`  Micro Price: $${analytics.micro_price.toFixed(2)}`);
  console.log(`  Imbalance: ${(analytics.imbalance * 100).toFixed(1)}%`);
  console.log(`  Liquidity Score: ${analytics.liquidity_score.toFixed(2)}`);
  
  // Calculate liquidity profile
  const profileJson = obAnalyzer.calculateLiquidityProfile(snapshotJson);
  const profile = JSON.parse(profileJson);
  
  console.log('\nLiquidity Profile:');
  console.log(`  Total Bid Depth: $${profile.total_bid_depth.toFixed(2)}`);
  console.log(`  Total Ask Depth: $${profile.total_ask_depth.toFixed(2)}`);
  
  // Calculate market impact for a $10,000 buy order
  const impactJson = obAnalyzer.calculateMarketImpact(snapshotJson, 10000, true);
  const impact = JSON.parse(impactJson);
  
  console.log('\nMarket Impact ($10k buy):');
  console.log(`  Avg Execution Price: $${impact.avg_execution_price.toFixed(2)}`);
  console.log(`  Price Impact: ${(impact.price_impact * 100).toFixed(2)}%`);
  console.log(`  Slippage: $${impact.slippage.toFixed(2)}`);
  console.log(`  Levels Consumed: ${impact.levels_consumed}`);
}

// Example 2: Portfolio Risk Analysis
async function portfolioRiskExample() {
  console.log('\n=== Portfolio Risk Analysis Example ===');
  
  const riskAnalyzer = new RiskAnalyzer(100000, 0.02, 252); // $100k, 2% risk, 252 days lookback
  
  // Update historical returns for portfolio symbols
  const symbols = ['AAPL', 'GOOGL', 'MSFT', 'AMZN', 'META'];
  
  // Simulate some returns data (in practice, load from historical data)
  for (const symbol of symbols) {
    const returns = generateRandomReturns(252);
    riskAnalyzer.updateReturns(symbol, returns);
  }
  
  // Current positions
  const positions = [
    { symbol: 'AAPL', quantity: 100, avgPrice: 150 },
    { symbol: 'GOOGL', quantity: 50, avgPrice: 140 },
    { symbol: 'MSFT', quantity: 75, avgPrice: 380 },
    { symbol: 'AMZN', quantity: 40, avgPrice: 170 },
    { symbol: 'META', quantity: 60, avgPrice: 480 }
  ];
  
  // Current prices
  const prices = {
    AAPL: 155,
    GOOGL: 145,
    MSFT: 390,
    AMZN: 175,
    META: 490
  };
  
  // Calculate portfolio risk
  const riskJson = riskAnalyzer.calculatePortfolioRisk(
    JSON.stringify(positions.map(p => [p.symbol, p.quantity, p.avgPrice])),
    JSON.stringify(prices)
  );
  const risk = JSON.parse(riskJson);
  
  console.log('Portfolio Risk Metrics:');
  console.log(`  VaR (95%): $${risk.total_var_95.toFixed(2)}`);
  console.log(`  VaR (99%): $${risk.total_var_99.toFixed(2)}`);
  console.log(`  CVaR (95%): $${risk.total_cvar_95.toFixed(2)}`);
  
  console.log('\nConcentration Metrics:');
  console.log(`  Herfindahl Index: ${risk.concentration_risk.herfindahl_index.toFixed(3)}`);
  console.log(`  Effective Positions: ${risk.concentration_risk.effective_number_of_positions.toFixed(1)}`);
  console.log(`  Top 5 Concentration: ${(risk.concentration_risk.top_5_concentration * 100).toFixed(1)}%`);
  
  console.log('\nCorrelation Analysis:');
  console.log(`  Average Correlation: ${risk.correlation_matrix.average_correlation.toFixed(3)}`);
  console.log(`  Max Correlation: ${risk.correlation_matrix.max_correlation[0]} vs ${risk.correlation_matrix.max_correlation[1]} = ${risk.correlation_matrix.max_correlation[2].toFixed(3)}`);
  console.log(`  Clustering Score: ${risk.correlation_matrix.clustering_score.toFixed(3)}`);
  
  console.log('\nStress Test Results:');
  for (const [scenario, loss] of Object.entries(risk.stress_test_results)) {
    console.log(`  ${scenario}: $${(loss as number).toFixed(2)}`);
  }
}

// Example 3: Dynamic Bet Sizing
async function betSizingExample() {
  console.log('\n=== Dynamic Bet Sizing Example ===');
  
  const riskAnalyzer = new RiskAnalyzer(100000, 0.02, 252);
  
  // Scenario 1: Strong signal in trending market
  console.log('\nScenario 1: Strong Signal, Trending Market');
  let positionSize = riskAnalyzer.calculatePositionSize(
    0.8,      // signal_strength
    0.9,      // signal_confidence
    0.015,    // volatility (1.5% daily)
    0.8,      // liquidity_score
    0.02,     // current_drawdown (2%)
    150,      // price
    145,      // stop_loss
    'trending'
  );
  
  let size = JSON.parse(positionSize);
  console.log(`  Shares: ${size.shares}`);
  console.log(`  Notional Value: $${size.notional_value.toFixed(2)}`);
  console.log(`  % of Capital: ${(size.percent_of_capital * 100).toFixed(2)}%`);
  console.log('  Adjustments:');
  for (const adj of size.adjustments) {
    console.log(`    ${adj.reason}: ${adj.factor.toFixed(2)}x`);
  }
  
  // Scenario 2: Weak signal in high volatility
  console.log('\nScenario 2: Weak Signal, High Volatility');
  positionSize = riskAnalyzer.calculatePositionSize(
    0.3,      // signal_strength
    0.5,      // signal_confidence
    0.03,     // volatility (3% daily)
    0.6,      // liquidity_score
    0.15,     // current_drawdown (15%)
    150,      // price
    null,     // no stop_loss
    'high_volatility'
  );
  
  size = JSON.parse(positionSize);
  console.log(`  Shares: ${size.shares}`);
  console.log(`  Notional Value: $${size.notional_value.toFixed(2)}`);
  console.log(`  % of Capital: ${(size.percent_of_capital * 100).toFixed(2)}%`);
  
  // Calculate optimal stop loss
  const supportLevels = [148, 145, 142, 140];
  const optimalStop = riskAnalyzer.calculateOptimalStopLoss(
    150,              // entry_price
    0.015,            // volatility
    supportLevels,
    2.5,              // atr
    true              // is_long
  );
  
  console.log(`\nOptimal Stop Loss: $${optimalStop.toFixed(2)}`);
}

// Example 4: Integrated Risk Management in Trading
async function integratedTradingExample() {
  console.log('\n=== Integrated Risk Management Example ===');
  
  const engine = new TradingEngine('backtest', {
    startTime: Date.now() - 30 * 24 * 60 * 60 * 1000, // 30 days ago
    endTime: Date.now(),
    speedMultiplier: 1
  });
  
  const riskAnalyzer = new RiskAnalyzer(100000, 0.02, 252);
  const obAnalyzer = new OrderbookAnalyzer();
  
  // Simulate a trading decision
  const symbol = 'AAPL';
  
  // 1. Check orderbook liquidity
  engine.updateQuote(symbol, 149.95, 150.05, 5000, 5500);
  const snapshot = engine.getOrderbookSnapshot(symbol, 10);
  const analytics = JSON.parse(obAnalyzer.analyzeOrderbook(snapshot));
  
  console.log('Pre-trade Analysis:');
  console.log(`  Liquidity Score: ${analytics.liquidity_score.toFixed(2)}`);
  console.log(`  Spread: ${analytics.spread_bps.toFixed(1)} bps`);
  console.log(`  Orderbook Imbalance: ${(analytics.imbalance * 100).toFixed(1)}%`);
  
  // 2. Calculate position size based on current conditions
  const positionSizeJson = riskAnalyzer.calculatePositionSize(
    0.7,                          // signal_strength
    0.8,                          // signal_confidence
    0.018,                        // volatility
    analytics.liquidity_score,    // from orderbook
    0.05,                         // current_drawdown
    150,                          // price
    147,                          // stop_loss
    'trending'
  );
  
  const positionSize = JSON.parse(positionSizeJson);
  console.log(`\nPosition Sizing:`);
  console.log(`  Recommended Shares: ${positionSize.shares}`);
  console.log(`  Risk-Adjusted Size: ${(positionSize.risk_adjusted_size * 100).toFixed(2)}%`);
  
  // 3. Check market impact before placing order
  const orderValue = positionSize.shares * 150;
  const impact = JSON.parse(obAnalyzer.calculateMarketImpact(snapshot, orderValue, true));
  
  console.log(`\nExpected Market Impact:`);
  console.log(`  Price Impact: ${(impact.price_impact * 100).toFixed(3)}%`);
  console.log(`  Expected Fill Price: $${impact.avg_execution_price.toFixed(2)}`);
  
  // 4. Risk check
  const riskCheck = engine.checkRisk({
    id: '123',
    symbol: symbol,
    side: 'buy',
    quantity: positionSize.shares,
    orderType: 'market',
    timeInForce: 'DAY'
  });
  
  const riskResult = JSON.parse(riskCheck);
  console.log(`\nRisk Check: ${riskResult.passed ? 'PASSED' : 'FAILED'}`);
  if (!riskResult.passed) {
    console.log('  Violations:', riskResult.violations);
  }
}

// Helper function to generate random returns
function generateRandomReturns(length: number): number[] {
  const returns: number[] = [];
  for (let i = 0; i < length; i++) {
    // Generate returns with mean 0.0005 (0.05%) and std dev 0.02 (2%)
    const return_ = (Math.random() - 0.5) * 0.04 + 0.0005;
    returns.push(return_);
  }
  return returns;
}

// Run all examples
async function runExamples() {
  try {
    await orderbookAnalyticsExample();
    await portfolioRiskExample();
    await betSizingExample();
    await integratedTradingExample();
  } catch (error) {
    console.error('Error running examples:', error);
  }
}

// Execute if running directly
if (require.main === module) {
  runExamples();
}