import { BaseStrategy, Signal } from '../BaseStrategy';
import { MarketData } from '../../types';
import { IndicatorManager } from '../indicators/IndicatorManager';
import { PositionManager, PositionSizingParams } from '../position/PositionManager';
import { getLogger } from '@stock-bot/logger';

const logger = getLogger('SimpleMovingAverageCrossoverV2');

export interface SMAStrategyConfig {
  fastPeriod?: number;
  slowPeriod?: number;
  positionSizePct?: number;
  riskPerTrade?: number;
  useATRStops?: boolean;
  minHoldingBars?: number;
  debugInterval?: number;
}

/**
 * Refactored SMA Crossover Strategy using new TA library
 */
export class SimpleMovingAverageCrossoverV2 extends BaseStrategy {
  private indicatorManager: IndicatorManager;
  private positionManager: PositionManager;
  
  // Strategy parameters
  private readonly config: Required<SMAStrategyConfig>;
  private lastTradeBar = new Map<string, number>();
  private barCount = new Map<string, number>();
  private totalSignals = 0;
  
  constructor(strategyConfig: any, modeManager?: any, executionService?: any) {
    super(strategyConfig, modeManager, executionService);
    
    // Initialize config with defaults
    this.config = {
      fastPeriod: 10,
      slowPeriod: 20,
      positionSizePct: 0.1,
      riskPerTrade: 0.02,
      useATRStops: true,
      minHoldingBars: 1,
      debugInterval: 20,
      ...strategyConfig.params
    };
    
    this.indicatorManager = new IndicatorManager();
    this.positionManager = new PositionManager(strategyConfig.initialCapital || 100000);
    
    logger.info(`SimpleMovingAverageCrossoverV2 initialized:`, this.config);
  }
  
  protected updateIndicators(data: MarketData): void {
    if (data.type !== 'bar') return;
    
    const { symbol, timestamp } = data.data;
    const { open, high, low, close, volume } = data.data;
    
    // Update bar count
    const currentBar = (this.barCount.get(symbol) || 0) + 1;
    this.barCount.set(symbol, currentBar);
    
    // First time seeing this symbol
    if (!this.indicatorManager.getHistoryLength(symbol)) {
      logger.info(`📊 Starting to track ${symbol} @ ${close}`);
      
      // Setup incremental indicators for real-time updates
      this.indicatorManager.setupIncrementalIndicator(symbol, 'fast_sma', {
        type: 'sma',
        period: this.config.fastPeriod
      });
      this.indicatorManager.setupIncrementalIndicator(symbol, 'slow_sma', {
        type: 'sma',
        period: this.config.slowPeriod
      });
      
      if (this.config.useATRStops) {
        this.indicatorManager.setupIncrementalIndicator(symbol, 'atr', {
          type: 'sma', // Using SMA as proxy for now
          period: 14
        });
      }
    }
    
    // Update price history
    this.indicatorManager.updatePrice({
      symbol,
      timestamp,
      open,
      high,
      low,
      close,
      volume
    });
    
    // Update position market prices
    const currentPrices = new Map([[symbol, close]]);
    this.positionManager.updateMarketPrices(currentPrices);
    
    // Log when we have enough data
    const historyLength = this.indicatorManager.getHistoryLength(symbol);
    if (historyLength === this.config.slowPeriod) {
      logger.info(`✅ ${symbol} has enough history (${historyLength} bars) to start trading`);
    }
  }

  protected async generateSignal(data: MarketData): Promise<Signal | null> {
    if (data.type !== 'bar') return null;
    
    const { symbol, timestamp } = data.data;
    const { close } = data.data;
    const historyLength = this.indicatorManager.getHistoryLength(symbol);
    
    // Need enough data for slow MA
    if (historyLength < this.config.slowPeriod) {
      if (historyLength % 5 === 0) {
        logger.debug(`${symbol} - Building history: ${historyLength}/${this.config.slowPeriod} bars`);
      }
      return null;
    }
    
    // Calculate indicators
    const fastMA = this.indicatorManager.getSMA(symbol, this.config.fastPeriod);
    const slowMA = this.indicatorManager.getSMA(symbol, this.config.slowPeriod);
    
    if (!fastMA || !slowMA) return null;
    
    // Get current and previous values
    const currentFast = this.indicatorManager.getLatest(fastMA);
    const currentSlow = this.indicatorManager.getLatest(slowMA);
    
    if (currentFast === null || currentSlow === null) return null;
    
    // Check for crossovers
    const goldenCross = this.indicatorManager.checkCrossover(fastMA, slowMA);
    const deathCross = this.indicatorManager.checkCrossunder(fastMA, slowMA);
    
    // Get current position
    const currentPosition = this.positionManager.getPositionQuantity(symbol);
    const currentBar = this.barCount.get(symbol) || 0;
    const lastTradeBar = this.lastTradeBar.get(symbol) || 0;
    const barsSinceLastTrade = lastTradeBar > 0 ? currentBar - lastTradeBar : Number.MAX_SAFE_INTEGER;
    
    // Enhanced debugging
    const maDiff = currentFast - currentSlow;
    const maDiffPct = (maDiff / currentSlow) * 100;
    const shouldLog = historyLength % this.config.debugInterval === 0 || 
                     Math.abs(maDiffPct) < 1.0 || 
                     goldenCross || 
                     deathCross;
    
    if (shouldLog) {
      const dateStr = new Date(timestamp).toISOString().split('T')[0];
      logger.info(`${symbol} @ ${dateStr} [Bar ${currentBar}]:`);
      logger.info(`  Price: $${close.toFixed(2)}`);
      logger.info(`  Fast MA (${this.config.fastPeriod}): $${currentFast.toFixed(2)}`);
      logger.info(`  Slow MA (${this.config.slowPeriod}): $${currentSlow.toFixed(2)}`);
      logger.info(`  MA Diff: ${maDiff.toFixed(2)} (${maDiffPct.toFixed(2)}%)`);
      logger.info(`  Position: ${currentPosition} shares`);
      
      // Show additional indicators if available
      const rsi = this.indicatorManager.getRSI(symbol);
      if (rsi) {
        const currentRSI = this.indicatorManager.getLatest(rsi);
        logger.info(`  RSI: ${currentRSI?.toFixed(2)}`);
      }
      
      if (goldenCross) logger.info(`  🟢 GOLDEN CROSS DETECTED!`);
      if (deathCross) logger.info(`  🔴 DEATH CROSS DETECTED!`);
    }
    
    // Check minimum holding period
    if (barsSinceLastTrade < this.config.minHoldingBars && lastTradeBar > 0) {
      return null;
    }
    
    // Position sizing parameters
    const sizingParams: PositionSizingParams = {
      accountBalance: this.positionManager.getAccountBalance(),
      riskPerTrade: this.config.riskPerTrade,
      volatilityAdjustment: this.config.useATRStops
    };
    
    if (this.config.useATRStops) {
      const atr = this.indicatorManager.getATR(symbol);
      if (atr) {
        sizingParams.atr = this.indicatorManager.getLatest(atr) || undefined;
      }
    }
    
    // Generate signals
    if (goldenCross) {
      logger.info(`🟢 Golden cross detected for ${symbol}`);
      
      if (currentPosition < 0) {
        // Close short position
        this.lastTradeBar.set(symbol, currentBar);
        this.totalSignals++;
        return {
          type: 'buy',
          symbol,
          strength: 0.8,
          reason: 'Golden cross - Closing short position',
          metadata: {
            fastMA: currentFast,
            slowMA: currentSlow,
            crossoverType: 'golden',
            price: close,
            quantity: Math.abs(currentPosition)
          }
        };
      } else if (currentPosition === 0) {
        // Calculate position size
        const positionSize = this.positionManager.calculatePositionSize(sizingParams, close);
        
        logger.info(`  Opening long position: ${positionSize} shares`);
        logger.info(`  Account balance: $${sizingParams.accountBalance.toFixed(2)}`);
        
        this.lastTradeBar.set(symbol, currentBar);
        this.totalSignals++;
        
        return {
          type: 'buy',
          symbol,
          strength: 0.8,
          reason: 'Golden cross - Fast MA crossed above Slow MA',
          metadata: {
            fastMA: currentFast,
            slowMA: currentSlow,
            crossoverType: 'golden',
            price: close,
            quantity: positionSize
          }
        };
      }
    } else if (deathCross && currentPosition > 0) {
      logger.info(`🔴 Death cross detected for ${symbol}`);
      
      this.lastTradeBar.set(symbol, currentBar);
      this.totalSignals++;
      
      return {
        type: 'sell',
        symbol,
        strength: 0.8,
        reason: 'Death cross - Fast MA crossed below Slow MA',
        metadata: {
          fastMA: currentFast,
          slowMA: currentSlow,
          crossoverType: 'death',
          price: close,
          quantity: currentPosition
        }
      };
    }
    
    return null;
  }
  
  protected async onOrderUpdate(update: any): Promise<void> {
    await super.onOrderUpdate(update);
    
    // Update position manager with fills
    if (update.status === 'filled' && update.fills?.length > 0) {
      for (const fill of update.fills) {
        this.positionManager.updatePosition({
          symbol: update.symbol,
          side: update.side,
          quantity: fill.quantity,
          price: fill.price,
          commission: fill.commission || 0,
          timestamp: new Date(fill.timestamp)
        });
      }
      
      // Log performance metrics periodically
      if (this.totalSignals % 5 === 0) {
        const metrics = this.positionManager.getPerformanceMetrics();
        logger.info('📊 Strategy Performance:', {
          trades: metrics.totalTrades,
          winRate: `${metrics.winRate.toFixed(2)}%`,
          totalPnL: `$${metrics.totalPnl.toFixed(2)}`,
          returnPct: `${metrics.returnPct.toFixed(2)}%`
        });
      }
    }
  }
  
  getPerformance(): any {
    const metrics = this.positionManager.getPerformanceMetrics();
    return {
      ...super.getPerformance(),
      ...metrics,
      totalSignals: this.totalSignals,
      openPositions: this.positionManager.getOpenPositions()
    };
  }
  
  // Optional: Get current state for debugging
  getState() {
    return {
      config: this.config,
      totalSignals: this.totalSignals,
      performance: this.getPerformance(),
      positions: Array.from(this.positions.entries())
    };
  }
}