import ssim from 'ssim.js'
import type { TraceEvent } from '../../../types/trace'
import type { ScreenshotEvent } from '../types/httpRequest'
import { SSIM_SIMILARITY_THRESHOLD } from './httpRequestConstants'

// Helper function to convert base64 image to ImageData for SSIM analysis
export const base64ToImageData = (base64: string): Promise<ImageData> => {
  return new Promise((resolve, reject) => {
    const img = new Image()
    img.onload = () => {
      const canvas = document.createElement('canvas')
      const ctx = canvas.getContext('2d')
      if (!ctx) {
        reject(new Error('Could not get canvas context'))
        return
      }
      
      canvas.width = img.width
      canvas.height = img.height
      ctx.drawImage(img, 0, 0)
      
      const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height)
      resolve(imageData)
    }
    img.onerror = () => reject(new Error('Failed to load image'))
    img.src = base64.startsWith('data:') ? base64 : `data:image/png;base64,${base64}`
  })
}

export const extractScreenshots = (traceEvents: TraceEvent[]): ScreenshotEvent[] => {
  const screenshots: ScreenshotEvent[] = []
  let index = 0
  
  // Debug: Check for any screenshot-related events
  const screenshotRelated = traceEvents.filter(event => 
    event.name.toLowerCase().includes('screenshot') ||
    event.cat.toLowerCase().includes('screenshot') ||
    event.name.toLowerCase().includes('snap') ||
    event.name.toLowerCase().includes('frame') ||
    event.cat.toLowerCase().includes('devtools')
  )
  
  console.log('Debug: Screenshot-related events found:', screenshotRelated.length)
  if (screenshotRelated.length > 0) {
    console.log('Debug: Screenshot-related sample:', screenshotRelated.slice(0, 5).map(e => ({
      name: e.name,
      cat: e.cat,
      hasArgs: !!e.args,
      argsKeys: e.args ? Object.keys(e.args) : []
    })))
  }

  for (const event of traceEvents) {
    // Look for screenshot events with more flexible matching
    if ((event.name === 'Screenshot' || event.name === 'screenshot') && 
        (event.cat === 'disabled-by-default-devtools.screenshot' || 
         event.cat.includes('screenshot') || 
         event.cat.includes('devtools')) &&
        event.args) {
      const args = event.args as any
      
      // Check multiple possible locations for screenshot data
      const snapshot = args.snapshot || args.data?.snapshot || args.image || args.data?.image
      
      if (snapshot && typeof snapshot === 'string') {
        // Accept both data URLs and base64 strings
        if (snapshot.startsWith('data:image/') || snapshot.startsWith('/9j/') || snapshot.length > 1000) {
          const screenshotData = snapshot.startsWith('data:image/') ? snapshot : `data:image/jpeg;base64,${snapshot}`
          screenshots.push({
            timestamp: event.ts, // This is in microseconds like other trace events
            screenshot: screenshotData,
            index: index++
          })
        }
      }
    }
  }

  console.log('Debug: Extracted screenshots:', screenshots.length)
  return screenshots.sort((a, b) => a.timestamp - b.timestamp)
}

export const findUniqueScreenshots = async (screenshots: ScreenshotEvent[], threshold: number = SSIM_SIMILARITY_THRESHOLD): Promise<ScreenshotEvent[]> => {
  if (screenshots.length === 0) return []

  const uniqueScreenshots: ScreenshotEvent[] = [screenshots[0]] // Always include first screenshot
  
  console.log('SSIM Analysis: Processing', screenshots.length, 'screenshots')
  
  // Compare each screenshot with the previous unique one using SSIM
  for (let i = 1; i < screenshots.length; i++) {
    const current = screenshots[i]
    const lastUnique = uniqueScreenshots[uniqueScreenshots.length - 1]
    
    try {
      // Convert both images to ImageData for SSIM analysis
      const [currentImageData, lastImageData] = await Promise.all([
        base64ToImageData(current.screenshot),
        base64ToImageData(lastUnique.screenshot)
      ])
      
      // Calculate SSIM similarity (0-1, where 1 is identical)
      const similarity = ssim(currentImageData, lastImageData)

      console.log(`SSIM Analysis: Screenshot ${i} similarity: ${similarity.mssim.toFixed(4)}`)
      
      // If similarity is below threshold, it's different enough to keep
      if (similarity.mssim < threshold) {
        uniqueScreenshots.push(current)
        console.log(`SSIM Analysis: Screenshot ${i} added (significant change detected)`)
      } else {
        console.log(`SSIM Analysis: Screenshot ${i} filtered out (too similar: ${similarity.mssim.toFixed(4)})`)
      }
    } catch (error) {
      console.warn('SSIM Analysis: Error comparing screenshots, falling back to string comparison:', error)
      // Fallback to simple string comparison if SSIM fails
      if (current.screenshot !== lastUnique.screenshot) {
        uniqueScreenshots.push(current)
      }
    }
  }

  console.log('SSIM Analysis: Filtered from', screenshots.length, 'to', uniqueScreenshots.length, 'unique screenshots')
  return uniqueScreenshots
}