#!/usr/bin/env node

/**
 * Complete AI Learning System Integration Test
 * 
 * Tests both stop loss decision learning AND risk/reward learning working together
 */

const fs = require('fs').promises;
const path = require('path');

// Simulated database for testing
const testDatabase = {
  stopLossDecisions: [],
  riskRewardSetups: [],
  tradeOutcomes: []
};

class TestStopLossDecisionLearner {
  constructor() {
    this.decisions = testDatabase.stopLossDecisions;
  }

  async recordDecision(context, decision, reasoning) {
    const record = {
      id: Date.now(),
      timestamp: new Date().toISOString(),
      marketConditions: context.marketConditions,
      distanceToSL: context.distanceToSL,
      decision: decision,
      reasoning: reasoning,
      outcome: null // Will be assessed later
    };
    
    this.decisions.push(record);
    console.log(`📝 SL Decision Recorded: ${decision} (Distance: ${context.distanceToSL}%)`);
    return record;
  }

  async getDecisionInsights() {
    const totalDecisions = this.decisions.length;
    const assessedDecisions = this.decisions.filter(d => d.outcome !== null);
    const correctDecisions = assessedDecisions.filter(d => d.outcome === 'CORRECT').length;
    
    return {
      totalDecisions,
      correctDecisions,
      accuracyRate: assessedDecisions.length > 0 ? Math.round((correctDecisions / assessedDecisions.length) * 100) : 0,
      recentPatterns: this.analyzePatterns()
    };
  }

  analyzePatterns() {
    const patterns = {};
    this.decisions.forEach(decision => {
      const key = decision.marketConditions?.trend || 'Unknown';
      if (!patterns[key]) {
        patterns[key] = { total: 0, correct: 0, decisions: [] };
      }
      patterns[key].total++;
      patterns[key].decisions.push(decision.decision);
      if (decision.outcome === 'CORRECT') patterns[key].correct++;
    });

    return Object.entries(patterns).map(([condition, data]) => ({
      condition,
      decision: data.decisions[data.decisions.length - 1] || 'UNKNOWN',
      successRate: data.total > 0 ? Math.round((data.correct / data.total) * 100) : 0,
      samples: data.total
    }));
  }
}

class TestRiskRewardLearner {
  constructor() {
    this.setups = testDatabase.riskRewardSetups;
    this.outcomes = testDatabase.tradeOutcomes;
  }

  async recordRiskRewardSetup(setup) {
    const record = {
      id: Date.now(),
      timestamp: new Date().toISOString(),
      symbol: setup.symbol,
      entryPrice: setup.entryPrice,
      stopLoss: setup.stopLoss,
      takeProfit: setup.takeProfit,
      riskAmount: setup.riskAmount,
      rewardAmount: setup.rewardAmount,
      riskRewardRatio: setup.rewardAmount / setup.riskAmount,
      marketConditions: setup.marketConditions,
      outcome: null // Will be set when trade closes
    };

    this.setups.push(record);
    console.log(`📊 R/R Setup Recorded: ${setup.symbol} R/R=${record.riskRewardRatio.toFixed(2)}`);
    return record;
  }

  async recordTradeOutcome(setupId, outcome) {
    const setup = this.setups.find(s => s.id === setupId);
    if (!setup) return;

    setup.outcome = outcome.type; // 'TAKE_PROFIT', 'STOP_LOSS', 'MANUAL_EXIT'
    setup.actualPnL = outcome.pnl;
    setup.exitTime = new Date().toISOString();

    console.log(`✅ Trade Outcome: ${outcome.type} (P&L: ${outcome.pnl > 0 ? '+' : ''}${outcome.pnl})`);
    return setup;
  }

  async getRiskRewardInsights() {
    const totalSetups = this.setups.length;
    const closedTrades = this.setups.filter(s => s.outcome);
    const takeProfitHits = closedTrades.filter(s => s.outcome === 'TAKE_PROFIT').length;
    const stopLossHits = closedTrades.filter(s => s.outcome === 'STOP_LOSS').length;

    const avgRatio = closedTrades.length > 0 
      ? closedTrades.reduce((sum, s) => sum + s.riskRewardRatio, 0) / closedTrades.length
      : 0;

    return {
      totalSetups,
      takeProfitHits,
      stopLossHits,
      tpHitRate: closedTrades.length > 0 ? Math.round((takeProfitHits / closedTrades.length) * 100) : 0,
      avgRiskRewardRatio: `1:${avgRatio.toFixed(1)}`,
      optimalRatios: this.analyzeOptimalRatios()
    };
  }

  analyzeOptimalRatios() {
    const conditionGroups = {};
    this.setups.filter(s => s.outcome).forEach(setup => {
      const condition = setup.marketConditions?.volatility || 'Unknown';
      if (!conditionGroups[condition]) {
        conditionGroups[condition] = { setups: [], tpHits: 0 };
      }
      conditionGroups[condition].setups.push(setup);
      if (setup.outcome === 'TAKE_PROFIT') {
        conditionGroups[condition].tpHits++;
      }
    });

    return Object.entries(conditionGroups).map(([condition, data]) => {
      const avgRatio = data.setups.reduce((sum, s) => sum + s.riskRewardRatio, 0) / data.setups.length;
      return {
        condition,
        optimalRatio: `1:${avgRatio.toFixed(1)}`,
        successRate: Math.round((data.tpHits / data.setups.length) * 100),
        samples: data.setups.length
      };
    });
  }
}

class TestEnhancedAutonomousRiskManager {
  constructor() {
    this.stopLossLearner = new TestStopLossDecisionLearner();
    this.riskRewardLearner = new TestRiskRewardLearner();
  }

  async recordTradeSetup(tradeData) {
    const setup = {
      symbol: tradeData.symbol,
      entryPrice: tradeData.entryPrice,
      stopLoss: tradeData.stopLoss,
      takeProfit: tradeData.takeProfit,
      riskAmount: Math.abs(tradeData.entryPrice - tradeData.stopLoss) * tradeData.size,
      rewardAmount: Math.abs(tradeData.takeProfit - tradeData.entryPrice) * tradeData.size,
      marketConditions: tradeData.marketConditions
    };

    return await this.riskRewardLearner.recordRiskRewardSetup(setup);
  }

  async makeStopLossDecision(context) {
    const decision = this.analyzeStopLossProximity(context);
    
    await this.stopLossLearner.recordDecision(context, decision.action, decision.reasoning);
    
    return decision;
  }

  analyzeStopLossProximity(context) {
    const { distanceToSL, marketConditions } = context;
    
    if (distanceToSL <= 1.0) {
      return {
        action: 'EXIT_EARLY',
        reasoning: `Very close to SL (${distanceToSL}%) - protecting capital`,
        confidence: 0.85
      };
    } else if (distanceToSL <= 2.5 && marketConditions?.trend === 'Bearish') {
      return {
        action: 'EXIT_EARLY', 
        reasoning: `Bearish trend + moderate SL distance (${distanceToSL}%)`,
        confidence: 0.72
      };
    } else if (distanceToSL <= 3.0 && marketConditions?.volatility === 'High') {
      return {
        action: 'REDUCE_POSITION',
        reasoning: `High volatility risk at ${distanceToSL}% from SL`,
        confidence: 0.68
      };
    } else {
      return {
        action: 'HOLD_POSITION',
        reasoning: `Sufficient distance (${distanceToSL}%) and favorable conditions`,
        confidence: 0.78
      };
    }
  }

  async recordTradeOutcome(setupId, outcome) {
    return await this.riskRewardLearner.recordTradeOutcome(setupId, outcome);
  }

  async getCompleteLearningStatus() {
    const slInsights = await this.stopLossLearner.getDecisionInsights();
    const rrInsights = await this.riskRewardLearner.getRiskRewardInsights();

    return {
      stopLossLearning: {
        status: 'ACTIVE',
        confidence: slInsights.accuracyRate > 75 ? 'HIGH' : slInsights.accuracyRate > 60 ? 'MEDIUM' : 'LOW',
        ...slInsights
      },
      riskRewardLearning: {
        status: 'ACTIVE',
        ...rrInsights
      },
      combinedInsights: {
        overallProfitability: this.calculateOverallProfitability(),
        improvementTrend: this.calculateImprovementTrend(),
        beachModeReady: slInsights.accuracyRate > 75 && rrInsights.tpHitRate > 65,
        systemMaturity: this.getSystemMaturity(slInsights, rrInsights),
        dataQuality: 'HIGH'
      }
    };
  }

  calculateOverallProfitability() {
    const closedTrades = this.riskRewardLearner.setups.filter(s => s.outcome && s.actualPnL !== undefined);
    if (closedTrades.length === 0) return 0;
    
    const totalPnL = closedTrades.reduce((sum, trade) => sum + trade.actualPnL, 0);
    const totalRisk = closedTrades.reduce((sum, trade) => sum + trade.riskAmount, 0);
    
    return Math.round((totalPnL / totalRisk) * 100);
  }

  calculateImprovementTrend() {
    const decisions = this.stopLossLearner.decisions;
    if (decisions.length < 10) return 'INITIALIZING';
    
    const recentDecisions = decisions.slice(-10);
    const olderDecisions = decisions.slice(-20, -10);
    
    const recentAccuracy = recentDecisions.filter(d => d.outcome === 'CORRECT').length / recentDecisions.length;
    const olderAccuracy = olderDecisions.filter(d => d.outcome === 'CORRECT').length / olderDecisions.length;
    
    if (recentAccuracy > olderAccuracy + 0.1) return 'EXCELLENT';
    if (recentAccuracy > olderAccuracy) return 'IMPROVING';
    return 'STABLE';
  }

  getSystemMaturity(slInsights, rrInsights) {
    const totalSamples = slInsights.totalDecisions + rrInsights.totalSetups;
    const avgPerformance = (slInsights.accuracyRate + rrInsights.tpHitRate) / 2;
    
    if (totalSamples > 100 && avgPerformance > 80) return 'EXPERT';
    if (totalSamples > 50 && avgPerformance > 70) return 'ADVANCED';
    if (totalSamples > 20 && avgPerformance > 60) return 'INTERMEDIATE';
    return 'BEGINNER';
  }
}

async function runCompleteIntegrationTest() {
  console.log('🎯 COMPLETE AI LEARNING SYSTEM INTEGRATION TEST');
  console.log('='.repeat(80));
  
  const aiSystem = new TestEnhancedAutonomousRiskManager();
  
  console.log('\n🚀 PHASE 1: Setting up multiple trade scenarios...\n');
  
  // Test scenarios with different market conditions
  const testScenarios = [
    {
      name: 'Low Volatility Bull Market',
      trade: {
        symbol: 'SOL-PERP',
        entryPrice: 100,
        stopLoss: 98,
        takeProfit: 104,
        size: 10,
        marketConditions: { volatility: 'Low', trend: 'Bullish' }
      },
      slProximityTests: [
        { distanceToSL: 1.2, expected: 'EXIT_EARLY' },
        { distanceToSL: 3.5, expected: 'HOLD_POSITION' }
      ],
      outcome: { type: 'TAKE_PROFIT', pnl: 40 }
    },
    {
      name: 'High Volatility Bear Market',
      trade: {
        symbol: 'ETH-PERP',
        entryPrice: 2000,
        stopLoss: 1940,
        takeProfit: 2080,
        size: 1,
        marketConditions: { volatility: 'High', trend: 'Bearish' }
      },
      slProximityTests: [
        { distanceToSL: 2.8, expected: 'REDUCE_POSITION' },
        { distanceToSL: 1.5, expected: 'EXIT_EARLY' }
      ],
      outcome: { type: 'STOP_LOSS', pnl: -60 }
    },
    {
      name: 'Medium Volatility Sideways',
      trade: {
        symbol: 'BTC-PERP',
        entryPrice: 50000,
        stopLoss: 49000,
        takeProfit: 51500,
        size: 0.1,
        marketConditions: { volatility: 'Medium', trend: 'Sideways' }
      },
      slProximityTests: [
        { distanceToSL: 4.0, expected: 'HOLD_POSITION' },
        { distanceToSL: 0.8, expected: 'EXIT_EARLY' }
      ],
      outcome: { type: 'TAKE_PROFIT', pnl: 150 }
    }
  ];

  // Execute test scenarios
  for (let i = 0; i < testScenarios.length; i++) {
    const scenario = testScenarios[i];
    console.log(`📊 Testing Scenario ${i + 1}: ${scenario.name}`);
    
    // Record trade setup
    const setup = await aiSystem.recordTradeSetup(scenario.trade);
    console.log(`   ✅ Trade setup recorded (ID: ${setup.id})`);
    
    // Test stop loss decisions
    for (const slTest of scenario.slProximityTests) {
      const context = {
        distanceToSL: slTest.distanceToSL,
        marketConditions: scenario.trade.marketConditions
      };
      
      const decision = await aiSystem.makeStopLossDecision(context);
      const correct = decision.action === slTest.expected;
      
      console.log(`   🎯 SL Decision at ${slTest.distanceToSL}%: ${decision.action} ${correct ? '✅' : '❌'}`);
      
      // Simulate outcome assessment (in real system this would happen later)
      const lastDecision = aiSystem.stopLossLearner.decisions[aiSystem.stopLossLearner.decisions.length - 1];
      lastDecision.outcome = correct ? 'CORRECT' : 'INCORRECT';
    }
    
    // Record trade outcome
    await aiSystem.recordTradeOutcome(setup.id, scenario.outcome);
    console.log(`   💰 Final outcome: ${scenario.outcome.type} (P&L: ${scenario.outcome.pnl > 0 ? '+' : ''}${scenario.outcome.pnl})`);
    console.log('');
  }

  console.log('\n🧠 PHASE 2: Analyzing complete learning results...\n');

  const learningStatus = await aiSystem.getCompleteLearningStatus();
  
  console.log('📊 STOP LOSS LEARNING RESULTS:');
  console.log(`   Total Decisions: ${learningStatus.stopLossLearning.totalDecisions}`);
  console.log(`   Correct Decisions: ${learningStatus.stopLossLearning.correctDecisions}`);
  console.log(`   Accuracy Rate: ${learningStatus.stopLossLearning.accuracyRate}%`);
  console.log(`   Confidence Level: ${learningStatus.stopLossLearning.confidence}`);
  console.log('');

  console.log('📈 RISK/REWARD LEARNING RESULTS:');
  console.log(`   Total Setups: ${learningStatus.riskRewardLearning.totalSetups}`);
  console.log(`   Take Profit Hits: ${learningStatus.riskRewardLearning.takeProfitHits}`);
  console.log(`   Stop Loss Hits: ${learningStatus.riskRewardLearning.stopLossHits}`);
  console.log(`   TP Hit Rate: ${learningStatus.riskRewardLearning.tpHitRate}%`);
  console.log(`   Average R/R Ratio: ${learningStatus.riskRewardLearning.avgRiskRewardRatio}`);
  console.log('');

  console.log('🎯 COMBINED INSIGHTS:');
  console.log(`   Overall Profitability: +${learningStatus.combinedInsights.overallProfitability}%`);
  console.log(`   Improvement Trend: ${learningStatus.combinedInsights.improvementTrend}`);
  console.log(`   System Maturity: ${learningStatus.combinedInsights.systemMaturity}`);
  console.log(`   Beach Mode Ready: ${learningStatus.combinedInsights.beachModeReady ? '🏖️ YES' : '⚠️ LEARNING'}`);
  console.log('');

  console.log('📋 LEARNED PATTERNS:');
  learningStatus.stopLossLearning.recentPatterns.forEach(pattern => {
    console.log(`   ${pattern.condition}: ${pattern.decision} (${pattern.successRate}% success, ${pattern.samples} samples)`);
  });
  console.log('');

  console.log('🎯 OPTIMAL R/R RATIOS BY CONDITION:');
  learningStatus.riskRewardLearning.optimalRatios.forEach(ratio => {
    console.log(`   ${ratio.condition}: ${ratio.optimalRatio} (${ratio.successRate}% success, ${ratio.samples} setups)`);
  });

  console.log('\n🏖️ BEACH MODE ASSESSMENT:');
  if (learningStatus.combinedInsights.beachModeReady) {
    console.log(`
✅ SYSTEM IS BEACH READY! 

Your AI has demonstrated:
✅ ${learningStatus.stopLossLearning.accuracyRate}% accuracy in stop loss decisions
✅ ${learningStatus.riskRewardLearning.tpHitRate}% take profit success rate  
✅ +${learningStatus.combinedInsights.overallProfitability}% overall profitability
✅ ${learningStatus.combinedInsights.systemMaturity} maturity level

🌊 Time to grab a piña colada! Your AI can handle the trading! 🏖️
`);
  } else {
    console.log(`
⚠️ SYSTEM STILL LEARNING

Current Status:
📊 SL Accuracy: ${learningStatus.stopLossLearning.accuracyRate}% (need >75%)
📈 TP Success: ${learningStatus.riskRewardLearning.tpHitRate}% (need >65%)
🎯 Maturity: ${learningStatus.combinedInsights.systemMaturity}

Keep trading to build more learning data! 📚
`);
  }

  console.log('\n✨ INTEGRATION TEST COMPLETE! ✨');
  console.log('\nThe AI system is now learning from BOTH:');
  console.log('🎯 Stop loss proximity decisions (when to exit vs hold)');
  console.log('📊 Risk/reward setup effectiveness (optimal ratios for different conditions)');
  console.log('\nThis creates a complete learning loop that optimizes:');
  console.log('• Risk management decisions in real-time');
  console.log('• Trade setup optimization for future trades');
  console.log('• Market condition adaptation');
  console.log('• Overall profitability through experience');

  return learningStatus;
}

// Run the complete integration test
if (require.main === module) {
  runCompleteIntegrationTest().catch(console.error);
}

module.exports = { runCompleteIntegrationTest };
