import puppeteer, { Browser, Page, Frame } from 'puppeteer'
import path from 'path'
import fs from 'fs/promises'
import { settingsManager } from './settings'

// Video recording support - Simple implementation without external dependencies
let isRecordingSupported = true
try {
  // Test if we can use basic screenshot recording
  require('fs/promises')
} catch (e) {
  console.warn('Basic video recording not available')
  isRecordingSupported = false
}

const TRADINGVIEW_EMAIL = process.env.TRADINGVIEW_EMAIL
const TRADINGVIEW_PASSWORD = process.env.TRADINGVIEW_PASSWORD
const TRADINGVIEW_LAYOUTS = (process.env.TRADINGVIEW_LAYOUTS || '').split(',').map(l => l.trim())
const PUPPETEER_EXECUTABLE_PATH = process.env.PUPPETEER_EXECUTABLE_PATH || '/usr/bin/chromium'

// Layout name to URL mapping
const LAYOUT_URLS: { [key: string]: string } = {
  'ai': 'Z1TzpUrf',
  'Diy module': 'vWVvjLhP',
  // Add more layout mappings as needed
}

// Construct layout URL with hash parameters
const getLayoutUrl = (layoutId: string, symbol: string, timeframe?: string): string => {
  const baseParams = `symbol=${symbol}${timeframe ? `&interval=${encodeURIComponent(timeframe)}` : ''}`
  return `https://www.tradingview.com/chart/${layoutId}/#${baseParams}`
}

export class TradingViewCapture {
  private browser: Browser | null = null
  private page: Page | null = null
  private loggedIn = false
  private recorder: any = null

  private async debugScreenshot(step: string, page: Page): Promise<void> {
    try {
      const timestamp = Date.now()
      const filename = `debug_${step.replace(/[^a-zA-Z0-9]/g, '_')}_${timestamp}.png`
      const screenshotsDir = path.join(process.cwd(), 'screenshots')
      await fs.mkdir(screenshotsDir, { recursive: true })
      const filePath = path.join(screenshotsDir, filename)
      
      await page.screenshot({ path: filePath as `${string}.png`, type: 'png', fullPage: true })
      
      // Also get page info for debugging
      const pageInfo = await page.evaluate(() => ({
        url: window.location.href,
        title: document.title,
        hasChart: document.querySelector('.chart-container, [data-name="chart"], canvas') !== null,
        bodyText: document.body.textContent?.substring(0, 500) || ''
      }))
      
      console.log(`🔍 DEBUG Screenshot [${step}]: ${filePath}`)
      console.log(`📄 Page Info:`, pageInfo)
    } catch (e) {
      console.error(`Failed to take debug screenshot for step ${step}:`, e)
    }
  }

  async init() {
    if (!this.browser) {
      // Check for debug mode from environment variable
      const isDebugMode = process.env.TRADINGVIEW_DEBUG === 'true'
      const isDocker = process.env.DOCKER_ENV === 'true' || process.env.NODE_ENV === 'production'
      
      // Docker-optimized browser args
      const dockerArgs = [
        '--no-sandbox',
        '--disable-setuid-sandbox',
        '--disable-dev-shm-usage',
        '--disable-accelerated-2d-canvas',
        '--no-first-run',
        '--no-zygote',
        '--disable-gpu',
        '--disable-background-timer-throttling',
        '--disable-backgrounding-occluded-windows',
        '--disable-renderer-backgrounding',
        '--disable-features=TranslateUI',
        '--disable-ipc-flooding-protection',
        '--memory-pressure-off',
        '--max_old_space_size=4096'
      ]

      // Additional args for non-Docker debug mode
      const debugArgs = isDebugMode && !isDocker ? ['--start-maximized'] : []
      
      this.browser = await puppeteer.launch({
        headless: isDocker ? true : !isDebugMode, // Always headless in Docker
        devtools: isDebugMode && !isDocker, // DevTools only in local debug mode
        slowMo: isDebugMode ? 250 : 0, // Slow down actions in debug mode
        args: [...dockerArgs, ...debugArgs],
        executablePath: PUPPETEER_EXECUTABLE_PATH
      })
      
      const mode = isDocker ? 'Docker headless mode' : (isDebugMode ? 'visible debug mode' : 'headless mode')
      console.log(`Puppeteer browser launched (${mode})`)
    }
    if (!this.page) {
      this.page = await this.browser.newPage()
      await this.page.setViewport({ width: 1920, height: 1080 })
      console.log('Puppeteer page created')
    }
    if (!this.loggedIn) {
      console.log('Logging in to TradingView...')
      await this.login()
      console.log('Logged in to TradingView')
    }
    return this.page
  }

  async login() {
    if (!TRADINGVIEW_EMAIL || !TRADINGVIEW_PASSWORD) {
      throw new Error('TradingView credentials not set in .env')
    }
    const page = this.page || (await this.browser!.newPage())
    
    // Start video recording for login process
    await this.startVideoRecording('login_process')
    
    console.log('Navigating to TradingView login page...')
    await page.goto('https://www.tradingview.com/#signin', { waitUntil: 'networkidle2' })
    
    // Debug screenshot after initial navigation
    await this.debugScreenshot('login_01_initial_page', page)
    
    // Check if we're already properly logged in with our account
    try {
      const loggedInIndicator = await page.waitForSelector('.tv-header__user-menu-button, [data-name="header-user-menu"]', { timeout: 3000 })
      if (loggedInIndicator) {
        // Check if we're logged in with our specific account by looking for account-specific elements
        const isProperlyLoggedIn = await page.evaluate(() => {
          // Look for specific logged-in indicators that show we have an actual account
          const hasUserMenu = document.querySelector('.tv-header__user-menu-button, [data-name="header-user-menu"]') !== null
          const notGuestSession = !document.body.textContent?.includes('Guest') && 
                                 !document.body.textContent?.includes('Sign up') &&
                                 !document.body.textContent?.includes('Get started for free')
          return hasUserMenu && notGuestSession
        })
        
        if (isProperlyLoggedIn) {
          console.log('Already properly logged in to TradingView with account')
          await this.debugScreenshot('login_02_already_logged_in', page)
          this.loggedIn = true
          return
        } else {
          console.log('Detected guest session, forcing proper login...')
          await this.debugScreenshot('login_02b_guest_session_detected', page)
          // Force logout first, then login
          try {
            await page.goto('https://www.tradingview.com/accounts/logout/', { waitUntil: 'networkidle2', timeout: 10000 })
            await new Promise(res => setTimeout(res, 2000))
          } catch (e) {
            console.log('Logout attempt completed, proceeding with login...')
          }
        }
      }
    } catch (e) {
      console.log('Not logged in yet, proceeding with login...')
      await this.debugScreenshot('login_03_not_logged_in', page)
    }
    
    // Reset login flag since we need to login
    this.loggedIn = false
    
    // Navigate to fresh login page
    console.log('Navigating to fresh login page...')
    await page.goto('https://www.tradingview.com/accounts/signin/', { waitUntil: 'networkidle2', timeout: 30000 })
    await this.debugScreenshot('login_04_fresh_login_page', page)
    
    try {
      // Wait for the page to load and look for login form
      console.log('Looking for login form...')
      await page.waitForSelector('form, input[type="email"], input[name="username"]', { timeout: 10000 })
      
      // Look for email input field with multiple selectors
      let emailInput = await page.$('input[name="username"]') || 
                      await page.$('input[name="email"]') || 
                      await page.$('input[type="email"]') || 
                      await page.$('input[placeholder*="email" i]')
      
      if (!emailInput) {
        // Try to find and click "Email" button if login options are presented
        console.log('Looking for email login option...')
        const emailButton = await page.evaluateHandle(() => {
          const buttons = Array.from(document.querySelectorAll('button, a, div[role="button"]'))
          return buttons.find(btn => {
            const text = btn.textContent?.toLowerCase() || ''
            return text.includes('email') || text.includes('continue with email') || text.includes('sign in with email')
          })
        })
        
        if (emailButton.asElement()) {
          console.log('Found email login button, clicking...')
          const elementHandle = emailButton.asElement() as any
          if (elementHandle) {
            await elementHandle.click()
          }
          await new Promise(res => setTimeout(res, 2000))
          await this.debugScreenshot('login_04b_after_email_button', page)
          
          // Now look for email input again
          emailInput = await page.waitForSelector('input[name="username"], input[name="email"], input[type="email"]', { timeout: 10000 })
        }
      }
      
      if (!emailInput) {
        throw new Error('Could not find email input field')
      }
      
      console.log('Found email input, filling credentials...')
      await emailInput.click() // Click to focus
      await emailInput.type(TRADINGVIEW_EMAIL, { delay: 50 })
      
      // Find password field
      const passwordInput = await page.waitForSelector('input[name="password"], input[type="password"]', { timeout: 5000 })
      if (!passwordInput) {
        throw new Error('Could not find password input field')
      }
      await passwordInput.click() // Click to focus
      await passwordInput.type(TRADINGVIEW_PASSWORD, { delay: 50 })
      
      await this.debugScreenshot('login_05_credentials_filled', page)
      
      // Find and click the sign in button
      let signInButton = await page.$('button[type="submit"]')
      if (!signInButton) {
        // Look for button with sign in text
        signInButton = await page.evaluateHandle(() => {
          const buttons = Array.from(document.querySelectorAll('button'))
          return buttons.find(btn => {
            const text = btn.textContent?.toLowerCase() || ''
            return text.includes('sign in') || text.includes('login') || text.includes('submit')
          })
        }).then(handle => handle.asElement()) as any
      }
      
      if (!signInButton) {
        throw new Error('Could not find sign in button')
      }
      
      console.log('Clicking sign in button...')
      await signInButton.click()
      await this.debugScreenshot('login_06_after_signin_click', page)
    } catch (e) {
      // Fallback: try to find email button first
      console.log('Fallback: looking for email button...')
      try {
        await page.waitForSelector('button', { timeout: 15000 })
        const buttons = await page.$$('button')
        let emailBtn = null
        
        // Look for email button with various text patterns
        for (const btn of buttons) {
          const text = await page.evaluate(el => el.innerText || el.textContent, btn)
          if (text && (
            text.trim().toLowerCase().includes('email') || 
            text.trim().toLowerCase().includes('sign in with email') ||
            text.trim().toLowerCase().includes('continue with email')
          )) {
            emailBtn = btn
            break
          }
        }
        
        if (emailBtn) {
          console.log('Found email button, clicking...')
          await emailBtn.click()
          await new Promise(res => setTimeout(res, 1000))
          
          // Now fill in the form
          const emailInput = await page.waitForSelector('input[name="username"], input[name="email"], input[type="email"], input[placeholder*="email" i]', { timeout: 10000 })
          if (!emailInput) {
            throw new Error('Could not find email input field after clicking email button')
          }
          await emailInput.click() // Click to focus
          await emailInput.type(TRADINGVIEW_EMAIL, { delay: 50 })
          
          const passwordInput = await page.waitForSelector('input[name="password"], input[type="password"], input[placeholder*="password" i]', { timeout: 5000 })
          if (!passwordInput) {
            throw new Error('Could not find password input field after clicking email button')
          }
          await passwordInput.click() // Click to focus
          await passwordInput.type(TRADINGVIEW_PASSWORD, { delay: 50 })
          
          const signInButton = await page.waitForSelector('button[type="submit"]', { timeout: 5000 })
          if (!signInButton) {
            // Try to find button with sign in text
            const buttons = await page.$$('button')
            let foundButton = null
            for (const btn of buttons) {
              const text = await page.evaluate(el => el.innerText || el.textContent, btn)
              if (text && (text.toLowerCase().includes('sign in') || text.toLowerCase().includes('login'))) {
                foundButton = btn
                break
              }
            }
            if (!foundButton) {
              throw new Error('Could not find sign in button after clicking email button')
            }
            await foundButton.click()
          } else {
            await signInButton.click()
          }
        } else {
          throw new Error('Could not find email button')
        }
      } catch (e2) {
        console.error('Could not find or click email button:', e2)
        const errorMessage = e2 instanceof Error ? e2.message : String(e2)
        throw new Error('Could not find or click email button on TradingView login page. ' + errorMessage)
      }
    }
    
    // Wait for navigation or dashboard (main page)
    try {
      console.log('Waiting for login to complete...')
      await page.waitForSelector('.tv-header__user-menu-button, .chart-container, [data-name="header-user-menu"]', { timeout: 30000 })
      
      // Check if we're on the Supercharts selection page
      const isSuperchartsPage = await page.evaluate(() => {
        const text = document.body.textContent || ''
        return text.includes('Supercharts') && text.includes('The one terminal to rule them all')
      })
      
      if (isSuperchartsPage) {
        console.log('🎯 On Supercharts selection page, clicking Supercharts...')
        
        // Look for Supercharts button/link
        let superchartsClicked = false
        
        // Try different approaches to find and click Supercharts
        try {
          // Approach 1: Look for direct link to chart
          const chartLink = await page.$('a[href*="/chart"]')
          if (chartLink) {
            console.log('Found direct chart link, clicking...')
            await chartLink.click()
            superchartsClicked = true
          }
        } catch (e) {
          console.log('Direct chart link not found, trying text-based search...')
        }
        
        if (!superchartsClicked) {
          // Approach 2: Find by text content
          const clicked = await page.evaluate(() => {
            const elements = Array.from(document.querySelectorAll('a, button, div[role="button"]'))
            for (const el of elements) {
              if (el.textContent?.includes('Supercharts')) {
                (el as HTMLElement).click()
                return true
              }
            }
            return false
          })
          superchartsClicked = clicked
        }
        
        if (superchartsClicked) {
          console.log('✅ Clicked Supercharts, waiting for charts interface...')
          // Wait for navigation to charts interface
          await new Promise(res => setTimeout(res, 3000))
          await page.waitForSelector('.chart-container, [data-name="chart"]', { timeout: 15000 })
          console.log('✅ Successfully navigated to Supercharts interface')
        } else {
          console.log('⚠️ Supercharts button not found, trying direct navigation...')
          // Fallback: navigate directly to charts
          await page.goto('https://www.tradingview.com/chart/', { waitUntil: 'networkidle2', timeout: 30000 })
        }
      }
      
      this.loggedIn = true
      console.log('TradingView login complete')
      await this.debugScreenshot('login_04_complete', page)
      
      // Stop video recording
      await this.stopVideoRecording()
    } catch (e) {
      console.error('Login navigation did not complete.')
      this.loggedIn = false
      
      // Stop video recording on error
      await this.stopVideoRecording()
      throw new Error('Login navigation did not complete.')
    }
  }

  async capture(symbol: string, filename: string, layouts?: string[], timeframe?: string) {
    console.log('Working directory:', process.cwd())
    
    // Load settings and update if provided
    const settings = await settingsManager.loadSettings()
    if (symbol && symbol !== settings.symbol) {
      await settingsManager.setSymbol(symbol)
    }
    if (timeframe && timeframe !== settings.timeframe) {
      await settingsManager.setTimeframe(timeframe)
    }
    if (layouts && JSON.stringify(layouts) !== JSON.stringify(settings.layouts)) {
      await settingsManager.setLayouts(layouts)
    }
    
    // Use saved settings if not provided
    const finalSymbol = symbol || settings.symbol
    const finalTimeframe = timeframe || settings.timeframe
    const finalLayouts = layouts || settings.layouts
    
    console.log('Using settings:', { symbol: finalSymbol, timeframe: finalTimeframe, layouts: finalLayouts })
    
    const page = await this.init()
    
    // Start video recording for capture process
    await this.startVideoRecording(`capture_${finalSymbol}_${finalTimeframe || 'default'}`)
    
    // Capture screenshots for each layout
    const screenshots: string[] = []
    
    for (let i = 0; i < finalLayouts.length; i++) {
      const layout = finalLayouts[i]
      console.log(`Processing layout ${i + 1}/${finalLayouts.length}: ${layout}`)
      
      // Check if we have a direct URL for this layout
      const layoutUrlPath = LAYOUT_URLS[layout]
      if (layoutUrlPath) {
        // Navigate to layout URL with hash parameters, then to base chart interface
        let layoutUrl = `https://www.tradingview.com/chart/${layoutUrlPath}/#symbol=${finalSymbol}`
        if (finalTimeframe) {
          layoutUrl += `&interval=${encodeURIComponent(finalTimeframe)}`
        }
        
        try {
          console.log('🎯 Navigating to layout URL:', layoutUrl)
          
          // Navigate to the specific layout URL with hash parameters and stay there
          await page.goto(layoutUrl, { waitUntil: 'networkidle2', timeout: 60000 })
          await this.debugScreenshot(`layout_${layout}_01_after_navigation`, page)
          
          // Check if we get a "Chart Not Found" or "can't open this chart layout" error
          const pageContent = await page.content()
          const currentUrl = page.url()
          const pageTitle = await page.title()
          
          const isPrivateLayout = pageContent.includes("can't open this chart layout") || 
                                 pageContent.includes("Chart Not Found") ||
                                 pageTitle.includes("Chart Not Found") ||
                                 await page.$('.tv-dialog__error, .tv-dialog__warning') !== null
          
          if (isPrivateLayout) {
            console.log(`⚠️ Layout "${layout}" appears to be private or not found. This might be due to:`)
            console.log('   1. Layout is private and requires proper account access')
            console.log('   2. Layout ID is incorrect or outdated')
            console.log('   3. Account doesn\'t have access to this layout')
            console.log(`   Current URL: ${currentUrl}`)
            console.log(`   Page title: ${pageTitle}`)
            await this.debugScreenshot(`layout_${layout}_01b_private_layout_detected`, page)
            
            // Check if we're properly logged in with account that should have access
            const loginStatus = await page.evaluate(() => {
              const hasUserMenu = document.querySelector('.tv-header__user-menu-button, [data-name="header-user-menu"]') !== null
              const hasGuestIndicators = document.body.textContent?.includes('Guest') || 
                                        document.body.textContent?.includes('Sign up') ||
                                        document.body.textContent?.includes('Get started for free')
              return { hasUserMenu, hasGuestIndicators, bodyText: document.body.textContent?.substring(0, 200) }
            })
            
            if (loginStatus.hasGuestIndicators || !loginStatus.hasUserMenu) {
              console.log('🔄 Detected we might not be properly logged in. Forcing re-login...')
              this.loggedIn = false
              await this.login()
              
              // Try the layout URL again after proper login
              console.log('🔄 Retrying layout URL after proper login...')
              await page.goto(layoutUrl, { waitUntil: 'networkidle2', timeout: 60000 })
              await this.debugScreenshot(`layout_${layout}_01d_retry_after_login`, page)
              
              // Check again if layout is accessible
              const retryPageContent = await page.content()
              const retryIsPrivate = retryPageContent.includes("can't open this chart layout") || 
                                   retryPageContent.includes("Chart Not Found") ||
                                   await page.title().then(t => t.includes("Chart Not Found"))
              
              if (retryIsPrivate) {
                console.log(`❌ Layout "${layout}" is still not accessible after proper login. Falling back to default chart.`)
              } else {
                console.log(`✅ Layout "${layout}" is now accessible after proper login!`)
                // Continue with normal flow
                return
              }
            }
            
            // Navigate to default chart with the symbol and timeframe
            const fallbackUrl = `https://www.tradingview.com/chart/?symbol=${finalSymbol}&interval=${encodeURIComponent(finalTimeframe || '5')}`
            console.log('🔄 Falling back to default chart:', fallbackUrl)
            await page.goto(fallbackUrl, { waitUntil: 'networkidle2', timeout: 60000 })
            await this.debugScreenshot(`layout_${layout}_01c_fallback_navigation`, page)
          }
          
          // Wait for the layout to load properly
          await new Promise(res => setTimeout(res, 5000))
          await this.debugScreenshot(`layout_${layout}_02_after_wait`, page)
          
          // Verify we're on the correct layout by checking if we can see chart content
          const layoutLoaded = await page.evaluate(() => {
            const hasChart = document.querySelector('.chart-container, [data-name="chart"], canvas') !== null
            const title = document.title
            const url = window.location.href
            return { hasChart, title, url }
          })
          
          console.log('📊 Layout verification:', layoutLoaded)
          await this.debugScreenshot(`layout_${layout}_03_after_verification`, page)
          
          if (!layoutLoaded.hasChart) {
            console.log('⚠️ Chart not detected, waiting longer for layout to load...')
            await new Promise(res => setTimeout(res, 5000))
            await this.debugScreenshot(`layout_${layout}_04_after_extra_wait`, page)
          }
          
          console.log(`✅ Successfully loaded layout "${layout}" and staying on it`)
          await this.debugScreenshot(`layout_${layout}_05_final_success`, page)
        } catch (e: any) {
          console.error(`Failed to load layout "${layout}":`, e)
          throw new Error(`Failed to load layout "${layout}": ` + (e.message || e))
        }
      } else {
        // Fallback to loading layout via menu (for layouts without direct URLs)
        console.log(`No direct URL found for layout "${layout}", trying menu navigation...`)
        
        // Navigate to base chart URL first
        let url = `https://www.tradingview.com/chart/?symbol=${finalSymbol}`
        if (finalTimeframe) {
          url += `&interval=${encodeURIComponent(finalTimeframe)}`
        }
        
        try {
          console.log('Navigating to base chart URL:', url)
          await page.goto(url, { waitUntil: 'networkidle2', timeout: 60000 })
          console.log('Successfully navigated to base chart')
        } catch (e: any) {
          console.error('Failed to load TradingView chart page:', e)
          throw new Error('Failed to load TradingView chart page: ' + (e.message || e))
        }
        
        // Try to load the layout via menu
        await this.loadLayout(page, layout)
      }
      
      // Wait for layout to load
      await new Promise(res => setTimeout(res, 3000))
      
      // Generate filename for this layout
      const layoutFilename = filename.replace('.png', `_${layout}.png`)
      const screenshotsDir = path.join(process.cwd(), 'screenshots')
      await fs.mkdir(screenshotsDir, { recursive: true })
      const filePath = path.join(screenshotsDir, layoutFilename)
      
      try {
        await this.debugScreenshot(`final_screenshot_${layout}_before_capture`, page)
        await page.screenshot({ path: filePath as `${string}.png`, type: 'png' })
        console.log(`Screenshot saved for layout ${layout}:`, filePath)
        screenshots.push(filePath)
      } catch (e: any) {
        const debugScreenshotErrorPath = path.resolve(`debug_screenshot_error_${layout}.png`) as `${string}.png`
        await page.screenshot({ path: debugScreenshotErrorPath })
        console.error(`Failed to capture screenshot for layout ${layout}:`, e)
        console.error('Screenshot on screenshot error:', debugScreenshotErrorPath)
        throw new Error(`Failed to capture screenshot for layout ${layout}: ` + (e.message || e))
      }
    }
    
    // Stop video recording
    await this.stopVideoRecording()
    
    return screenshots
  }

  private async loadLayout(page: Page, layout: string): Promise<void> {
    try {
      console.log('Loading layout using direct URL:', layout)
      
      // Check if we have a direct URL for this layout
      const layoutUrlPath = LAYOUT_URLS[layout]
      if (!layoutUrlPath) {
        console.log(`No direct URL found for layout "${layout}". Available layouts:`, Object.keys(LAYOUT_URLS))
        console.log('Skipping layout loading and continuing with default chart')
        return
      }
      
      // This method is deprecated - the layout loading logic is now in captureScreenshots
      console.log('Note: This method is deprecated. Layout loading handled in captureScreenshots.')
      
    } catch (e: any) {
      console.error(`Failed to load layout "${layout}":`, e)
      console.log('Continuing with default chart layout...')
    }
  }

  private async startVideoRecording(filename: string): Promise<void> {
    if (!isRecordingSupported || !this.page) {
      console.log('Video recording not available or page not initialized')
      return
    }

    try {
      const isRecordingEnabled = process.env.TRADINGVIEW_RECORD_VIDEO === 'true'
      const isDebugMode = process.env.TRADINGVIEW_DEBUG === 'true'
      
      if (!isRecordingEnabled && !isDebugMode) {
        console.log('Video recording disabled (set TRADINGVIEW_RECORD_VIDEO=true to enable)')
        return
      }

      const videosDir = path.join(process.cwd(), 'videos')
      await fs.mkdir(videosDir, { recursive: true })
      
      const timestamp = Date.now()
      const videoFilename = `${filename.replace('.png', '')}_${timestamp}`
      
      // Simple screenshot-based recording
      this.recorder = {
        isRecording: true,
        filename: videoFilename,
        videosDir,
        screenshotCount: 0,
        interval: null as NodeJS.Timeout | null
      }

      // Take screenshots every 2 seconds for a basic "video"
      this.recorder.interval = setInterval(async () => {
        if (this.recorder && this.recorder.isRecording && this.page) {
          try {
            const screenshotPath = path.join(this.recorder.videosDir, `${this.recorder.filename}_frame_${String(this.recorder.screenshotCount).padStart(4, '0')}.png`)
            await this.page.screenshot({ path: screenshotPath as `${string}.png`, type: 'png' })
            this.recorder.screenshotCount++
          } catch (e) {
            console.error('Failed to capture video frame:', e)
          }
        }
      }, 2000)

      console.log(`🎥 Video recording started (screenshot mode): ${videosDir}/${videoFilename}_frame_*.png`)
    } catch (e) {
      console.error('Failed to start video recording:', e)
      this.recorder = null
    }
  }

  private async stopVideoRecording(): Promise<string | null> {
    if (!this.recorder) {
      return null
    }

    try {
      this.recorder.isRecording = false
      if (this.recorder.interval) {
        clearInterval(this.recorder.interval)
      }
      
      const videoPath = `${this.recorder.videosDir}/${this.recorder.filename}_frames`
      console.log(`🎥 Video recording stopped: ${this.recorder.screenshotCount} frames saved to ${videoPath}_*.png`)
      
      // Optionally create a simple HTML viewer for the frames
      const htmlPath = path.join(this.recorder.videosDir, `${this.recorder.filename}_viewer.html`)
      const framesList = Array.from({length: this.recorder.screenshotCount}, (_, i) => 
        `${this.recorder!.filename}_frame_${String(i).padStart(4, '0')}.png`
      )
      
      const htmlContent = `
<!DOCTYPE html>
<html>
<head>
    <title>Video Recording: ${this.recorder.filename}</title>
    <style>
        body { font-family: Arial, sans-serif; margin: 20px; }
        .controls { margin: 20px 0; }
        button { padding: 10px 20px; margin: 5px; }
        #currentFrame { max-width: 100%; border: 1px solid #ccc; }
        .info { margin: 10px 0; color: #666; }
    </style>
</head>
<body>
    <h1>Video Recording: ${this.recorder.filename}</h1>
    <div class="controls">
        <button onclick="play()">Play</button>
        <button onclick="pause()">Pause</button>
        <button onclick="prevFrame()">Previous</button>
        <button onclick="nextFrame()">Next</button>
        <span>Frame: <span id="frameNumber">1</span> / ${this.recorder.screenshotCount}</span>
    </div>
    <div class="info">
        <p>Total frames: ${this.recorder.screenshotCount} | Captured every 2 seconds</p>
    </div>
    <img id="currentFrame" src="${framesList[0] || ''}" alt="Video frame">
    
    <script>
        const frames = ${JSON.stringify(framesList)};
        let currentFrame = 0;
        let playing = false;
        let playInterval = null;
        
        function updateFrame() {
            document.getElementById('currentFrame').src = frames[currentFrame];
            document.getElementById('frameNumber').textContent = currentFrame + 1;
        }
        
        function play() {
            if (playing) return;
            playing = true;
            playInterval = setInterval(() => {
                currentFrame = (currentFrame + 1) % frames.length;
                updateFrame();
            }, 500); // Play at 2fps
        }
        
        function pause() {
            playing = false;
            if (playInterval) clearInterval(playInterval);
        }
        
        function nextFrame() {
            pause();
            currentFrame = (currentFrame + 1) % frames.length;
            updateFrame();
        }
        
        function prevFrame() {
            pause();
            currentFrame = currentFrame > 0 ? currentFrame - 1 : frames.length - 1;
            updateFrame();
        }
    </script>
</body>
</html>`
      
      await fs.writeFile(htmlPath, htmlContent, 'utf8')
      console.log(`📄 Video viewer created: ${htmlPath}`)
      
      this.recorder = null
      return videoPath
    } catch (e) {
      console.error('Failed to stop video recording:', e)
      this.recorder = null
      return null
    }
  }

  async cleanup() {
    try {
      // Stop any ongoing video recording
      if (this.recorder) {
        await this.stopVideoRecording()
      }
      
      // Close the page
      if (this.page) {
        await this.page.close()
        this.page = null
      }
      
      // Close the browser
      if (this.browser) {
        await this.browser.close()
        this.browser = null
      }
      
      this.loggedIn = false
      console.log('TradingViewCapture cleaned up successfully')
    } catch (e) {
      console.error('Error during cleanup:', e)
    }
  }
}

export const tradingViewCapture = new TradingViewCapture()
