/**
 * AI Analysis Service
 * Uses Claude/Anthropic API to analyze options flow data and provide trading insights
 */

import Anthropic from '@anthropic-ai/sdk';
import { fetchYahooFinanceData } from './yahooFinanceService.js';

let anthropicClient = null;

/**
 * Initialize Anthropic client
 */
function getClient() {
  if (!anthropicClient) {
    const apiKey = process.env.ANTHROPIC_API_KEY;
    if (!apiKey) {
      throw new Error('ANTHROPIC_API_KEY environment variable is not set');
    }
    anthropicClient = new Anthropic({ apiKey });
  }
  return anthropicClient;
}

// fetchYahooFinanceData is now imported from yahooFinanceService.js

/**
 * Generate enhanced AI analysis with S/R context and entry/exit strategies
 */
export async function generateEnhancedAIAnalysis(flowData, srLevels = null, pricePositioning = null, yahooData = null) {
  try {
    const client = getClient();
    
    // Prepare context from flow data
    const symbol = flowData.symbol_norm || flowData.Symbol || 'UNKNOWN';
    const score = flowData.rocketScore || flowData.rocket_score || 0;
    const netPremium = ((flowData.bull_total || 0) - (flowData.bear_total || 0)) / 1000000;
    const premium = (flowData.premium_num || 0) / 1000000;
    const volume = flowData.vol_num || flowData.Volume || 0;
    const strike = flowData.strike_num || flowData.Strike || 0;
    const spot = flowData.spot_num || flowData.Spot || 0;
    const callPut = flowData.cp_norm || flowData.CallPut || 'UNKNOWN';
    const direction = flowData.direction || (netPremium > 0 ? 'BULL' : 'BEAR');
    const session = flowData.session_bucket || 'RTH';
    const tapeAligned = flowData.tapeAligned || flowData.tape_alignment === 1;
    const catalyst = flowData.near_alert_type || 'None';
    const pctVsRthOpen = flowData.PctVsRthOpen || flowData.pct_vs_rth_open || 0;
    const badges = flowData.badgesRaw?.more || '';
    const isRealMoney = badges?.includes('💎');
    const isHighConviction = badges?.includes('⭐');
    
    // Fetch Yahoo Finance data if not provided
    if (!yahooData) {
      yahooData = await fetchYahooFinanceData(symbol);
    }
    
    const currentPrice = yahooData?.currentPrice || spot || 0;
    
    // Build S/R context string
    let srContext = '';
    if (srLevels && pricePositioning) {
      srContext = `
SUPPORT/RESISTANCE ANALYSIS:
- Current Price: $${currentPrice.toFixed(2)}
- Nearest Support: ${srLevels.nearestSupport ? `$${srLevels.nearestSupport.price.toFixed(2)} (${pricePositioning.supportPct?.toFixed(2) || 'N/A'}% away, strength: ${srLevels.nearestSupport.strength}/10)` : 'None identified'}
- Nearest Resistance: ${srLevels.nearestResistance ? `$${srLevels.nearestResistance.price.toFixed(2)} (${pricePositioning.resistancePct?.toFixed(2) || 'N/A'}% away, strength: ${srLevels.nearestResistance.strength}/10)` : 'None identified'}
- Price Zone: ${pricePositioning.zone}
- Risk Level: ${pricePositioning.riskLevel}

KEY SUPPORT LEVELS:
${srLevels.supports.map(s => `  - $${s.price.toFixed(2)} (${s.source}, strength: ${s.strength}/10)`).join('\n')}

KEY RESISTANCE LEVELS:
${srLevels.resistances.map(r => `  - $${r.price.toFixed(2)} (${r.source}, strength: ${r.strength}/10)`).join('\n')}
`;
    }
    
    // Ensure numeric values for formatting
    const strikeNum = typeof strike === 'number' ? strike : parseFloat(strike) || 0;
    const spotNum = typeof spot === 'number' ? spot : parseFloat(spot) || 0;
    const premiumNum = typeof premium === 'number' ? premium : parseFloat(premium) || 0;
    const netPremiumNum = typeof netPremium === 'number' ? netPremium : parseFloat(netPremium) || 0;
    const scoreNum = typeof score === 'number' ? score : parseFloat(score) || 0;
    const pctVsRthOpenNum = typeof pctVsRthOpen === 'number' ? pctVsRthOpen : parseFloat(pctVsRthOpen) || 0;
    
    // Build enhanced prompt
    const prompt = `You are a world-class hedge fund trader and options flow expert. Analyze this institutional options flow with support/resistance context and provide professional-grade trading strategies.

OPTIONS FLOW DATA:
- Symbol: ${symbol}
- Score: ${scoreNum.toFixed(1)}/10
- Net Premium: $${Math.abs(netPremiumNum).toFixed(2)}M (${direction === 'BULL' ? 'Bullish' : 'Bearish'})
- Premium: $${premiumNum.toFixed(2)}M
- Volume: ${volume.toLocaleString()} contracts
- Type: ${callPut}
- Strike: $${strikeNum.toFixed(2)}
- Spot: $${spotNum.toFixed(2)}
- Session: ${session}
- Tape Aligned: ${tapeAligned ? 'Yes' : 'No'}
- Catalyst: ${catalyst}
- Price vs RTH Open: ${pctVsRthOpenNum > 0 ? '+' : ''}${pctVsRthOpenNum.toFixed(2)}%
- Real Money Flow: ${isRealMoney ? 'Yes (💎)' : 'No'}
- High Conviction: ${isHighConviction ? 'Yes (⭐)' : 'No'}

${yahooData ? `STOCK DATA:
- Current Price: $${yahooData.currentPrice?.toFixed(2) || 'N/A'}
- Previous Close: $${yahooData.previousClose?.toFixed(2) || 'N/A'}
- Open: $${yahooData.open?.toFixed(2) || 'N/A'}
- High: $${yahooData.high?.toFixed(2) || 'N/A'}
- Low: $${yahooData.low?.toFixed(2) || 'N/A'}
- Change: ${yahooData.changePercent > 0 ? '+' : ''}${yahooData.changePercent?.toFixed(2) || '0.00'}%
- Volume: ${yahooData.volume?.toLocaleString() || 'N/A'}
` : ''}
${srContext}

Provide a comprehensive analysis with:
1. Overall assessment (Bullish/Bearish/Neutral) with conviction level
2. Key factors driving the signal
3. Entry strategy with specific price levels and triggers
4. Stop loss levels (tight and wide)
5. Profit targets (T1, T2, T3) with R:R ratios
6. Risk management notes
7. Entry/exit timing recommendations

Format as JSON:
{
  "assessment": "BULLISH|BEARISH|NEUTRAL",
  "conviction": 1-10,
  "summary": "2-3 sentence summary",
  "keyFactors": ["factor1", "factor2", "factor3"],
  "entryStrategy": {
    "primary": "Main entry level/strategy",
    "aggressive": "Aggressive entry if available",
    "conservative": "Conservative entry with confirmation",
    "triggers": ["trigger1", "trigger2"],
    "invalidates": ["invalidation1"]
  },
  "stopLoss": {
    "tight": "$XX.XX (X.X% risk)",
    "wide": "$XX.XX (X.X% risk)",
    "reasoning": "Why these levels"
  },
  "targets": {
    "t1": "$XX.XX (R:R X.X:1, probability: X%)",
    "t2": "$XX.XX (R:R X.X:1, probability: X%)",
    "t3": "$XX.XX (R:R X.X:1, probability: X%)"
  },
  "riskManagement": "Risk management notes",
  "timing": {
    "entry": "When to enter (e.g., 'On pullback to support', 'Breakout above resistance')",
    "exit": "When to exit (e.g., 'At resistance', 'Trail stop at T1')"
  },
  "warnings": ["warning1", "warning2"]
}`;

    // Use model from env or default to stable version
    const modelName = process.env.ANTHROPIC_MODEL || 'claude-sonnet-4-5-20250929';
    
    const message = await client.messages.create({
      model: modelName,
      max_tokens: 2000,
      messages: [{
        role: 'user',
        content: prompt
      }]
    });

    // Extract JSON from response
    const responseText = message.content[0].text;
    let analysis;
    
    try {
      // Try to extract JSON from markdown code blocks
      const jsonMatch = responseText.match(/```json\s*([\s\S]*?)\s*```/) || 
                       responseText.match(/```\s*([\s\S]*?)\s*```/) ||
                       [null, responseText];
      const jsonText = jsonMatch[1] || responseText;
      analysis = JSON.parse(jsonText);
    } catch (parseError) {
      // Fallback: create structured response from text
      console.warn('Failed to parse AI response as JSON, using fallback');
      analysis = {
        assessment: direction,
        conviction: Math.min(10, Math.max(1, Math.round(scoreNum))),
        summary: responseText.substring(0, 300),
        keyFactors: [],
        entryStrategy: {
          primary: `Enter on ${direction === 'BULL' ? 'pullback' : 'rally'} to key level`,
          triggers: [],
          invalidates: []
        },
        stopLoss: {
          tight: 'Calculate based on S/R',
          wide: 'Calculate based on S/R',
          reasoning: 'Based on support/resistance levels'
        },
        targets: {
          t1: 'First target at next resistance',
          t2: 'Second target at extended resistance',
          t3: 'Third target for swing trade'
        },
        riskManagement: 'Manage risk based on position sizing',
        timing: {
          entry: 'Wait for confirmation',
          exit: 'Trail stop or take profit at targets'
        },
        warnings: ['Analysis may be incomplete']
      };
    }

    return {
      success: true,
      analysis,
      yahooData,
      srLevels,
      pricePositioning,
      timestamp: new Date().toISOString()
    };

  } catch (error) {
    console.error('Enhanced AI Analysis error:', error);
    return {
      success: false,
      error: error.message,
      analysis: {
        assessment: 'NEUTRAL',
        conviction: 5,
        summary: 'Analysis unavailable',
        keyFactors: [],
        entryStrategy: { primary: 'Wait', triggers: [], invalidates: [] },
        stopLoss: { tight: 'N/A', wide: 'N/A', reasoning: 'N/A' },
        targets: { t1: 'N/A', t2: 'N/A', t3: 'N/A' },
        riskManagement: 'Unable to generate analysis',
        timing: { entry: 'Wait', exit: 'N/A' },
        warnings: ['Analysis unavailable']
      }
    };
  }
}

/**
 * Generate AI analysis for options flow data
 */
export async function generateAIAnalysis(flowData, yahooData = null) {
  try {
    const client = getClient();
    
    // Prepare context from flow data
    const symbol = flowData.symbol_norm || flowData.Symbol || 'UNKNOWN';
    const score = flowData.rocketScore || flowData.rocket_score || 0;
    const netPremium = ((flowData.bull_total || 0) - (flowData.bear_total || 0)) / 1000000;
    const premium = (flowData.premium_num || 0) / 1000000;
    const volume = flowData.vol_num || flowData.Volume || 0;
    const strike = flowData.strike_num || flowData.Strike || 0;
    const spot = flowData.spot_num || flowData.Spot || 0;
    const callPut = flowData.cp_norm || flowData.CallPut || 'UNKNOWN';
    const direction = flowData.direction || (netPremium > 0 ? 'BULL' : 'BEAR');
    const session = flowData.session_bucket || 'RTH';
    const tapeAligned = flowData.tapeAligned || flowData.tape_alignment === 1;
    const catalyst = flowData.near_alert_type || 'None';
    const pctVsRthOpen = flowData.PctVsRthOpen || flowData.pct_vs_rth_open || 0;
    const badges = flowData.badgesRaw?.more || '';
    const isRealMoney = badges?.includes('💎');
    const isHighConviction = badges?.includes('⭐');
    
    // Fetch Yahoo Finance data if not provided
    if (!yahooData) {
      yahooData = await fetchYahooFinanceData(symbol);
    }
    
    // Ensure numeric values for formatting
    const strikeNum = typeof strike === 'number' ? strike : parseFloat(strike) || 0;
    const spotNum = typeof spot === 'number' ? spot : parseFloat(spot) || 0;
    const premiumNum = typeof premium === 'number' ? premium : parseFloat(premium) || 0;
    const netPremiumNum = typeof netPremium === 'number' ? netPremium : parseFloat(netPremium) || 0;
    const scoreNum = typeof score === 'number' ? score : parseFloat(score) || 0;
    const pctVsRthOpenNum = typeof pctVsRthOpen === 'number' ? pctVsRthOpen : parseFloat(pctVsRthOpen) || 0;
    
    // Build prompt
    const prompt = `You are an expert options flow analyst. Analyze this institutional options flow and provide concise, actionable trading insights.

OPTIONS FLOW DATA:
- Symbol: ${symbol}
- Score: ${scoreNum.toFixed(1)}/10
- Net Premium: $${Math.abs(netPremiumNum).toFixed(2)}M (${direction === 'BULL' ? 'Bullish' : 'Bearish'})
- Premium: $${premiumNum.toFixed(2)}M
- Volume: ${volume.toLocaleString()} contracts
- Type: ${callPut}
- Strike: $${strikeNum.toFixed(2)}
- Spot: $${spotNum.toFixed(2)}
- Session: ${session}
- Tape Aligned: ${tapeAligned ? 'Yes' : 'No'}
- Catalyst: ${catalyst}
- Price vs RTH Open: ${pctVsRthOpenNum > 0 ? '+' : ''}${pctVsRthOpenNum.toFixed(2)}%
- Real Money Flow: ${isRealMoney ? 'Yes (💎)' : 'No'}
- High Conviction: ${isHighConviction ? 'Yes (⭐)' : 'No'}

${yahooData ? `STOCK DATA (Yahoo Finance):
- Current Price: $${yahooData.currentPrice?.toFixed(2) || 'N/A'}
- Previous Close: $${yahooData.previousClose?.toFixed(2) || 'N/A'}
- Open: $${yahooData.open?.toFixed(2) || 'N/A'}
- Change: ${yahooData.changePercent > 0 ? '+' : ''}${yahooData.changePercent?.toFixed(2) || '0.00'}%
- Volume: ${yahooData.volume?.toLocaleString() || 'N/A'}
` : ''}

Provide a concise analysis (2-3 sentences max) with:
1. Overall assessment (Bullish/Bearish/Neutral)
2. Key risk factors or opportunities
3. Clear action recommendation (Enter/Wait/Avoid)

Format as JSON:
{
  "assessment": "BULLISH|BEARISH|NEUTRAL",
  "summary": "Brief 1-2 sentence summary",
  "keyFactors": ["factor1", "factor2", "factor3"],
  "recommendation": "ENTER|WAIT|AVOID",
  "reasoning": "Brief explanation",
  "riskLevel": "LOW|MEDIUM|HIGH",
  "timeHorizon": "INTRADAY|SWING|POSITION"
}`;

    // Use model from env or default to stable version
    const modelName = process.env.ANTHROPIC_MODEL || 'claude-sonnet-4-5-20250929';
    
    const message = await client.messages.create({
      model: modelName,
      max_tokens: 500,
      messages: [{
        role: 'user',
        content: prompt
      }]
    });

    // Extract JSON from response
    const responseText = message.content[0].text;
    let analysis;
    
    try {
      // Try to extract JSON from markdown code blocks
      const jsonMatch = responseText.match(/```json\s*([\s\S]*?)\s*```/) || 
                       responseText.match(/```\s*([\s\S]*?)\s*```/) ||
                       [null, responseText];
      const jsonText = jsonMatch[1] || responseText;
      analysis = JSON.parse(jsonText);
    } catch (parseError) {
      // Fallback: create structured response from text
      console.warn('Failed to parse AI response as JSON, using fallback');
      analysis = {
        assessment: direction,
        summary: responseText.substring(0, 200),
        keyFactors: [],
        recommendation: score >= 2.0 ? 'ENTER' : 'WAIT',
        reasoning: responseText,
        riskLevel: score < 2.0 ? 'HIGH' : score < 5.0 ? 'MEDIUM' : 'LOW',
        timeHorizon: 'INTRADAY'
      };
    }

    return {
      success: true,
      analysis,
      yahooData,
      timestamp: new Date().toISOString()
    };

  } catch (error) {
    console.error('AI Analysis error:', error);
    return {
      success: false,
      error: error.message,
      analysis: {
        assessment: 'NEUTRAL',
        summary: 'Analysis unavailable',
        keyFactors: [],
        recommendation: 'WAIT',
        reasoning: 'Unable to generate analysis',
        riskLevel: 'MEDIUM',
        timeHorizon: 'INTRADAY'
      }
    };
  }
}

/**
 * Batch analyze multiple flows (with rate limiting)
 */
export async function batchAIAnalysis(flows, delayMs = 1000) {
  const results = [];
  
  for (let i = 0; i < flows.length; i++) {
    const flow = flows[i];
    try {
      const analysis = await generateAIAnalysis(flow);
      results.push({ flow, analysis });
      
      // Rate limiting between requests
      if (i < flows.length - 1) {
        await new Promise(resolve => setTimeout(resolve, delayMs));
      }
    } catch (error) {
      console.error(`Error analyzing flow ${i}:`, error);
      results.push({ flow, analysis: { success: false, error: error.message } });
    }
  }
  
  return results;
}

