import { tradingViewAutomation, TradingViewAutomation, TradingViewCredentials } from './tradingview-automation'
import { progressTracker } from './progress-tracker'
import fs from 'fs/promises'
import path from 'path'

export interface BatchScreenshotConfig {
  symbol: string
  timeframes: string[] // Multiple timeframes
  layouts?: string[] // Multiple chart layouts
  credentials?: TradingViewCredentials
  sessionId?: string
}

export interface ScreenshotBatch {
  symbol: string
  timeframe: string
  layout: string
  filepath: string
  timestamp: number
}

// Layout URL mappings for direct navigation
const LAYOUT_URLS: { [key: string]: string } = {
  'ai': 'Z1TzpUrf',    // RSI + EMAs + MACD
  'diy': 'vWVvjLhP'    // Stochastic RSI + VWAP + OBV
}

export class BatchScreenshotService {
  private static readonly OPERATION_TIMEOUT = 180000 // 3 minutes for batch operations
  private aiSession: TradingViewAutomation | null = null
  private diySession: TradingViewAutomation | null = null
  private sessionId: string

  constructor(sessionId?: string) {
    this.sessionId = sessionId || `batch_${Date.now()}`
  }

  /**
   * Capture screenshots for multiple timeframes and layouts in parallel
   * This dramatically speeds up analysis by batching all screenshots
   */
  async captureMultipleTimeframes(config: BatchScreenshotConfig): Promise<ScreenshotBatch[]> {
    console.log('🚀 Batch Screenshot Service - Multi-Timeframe Capture')
    console.log('📋 Config:', config)

    const { symbol, timeframes, layouts = ['ai', 'diy'], sessionId } = config
    const screenshotBatches: ScreenshotBatch[] = []

    if (sessionId) {
      progressTracker.updateStep(sessionId, 'init', 'active', `Initializing batch capture for ${timeframes.length} timeframes`)
    }

    try {
      // Ensure screenshots directory exists
      const screenshotsDir = path.join(process.cwd(), 'screenshots')
      await fs.mkdir(screenshotsDir, { recursive: true })

      console.log(`\n🔄 Starting batch capture: ${timeframes.length} timeframes × ${layouts.length} layouts = ${timeframes.length * layouts.length} screenshots`)

      if (sessionId) {
        progressTracker.updateStep(sessionId, 'auth', 'active', 'Initializing browser sessions')
      }

      // Create parallel promises for each layout
      const layoutPromises = layouts.map(async (layout) => {
        const session = await this.getOrCreateSession(layout, config.credentials)
        const layoutResults: ScreenshotBatch[] = []

        console.log(`📊 Starting ${layout.toUpperCase()} session for ${timeframes.length} timeframes`)

        if (sessionId) {
          progressTracker.updateStep(sessionId, 'navigation', 'active', `Navigating ${layout} layout to ${symbol}`)
        }

        // Navigate to first timeframe to establish base chart
        const firstTimeframe = timeframes[0]
        await this.navigateToChart(session, symbol, firstTimeframe, layout)

        console.log(`✅ ${layout.toUpperCase()} session established on ${symbol} ${firstTimeframe}`)

        // Now capture all timeframes for this layout sequentially (but layouts run in parallel)
        for (let i = 0; i < timeframes.length; i++) {
          const timeframe = timeframes[i]
          
          try {
            if (sessionId) {
              progressTracker.updateStep(sessionId, 'capture', 'active', 
                `Capturing ${layout} ${timeframe} (${i + 1}/${timeframes.length})`)
            }

            console.log(`📸 ${layout.toUpperCase()}: Capturing ${symbol} ${timeframe}...`)

            // Change timeframe if not the first one
            if (i > 0) {
              await this.changeTimeframe(session, timeframe, symbol)
            }

            // Take screenshot
            const timestamp = Date.now()
            const filename = `${symbol}_${timeframe}_${layout}_${timestamp}.png`
            const filepath = path.join(screenshotsDir, filename)

            await session.takeScreenshot({ filename })

            const batch: ScreenshotBatch = {
              symbol,
              timeframe,
              layout,
              filepath: filename,  // Store relative filename for compatibility
              timestamp
            }

            layoutResults.push(batch)
            console.log(`✅ ${layout.toUpperCase()}: ${timeframe} captured → ${filename}`)

            // Small delay between timeframe changes to ensure chart loads
            if (i < timeframes.length - 1) {
              await new Promise(resolve => setTimeout(resolve, 2000))
            }

          } catch (error) {
            console.error(`❌ ${layout.toUpperCase()}: Failed to capture ${timeframe}:`, error)
          }
        }

        console.log(`🎯 ${layout.toUpperCase()} session completed: ${layoutResults.length}/${timeframes.length} screenshots`)
        return layoutResults
      })

      // Wait for all layout sessions to complete
      const allLayoutResults = await Promise.all(layoutPromises)
      
      // Flatten results
      screenshotBatches.push(...allLayoutResults.flat())

      if (sessionId) {
        progressTracker.updateStep(sessionId, 'capture', 'completed', 
          `Batch capture completed: ${screenshotBatches.length} screenshots`)
      }

      console.log(`\n🎯 BATCH CAPTURE COMPLETED`)
      console.log(`📊 Total Screenshots: ${screenshotBatches.length}`)
      console.log(`⏱️ Efficiency: ${timeframes.length * layouts.length} screenshots captured with ${layouts.length} parallel sessions`)

      return screenshotBatches

    } catch (error: any) {
      console.error('❌ Batch screenshot capture failed:', error)
      
      if (sessionId) {
        progressTracker.updateStep(sessionId, 'capture', 'error', `Batch capture failed: ${error?.message || 'Unknown error'}`)
      }
      
      throw error
    }
  }

  /**
   * Get or create a persistent session for a layout
   */
  private async getOrCreateSession(layout: string, credentials?: TradingViewCredentials): Promise<TradingViewAutomation> {    
    if (layout === 'ai' && this.aiSession) {
      return this.aiSession
    }
    
    if (layout === 'diy' && this.diySession) {
      return this.diySession
    }

    // Create new session
    console.log(`🔧 Creating new ${layout.toUpperCase()} session...`)
    const session = new TradingViewAutomation()
    
    // Initialize and login
    await session.init()
    await session.login(credentials || {
      email: process.env.TRADINGVIEW_EMAIL || '',
      password: process.env.TRADINGVIEW_PASSWORD || ''
    })

    // Store session
    if (layout === 'ai') {
      this.aiSession = session
    } else {
      this.diySession = session
    }

    return session
  }

  /**
   * Navigate to a specific chart with symbol, timeframe, and layout
   */
  private async navigateToChart(session: TradingViewAutomation, symbol: string, timeframe: string, layout: string): Promise<void> {
    const layoutId = LAYOUT_URLS[layout]
    if (!layoutId) {
      throw new Error(`Unknown layout: ${layout}`)
    }

    // Use the navigateToLayout method
    console.log(`🌐 ${layout.toUpperCase()}: Navigating to layout ${layoutId} with ${symbol}`)
    const success = await session.navigateToLayout(layoutId, symbol, this.normalizeTimeframe(timeframe))
    
    if (!success) {
      throw new Error(`Failed to navigate to ${layout} layout`)
    }

    // Wait for chart to fully load
    await new Promise(resolve => setTimeout(resolve, 5000))
  }

  /**
   * Change timeframe on an existing chart session
   */
  private async changeTimeframe(session: TradingViewAutomation, timeframe: string, symbol: string): Promise<void> {
    console.log(`⏱️ Changing timeframe to ${timeframe}`)
    
    // Use navigateToSymbol with timeframe parameter to change timeframe
    const success = await session.navigateToSymbol(symbol, this.normalizeTimeframe(timeframe))
    
    if (!success) {
      console.warn(`Failed to change timeframe to ${timeframe}, continuing...`)
    }
    
    // Wait for chart to reload with new timeframe
    await new Promise(resolve => setTimeout(resolve, 3000))
  }

  /**
   * Normalize timeframe for TradingView URL compatibility
   */
  private normalizeTimeframe(timeframe: string): string {
    const timeframeMap: { [key: string]: string } = {
      '5m': '5',
      '15m': '15', 
      '30m': '30',
      '1h': '60',
      '2h': '120',
      '4h': '240',
      '1d': 'D',
      '1w': 'W',
      '1M': 'M'
    }
    
    return timeframeMap[timeframe] || timeframe
  }

  /**
   * Clean up all sessions
   */
  async cleanup(): Promise<void> {
    console.log('🧹 Cleaning up batch screenshot sessions...')
    
    try {
      if (this.aiSession) {
        await this.aiSession.forceCleanup()
        this.aiSession = null
      }
      
      if (this.diySession) {
        await this.diySession.forceCleanup()
        this.diySession = null
      }
      
      console.log('✅ Batch screenshot cleanup completed')
    } catch (error) {
      console.error('❌ Batch screenshot cleanup failed:', error)
    }
  }

  /**
   * Convert batch results to format expected by existing systems
   */
  static formatBatchForAnalysis(batches: ScreenshotBatch[]): { [timeframe: string]: string[] } {
    const timeframeGroups: { [timeframe: string]: string[] } = {}
    
    for (const batch of batches) {
      if (!timeframeGroups[batch.timeframe]) {
        timeframeGroups[batch.timeframe] = []
      }
      timeframeGroups[batch.timeframe].push(batch.filepath)
    }
    
    return timeframeGroups
  }
}

// Export a factory function instead of a singleton instance
export const createBatchScreenshotService = (sessionId?: string) => new BatchScreenshotService(sessionId)
