import { NextResponse } from 'next/server' import { enhancedScreenshotService } from '../../../lib/enhanced-screenshot' import { aiAnalysisService } from '../../../lib/ai-analysis' import { progressTracker } from '../../../lib/progress-tracker' import { PrismaClient } from '@prisma/client'; const prisma = new PrismaClient(); // Store analysis results for AI learning async function storeAnalysisForLearning(symbol, analysis) { try { console.log('💾 Storing analysis for AI learning...') // Extract market conditions for learning const marketConditions = { marketSentiment: analysis.marketSentiment || 'NEUTRAL', keyLevels: analysis.keyLevels || {}, trends: analysis.trends || {}, timeframes: ['5m', '15m', '30m'], // Multi-timeframe analysis timestamp: new Date().toISOString() } await prisma.aILearningData.create({ data: { userId: 'default-user', // Use same default user as ai-learning-status symbol: symbol, timeframe: 'MULTI', // Indicates multi-timeframe batch analysis analysisData: JSON.stringify(analysis), marketConditions: JSON.stringify(marketConditions), confidenceScore: Math.round(analysis.confidence || 50), createdAt: new Date() } }) console.log(`✅ Analysis stored for learning: ${symbol} - ${analysis.recommendation || 'HOLD'} (${analysis.confidence || 50}% confidence)`) } catch (error) { console.error('❌ Failed to store analysis for learning:', error) } } export async function POST(request) { try { const body = await request.json() const { symbol, layouts, timeframes, selectedLayouts, analyze = true } = body console.log('📊 Batch analysis request:', { symbol, layouts, timeframes, selectedLayouts, analyze }) // Validate inputs if (!symbol || !timeframes || !Array.isArray(timeframes) || timeframes.length === 0) { return NextResponse.json( { success: false, error: 'Invalid request: symbol and timeframes array required' }, { status: 400 } ) } // Generate unique session ID for progress tracking const sessionId = `batch_analysis_${Date.now()}_${Math.random().toString(36).substr(2, 9)}` console.log('🔍 Created batch analysis session ID:', sessionId) // Create progress tracking session with initial steps const initialSteps = [ { id: 'init', title: 'Initializing Batch Analysis', description: 'Starting multi-timeframe analysis...', status: 'pending' }, { id: 'auth', title: 'TradingView Authentication', description: 'Logging into TradingView accounts', status: 'pending' }, { id: 'navigation', title: 'Chart Navigation', description: 'Navigating to chart layouts', status: 'pending' }, { id: 'loading', title: 'Chart Data Loading', description: 'Waiting for chart data and indicators', status: 'pending' }, { id: 'capture', title: 'Screenshot Capture', description: `Capturing screenshots for ${timeframes.length} timeframes`, status: 'pending' }, { id: 'analysis', title: 'AI Analysis', description: 'Analyzing all screenshots with AI', status: 'pending' } ] // Create the progress session progressTracker.createSession(sessionId, initialSteps) // Prepare base configuration const baseConfig = { symbol: symbol || 'BTCUSD', layouts: layouts || selectedLayouts || ['ai', 'diy'], sessionId, credentials: { email: process.env.TRADINGVIEW_EMAIL, password: process.env.TRADINGVIEW_PASSWORD } } console.log('🔧 Base config:', baseConfig) let allScreenshots = [] const screenshotResults = [] try { // STEP 1: Collect ALL screenshots from ALL timeframes FIRST console.log(`🔄 Starting batch screenshot collection for ${timeframes.length} timeframes...`) progressTracker.updateStep(sessionId, 'init', 'active', 'Starting batch screenshot collection...') for (let i = 0; i < timeframes.length; i++) { const timeframe = timeframes[i] const timeframeLabel = getTimeframeLabel(timeframe) console.log(`📸 Collecting screenshots for ${symbol} ${timeframeLabel} (${i + 1}/${timeframes.length})`) // Update progress for current timeframe progressTracker.updateStep(sessionId, 'capture', 'active', `Capturing ${timeframeLabel} screenshots (${i + 1}/${timeframes.length})` ) try { const config = { ...baseConfig, timeframe: timeframe, sessionId: i === 0 ? sessionId : undefined // Only track progress for first timeframe } // Capture screenshots WITHOUT analysis const screenshots = await enhancedScreenshotService.captureWithLogin(config) if (screenshots && screenshots.length > 0) { console.log(`✅ Captured ${screenshots.length} screenshots for ${timeframeLabel}`) // Store screenshots with metadata const screenshotData = { timeframe: timeframe, timeframeLabel: timeframeLabel, screenshots: screenshots, success: true } screenshotResults.push(screenshotData) allScreenshots.push(...screenshots) } else { console.warn(`⚠️ No screenshots captured for ${timeframeLabel}`) screenshotResults.push({ timeframe: timeframe, timeframeLabel: timeframeLabel, screenshots: [], success: false, error: 'No screenshots captured' }) } } catch (timeframeError) { console.error(`❌ Error capturing ${timeframeLabel}:`, timeframeError) screenshotResults.push({ timeframe: timeframe, timeframeLabel: timeframeLabel, screenshots: [], success: false, error: timeframeError.message }) } // Small delay between captures if (i < timeframes.length - 1) { await new Promise(resolve => setTimeout(resolve, 1000)) } } console.log(`📊 Batch screenshot collection completed: ${allScreenshots.length} total screenshots`) progressTracker.updateStep(sessionId, 'capture', 'completed', `Captured ${allScreenshots.length} total screenshots`) // STEP 2: Send ALL screenshots to AI for comprehensive analysis let analysis = null if (analyze && allScreenshots.length > 0) { console.log(`🤖 Starting comprehensive AI analysis on ${allScreenshots.length} screenshots...`) progressTracker.updateStep(sessionId, 'analysis', 'active', 'Running comprehensive AI analysis...') try { if (allScreenshots.length === 1) { analysis = await aiAnalysisService.analyzeScreenshot(allScreenshots[0]) } else { analysis = await aiAnalysisService.analyzeMultipleScreenshots(allScreenshots) } if (analysis) { console.log('✅ Comprehensive AI analysis completed') progressTracker.updateStep(sessionId, 'analysis', 'completed', 'AI analysis completed successfully!') // Store analysis for learning await storeAnalysisForLearning(symbol, analysis) } else { console.log('⏳ AI analysis returned null (possibly rate limited) - continuing without analysis') progressTracker.updateStep(sessionId, 'analysis', 'skipped', 'AI analysis skipped due to rate limits or other issues') analysis = null } } catch (analysisError) { console.error('❌ AI analysis failed:', analysisError) progressTracker.updateStep(sessionId, 'analysis', 'error', `AI analysis failed: ${analysisError.message}`) // Don't fail the entire request - return screenshots without analysis analysis = null } } // STEP 3: Format comprehensive results const result = { success: true, type: 'batch_analysis', sessionId, timestamp: Date.now(), symbol: symbol, timeframes: timeframes, layouts: baseConfig.layouts, summary: `Batch analysis completed for ${timeframes.length} timeframes`, totalScreenshots: allScreenshots.length, screenshotResults: screenshotResults, allScreenshots: allScreenshots.map(path => ({ url: `/screenshots/${path.split('/').pop()}`, timestamp: Date.now() })), analysis: analysis, // Comprehensive analysis of ALL screenshots message: `Successfully captured ${allScreenshots.length} screenshots${analysis ? ' with comprehensive AI analysis' : ''}` } // Clean up session setTimeout(() => progressTracker.deleteSession(sessionId), 2000) // Trigger post-analysis cleanup in development mode if (process.env.NODE_ENV === 'development') { try { const { default: aggressiveCleanup } = await import('../../../lib/aggressive-cleanup') // Run cleanup in background, don't block the response aggressiveCleanup.runPostAnalysisCleanup().catch(console.error) } catch (cleanupError) { console.error('Error triggering post-batch-analysis cleanup:', cleanupError) } } return NextResponse.json(result) } catch (error) { console.error('❌ Batch analysis failed:', error) progressTracker.updateStep(sessionId, 'analysis', 'error', `Batch analysis failed: ${error.message}`) setTimeout(() => progressTracker.deleteSession(sessionId), 5000) return NextResponse.json( { success: false, error: 'Batch analysis failed', message: error.message, sessionId: sessionId }, { status: 500 } ) } } catch (error) { console.error('Batch analysis API error:', error) return NextResponse.json( { success: false, error: 'Batch analysis failed', message: error.message }, { status: 500 } ) } } // Helper function to get timeframe label function getTimeframeLabel(timeframe) { const timeframes = [ { label: '1m', value: '1' }, { label: '5m', value: '5' }, { label: '15m', value: '15' }, { label: '30m', value: '30' }, { label: '1h', value: '60' }, { label: '2h', value: '120' }, { label: '4h', value: '240' }, { label: '1d', value: 'D' }, { label: '1w', value: 'W' }, { label: '1M', value: 'M' }, ] return timeframes.find(t => t.value === timeframe)?.label || timeframe } export async function GET() { return NextResponse.json({ message: 'Batch Analysis API - use POST method for multi-timeframe analysis', endpoints: { POST: '/api/batch-analysis - Run multi-timeframe analysis with parameters' } }) }