/**
 * Examples of using the Rust-based Technical Analysis library
 */

import { IncrementalIndicators, SignalGenerator, TechnicalAnalysis } from '../src/indicators/TechnicalAnalysis';

// Example 1: Basic indicator calculations
async function basicIndicatorExample() {
  console.log('=== Basic Indicator Example ===');
  
  const ta = new TechnicalAnalysis();
  
  // Sample price data
  const prices = [
    100, 102, 101, 103, 105, 104, 106, 108, 107, 109,
    111, 110, 112, 114, 113, 115, 117, 116, 118, 120
  ];
  
  // Calculate various indicators
  const sma10 = ta.sma(prices, 10);
  const ema10 = ta.ema(prices, 10);
  const rsi14 = ta.rsi(prices, 14);
  
  console.log(`SMA(10): ${sma10.map(v => v.toFixed(2)).join(', ')}`);
  console.log(`EMA(10): ${ema10.map(v => v.toFixed(2)).join(', ')}`);
  console.log(`RSI(14): ${rsi14.map(v => v.toFixed(2)).join(', ')}`);
  
  // Latest values
  console.log(`\nLatest SMA: ${TechnicalAnalysis.latest(sma10)?.toFixed(2)}`);
  console.log(`Latest EMA: ${TechnicalAnalysis.latest(ema10)?.toFixed(2)}`);
  console.log(`Latest RSI: ${TechnicalAnalysis.latest(rsi14)?.toFixed(2)}`);
}

// Example 2: Real-time streaming indicators
async function streamingIndicatorExample() {
  console.log('\n=== Streaming Indicator Example ===');
  
  const manager = new IncrementalIndicators();
  
  // Create indicators
  manager.createSMA('sma_fast', 5);
  manager.createSMA('sma_slow', 10);
  manager.createEMA('ema', 10);
  manager.createRSI('rsi', 14);
  
  // Simulate real-time price updates
  console.log('Processing real-time price updates...');
  for (let i = 0; i < 20; i++) {
    const price = 100 + Math.sin(i * 0.3) * 5 + Math.random() * 2;
    
    const smaFast = manager.update('sma_fast', price);
    const smaSlow = manager.update('sma_slow', price);
    const ema = manager.update('ema', price);
    const rsi = manager.update('rsi', price);
    
    if (i >= 14) { // Once we have enough data
      console.log(`Price: ${price.toFixed(2)} | SMA5: ${smaFast?.toFixed(2)} | SMA10: ${smaSlow?.toFixed(2)} | EMA: ${ema?.toFixed(2)} | RSI: ${rsi?.toFixed(2)}`);
    }
  }
}

// Example 3: Complex indicators (MACD, Bollinger Bands, Stochastic)
async function complexIndicatorExample() {
  console.log('\n=== Complex Indicator Example ===');
  
  const ta = new TechnicalAnalysis();
  
  // Generate more realistic price data
  const generatePrices = (count: number) => {
    const prices = { close: [], high: [], low: [], volume: [] } as any;
    let basePrice = 100;
    
    for (let i = 0; i < count; i++) {
      const change = (Math.random() - 0.5) * 2;
      basePrice += change;
      const high = basePrice + Math.random() * 1;
      const low = basePrice - Math.random() * 1;
      const close = low + Math.random() * (high - low);
      
      prices.close.push(close);
      prices.high.push(high);
      prices.low.push(low);
      prices.volume.push(Math.random() * 1000000 + 500000);
    }
    
    return prices;
  };
  
  const prices = generatePrices(50);
  
  // Calculate MACD
  const macd = ta.macd(prices.close);
  console.log(`MACD Line: ${TechnicalAnalysis.latest(macd.macd)?.toFixed(3)}`);
  console.log(`Signal Line: ${TechnicalAnalysis.latest(macd.signal)?.toFixed(3)}`);
  console.log(`Histogram: ${TechnicalAnalysis.latest(macd.histogram)?.toFixed(3)}`);
  
  // Calculate Bollinger Bands
  const bb = ta.bollingerBands(prices.close, 20, 2);
  const currentPrice = prices.close[prices.close.length - 1];
  const bbPercent = (currentPrice - TechnicalAnalysis.latest(bb.lower)!) / 
                    (TechnicalAnalysis.latest(bb.upper)! - TechnicalAnalysis.latest(bb.lower)!);
  
  console.log(`\nBollinger Bands:`);
  console.log(`Upper: ${TechnicalAnalysis.latest(bb.upper)?.toFixed(2)}`);
  console.log(`Middle: ${TechnicalAnalysis.latest(bb.middle)?.toFixed(2)}`);
  console.log(`Lower: ${TechnicalAnalysis.latest(bb.lower)?.toFixed(2)}`);
  console.log(`%B: ${(bbPercent * 100).toFixed(2)}%`);
  
  // Calculate Stochastic
  const stoch = ta.stochastic(prices.high, prices.low, prices.close, 14, 3, 3);
  console.log(`\nStochastic:`);
  console.log(`%K: ${TechnicalAnalysis.latest(stoch.k)?.toFixed(2)}`);
  console.log(`%D: ${TechnicalAnalysis.latest(stoch.d)?.toFixed(2)}`);
  
  // Calculate ATR
  const atr = ta.atr(prices.high, prices.low, prices.close, 14);
  console.log(`\nATR(14): ${TechnicalAnalysis.latest(atr)?.toFixed(3)}`);
}

// Example 4: Trading signal generation
async function signalGenerationExample() {
  console.log('\n=== Signal Generation Example ===');
  
  const generator = new SignalGenerator();
  
  // Generate trending market data
  const generateTrendingPrices = (count: number, trend: 'up' | 'down' | 'sideways') => {
    const prices = { close: [], high: [], low: [], volume: [] } as any;
    let basePrice = 100;
    
    for (let i = 0; i < count; i++) {
      const trendComponent = trend === 'up' ? 0.1 : trend === 'down' ? -0.1 : 0;
      const noise = (Math.random() - 0.5) * 2;
      basePrice += trendComponent + noise;
      
      const high = basePrice + Math.random() * 1;
      const low = basePrice - Math.random() * 1;
      const close = low + Math.random() * (high - low);
      
      prices.close.push(close);
      prices.high.push(high);
      prices.low.push(low);
      prices.volume.push(Math.random() * 1000000 + 500000);
    }
    
    return prices;
  };
  
  // Test different market conditions
  const scenarios = [
    { name: 'Uptrend', data: generateTrendingPrices(50, 'up') },
    { name: 'Downtrend', data: generateTrendingPrices(50, 'down') },
    { name: 'Sideways', data: generateTrendingPrices(50, 'sideways') }
  ];
  
  for (const scenario of scenarios) {
    const signal = generator.generateSignals('TEST', scenario.data, Date.now());
    console.log(`\n${scenario.name} Market:`);
    console.log(`Signal: ${signal.action} (strength: ${signal.strength.toFixed(2)})`);
    console.log(`Reason: ${signal.reason}`);
    console.log(`Indicators: RSI=${signal.indicators.rsi?.toFixed(2)}, MACD=${signal.indicators.macd?.toFixed(3)}`);
  }
}

// Example 5: Crossover detection
async function crossoverExample() {
  console.log('\n=== Crossover Detection Example ===');
  
  const ta = new TechnicalAnalysis();
  
  // Generate price data with clear trend changes
  const prices: number[] = [];
  for (let i = 0; i < 100; i++) {
    if (i < 30) {
      prices.push(100 + i * 0.3); // Uptrend
    } else if (i < 60) {
      prices.push(109 - (i - 30) * 0.3); // Downtrend
    } else {
      prices.push(100 + (i - 60) * 0.2); // Uptrend again
    }
  }
  
  // Calculate moving averages
  const fastMA = ta.sma(prices, 10);
  const slowMA = ta.sma(prices, 20);
  
  // Detect crossovers
  console.log('Checking for crossovers in the last 10 bars:');
  for (let i = Math.max(0, fastMA.length - 10); i < fastMA.length; i++) {
    const fast = fastMA.slice(0, i + 1);
    const slow = slowMA.slice(0, i + 1);
    
    if (TechnicalAnalysis.crossover(fast, slow)) {
      console.log(`Bullish crossover at index ${i + 20}`);
    } else if (TechnicalAnalysis.crossunder(fast, slow)) {
      console.log(`Bearish crossover at index ${i + 20}`);
    }
  }
}

// Run all examples
async function runExamples() {
  try {
    await basicIndicatorExample();
    await streamingIndicatorExample();
    await complexIndicatorExample();
    await signalGenerationExample();
    await crossoverExample();
  } catch (error) {
    console.error('Error running examples:', error);
  }
}

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