import { PrismaClient } from '@prisma/client'
import { aiAnalysisService, AnalysisResult } from './ai-analysis'
import { enhancedScreenshotService } from './enhanced-screenshot-simple'
import { TradingViewCredentials } from './tradingview-automation'
import { progressTracker, ProgressStatus } from './progress-tracker'
import aggressiveCleanup from './aggressive-cleanup'
import { analysisCompletionFlag } from './analysis-completion-flag'
import priceMonitorService from './price-monitor'

import prisma from '../lib/prisma'
import AILeverageCalculator from './ai-leverage-calculator'
import AIDCAManager from './ai-dca-manager'

export interface AutomationConfig {
  userId: string
  mode: 'SIMULATION' | 'LIVE'
  symbol: string
  timeframe: string
  selectedTimeframes?: string[] // Multi-timeframe support from UI
  tradingAmount: number
  maxLeverage: number
  // stopLossPercent and takeProfitPercent removed - AI calculates these automatically
  maxDailyTrades: number
  riskPercentage: number
  dexProvider?: string // DEX provider (DRIFT or JUPITER)
}

export interface AutomationStatus {
  isActive: boolean
  mode: 'SIMULATION' | 'LIVE'
  symbol: string
  timeframe: string
  totalTrades: number
  successfulTrades: number
  winRate: number
  totalPnL: number
  lastAnalysis?: Date
  lastTrade?: Date
  nextScheduled?: Date
  errorCount: number
  lastError?: string
  nextAnalysisIn?: number // Seconds until next analysis
  analysisInterval?: number // Analysis interval in seconds
  currentCycle?: number // Current automation cycle
}

export class AutomationService {
  private isRunning = false
  protected config: AutomationConfig | null = null
  private intervalId: NodeJS.Timeout | null = null
  private stats = {
    totalTrades: 0,
    successfulTrades: 0,
    winRate: 0,
    totalPnL: 0,
    errorCount: 0,
    lastError: null as string | null
  }

  async startAutomation(config: AutomationConfig): Promise<boolean> {
    try {
      console.log(`🔧 DEBUG: startAutomation called - isRunning: ${this.isRunning}, config exists: ${!!this.config}`)
      
      if (this.isRunning) {
        console.log(`⚠️ DEBUG: Automation already running - rejecting restart attempt`)
        throw new Error('Automation is already running')
      }

      this.config = config
      this.isRunning = true
      
      console.log(`🤖 Starting automation for ${config.symbol} ${config.timeframe} in ${config.mode} mode`)
      
      // Ensure user exists in database
      await prisma.user.upsert({
        where: { id: config.userId },
        update: {},
        create: {
          id: config.userId,
          email: `${config.userId}@example.com`,
          name: config.userId,
          createdAt: new Date(),
          updatedAt: new Date()
        }
      })
      
      // Delete any existing automation session for this user/symbol/timeframe
      await prisma.automationSession.deleteMany({
        where: {
          userId: config.userId,
          symbol: config.symbol,
          timeframe: config.timeframe
        }
      })
      
      // Create new automation session in database
      await prisma.automationSession.create({
        data: {
          userId: config.userId,
          status: 'ACTIVE',
          mode: config.mode,
          symbol: config.symbol,
          timeframe: config.timeframe,
          settings: {
            tradingAmount: config.tradingAmount,
            maxLeverage: config.maxLeverage,
            // stopLossPercent and takeProfitPercent removed - AI calculates these automatically
            maxDailyTrades: config.maxDailyTrades,
            selectedTimeframes: config.selectedTimeframes,
            riskPercentage: config.riskPercentage
          },
          startBalance: config.tradingAmount,
          currentBalance: config.tradingAmount,
          createdAt: new Date(),
          updatedAt: new Date()
        }
      })

      // Start automation cycle
      // Start automation cycle (price-based if positions exist, time-based if not)
      await this.startAutomationCycle()
      
      // Start price monitoring
      await priceMonitorService.startMonitoring()
      
      // Set up price monitor event listeners for automatic analysis triggering
      priceMonitorService.on('tp_approach', async (data) => {
        if (data.symbol === this.config?.symbol) {
          console.log(`🎯 TP approach detected for ${data.symbol}, triggering analysis...`)
          await this.triggerPriceBasedAnalysis('TP_APPROACH', data)
        }
      })
      
      priceMonitorService.on('sl_approach', async (data) => {
        if (data.symbol === this.config?.symbol) {
          console.log(`⚠️ SL approach detected for ${data.symbol}, triggering analysis...`)
          await this.triggerPriceBasedAnalysis('SL_APPROACH', data)
        }
      })
      
      priceMonitorService.on('critical_level', async (data) => {
        if (data.symbol === this.config?.symbol) {
          console.log(`🚨 Critical level reached for ${data.symbol}, triggering urgent analysis...`)
          await this.triggerPriceBasedAnalysis('CRITICAL', data)
        }
      })
      
      return true
    } catch (error) {
      console.error('Failed to start automation:', error)
      this.stats.errorCount++
      this.stats.lastError = error instanceof Error ? error.message : 'Unknown error'
      return false
    }
  }

  private async startAutomationCycle(): Promise<void> {
    if (!this.config) return

    // Check if we have open positions - if so, only use price-based triggers
    const hasPositions = await this.hasOpenPositions()
    if (hasPositions) {
      console.log(`📊 Open positions detected for ${this.config.symbol} - switching to price-proximity mode only`)
      console.log(`🎯 Automation will only trigger on SL/TP approach or critical levels`)
      // Don't start time-based cycles when positions exist
      // Price monitor events (sl_approach, tp_approach, critical_level) are already set up
      return
    }

    // No positions - start normal time-based automation cycle
    const intervalMs = this.getIntervalFromTimeframe(this.config.timeframe)
    
    console.log(`🔄 Starting automation cycle every ${intervalMs/1000} seconds`)
    
    this.intervalId = setInterval(async () => {
      if (this.isRunning && this.config) {
        // Double-check positions before each cycle
        const stillHasPositions = await this.hasOpenPositions()
        if (stillHasPositions) {
          console.log(`📊 Positions opened during automation - stopping time-based cycles`)
          this.stopTimeCycles()
          return
        }
        await this.runAutomationCycle()
      }
    }, intervalMs)

    // Run first cycle immediately
    this.runAutomationCycle()
  }

  private stopTimeCycles(): void {
    if (this.intervalId) {
      clearInterval(this.intervalId)
      this.intervalId = null
      console.log('⏸️ Time-based automation cycles stopped - now in price-proximity mode only')
    }
  }

  private getIntervalFromTimeframe(timeframe: string): number {
    // Check if this is a scalping strategy (multiple short timeframes)
    if (this.config?.selectedTimeframes) {
      const timeframes = this.config.selectedTimeframes
      const isScalping = timeframes.includes('5') || timeframes.includes('3') || (timeframes.length > 1 && timeframes.every((tf: string) => ['1', '3', '5', '15', '30'].includes(tf)))
      if (isScalping) {
        console.log('🎯 Scalping strategy detected - using frequent analysis (2-3 minutes)')
        return 2 * 60 * 1000 // 2 minutes for scalping
      }
      
      // Day trading strategy (short-medium timeframes)
      const isDayTrading = timeframes.includes('60') || timeframes.includes('120') ||
                          timeframes.some(tf => ['30', '60', '120'].includes(tf))
      
      if (isDayTrading) {
        console.log('⚡ Day trading strategy detected - using moderate analysis (5-10 minutes)')
        return 5 * 60 * 1000 // 5 minutes for day trading
      }
      
      // Swing trading (longer timeframes)
      const isSwingTrading = timeframes.includes('240') || timeframes.includes('D') ||
                            timeframes.some(tf => ['240', '480', 'D', '1d'].includes(tf))
      
      if (isSwingTrading) {
        console.log('🎯 Swing trading strategy detected - using standard analysis (15-30 minutes)')
        return 15 * 60 * 1000 // 15 minutes for swing trading
      }
    }

    // Fallback to timeframe-based intervals
    const intervals: { [key: string]: number } = {
      '1m': 60 * 1000,
      '3m': 3 * 60 * 1000,
      '5m': 5 * 60 * 1000,
      '15m': 15 * 60 * 1000,
      '30m': 30 * 60 * 1000,
      '1h': 60 * 60 * 1000,
      '2h': 2 * 60 * 60 * 1000,
      '4h': 4 * 60 * 60 * 1000,
      '1d': 24 * 60 * 60 * 1000
    }
    
    return intervals[timeframe] || intervals['1h'] // Default to 1 hour
  }

  private async runAutomationCycle(): Promise<void> {
    // Check if automation should still be running
    if (!this.isRunning || !this.config) {
      console.log('🛑 Automation cycle stopped - isRunning:', this.isRunning, 'config:', !!this.config)
      return
    }

    try {
      console.log(`🔍 Running automation cycle for ${this.config.symbol} ${this.config.timeframe}`)
      
      // Update next scheduled time in database for timer display
      const intervalMs = this.getIntervalFromTimeframe(this.config.timeframe)
      const nextScheduled = new Date(Date.now() + intervalMs)
      
      try {
        await prisma.automationSession.updateMany({
          where: { 
            userId: this.config.userId,
            status: 'ACTIVE'
          },
          data: { 
            nextScheduled: nextScheduled,
            lastAnalysis: new Date()
          }
        })
        console.log(`⏰ Next analysis scheduled for: ${nextScheduled.toLocaleTimeString()}`)
      } catch (dbError) {
        console.error('Failed to update next scheduled time:', dbError)
      }
      
      // Step 1: Check for open positions first - DON'T analyze if positions exist unless DCA is needed
      const hasPositions = await this.hasOpenPositions()
      if (hasPositions) {
        console.log(`📊 Open position detected for ${this.config.symbol}, checking for DCA only`)
        
        // Only check for DCA opportunities on existing positions
        const dcaOpportunity = await this.checkForDCAOpportunity()
        if (dcaOpportunity.shouldDCA) {
          console.log('🔄 DCA opportunity found, executing position scaling')
          await this.executeDCA(dcaOpportunity)
          await this.runPostCycleCleanup('dca_executed')
        } else {
          console.log('📊 Position monitoring only - no new analysis needed')
          await this.runPostCycleCleanup('position_monitoring_only')
        }
        return
      }

      // Step 2: Check daily trade limit - DISABLED (no limits needed)
      // const todayTrades = await this.getTodayTradeCount(this.config.userId)
      // if (todayTrades >= this.config.maxDailyTrades) {
      //   console.log(`📊 Daily trade limit reached (${todayTrades}/${this.config.maxDailyTrades})`)
      //   // Run cleanup even when trade limit is reached
      //   await this.runPostCycleCleanup('trade_limit_reached')
      //   return
      // }

      // Step 3: Take screenshot and analyze with error handling
      console.log('📊 Performing analysis...')
      const analysisResult = await this.performAnalysis()
      if (!analysisResult) {
        console.log('❌ Analysis failed, skipping cycle')
        console.log(`⏰ Next analysis in ${this.getIntervalFromTimeframe(this.config.timeframe)/1000} seconds`)
        // Run cleanup when analysis fails
        await this.runPostCycleCleanup('analysis_failed')
        return
      }

      // Step 3: Store analysis for learning
      await this.storeAnalysisForLearning(analysisResult)

      // Step 4: Update session with latest analysis
      await this.updateSessionWithAnalysis(analysisResult)

      // Step 5: Make trading decision
      const tradeDecision = await this.makeTradeDecision(analysisResult)
      if (!tradeDecision) {
        console.log('📊 No trading opportunity found')
        // Run cleanup when no trading opportunity
        await this.runPostCycleCleanup('no_opportunity')
        return
      }

      // Step 6: Execute trade
      await this.executeTrade(tradeDecision)
      
      // Run cleanup after successful trade execution
      await this.runPostCycleCleanup('trade_executed')

    } catch (error) {
      console.error('Error in automation cycle:', error)
      this.stats.errorCount++
      this.stats.lastError = error instanceof Error ? error.message : 'Unknown error'
      
      // Run cleanup on error
      await this.runPostCycleCleanup('error')
    }
  }

  private async runPostCycleCleanup(reason: string): Promise<void> {
    console.log(`🧹 Running post-cycle cleanup (reason: ${reason})`)
    
    // Longer delay to ensure all analysis processes AND trading decision have finished
    await new Promise(resolve => setTimeout(resolve, 10000)) // 10 seconds
    
    try {
      // Use the new post-analysis cleanup that respects completion flags
      await aggressiveCleanup.runPostAnalysisCleanup()
      console.log(`✅ Post-cycle cleanup completed for: ${reason}`)
    } catch (error) {
      console.error('Error in post-cycle cleanup:', error)
    }
  }

  private async performAnalysis(): Promise<{
    screenshots: string[]
    analysis: AnalysisResult | null
  } | null> {
    // Generate unique session ID for this analysis
    const sessionId = `automation-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`
    
    // Mark the start of analysis cycle to prevent cleanup interruption
    analysisCompletionFlag.startAnalysisCycle(sessionId)
    
    try {
      console.log(`📸 Starting multi-timeframe analysis with dual layouts... (Session: ${sessionId})`)
      
      // Create progress tracking session
      const progressSteps = [
        { id: 'init', title: 'Initialize', description: 'Starting multi-timeframe analysis', status: 'pending' as const },
        { id: 'capture', title: 'Capture', description: 'Capturing screenshots for all timeframes', status: 'pending' as const },
        { id: 'analysis', title: 'Analysis', description: 'Running AI analysis on screenshots', status: 'pending' as const },
        { id: 'complete', title: 'Complete', description: 'Analysis complete', status: 'pending' as const }
      ]
      
      progressTracker.createSession(sessionId, progressSteps)
      progressTracker.updateStep(sessionId, 'init', 'active', 'Starting multi-timeframe analysis...')
      
      // Use selected timeframes from UI, fallback to default if not provided
      const timeframes = this.config!.selectedTimeframes || ['1h']
      const symbol = this.config!.symbol
      
      console.log(`🔍 Analyzing ${symbol} across timeframes: ${timeframes.join(', ')} with AI + DIY layouts`)
      
      progressTracker.updateStep(sessionId, 'init', 'completed', `Starting analysis for ${timeframes.length} timeframes`)
      progressTracker.updateStep(sessionId, 'capture', 'active', 'Capturing screenshots...')
      
      // Analyze each timeframe with both AI and DIY layouts
      const multiTimeframeResults = await this.analyzeMultiTimeframeWithDualLayouts(symbol, timeframes, sessionId)
      
      // Check if all analyses failed (browser automation issues)
      const validResults = multiTimeframeResults.filter(result => result.analysis !== null)
      
      if (validResults.length === 0) {
        console.log('❌ All timeframe analyses failed - likely browser automation failure')
        console.log(`⏰ Browser automation issues detected - next analysis in ${this.getIntervalFromTimeframe(this.config!.timeframe)/1000} seconds`)
        progressTracker.updateStep(sessionId, 'capture', 'error', 'Browser automation failed - will retry on next cycle')
        progressTracker.deleteSession(sessionId)
        // Mark analysis as complete to allow cleanup
        analysisCompletionFlag.markAnalysisComplete(sessionId)
        return null
      }
      
      progressTracker.updateStep(sessionId, 'capture', 'completed', `Captured ${validResults.length} timeframe analyses`)
      progressTracker.updateStep(sessionId, 'analysis', 'active', 'Processing multi-timeframe results...')
      
      // Process and combine multi-timeframe results using valid results only
      const combinedResult = this.combineMultiTimeframeAnalysis(validResults)
      
      if (!combinedResult.analysis) {
        console.log('❌ Failed to combine multi-timeframe analysis')
        progressTracker.updateStep(sessionId, 'analysis', 'error', 'Failed to combine analysis results')
        progressTracker.deleteSession(sessionId)
        // Mark analysis as complete to allow cleanup
        analysisCompletionFlag.markAnalysisComplete(sessionId)
        return null
      }

      console.log(`✅ Multi-timeframe analysis completed: ${combinedResult.analysis.recommendation} with ${combinedResult.analysis.confidence}% confidence`)
      console.log(`📊 Timeframe alignment: ${this.analyzeTimeframeAlignment(multiTimeframeResults)}`)
      
      progressTracker.updateStep(sessionId, 'analysis', 'completed', `Analysis complete: ${combinedResult.analysis.recommendation}`)
      progressTracker.updateStep(sessionId, 'complete', 'completed', 'Multi-timeframe analysis finished')
      
      // Clean up session after successful completion
      setTimeout(() => {
        progressTracker.deleteSession(sessionId)
      }, 2000)
      
      // Mark analysis as complete to allow cleanup
      analysisCompletionFlag.markAnalysisComplete(sessionId)
      
      return combinedResult
      
    } catch (error) {
      console.error('Error performing multi-timeframe analysis:', error)
      progressTracker.updateStep(sessionId, 'analysis', 'error', error instanceof Error ? error.message : 'Unknown error')
      setTimeout(() => {
        progressTracker.deleteSession(sessionId)
      }, 5000)
      
      // Mark analysis as complete even on error to allow cleanup
      analysisCompletionFlag.markAnalysisComplete(sessionId)
      
      return null
    }
  }

  private async analyzeMultiTimeframeWithDualLayouts(
    symbol: string, 
    timeframes: string[],
    sessionId: string
  ): Promise<Array<{ symbol: string; timeframe: string; analysis: AnalysisResult | null }>> {
    const results: Array<{ symbol: string; timeframe: string; analysis: AnalysisResult | null }> = []

    for (let i = 0; i < timeframes.length; i++) {
      const timeframe = timeframes[i]
      try {
        console.log(`📊 Analyzing ${symbol} ${timeframe} with AI + DIY layouts... (${i + 1}/${timeframes.length})`)
        
        // Update progress for timeframe
        progressTracker.updateTimeframeProgress(sessionId, i + 1, timeframes.length, timeframe)
        
        // Use the dual-layout configuration for each timeframe
        const screenshotConfig = {
          symbol: symbol,
          timeframe: timeframe,
          layouts: ['ai', 'diy'],
          sessionId: sessionId
        }

        const result = await aiAnalysisService.captureAndAnalyzeWithConfig(screenshotConfig)
        
        if (result.analysis) {
          console.log(`✅ ${timeframe} analysis: ${result.analysis.recommendation} (${result.analysis.confidence}% confidence)`)
          results.push({
            symbol,
            timeframe,
            analysis: result.analysis
          })
        } else {
          console.log(`❌ ${timeframe} analysis failed`)
          results.push({
            symbol,
            timeframe,
            analysis: null
          })
        }

        // Small delay between captures to avoid overwhelming the system
        await new Promise(resolve => setTimeout(resolve, 3000))

      } catch (error) {
        console.error(`Failed to analyze ${symbol} ${timeframe}:`, error)
        results.push({
          symbol,
          timeframe,
          analysis: null
        })
      }
    }

    return results
  }

  private combineMultiTimeframeAnalysis(results: Array<{ symbol: string; timeframe: string; analysis: AnalysisResult | null }>): {
    screenshots: string[]
    analysis: AnalysisResult | null
  } {
    const validResults = results.filter(r => r.analysis !== null)
    
    if (validResults.length === 0) {
      return { screenshots: [], analysis: null }
    }

    // Get the primary timeframe (first selected or default) as base
    const selectedTimeframes = this.config!.selectedTimeframes || ['1h']
    const primaryTimeframe = selectedTimeframes[0] || '1h'
    const primaryResult = validResults.find(r => r.timeframe === primaryTimeframe) || validResults[0]
    const screenshots = validResults.length > 0 ? [primaryResult.timeframe] : []

    // Calculate weighted confidence based on timeframe alignment
    const alignment = this.calculateTimeframeAlignment(validResults)
    const baseAnalysis = primaryResult.analysis!

    // Adjust confidence based on timeframe alignment
    const adjustedConfidence = Math.round(baseAnalysis.confidence * alignment.score)

    // Create combined analysis with multi-timeframe reasoning
    const combinedAnalysis: AnalysisResult = {
      ...baseAnalysis,
      confidence: adjustedConfidence,
      reasoning: `Multi-timeframe Dual-Layout Analysis (${results.map(r => r.timeframe).join(', ')}): ${baseAnalysis.reasoning}
      
📊 Each timeframe analyzed with BOTH AI layout (RSI, MACD, EMAs) and DIY layout (Stochastic RSI, VWAP, OBV)
⏱️ Timeframe Alignment: ${alignment.description}
� Signal Strength: ${alignment.strength}
🎯 Confidence Adjustment: ${baseAnalysis.confidence}% → ${adjustedConfidence}% (${alignment.score >= 1 ? 'Enhanced' : 'Reduced'} due to timeframe ${alignment.score >= 1 ? 'alignment' : 'divergence'})
      
🔬 Analysis Details:
${validResults.map(r => `• ${r.timeframe}: ${r.analysis?.recommendation} (${r.analysis?.confidence}% confidence)`).join('\n')}`,
      
      keyLevels: this.consolidateKeyLevels(validResults),
      marketSentiment: this.consolidateMarketSentiment(validResults)
    }

    return {
      screenshots,
      analysis: combinedAnalysis
    }
  }

  private calculateTimeframeAlignment(results: Array<{ symbol: string; timeframe: string; analysis: AnalysisResult | null }>): {
    score: number
    description: string
    strength: string
  } {
    const recommendations = results.map(r => r.analysis?.recommendation).filter(Boolean)
    const buySignals = recommendations.filter(r => r === 'BUY').length
    const sellSignals = recommendations.filter(r => r === 'SELL').length
    const holdSignals = recommendations.filter(r => r === 'HOLD').length
    
    const total = recommendations.length
    const maxSignals = Math.max(buySignals, sellSignals, holdSignals)
    const alignmentRatio = maxSignals / total

    let score = 1.0
    let description = ''
    let strength = ''

    if (alignmentRatio >= 0.75) {
      score = 1.2 // Boost confidence
      description = `Strong alignment (${maxSignals}/${total} timeframes agree)`
      strength = 'Strong'
    } else if (alignmentRatio >= 0.5) {
      score = 1.0 // Neutral
      description = `Moderate alignment (${maxSignals}/${total} timeframes agree)`
      strength = 'Moderate'
    } else {
      score = 0.8 // Reduce confidence
      description = `Weak alignment (${maxSignals}/${total} timeframes agree)`
      strength = 'Weak'
    }

    return { score, description, strength }
  }

  private consolidateKeyLevels(results: Array<{ symbol: string; timeframe: string; analysis: AnalysisResult | null }>): any {
    const allLevels = results.map(r => r.analysis?.keyLevels).filter(Boolean)
    if (allLevels.length === 0) return {}

    // Use the primary timeframe levels (first selected) as primary, or first available
    const selectedTimeframes = this.config!.selectedTimeframes || ['1h']
    const primaryTimeframe = selectedTimeframes[0] || '1h'
    const primaryLevels = results.find(r => r.timeframe === primaryTimeframe)?.analysis?.keyLevels || allLevels[0]
    
    return {
      ...primaryLevels,
      note: `Consolidated from ${allLevels.length} timeframes`
    }
  }

  private consolidateMarketSentiment(results: Array<{ symbol: string; timeframe: string; analysis: AnalysisResult | null }>): 'BULLISH' | 'BEARISH' | 'NEUTRAL' {
    const sentiments = results.map(r => r.analysis?.marketSentiment).filter(Boolean)
    if (sentiments.length === 0) return 'NEUTRAL'

    // Use the primary timeframe sentiment (first selected) as primary, or first available
    const selectedTimeframes = this.config!.selectedTimeframes || ['1h']
    const primaryTimeframe = selectedTimeframes[0] || '1h'
    const primarySentiment = results.find(r => r.timeframe === primaryTimeframe)?.analysis?.marketSentiment || sentiments[0]
    
    return primarySentiment || 'NEUTRAL'
  }

  private analyzeTimeframeAlignment(results: Array<{ symbol: string; timeframe: string; analysis: AnalysisResult | null }>): string {
    const recommendations = results.map(r => ({
      timeframe: r.timeframe,
      recommendation: r.analysis?.recommendation,
      confidence: r.analysis?.confidence || 0
    }))

    const summary = recommendations.map(r => `${r.timeframe}: ${r.recommendation} (${r.confidence}%)`).join(', ')
    return summary
  }

  private async storeAnalysisForLearning(result: {
    screenshots: string[]
    analysis: AnalysisResult | null
  }): Promise<void> {
    try {
      if (!result.analysis) return
      
      await prisma.aILearningData.create({
        data: {
          userId: this.config!.userId,
          symbol: this.config!.symbol,
          timeframe: this.config!.timeframe,
          screenshot: result.screenshots[0] || '',
          analysisData: JSON.stringify(result.analysis),
          marketConditions: JSON.stringify({
            marketSentiment: result.analysis.marketSentiment,
            keyLevels: result.analysis.keyLevels,
            timestamp: new Date().toISOString()
          }),
          confidenceScore: result.analysis.confidence,
          createdAt: new Date()
        }
      })
    } catch (error) {
      console.error('Error storing analysis for learning:', error)
    }
  }

  private async updateSessionWithAnalysis(result: {
    screenshots: string[]
    analysis: AnalysisResult | null
  }): Promise<void> {
    try {
      if (!result.analysis) return
      
      // Store the analysis decision in a field that works for now
      const analysisDecision = `${result.analysis.recommendation} with ${result.analysis.confidence}% confidence - ${result.analysis.summary}`
      
      // Update the current session with the latest analysis
      await prisma.automationSession.updateMany({
        where: {
          userId: this.config!.userId,
          symbol: this.config!.symbol,
          timeframe: this.config!.timeframe,
          status: 'ACTIVE'
        },
        data: {
          lastAnalysis: new Date(),
          lastError: analysisDecision // Temporarily store analysis here
        }
      })

      // Also log the analysis for debugging
      console.log('📊 Analysis stored in database:', {
        recommendation: result.analysis.recommendation,
        confidence: result.analysis.confidence,
        summary: result.analysis.summary
      })
    } catch (error) {
      console.error('Failed to update session with analysis:', error)
    }
  }

  private async makeTradeDecision(result: {
    screenshots: string[]
    analysis: AnalysisResult | null
  }): Promise<any | null> {
    try {
      const analysis = result.analysis
      if (!analysis) return null
      
      // Only trade if confidence is high enough
      if (analysis.confidence < 70) {
        console.log(`📊 Confidence too low: ${analysis.confidence}%`)
        return null
      }

      // Only trade if direction is clear
      if (analysis.recommendation === 'HOLD') {
        console.log('📊 No clear direction signal')
        return null
      }

      // ✅ ENHANCED: Support both BUY and SELL signals
      if (analysis.recommendation === 'SELL') {
        // Check if we have SOL position to sell
        const hasPosition = await this.checkCurrentPosition()
        if (!hasPosition) {
          console.log('📊 SELL signal but no SOL position to sell - skipping')
          return null
        }
        console.log('📉 SELL signal detected with existing SOL position')
      } else if (analysis.recommendation === 'BUY') {
        console.log('📈 BUY signal detected')
      }

      // Calculate AI-driven position size with optimal leverage
      const positionResult = await this.calculatePositionSize(analysis)

      return {
        direction: analysis.recommendation,
        confidence: analysis.confidence,
        positionSize: positionResult.tokenAmount,
        leverageUsed: positionResult.leverageUsed,
        marginRequired: positionResult.marginRequired,
        liquidationPrice: positionResult.liquidationPrice,
        riskAssessment: positionResult.riskAssessment,
        stopLoss: this.calculateStopLoss(analysis),
        takeProfit: this.calculateTakeProfit(analysis),
        marketSentiment: analysis.marketSentiment,
        currentPrice: analysis.entry?.price || 190 // Store current price for calculations
      }
      
    } catch (error) {
      console.error('Error making trade decision:', error)
      return null
    }
  }

  // ✅ NEW: Check if we have SOL position available to sell
  private async checkCurrentPosition(): Promise<boolean> {
    try {
      // Check actual Drift positions instead of database records
      const response = await fetch('http://localhost:3000/api/drift/positions')
      if (!response.ok) {
        console.error('Failed to fetch Drift positions:', response.statusText)
        return false
      }
      
      const data = await response.json()
      const positions = data.positions || []
      
      // Check if we have any positions for our symbol
      const symbolPositions = positions.filter((pos: any) => {
        const marketSymbol = pos.marketSymbol || pos.market?.symbol || ''
        return marketSymbol.includes(this.config!.symbol.replace('USD', ''))
      })

      console.log(`🔍 Current ${this.config!.symbol} positions: ${symbolPositions.length}`)
      if (symbolPositions.length > 0) {
        symbolPositions.forEach((pos: any) => {
          console.log(`� Position: ${pos.marketSymbol} ${pos.side} ${pos.baseAssetAmount} @ $${pos.entryPrice}`)
        })
      }

      return symbolPositions.length > 0
      
    } catch (error) {
      console.error('❌ Error checking current Drift position:', error)
      // If we can't check, default to allowing the trade (fail-safe)
      return true
    }
  }

  private async calculatePositionSize(analysis: any): Promise<{
    tokenAmount: number
    leverageUsed: number
    marginRequired: number
    liquidationPrice: number
    riskAssessment: string
  }> {
    console.log('🧠 AI Position Sizing with Dynamic Leverage Calculation...')
    
    // ✅ ENHANCED: Handle SELL positions with AI leverage for shorting
    if (analysis.recommendation === 'SELL') {
      return await this.calculateSellPositionWithLeverage(analysis)
    }
    
    // Get account balance
    const balanceResponse = await fetch(`${process.env.NEXT_PUBLIC_API_URL || 'http://localhost:3000'}/api/drift/balance`)
    const balanceData = await balanceResponse.json()
    
    if (!balanceData.success) {
      throw new Error('Could not fetch account balance for position sizing')
    }

    const accountValue = balanceData.accountValue || balanceData.totalCollateral
    const availableBalance = balanceData.availableBalance
    
    console.log(`💰 Account Status: Value=$${accountValue.toFixed(2)}, Available=$${availableBalance.toFixed(2)}`)

    // Get current price for entry
    let currentPrice = analysis.entry?.price || analysis.currentPrice
    
    if (!currentPrice) {
      try {
        const { default: PriceFetcher } = await import('./price-fetcher')
        currentPrice = await PriceFetcher.getCurrentPrice(this.config?.symbol || 'SOLUSD')
        console.log(`📊 Using current ${this.config?.symbol || 'SOLUSD'} price: $${currentPrice}`)
      } catch (error) {
        console.error('Error fetching price for position sizing, using fallback:', error)
        currentPrice = this.config?.symbol === 'SOLUSD' ? 189 : 100
      }
    }

    // Calculate stop loss price from analysis
    const stopLossPercent = this.calculateAIStopLoss(analysis) / 100
    const direction = analysis.recommendation === 'BUY' ? 'long' : 'short'
    
    let stopLossPrice: number
    if (direction === 'long') {
      stopLossPrice = currentPrice * (1 - stopLossPercent)
    } else {
      stopLossPrice = currentPrice * (1 + stopLossPercent)  
    }

    console.log(`🎯 Position Parameters: Entry=$${currentPrice}, StopLoss=$${stopLossPrice.toFixed(4)}, Direction=${direction}`)

    // Use AI Leverage Calculator for optimal leverage
    const leverageResult = AILeverageCalculator.calculateOptimalLeverage({
      accountValue,
      availableBalance,
      entryPrice: currentPrice,
      stopLossPrice,
      side: direction,
      maxLeverageAllowed: this.config!.maxLeverage || 20, // Platform max leverage
      safetyBuffer: 0.10 // 10% safety buffer between liquidation and stop loss
    })

    // Calculate final position size
    const baseAmount = accountValue < 1000 ? availableBalance : availableBalance * 0.5
    const leveragedAmount = baseAmount * leverageResult.recommendedLeverage
    const tokenAmount = leveragedAmount / currentPrice

    console.log(`� AI Position Result:`, {
      baseAmount: `$${baseAmount.toFixed(2)}`,
      leverage: `${leverageResult.recommendedLeverage.toFixed(1)}x`,
      leveragedAmount: `$${leveragedAmount.toFixed(2)}`,
      tokenAmount: tokenAmount.toFixed(4),
      riskLevel: leverageResult.riskAssessment,
      reasoning: leverageResult.reasoning
    })

    return {
      tokenAmount,
      leverageUsed: leverageResult.recommendedLeverage,
      marginRequired: leverageResult.marginRequired,
      liquidationPrice: leverageResult.liquidationPrice,
      riskAssessment: leverageResult.riskAssessment
    }
  }

  // ✅ NEW: Calculate SOL amount to sell for SELL orders
  private async calculateSellAmount(analysis: any): Promise<number> {
    try {
      // Get current SOL holdings from recent open trades
      const openTrades = await prisma.trade.findMany({
        where: {
          userId: this.config!.userId,
          symbol: this.config!.symbol,
          status: 'OPEN',
          side: 'BUY' // Only BUY trades represent SOL holdings
        },
        orderBy: { createdAt: 'desc' }
      })

      let totalSOLHoldings = 0
      for (const trade of openTrades) {
        totalSOLHoldings += trade.amount
      }

      // Risk-adjusted sell amount (don't sell everything at once)
      const riskAdjustment = this.config!.riskPercentage / 100
      const confidenceAdjustment = analysis.confidence / 100
      const sellAmount = totalSOLHoldings * riskAdjustment * confidenceAdjustment

      console.log(`💰 SELL Position calculation: ${totalSOLHoldings.toFixed(4)} SOL holdings × ${(riskAdjustment * confidenceAdjustment * 100).toFixed(1)}% = ${sellAmount.toFixed(4)} SOL to sell`)
      
      return Math.max(sellAmount, 0.001) // Minimum 0.001 SOL
      
    } catch (error) {
      console.error('❌ Error calculating sell amount:', error)
      return 0.01 // Fallback: sell 0.01 SOL
    }
  }

  // ✅ NEW: Calculate leveraged short position for SELL orders
  private async calculateSellPositionWithLeverage(analysis: any): Promise<{
    tokenAmount: number
    leverageUsed: number
    marginRequired: number
    liquidationPrice: number
    riskAssessment: string
  }> {
    try {
      console.log('📉 Calculating SELL position with AI leverage...')
      
      // Get account balance for leverage calculation
      const balanceResponse = await fetch(`${process.env.NEXT_PUBLIC_API_URL || 'http://localhost:3000'}/api/drift/balance`)
      const balanceData = await balanceResponse.json()
      
      const accountValue = balanceData.accountValue || balanceData.totalCollateral
      const availableBalance = balanceData.availableBalance

      // Get current price
      let currentPrice = analysis.entry?.price || analysis.currentPrice
      if (!currentPrice) {
        const { default: PriceFetcher } = await import('./price-fetcher')
        currentPrice = await PriceFetcher.getCurrentPrice(this.config?.symbol || 'SOLUSD')
      }

      // Calculate stop loss for short position (above entry price)
      const stopLossPercent = this.calculateAIStopLoss(analysis) / 100
      const stopLossPrice = currentPrice * (1 + stopLossPercent)

      console.log(`🎯 SHORT Position Parameters: Entry=$${currentPrice}, StopLoss=$${stopLossPrice.toFixed(4)}`)

      // Use AI leverage for short position
      const leverageResult = AILeverageCalculator.calculateOptimalLeverage({
        accountValue,
        availableBalance,
        entryPrice: currentPrice,
        stopLossPrice,
        side: 'short',
        maxLeverageAllowed: this.config!.maxLeverage || 20,
        safetyBuffer: 0.10
      })

      // Calculate leveraged short amount
      const baseAmount = accountValue < 1000 ? availableBalance : availableBalance * 0.5
      const leveragedAmount = baseAmount * leverageResult.recommendedLeverage
      const tokenAmount = leveragedAmount / currentPrice

      console.log(`📉 SELL Position with AI Leverage:`, {
        baseAmount: `$${baseAmount.toFixed(2)}`,
        leverage: `${leverageResult.recommendedLeverage.toFixed(1)}x`,
        leveragedAmount: `$${leveragedAmount.toFixed(2)}`,
        tokenAmount: tokenAmount.toFixed(4),
        riskLevel: leverageResult.riskAssessment,
        reasoning: leverageResult.reasoning
      })

      return {
        tokenAmount,
        leverageUsed: leverageResult.recommendedLeverage,
        marginRequired: leverageResult.marginRequired,
        liquidationPrice: leverageResult.liquidationPrice,
        riskAssessment: leverageResult.riskAssessment
      }

    } catch (error) {
      console.error('Error calculating SELL position with leverage:', error)
      return {
        tokenAmount: 0.01, // Fallback small amount
        leverageUsed: 1,
        marginRequired: 0,
        liquidationPrice: 0,
        riskAssessment: 'HIGH'
      }
    }
  }

  private calculateStopLoss(analysis: any): number {
    // ✅ AI-FIRST: Use AI analysis stopLoss if available
    if (analysis.stopLoss?.price) {
      const currentPrice = analysis.entry?.price || 189
      const stopLossPrice = analysis.stopLoss.price
      
      // Convert absolute price to percentage
      if (analysis.recommendation === 'BUY') {
        return ((currentPrice - stopLossPrice) / currentPrice) * 100
      } else if (analysis.recommendation === 'SELL') {
        return ((stopLossPrice - currentPrice) / currentPrice) * 100
      }
    }
    
    // If AI provides explicit stop loss percentage, use it
    if (analysis.stopLossPercent) {
      return analysis.stopLossPercent
    }
    
    // Fallback: Dynamic stop loss based on market volatility (AI-calculated)
    // AI determines volatility-based stop loss (0.5% to 2% range)
    return this.calculateAIStopLoss(analysis)
  }

  private calculateTakeProfit(analysis: any): number {
    // ✅ AI-FIRST: Use AI analysis takeProfit if available
    if (analysis.takeProfits?.tp1?.price) {
      const currentPrice = analysis.entry?.price || 150
      const takeProfitPrice = analysis.takeProfits.tp1.price
      
      // Convert absolute price to percentage
      if (analysis.recommendation === 'BUY') {
        return ((takeProfitPrice - currentPrice) / currentPrice) * 100
      } else if (analysis.recommendation === 'SELL') {
        return ((currentPrice - takeProfitPrice) / currentPrice) * 100
      }
    }
    
    // If AI provides explicit take profit percentage, use it
    if (analysis.takeProfitPercent) {
      return analysis.takeProfitPercent
    }
    
    // Fallback: Dynamic take profit based on AI risk/reward optimization
    return this.calculateAITakeProfit(analysis)
  }

  // AI-calculated dynamic stop loss based on volatility and market conditions
  private calculateAIStopLoss(analysis: any): number {
    // Extract confidence and market sentiment for adaptive stop loss
    const confidence = analysis.confidence || 70
    const volatility = analysis.marketConditions?.volatility || 'MEDIUM'
    
    // Base stop loss percentages (proven to work from our testing)
    let baseStopLoss = 0.8 // 0.8% base (proven effective)
    
    // Adjust based on volatility
    if (volatility === 'HIGH') {
      baseStopLoss = 1.2 // Wider stop loss for high volatility
    } else if (volatility === 'LOW') {
      baseStopLoss = 0.5 // Tighter stop loss for low volatility
    }
    
    // Adjust based on confidence (higher confidence = tighter stop loss)
    if (confidence > 85) {
      baseStopLoss *= 0.8 // 20% tighter for high confidence
    } else if (confidence < 70) {
      baseStopLoss *= 1.3 // 30% wider for low confidence
    }
    
    return Math.max(0.3, Math.min(2.0, baseStopLoss)) // Cap between 0.3% and 2%
  }

  // AI-calculated dynamic take profit based on market conditions and risk/reward
  private calculateAITakeProfit(analysis: any): number {
    const stopLossPercent = this.calculateAIStopLoss(analysis)
    const confidence = analysis.confidence || 70
    
    // Target minimum 1.5:1 risk/reward ratio, scaled by confidence
    let baseRiskReward = 1.5
    
    if (confidence > 85) {
      baseRiskReward = 2.0 // Higher reward target for high confidence
    } else if (confidence < 70) {
      baseRiskReward = 1.2 // Lower reward target for low confidence
    }
    
    const takeProfitPercent = stopLossPercent * baseRiskReward
    return Math.max(0.5, Math.min(5.0, takeProfitPercent)) // Cap between 0.5% and 5%
  }

  private async executeTrade(decision: any): Promise<void> {
    try {
      console.log(`🎯 Executing ${this.config!.mode} trade: ${decision.direction} ${decision.positionSize} ${this.config!.symbol}`)
      
      let tradeResult: any
      
      if (this.config!.mode === 'SIMULATION') {
        // Execute simulation trade
        tradeResult = await this.executeSimulationTrade(decision)
      } else {
        // Execute live trade via Drift Protocol
        console.log(`💰 LIVE TRADE: $${this.config!.tradingAmount} trading amount configured`)
        tradeResult = await this.executeLiveTrade(decision)
        
        // If live trade failed, fall back to simulation for data consistency
        if (!tradeResult || !tradeResult.success) {
          console.log('⚠️ Live trade failed, falling back to simulation for record keeping')
          tradeResult = await this.executeSimulationTrade(decision)
          tradeResult.status = 'FAILED'
          tradeResult.error = 'Drift Protocol execution failed'
        }
      }

      // Store trade in database
      await this.storeTrade(decision, tradeResult)

      // Update stats
      this.updateStats(tradeResult)

      console.log(`✅ Trade executed successfully: ${tradeResult.transactionId || 'SIMULATION'}`)
      
      // Force cleanup after successful trade execution
      if (tradeResult.status !== 'FAILED') {
        setTimeout(async () => {
          try {
            await aggressiveCleanup.forceCleanupAfterTrade()
          } catch (error) {
            console.error('Error in post-trade cleanup:', error)
          }
        }, 2000) // 2 second delay
      }
      
    } catch (error) {
      console.error('Error executing trade:', error)
      this.stats.errorCount++
      this.stats.lastError = error instanceof Error ? error.message : 'Trade execution failed'
    }
  }

  private async executeSimulationTrade(decision: any): Promise<any> {
    // Simulate trade execution with realistic parameters
    let currentPrice = decision.currentPrice
    
    // If no current price provided, fetch real price
    if (!currentPrice) {
      try {
        const { default: PriceFetcher } = await import('./price-fetcher')
        currentPrice = await PriceFetcher.getCurrentPrice(this.config?.symbol || 'SOLUSD')
        console.log(`📊 Fetched real ${this.config?.symbol || 'SOLUSD'} price: $${currentPrice}`)
      } catch (error) {
        console.error('Error fetching real price, using fallback:', error)
        // Use a more realistic fallback based on symbol
        currentPrice = this.config?.symbol === 'SOLUSD' ? 189 : 100
      }
    }
    
    const slippage = Math.random() * 0.005 // 0-0.5% slippage
    const executionPrice = currentPrice * (1 + (Math.random() > 0.5 ? slippage : -slippage))
    
    return {
      transactionId: `SIM_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
      executionPrice,
      amount: decision.positionSize,
      direction: decision.direction,
      status: 'OPEN', // Trades start as OPEN, not COMPLETED
      timestamp: new Date(),
      fees: decision.positionSize * 0.001, // 0.1% fee
      slippage: slippage * 100
    }
  }

  private async executeLiveTrade(decision: any): Promise<any> {
    // Execute real trade via Drift Protocol with AI-calculated leverage
    console.log(`🌊 Executing Drift trade: ${decision.direction} ${this.config!.symbol}`)
    console.log(`🧠 AI Leverage: ${decision.leverageUsed.toFixed(1)}x (Risk: ${decision.riskAssessment})`)
    console.log(`💀 Liquidation Price: $${decision.liquidationPrice.toFixed(4)}`)
    
    // Calculate AI-generated stop loss and take profit from analysis
    const stopLossPercent = decision.stopLoss || this.calculateAIStopLoss(decision)
    const takeProfitPercent = decision.takeProfit || this.calculateAITakeProfit(decision)
    
    console.log(`🎯 AI Risk Management: SL=${stopLossPercent}%, TP=${takeProfitPercent}%`)

    // Call the unified trading API endpoint that routes to Drift
    const tradeResponse = await fetch(`${process.env.NEXT_PUBLIC_API_URL || 'http://localhost:3000'}/api/automation/trade`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        dexProvider: this.config!.dexProvider || 'DRIFT',
        action: 'place_order',
        symbol: this.config!.symbol,
        amount: this.config!.tradingAmount,
        side: decision.direction.toLowerCase(),
        leverage: decision.leverageUsed || this.config!.maxLeverage || 2, // Use AI-calculated leverage
        stopLoss: true,
        takeProfit: true,
        stopLossPercent: stopLossPercent,
        takeProfitPercent: takeProfitPercent,
        mode: this.config!.mode || 'SIMULATION',
        // Include AI leverage details for logging
        aiLeverageDetails: {
          calculatedLeverage: decision.leverageUsed,
          liquidationPrice: decision.liquidationPrice,
          riskAssessment: decision.riskAssessment,
          marginRequired: decision.marginRequired
        }
      })
    })

    const tradeResult = await tradeResponse.json()

    // Convert Drift result to standard trade result format
    if (tradeResult.success) {
      return {
        transactionId: tradeResult.result?.transactionId || tradeResult.result?.txId,
        executionPrice: tradeResult.result?.executionPrice,
        amount: tradeResult.result?.amount,
        direction: decision.direction,
        status: 'COMPLETED',
        timestamp: new Date(),
        leverage: decision.leverageUsed || tradeResult.leverageUsed || this.config!.maxLeverage,
        liquidationPrice: decision.liquidationPrice,
        riskAssessment: decision.riskAssessment,
        stopLoss: stopLossPercent,
        takeProfit: takeProfitPercent,
        tradingAmount: this.config!.tradingAmount,
        dexProvider: 'DRIFT'
      }
    } else {
      throw new Error(tradeResult.error || 'Drift trade execution failed')
    }
  }

  private async storeTrade(decision: any, result: any): Promise<void> {
    try {
      // Ensure we have a valid price for database storage
      const executionPrice = result.executionPrice || decision.currentPrice || decision.entryPrice
      
      if (!executionPrice) {
        console.error('❌ No valid price available for trade storage. Result:', result)
        console.error('❌ Decision data:', { currentPrice: decision.currentPrice, entryPrice: decision.entryPrice })
        return
      }

      // For live trades, use the actual amounts from Drift
      const tradeAmount = result.tradingAmount ? this.config!.tradingAmount : decision.positionSize
      const actualAmount = result.amount || decision.positionSize

      console.log(`💾 Storing trade: ${decision.direction} ${actualAmount} ${this.config!.symbol} at $${executionPrice}`)

      await prisma.trade.create({
        data: {
          userId: this.config!.userId,
          symbol: this.config!.symbol,
          side: decision.direction,
          amount: actualAmount,
          price: executionPrice,
          status: result.status || 'COMPLETED',
          driftTxId: result.transactionId || result.txId,
          fees: result.fees || 0,
          stopLoss: decision.stopLoss,
          takeProfit: decision.takeProfit,
          isAutomated: true,
          tradingMode: this.config!.mode,
          confidence: decision.confidence,
          marketSentiment: decision.marketSentiment,
          createdAt: new Date(),
          // Add AI leverage information
          leverage: result.leverage || decision.leverageUsed,
          // Add Drift-specific fields for live trades
          ...(this.config!.mode === 'LIVE' && result.tradingAmount && {
            realTradingAmount: this.config!.tradingAmount,
            driftTxId: result.transactionId
          }),
          // Add AI leverage details in learning data
          learningData: JSON.stringify({
            aiLeverage: {
              calculatedLeverage: decision.leverageUsed,
              liquidationPrice: decision.liquidationPrice,
              riskAssessment: decision.riskAssessment,
              marginRequired: decision.marginRequired,
              balanceStrategy: result.accountValue < 1000 ? 'AGGRESSIVE_100%' : 'CONSERVATIVE_50%'
            }
          })
        }
      })
      
      console.log('✅ Trade stored in database successfully')
    } catch (error) {
      console.error('❌ Error storing trade:', error)
    }
  }

  private updateStats(result: any): void {
    this.stats.totalTrades++
    
    if (result.status === 'COMPLETED') {
      this.stats.successfulTrades++
      this.stats.winRate = (this.stats.successfulTrades / this.stats.totalTrades) * 100
      
      // Update PnL (simplified calculation)
      const pnl = result.amount * 0.01 * (Math.random() > 0.5 ? 1 : -1) // Random PnL for demo
      this.stats.totalPnL += pnl
    }
  }

  private async getTodayTradeCount(userId: string): Promise<number> {
    const today = new Date()
    today.setHours(0, 0, 0, 0)
    
    const count = await prisma.trade.count({
      where: {
        userId,
        isAutomated: true,
        createdAt: {
          gte: today
        }
      }
    })
    
    return count
  }

  /**
   * Determine if current strategy is scalping based on selected timeframes
   */
  private isScalpingStrategy(): boolean {
    if (!this.config) return false
    
    if (this.config.selectedTimeframes) {
      const timeframes = this.config.selectedTimeframes
      const isScalping = timeframes.includes('5') || timeframes.includes('3') || 
                        (timeframes.length > 1 && timeframes.every((tf: string) => ['1', '3', '5', '15', '30'].includes(tf)))
      return isScalping
    }
    
    // Fallback to single timeframe check
    return ['1m', '3m', '5m'].includes(this.config.timeframe)
  }

  /**
   * Check if there are any open positions for current symbol
   */
  setTempConfig(config: any): void {
    this.config = config as AutomationConfig;
  }

  clearTempConfig(): void {
    this.config = null;
  }

  async hasOpenPositions(): Promise<boolean> {
    if (!this.config) return false
    
    try {
      // Check actual Drift positions instead of database records
      const response = await fetch('http://localhost:3000/api/drift/positions')
      if (!response.ok) {
        console.error('Failed to fetch Drift positions:', response.statusText)
        return false
      }
      
      const data = await response.json()
      const positions = data.positions || []
      
      // Check if there are any positions for our symbol
      const symbolPositions = positions.filter((pos: any) => {
        const marketSymbol = pos.marketSymbol || pos.market?.symbol || ''
        return marketSymbol.includes(this.config!.symbol.replace('USD', ''))
      })
      
      console.log(`🔍 Found ${symbolPositions.length} open Drift positions for ${this.config.symbol}`)
      return symbolPositions.length > 0
    } catch (error) {
      console.error('Error checking Drift positions:', error)
      return false
    }
  }

  /**
   * Placeholder methods for new actions (to be implemented)
   */
  private async adjustStopLoss(newSLPrice: number): Promise<void> {
    console.log(`🎯 Adjusting stop loss to $${newSLPrice.toFixed(4)} (placeholder implementation)`)
    // TODO: Implement actual SL adjustment via Drift SDK
  }

  private async exitPosition(reason: string): Promise<void> {
    console.log(`🚪 Exiting position due to: ${reason} (placeholder implementation)`)
    // TODO: Implement actual position exit via Drift SDK
  }

  async stopAutomation(): Promise<boolean> {
    try {
      console.log('🛑 Stopping automation service...')
      this.isRunning = false
      
      // Clear the interval if it exists
      if (this.intervalId) {
        console.log('🛑 Clearing automation interval')
        clearInterval(this.intervalId)
        this.intervalId = null
      }
      
      // Store config reference before clearing it
      const configRef = this.config
      
      // Stop price monitoring with force stop if needed
      try {
        await priceMonitorService.stopMonitoring()
        console.log('📊 Price monitoring stopped')
        
        // Double-check and force stop if still running
        setTimeout(() => {
          if (priceMonitorService.isMonitoring()) {
            console.log('⚠️  Price monitor still running, forcing stop...')
            priceMonitorService.stopMonitoring()
          }
        }, 1000)
      } catch (error) {
        console.error('Failed to stop price monitoring:', error)
        // Force stop via API as fallback
        try {
          await fetch('http://localhost:3000/api/price-monitor', {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({ action: 'stop_monitoring' })
          })
          console.log('📊 Price monitoring force-stopped via API')
        } catch (apiError) {
          console.error('Failed to force stop price monitoring:', apiError)
        }
      }
      
      // Update database session status to STOPPED
      if (configRef) {
        await prisma.automationSession.updateMany({
          where: {
            userId: configRef.userId,
            symbol: configRef.symbol,
            timeframe: configRef.timeframe,
            status: 'ACTIVE'
          },
          data: {
            status: 'STOPPED',
            updatedAt: new Date()
          }
        })
        console.log('🛑 Database session status updated to STOPPED')
      }
      
      // Reset config AFTER using it for database update
      this.config = null
      
      console.log('🛑 Automation stopped')
      return true
    } catch (error) {
      console.error('Failed to stop automation:', error)
      return false
    }
  }

  async pauseAutomation(): Promise<boolean> {
    try {
      if (!this.isRunning) {
        return false
      }

      this.isRunning = false
      console.log('⏸️ Automation paused')
      return true
    } catch (error) {
      console.error('Failed to pause automation:', error)
      return false
    }
  }

  async resumeAutomation(): Promise<boolean> {
    try {
      if (!this.config) {
        return false
      }

      this.isRunning = true
      console.log('▶️ Automation resumed')
      return true
    } catch (error) {
      console.error('Failed to resume automation:', error)
      return false
    }
  }

  async getStatus(): Promise<AutomationStatus | null> {
    try {
      // Get the latest active automation session from database first
      const session = await prisma.automationSession.findFirst({
        where: { status: 'ACTIVE' },
        orderBy: { createdAt: 'desc' }
      })

      if (!session) {
        return null
      }

      // If we have a session but automation is not running in memory,
      // it means the server was restarted but the session is still active
      const isActiveInMemory = this.isRunning && this.config !== null
      
      // Auto-restart automation if session exists but not running in memory
      if (!isActiveInMemory) {
        console.log('🔄 Found active session but automation not running, checking if restart is appropriate...')
        
        // Don't auto-restart if there are open positions unless only DCA is needed
        const tempConfig = { userId: session.userId, symbol: session.symbol }
        this.config = tempConfig as AutomationConfig // Temporarily set config for position check
        const hasPositions = await this.hasOpenPositions()
        this.config = null // Clear temp config
        
        if (hasPositions) {
          console.log('📊 Open positions detected - preventing auto-restart to avoid unwanted analysis')
          console.log('💡 Use manual start to override this safety check if needed')
          return {
            isActive: false,
            mode: session.mode as 'SIMULATION' | 'LIVE',
            symbol: session.symbol,
            timeframe: session.timeframe,
            totalTrades: session.totalTrades,
            successfulTrades: session.successfulTrades,
            winRate: session.winRate,
            totalPnL: session.totalPnL,
            lastAnalysis: session.lastAnalysis || undefined,
            lastTrade: session.lastTrade || undefined,
            nextScheduled: session.nextScheduled || undefined,
            errorCount: session.errorCount,
            lastError: session.lastError || undefined,
            nextAnalysisIn: 0,
            analysisInterval: 0
          }
        } else {
          console.log('✅ No open positions - safe to auto-restart automation')
          await this.autoRestartFromSession(session)
        }
      }

      // Calculate next analysis timing
      const analysisInterval = Math.floor(this.getIntervalFromTimeframe(session.timeframe) / 1000) // Convert to seconds
      let nextAnalysisIn = 0
      
      if (this.isRunning && session.nextScheduled) {
        const nextScheduledTime = new Date(session.nextScheduled).getTime()
        const currentTime = Date.now()
        nextAnalysisIn = Math.max(0, Math.floor((nextScheduledTime - currentTime) / 1000))
      }
      
      return {
        isActive: this.isRunning && this.config !== null,
        mode: session.mode as 'SIMULATION' | 'LIVE',
        symbol: session.symbol,
        timeframe: session.timeframe,
        totalTrades: session.totalTrades,
        successfulTrades: session.successfulTrades,
        winRate: session.winRate,
        totalPnL: session.totalPnL,
        errorCount: session.errorCount,
        lastError: session.lastError || undefined,
        lastAnalysis: session.lastAnalysis || undefined,
        lastTrade: session.lastTrade || undefined,
        nextScheduled: session.nextScheduled || undefined,
        nextAnalysisIn: nextAnalysisIn,
        analysisInterval: analysisInterval,
        currentCycle: session.totalTrades || 0
      }
    } catch (error) {
      console.error('Failed to get automation status:', error)
      return null
    }
  }

  private async autoRestartFromSession(session: any): Promise<void> {
    try {
      const settings = session.settings || {}
      const config: AutomationConfig = {
        userId: session.userId,
        mode: session.mode,
        symbol: session.symbol,
        timeframe: session.timeframe,
        tradingAmount: settings.tradingAmount || 100,
        maxLeverage: settings.maxLeverage || 3,
        // stopLossPercent and takeProfitPercent removed - AI calculates these automatically
        maxDailyTrades: settings.maxDailyTrades || 5,
        riskPercentage: settings.riskPercentage || 2
      }

      await this.startAutomation(config)
      console.log('✅ Automation auto-restarted successfully')
    } catch (error) {
      console.error('Failed to auto-restart automation:', error)
    }
  }

  async getLearningInsights(userId: string): Promise<{
    totalAnalyses: number
    avgAccuracy: number
    bestTimeframe: string
    worstTimeframe: string
    commonFailures: string[]
    recommendations: string[]
  }> {
    try {
      // For now, return mock data with dynamic timeframe
      const selectedTimeframes = this.config?.selectedTimeframes || ['1h']
      const primaryTimeframe = selectedTimeframes[0] || '1h'
      
      return {
        totalAnalyses: 150,
        avgAccuracy: 0.72,
        bestTimeframe: primaryTimeframe,
        worstTimeframe: '15m',
        commonFailures: [
          'Low confidence predictions',
          'Missed support/resistance levels',
          'Timeframe misalignment'
        ],
        recommendations: [
          `Focus on ${primaryTimeframe} timeframe for better accuracy`,
          'Wait for higher confidence signals (>75%)',
          'Use multiple timeframe confirmation'
        ]
      }
    } catch (error) {
      console.error('Failed to get learning insights:', error)
      return {
        totalAnalyses: 0,
        avgAccuracy: 0,
        bestTimeframe: 'Unknown',
        worstTimeframe: 'Unknown',
        commonFailures: [],
        recommendations: []
      }
    }
  }

  /**
   * Trigger analysis based on price movement alerts
   */
  private async triggerPriceBasedAnalysis(
    trigger: 'TP_APPROACH' | 'SL_APPROACH' | 'CRITICAL',
    data: any
  ): Promise<void> {
    if (!this.config || !this.isRunning) {
      console.log('❌ Cannot trigger price-based analysis: automation not running')
      return
    }

    const sessionId = `price-trigger-${Date.now()}`
    
    try {
      console.log(`🔥 Price-based analysis triggered by ${trigger} for ${data.symbol}`)
      console.log(`📊 Current price: $${data.currentPrice}, Target: $${data.targetPrice}`)
      
      // Create progress tracker for this analysis
      const steps = [
        { id: 'trigger', title: 'Triggered by price movement', description: 'Analysis initiated by price alert', status: 'pending' as ProgressStatus },
        { id: 'screenshot', title: 'Capturing screenshots', description: 'Taking fresh market screenshots', status: 'pending' as ProgressStatus },
        { id: 'analysis', title: 'Running AI analysis', description: 'Analyzing current market conditions', status: 'pending' as ProgressStatus },
        { id: 'evaluation', title: 'Evaluating position', description: 'Checking position adjustments', status: 'pending' as ProgressStatus },
        { id: 'complete', title: 'Analysis complete', description: 'Price-based analysis finished', status: 'pending' as ProgressStatus }
      ]
      
      progressTracker.createSession(sessionId, steps)

      progressTracker.updateStep(sessionId, 'trigger', 'active', `${trigger}: ${data.symbol} at $${data.currentPrice}`)

      // Run enhanced screenshot capture with current symbol/timeframe
      progressTracker.updateStep(sessionId, 'screenshot', 'active')
      
      const screenshotConfig = {
        symbol: this.config.symbol,
        timeframe: this.config.timeframe,
        layouts: ['ai', 'diy'],
        sessionId
      }

      const screenshots = await enhancedScreenshotService.captureWithLogin(screenshotConfig)

      if (!screenshots || screenshots.length === 0) {
        throw new Error('Failed to capture screenshots for price-based analysis')
      }

      progressTracker.updateStep(sessionId, 'screenshot', 'completed', `Captured ${screenshots.length} screenshots`)
      progressTracker.updateStep(sessionId, 'analysis', 'active')

      // Simplified analysis call - just use the first screenshot
      const analysisResult = await aiAnalysisService.analyzeScreenshot(screenshots[0])

      if (!analysisResult) {
        throw new Error('AI analysis returned null result')
      }

      progressTracker.updateStep(sessionId, 'analysis', 'completed', `Analysis: ${analysisResult.recommendation}`)
      progressTracker.updateStep(sessionId, 'evaluation', 'active')

      // Store the triggered analysis in trading journal
      await prisma.tradingJournal.create({
        data: {
          userId: this.config.userId,
          screenshotUrl: screenshots[0] || '',
          aiAnalysis: analysisResult.reasoning || 'No analysis available',
          confidence: analysisResult.confidence || 0,
          recommendation: analysisResult.recommendation || 'HOLD',
          symbol: this.config.symbol,
          timeframe: this.config.timeframe,
          sessionId,
          notes: `Price-triggered analysis: ${trigger} - Current: $${data.currentPrice}, Target: $${data.targetPrice}`,
          marketSentiment: analysisResult.marketSentiment || 'Unknown',
          tradingMode: this.config.mode,
          isAutomated: true,
          priceAtAnalysis: data.currentPrice,
          marketCondition: trigger,
          createdAt: new Date()
        }
      })

      // Enhanced action logic for intelligent scalping optimization
      if (trigger === 'SL_APPROACH') {
        console.log('🔍 Stop Loss approaching - analyzing intelligent scalping action')
        
        const slAction = await this.analyzeSLApproachAction(analysisResult, data)
        
        if (slAction.action === 'DCA_REVERSAL' && slAction.shouldExecute) {
          console.log('🔄 Executing DCA reversal to average down position')
          await this.executeDCA(slAction.dcaResult)
        } else if (slAction.action === 'EARLY_EXIT' && slAction.shouldExecute) {
          console.log('🚪 Executing early exit before stop loss hit')
          // TODO: Implement early exit logic
        } else if (slAction.action === 'ADJUST_SL' && slAction.shouldExecute) {
          console.log('📊 Adjusting stop loss based on market reversal signals')
          // TODO: Implement SL adjustment logic
        } else {
          console.log(`💡 SL Approach Action: ${slAction.action} (not executing: ${slAction.reasoning})`)
        }
      }
      
      // Log important insights for potential position adjustments
      if (analysisResult.recommendation === 'SELL' && trigger === 'SL_APPROACH') {
        console.log('⚠️ AI recommends SELL while approaching Stop Loss - consider early exit')
      } else if (analysisResult.recommendation === 'BUY' && trigger === 'TP_APPROACH') {
        console.log('🎯 AI recommends BUY while approaching Take Profit - consider extending position')
      }

      progressTracker.updateStep(sessionId, 'evaluation', 'completed')
      progressTracker.updateStep(sessionId, 'complete', 'completed', 
        `${analysisResult.recommendation} (${analysisResult.confidence}% confidence)`)
      
      console.log(`✅ Price-based analysis completed (${trigger}): ${analysisResult.recommendation} with ${analysisResult.confidence}% confidence`)

    } catch (error) {
      console.error(`❌ Price-based analysis failed (${trigger}):`, error)
      
      progressTracker.updateStep(sessionId, 'complete', 'error', 
        `Error: ${error instanceof Error ? error.message : 'Unknown error'}`)
      
      this.stats.errorCount++
      this.stats.lastError = error instanceof Error ? error.message : 'Unknown error'
    }
  }

  /**
   * Check for DCA opportunities on existing open positions
   */
  private async checkForDCAOpportunity(): Promise<any> {
    try {
      if (!this.config) return { shouldDCA: false }

      // Get current open positions
      const openPositions = await prisma.trade.findMany({
        where: {
          userId: this.config.userId,
          status: 'open',
          symbol: this.config.symbol
        },
        orderBy: { createdAt: 'desc' },
        take: 1
      })

      if (openPositions.length === 0) {
        return { shouldDCA: false, reasoning: 'No open positions to DCA' }
      }

      const currentPosition = openPositions[0]
      
      // Get current market price
      let currentPrice: number
      try {
        const { default: PriceFetcher } = await import('./price-fetcher')
        currentPrice = await PriceFetcher.getCurrentPrice(this.config.symbol)
      } catch (error) {
        console.error('Error fetching current price for DCA analysis:', error)
        return { shouldDCA: false, reasoning: 'Cannot fetch current price' }
      }

      // Get account status for DCA calculation (simplified version)
      const accountStatus = {
        accountValue: 1000, // Could integrate with actual account status
        availableBalance: 500,
        leverage: currentPosition.leverage || 1,
        liquidationPrice: 0
      }

      // Analyze DCA opportunity using AI DCA Manager
      const dcaParams = {
        currentPosition: {
          side: currentPosition.side as 'long' | 'short',
          size: currentPosition.amount || 0,
          entryPrice: currentPosition.entryPrice || currentPosition.price,
          currentPrice,
          unrealizedPnl: currentPosition.profit || 0,
          stopLoss: currentPosition.stopLoss || 0,
          takeProfit: currentPosition.takeProfit || 0
        },
        accountStatus,
        marketData: {
          price: currentPrice,
          priceChange24h: 0, // Could fetch from price API if needed
          volume: 0,
          support: (currentPosition.entryPrice || currentPosition.price) * 0.95, // Estimate
          resistance: (currentPosition.entryPrice || currentPosition.price) * 1.05 // Estimate
        },
        maxLeverageAllowed: this.config.maxLeverage || 20
      }

      const dcaResult = AIDCAManager.analyzeDCAOpportunity(dcaParams)
      
      console.log('🔍 DCA Analysis Result:', {
        shouldDCA: dcaResult.shouldDCA,
        confidence: dcaResult.confidence,
        reasoning: dcaResult.reasoning,
        dcaAmount: dcaResult.dcaAmount?.toFixed(4),
        riskLevel: dcaResult.riskAssessment
      })

      return dcaResult

    } catch (error) {
      console.error('Error checking DCA opportunity:', error)
      return { shouldDCA: false, reasoning: 'DCA analysis failed' }
    }
  }

  /**
   * Execute DCA by scaling into existing position
   */
  private async executeDCA(dcaResult: any): Promise<void> {
    try {
      if (!this.config || !dcaResult.shouldDCA) return

      console.log('🔄 Executing DCA scaling:', {
        amount: dcaResult.dcaAmount?.toFixed(4),
        newAverage: dcaResult.newAveragePrice?.toFixed(4),
        newLeverage: dcaResult.newLeverage?.toFixed(1) + 'x',
        confidence: dcaResult.confidence + '%'
      })

      // Get current open position
      const openPosition = await prisma.trade.findFirst({
        where: {
          userId: this.config.userId,
          status: 'open',
          symbol: this.config.symbol
        },
        orderBy: { createdAt: 'desc' }
      })

      if (!openPosition) {
        console.error('❌ No open position found for DCA')
        return
      }

      // Execute DCA trade via Drift Protocol (simplified for now)
      if (this.config.mode === 'LIVE') {
        console.log('📈 Live DCA would execute via Drift Protocol (not implemented yet)')
        // TODO: Implement live DCA execution
      }

      // Update position with new averages (both LIVE and SIMULATION)
      await this.updatePositionAfterDCA(openPosition.id, dcaResult)
      
      // Create DCA record for tracking
      await this.createDCARecord(openPosition.id, dcaResult)
      
      console.log('✅ DCA executed successfully')

    } catch (error) {
      console.error('Error executing DCA:', error)
    }
  }

  /**
   * Update position after DCA execution
   */
  private async updatePositionAfterDCA(positionId: string, dcaResult: any): Promise<void> {
    try {
      // Calculate new position metrics
      const newSize = dcaResult.dcaAmount * (dcaResult.newLeverage || 1)
      
      await prisma.trade.update({
        where: { id: positionId },
        data: {
          amount: { increment: newSize },
          entryPrice: dcaResult.newAveragePrice,
          stopLoss: dcaResult.newStopLoss,
          takeProfit: dcaResult.newTakeProfit,
          leverage: dcaResult.newLeverage,
          aiAnalysis: `DCA: ${dcaResult.reasoning}`,
          updatedAt: new Date()
        }
      })

      console.log('📊 Position updated after DCA:', {
        newAverage: dcaResult.newAveragePrice?.toFixed(4),
        newSL: dcaResult.newStopLoss?.toFixed(4),
        newTP: dcaResult.newTakeProfit?.toFixed(4),
        newLeverage: dcaResult.newLeverage?.toFixed(1) + 'x'
      })

    } catch (error) {
      console.error('Error updating position after DCA:', error)
    }
  }

  /**
   * Create DCA record for tracking and analysis
   */
  private async createDCARecord(positionId: string, dcaResult: any): Promise<void> {
    try {
      await prisma.dCARecord.create({
        data: {
          tradeId: positionId,
          dcaAmount: dcaResult.dcaAmount,
          dcaPrice: dcaResult.newAveragePrice, // Current market price for DCA entry
          newAveragePrice: dcaResult.newAveragePrice,
          newStopLoss: dcaResult.newStopLoss,
          newTakeProfit: dcaResult.newTakeProfit,
          newLeverage: dcaResult.newLeverage,
          confidence: dcaResult.confidence,
          reasoning: dcaResult.reasoning,
          riskAssessment: dcaResult.riskAssessment,
          createdAt: new Date()
        }
      })

      console.log('📝 DCA record created for tracking')
    } catch (error) {
      console.error('Error creating DCA record:', error)
    }
  }

  /**
   * Intelligent analysis when stop loss is approaching for scalping strategies
   */
  private async analyzeSLApproachAction(
    analysisResult: any, 
    priceData: any
  ): Promise<{
    action: 'DCA_REVERSAL' | 'EARLY_EXIT' | 'ADJUST_SL' | 'HOLD',
    shouldExecute: boolean,
    reasoning: string,
    dcaResult?: any
  }> {
    try {
      if (!this.config) {
        return { action: 'HOLD', shouldExecute: false, reasoning: 'No configuration available' }
      }

      // Only apply intelligent SL logic for scalping strategies
      if (!this.isScalpingStrategy()) {
        return { 
          action: 'HOLD', 
          shouldExecute: false, 
          reasoning: 'Not a scalping timeframe - using standard SL approach' 
        }
      }

      // Check if we have open positions to work with
      const hasPositions = await this.hasOpenPositions()
      if (!hasPositions) {
        return { 
          action: 'HOLD', 
          shouldExecute: false, 
          reasoning: 'No open positions to manage' 
        }
      }

      // Analyze market reversal signals based on AI recommendation and confidence
      const confidence = analysisResult.confidence || 0
      const recommendation = analysisResult.recommendation || 'HOLD'
      
      // Strong BUY signal while approaching SL suggests potential reversal
      if (recommendation === 'BUY' && confidence >= 75) {
        console.log('🔄 Strong BUY signal detected while approaching SL - checking DCA opportunity')
        
        // Check DCA opportunity for potential reversal
        const dcaOpportunity = await this.checkForDCAOpportunity()
        
        if (dcaOpportunity.shouldDCA) {
          return {
            action: 'DCA_REVERSAL',
            shouldExecute: true,
            reasoning: `AI shows ${confidence}% confidence BUY signal - DCA to average down`,
            dcaResult: dcaOpportunity
          }
        } else {
          return {
            action: 'ADJUST_SL',
            shouldExecute: true,
            reasoning: `AI shows ${confidence}% confidence BUY signal - adjust SL to give more room`
          }
        }
      }
      
      // Strong SELL signal confirms downtrend - early exit
      else if (recommendation === 'SELL' && confidence >= 80) {
        return {
          action: 'EARLY_EXIT',
          shouldExecute: true,
          reasoning: `AI shows ${confidence}% confidence SELL signal - exit before SL hit`
        }
      }
      
      // Medium confidence signals - more conservative approach
      else if (confidence >= 60) {
        return {
          action: 'ADJUST_SL',
          shouldExecute: recommendation === 'BUY',
          reasoning: `Medium confidence ${recommendation} - ${recommendation === 'BUY' ? 'adjust SL' : 'maintain position'}`
        }
      }
      
      // Low confidence or HOLD - maintain current strategy
      else {
        return {
          action: 'HOLD',
          shouldExecute: false,
          reasoning: `Low confidence (${confidence}%) or HOLD signal - let SL trigger naturally`
        }
      }

    } catch (error) {
      console.error('Error analyzing SL approach action:', error)
      return { 
        action: 'HOLD', 
        shouldExecute: false, 
        reasoning: 'Error in SL approach analysis' 
      }
    }
  }
}

export const automationService = new AutomationService()
