/**
 * Simplified Stop Loss Learning System
 * 
 * Simplified approach focusing on essential learning patterns
 * without complex statistical analysis.
 */

import { PrismaClient } from '@prisma/client';
import { getDB } from './db.js';

class SimplifiedStopLossLearner {
  constructor() {
    this.learningThresholds = {
      emergency: 1.0,  // Emergency exit at 1% from SL
      risk: 2.0,       // High risk at 2% from SL
      mediumRisk: 5.0  // Medium risk at 5% from SL
    };
  }

  async log(message) {
    console.log(`[${new Date().toISOString()}] 🧠 SL Learner: ${message}`);
  }

  /**
   * Record a stop loss related decision for learning
   */
  async recordDecision(decisionData) {
    try {
      const learningRecord = {
        type: 'STOP_LOSS_DECISION',
        tradeId: decisionData.tradeId,
        symbol: decisionData.symbol,
        decision: decisionData.decision,
        distanceFromSL: decisionData.distanceFromSL,
        reasoning: decisionData.reasoning,
        marketConditions: decisionData.marketConditions,
        expectedOutcome: decisionData.expectedOutcome,
        timestamp: new Date().toISOString()
      };

      const prisma = await getDB();
      const record = await prisma.ai_learning_data.create({
        data: {
          id: `sl_decision_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
          userId: 'default-user',
          symbol: decisionData.symbol,
          timeframe: 'DECISION',
          analysisData: JSON.stringify(learningRecord),
          marketConditions: JSON.stringify(decisionData.marketConditions || {}),
          confidenceScore: 50 // Neutral starting confidence
        }
      });

      await this.log(`📝 Decision recorded: ${decisionData.decision} for ${decisionData.symbol} at ${decisionData.distanceFromSL}%`);
      
      return record.id;
    } catch (error) {
      await this.log(`❌ Error recording decision: ${error.message}`);
      return null;
    }
  }

  /**
   * Update the outcome of a previously recorded decision
   */
  async assessDecisionOutcome(outcomeData) {
    try {
      const prisma = await getDB();
      
      // Find the original decision record
      const originalRecord = await prisma.ai_learning_data.findUnique({
        where: { id: outcomeData.decisionId }
      });

      if (!originalRecord) {
        await this.log(`⚠️ Original decision ${outcomeData.decisionId} not found`);
        return false;
      }

      // Parse the original decision data
      const originalDecision = JSON.parse(originalRecord.analysisData);
      
      // Create outcome record with learning data
      const outcomeRecord = {
        type: 'STOP_LOSS_OUTCOME',
        originalDecisionId: outcomeData.decisionId,
        actualOutcome: outcomeData.actualOutcome,
        timeToOutcome: outcomeData.timeToOutcome,
        pnlImpact: outcomeData.pnlImpact,
        wasCorrect: this.evaluateDecisionCorrectness(originalDecision, outcomeData),
        learningData: {
          originalDecision: originalDecision.decision,
          distanceFromSL: originalDecision.distanceFromSL,
          outcome: outcomeData.actualOutcome,
          profitability: outcomeData.pnlImpact > 0 ? 'PROFITABLE' : 'LOSS'
        },
        timestamp: new Date().toISOString()
      };

      await prisma.ai_learning_data.create({
        data: {
          id: `sl_outcome_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
          userId: 'default-user',
          symbol: originalDecision.symbol,
          timeframe: 'OUTCOME',
          analysisData: JSON.stringify(outcomeRecord),
          marketConditions: originalRecord.marketConditions,
          confidenceScore: outcomeRecord.wasCorrect ? 75 : 25
        }
      });

      await this.log(`✅ Outcome assessed for ${outcomeData.decisionId}: ${outcomeData.actualOutcome} (${outcomeRecord.wasCorrect ? 'CORRECT' : 'INCORRECT'})`);
      
      // Update learning thresholds based on outcomes
      await this.updateThresholdsFromOutcome(originalDecision, outcomeRecord);
      
      return true;
    } catch (error) {
      await this.log(`❌ Error assessing outcome: ${error.message}`);
      return false;
    }
  }

  /**
   * Evaluate if the original decision was correct based on outcome
   */
  evaluateDecisionCorrectness(originalDecision, outcome) {
    const decision = originalDecision.decision;
    const actualOutcome = outcome.actualOutcome;
    const pnlImpact = outcome.pnlImpact;

    // Define what constitutes a "correct" decision
    if (decision === 'EMERGENCY_EXIT' && (actualOutcome === 'STOPPED_OUT' || pnlImpact < -50)) {
      return true; // Correctly identified emergency
    }
    
    if (decision === 'HOLD_POSITION' && pnlImpact > 0) {
      return true; // Correctly held profitable position
    }
    
    if (decision === 'ADJUST_STOP_LOSS' && actualOutcome === 'TAKE_PROFIT') {
      return true; // Adjustment led to profitable exit
    }

    // FIXED: Add evaluation for MONITOR and ENHANCED_MONITORING decisions
    if ((decision === 'MONITOR' || decision === 'ENHANCED_MONITORING') && pnlImpact > 0) {
      return true; // Correctly monitored and position became profitable
    }
    
    // FIXED: Add evaluation for neutral outcomes - if no major loss, monitoring was appropriate
    if ((decision === 'MONITOR' || decision === 'ENHANCED_MONITORING') && 
        (actualOutcome === 'NEUTRAL_POSITIVE' || actualOutcome === 'NEUTRAL_NEGATIVE') && 
        pnlImpact > -10) { // Allow small losses as acceptable monitoring outcomes
      return true; // Monitoring decision was reasonable - no major loss occurred
    }
    
    // FIXED: Emergency exit should also be considered correct if it prevented larger losses
    if (decision === 'EMERGENCY_EXIT' && pnlImpact > -100) {
      return true; // Emergency exit prevented catastrophic loss
    }

    return false;
  }

  /**
   * Get smart recommendation based on learned patterns
   */
  async getSmartRecommendation(requestData) {
    try {
      const { distanceFromSL, symbol, marketConditions } = requestData;
      
      // Get historical data for similar situations
      const prisma = await getDB();
      const similarDecisions = await prisma.ai_learning_data.findMany({
        where: {
          symbol: symbol,
          analysisData: {
            string_contains: 'STOP_LOSS_DECISION'
          }
        },
        orderBy: { createdAt: 'desc' },
        take: 20
      });

      // Analyze patterns from similar situations
      let recommendation = this.getBaseRecommendation(distanceFromSL);
      
      if (similarDecisions.length >= 3) {
        const learnedRecommendation = await this.analyzePatterns(similarDecisions, distanceFromSL);
        if (learnedRecommendation) {
          recommendation = learnedRecommendation;
        }
      }

      await this.log(`🎯 Smart recommendation for ${symbol} at ${distanceFromSL}%: ${recommendation.action}`);
      
      return recommendation;
    } catch (error) {
      await this.log(`❌ Error getting smart recommendation: ${error.message}`);
      return this.getBaseRecommendation(distanceFromSL);
    }
  }

  /**
   * Get base recommendation using current thresholds
   */
  getBaseRecommendation(distanceFromSL) {
    if (distanceFromSL <= this.learningThresholds.emergency) {
      return {
        action: 'EMERGENCY_EXIT',
        confidence: 0.8,
        reasoning: `Very close to SL (${distanceFromSL}%), emergency exit recommended`
      };
    } else if (distanceFromSL <= this.learningThresholds.risk) {
      return {
        action: 'HIGH_ALERT',
        confidence: 0.7,
        reasoning: `Close to SL (${distanceFromSL}%), monitor closely`
      };
    } else if (distanceFromSL <= this.learningThresholds.mediumRisk) {
      return {
        action: 'MONITOR',
        confidence: 0.6,
        reasoning: `Moderate distance from SL (${distanceFromSL}%), continue monitoring`
      };
    } else {
      return {
        action: 'HOLD_POSITION',
        confidence: 0.5,
        reasoning: `Safe distance from SL (${distanceFromSL}%), maintain position`
      };
    }
  }

  /**
   * Analyze historical patterns to improve recommendations
   */
  async analyzePatterns(decisions, currentDistance) {
    const outcomes = await this.getOutcomesForDecisions(decisions);
    
    // Find decisions made at similar distances
    const similarDistanceDecisions = decisions.filter(d => {
      const data = JSON.parse(d.analysisData);
      const distance = data.distanceFromSL;
      return Math.abs(distance - currentDistance) <= 1.0; // Within 1%
    });

    if (similarDistanceDecisions.length < 2) {
      return null; // Not enough similar data
    }

    // Analyze success rate of different actions at this distance
    const actionSuccess = {};
    
    for (const decision of similarDistanceDecisions) {
      const decisionData = JSON.parse(decision.analysisData);
      const action = decisionData.decision;
      const outcome = outcomes.find(o => o.originalDecisionId === decision.id);
      
      if (outcome) {
        if (!actionSuccess[action]) {
          actionSuccess[action] = { total: 0, successful: 0 };
        }
        actionSuccess[action].total++;
        if (outcome.wasCorrect) {
          actionSuccess[action].successful++;
        }
      }
    }

    // Find the action with highest success rate
    let bestAction = null;
    let bestSuccessRate = 0;
    
    for (const [action, stats] of Object.entries(actionSuccess)) {
      if (stats.total >= 2) { // Need at least 2 samples
        const successRate = stats.successful / stats.total;
        if (successRate > bestSuccessRate) {
          bestSuccessRate = successRate;
          bestAction = action;
        }
      }
    }

    if (bestAction && bestSuccessRate > 0.6) {
      return {
        action: bestAction,
        confidence: bestSuccessRate,
        reasoning: `Learned pattern: ${bestAction} successful ${Math.round(bestSuccessRate * 100)}% of time at this distance`
      };
    }

    return null;
  }

  /**
   * Get outcomes for a set of decisions
   */
  async getOutcomesForDecisions(decisions) {
    const prisma = await getDB();
    const decisionIds = decisions.map(d => d.id);
    
    const outcomes = await prisma.ai_learning_data.findMany({
      where: {
        analysisData: {
          string_contains: 'STOP_LOSS_OUTCOME'
        }
      }
    });

    return outcomes.map(o => JSON.parse(o.analysisData))
      .filter(outcome => decisionIds.includes(outcome.originalDecisionId));
  }

  /**
   * Update learning thresholds based on outcome data
   */
  async updateThresholdsFromOutcome(originalDecision, outcome) {
    // Simple threshold adjustment based on outcomes
    const distance = originalDecision.distanceFromSL;
    const wasCorrect = outcome.wasCorrect;
    
    if (!wasCorrect) {
      // If decision was wrong, adjust thresholds slightly
      if (originalDecision.decision === 'HOLD_POSITION' && outcome.actualOutcome === 'STOPPED_OUT') {
        // We should have exited earlier - make thresholds more conservative
        this.learningThresholds.emergency = Math.min(2.0, this.learningThresholds.emergency + 0.1);
        this.learningThresholds.risk = Math.min(3.0, this.learningThresholds.risk + 0.1);
      }
    }

    await this.log(`🔧 Thresholds updated: emergency=${this.learningThresholds.emergency}, risk=${this.learningThresholds.risk}`);
  }

  /**
   * Get current learning status and statistics
   */
  async analyzeDecisionPatterns() {
    try {
      const prisma = await getDB();
      
      // Get recent decisions and outcomes
      const decisions = await prisma.ai_learning_data.findMany({
        where: {
          analysisData: {
            string_contains: 'STOP_LOSS_DECISION'
          },
          createdAt: {
            gte: new Date(Date.now() - 7 * 24 * 60 * 60 * 1000) // Last 7 days
          }
        },
        orderBy: { createdAt: 'desc' }
      });

      const outcomes = await prisma.ai_learning_data.findMany({
        where: {
          analysisData: {
            string_contains: 'STOP_LOSS_OUTCOME'
          },
          createdAt: {
            gte: new Date(Date.now() - 7 * 24 * 60 * 60 * 1000) // Last 7 days
          }
        }
      });

      // Analyze patterns
      const patterns = {
        totalDecisions: decisions.length,
        totalOutcomes: outcomes.length,
        successfulDecisions: outcomes.filter(o => JSON.parse(o.analysisData).wasCorrect).length,
        successRate: outcomes.length > 0 ? outcomes.filter(o => JSON.parse(o.analysisData).wasCorrect).length / outcomes.length : 0,
        learnedThresholds: this.learningThresholds
      };

      return patterns;
    } catch (error) {
      await this.log(`❌ Error analyzing patterns: ${error.message}`);
      return {
        totalDecisions: 0,
        totalOutcomes: 0,
        successfulDecisions: 0,
        successRate: 0,
        learnedThresholds: this.learningThresholds
      };
    }
  }

  /**
   * Get learning status
   */
  async getLearningStatus() {
    try {
      const prisma = await getDB();
      const totalDecisions = await prisma.ai_learning_data.count({
        where: {
          analysisData: {
            string_contains: 'STOP_LOSS_DECISION'
          }
        }
      });

      const recentDecisions = await prisma.ai_learning_data.count({
        where: {
          analysisData: {
            string_contains: 'STOP_LOSS_DECISION'
          },
          createdAt: {
            gte: new Date(Date.now() - 24 * 60 * 60 * 1000) // Last 24 hours
          }
        }
      });

      return {
        totalDecisions,
        recentDecisions,
        thresholds: this.learningThresholds,
        isActive: totalDecisions > 0
      };

    } catch (error) {
      await this.log(`❌ Error getting learning status: ${error.message}`);
      return {
        totalDecisions: 0,
        recentDecisions: 0,
        thresholds: this.learningThresholds,
        isActive: false
      };
    }
  }

  /**
   * Generate comprehensive learning report
   * Compatible implementation for enhanced-autonomous-risk-manager
   */
  async generateLearningReport() {
    try {
      const status = await this.getLearningStatus();
      const patterns = await this.analyzeDecisionPatterns();
      
      // Calculate system confidence based on decisions made
      const systemConfidence = this.calculateSystemConfidence(status.totalDecisions, status.recentDecisions, patterns.successRate);
      
      const report = {
        timestamp: new Date().toISOString(),
        summary: {
          totalDecisions: status.totalDecisions,
          recentDecisions: status.recentDecisions,
          successfulPatterns: patterns.successfulDecisions,
          learningThresholds: this.learningThresholds,
          systemConfidence: systemConfidence,
          isActive: status.isActive,
          successRate: patterns.successRate
        },
        insights: {
          emergencyThreshold: this.learningThresholds.emergency,
          riskThreshold: this.learningThresholds.risk,
          mediumRiskThreshold: this.learningThresholds.mediumRisk,
          confidenceLevel: systemConfidence > 0.7 ? 'HIGH' : systemConfidence > 0.4 ? 'MEDIUM' : 'LOW',
          totalOutcomes: patterns.totalOutcomes,
          decisionAccuracy: patterns.successRate
        },
        recommendations: this.generateSystemRecommendations(status, patterns)
      };

      await this.log(`📊 Learning report generated: ${report.summary.totalDecisions} decisions, ${(systemConfidence * 100).toFixed(1)}% confidence, ${(patterns.successRate * 100).toFixed(1)}% success rate`);
      
      return report;
    } catch (error) {
      await this.log(`❌ Error generating learning report: ${error.message}`);
      return {
        timestamp: new Date().toISOString(),
        summary: {
          totalDecisions: 0,
          recentDecisions: 0,
          systemConfidence: 0.0,
          isActive: false
        },
        error: error.message
      };
    }
  }

  /**
   * Calculate system confidence based on learning data
   */
  calculateSystemConfidence(totalDecisions, recentDecisions, successRate = 0) {
    if (totalDecisions < 5) return 0.3; // Low confidence with insufficient data
    if (totalDecisions < 20) return 0.4 + (successRate * 0.2); // Medium-low confidence boosted by success
    if (totalDecisions < 50) return 0.6 + (successRate * 0.2); // Medium confidence boosted by success
    
    // High confidence with lots of data, scaled by recent activity and success rate
    const recentActivityFactor = Math.min(1.0, recentDecisions / 10);
    const successFactor = successRate || 0.5; // Default to neutral if no success data
    return Math.min(0.95, 0.7 + (recentActivityFactor * 0.1) + (successFactor * 0.15)); // Cap at 95%
  }

  /**
   * Generate system recommendations based on learning status
   */
  generateSystemRecommendations(status, patterns) {
    const recommendations = [];
    
    if (status.totalDecisions < 10) {
      recommendations.push({
        type: 'DATA_COLLECTION',
        message: 'Need more decision data for reliable learning',
        priority: 'HIGH'
      });
    }
    
    if (status.recentDecisions < 3) {
      recommendations.push({
        type: 'ACTIVITY_LOW',
        message: 'Recent trading activity is low - learning may be stale',
        priority: 'MEDIUM'
      });
    }
    
    if (patterns && patterns.successRate < 0.4 && patterns.totalOutcomes >= 5) {
      recommendations.push({
        type: 'THRESHOLD_ADJUSTMENT',
        message: 'Low success rate detected - consider adjusting decision thresholds',
        priority: 'HIGH'
      });
    }
    
    if (status.totalDecisions >= 20 && patterns && patterns.successRate > 0.6) {
      recommendations.push({
        type: 'SYSTEM_PERFORMING',
        message: 'System learning effectively with good success rate',
        priority: 'LOW'
      });
    }
    
    if (status.totalDecisions >= 50) {
      recommendations.push({
        type: 'OPTIMIZATION_READY',
        message: 'Sufficient data available for advanced threshold optimization',
        priority: 'LOW'
      });
    }
    
    return recommendations;
  }
}

export { SimplifiedStopLossLearner };
