import { useState, useMemo, useEffect } from 'react'
import { useDatabaseTraceData } from '../hooks/useDatabaseTraceData'
import type { TraceEvent } from '../../types/trace'
import ssim from 'ssim.js'
import BabylonViewer from '../BabylonViewer'
import BabylonTimelineViewer from '../BabylonTimelineViewer'

interface QueueAnalysis {
  reason: 'connection_limit' | 'priority_queue' | 'resource_contention' | 'unknown'
  description: string
  concurrentRequests: number
  connectionId?: number
  relatedRequests?: string[]
}

interface CDNAnalysis {
  provider: 'cloudflare' | 'akamai' | 'aws_cloudfront' | 'fastly' | 'azure_cdn' | 'google_cdn' | 'cdn77' | 'keycdn' | 'unknown'
  isEdge: boolean
  cacheStatus?: 'hit' | 'miss' | 'expired' | 'bypass' | 'unknown'
  edgeLocation?: string
  confidence: number // 0-1 confidence score
  detectionMethod: string // How we detected it
}

interface ScreenshotEvent {
  timestamp: number
  screenshot: string // base64 image data
  index: number
}

interface HTTPRequest {
  requestId: string
  url: string
  hostname: string
  method: string
  resourceType: string
  priority: string
  statusCode?: number
  mimeType?: string
  protocol?: string
  events: {
    willSendRequest?: TraceEvent
    sendRequest?: TraceEvent
    receiveResponse?: TraceEvent
    receivedData?: TraceEvent[]
    finishLoading?: TraceEvent
  }
  timing: {
    start: number
    startOffset?: number
    end?: number
    duration?: number
    queueTime?: number
    serverLatency?: number
    networkDuration?: number
    dnsStart?: number
    dnsEnd?: number
    connectStart?: number
    connectEnd?: number
    sslStart?: number
    sslEnd?: number
    sendStart?: number
    sendEnd?: number
    receiveHeadersStart?: number
    receiveHeadersEnd?: number
  }
  responseHeaders?: Array<{ name: string, value: string }>
  encodedDataLength?: number
  contentLength?: number
  fromCache: boolean
  connectionReused: boolean
  queueAnalysis?: QueueAnalysis
  cdnAnalysis?: CDNAnalysis
}

const ITEMS_PER_PAGE = 25

// SSIM threshold for screenshot similarity (0-1, where 1 is identical)
// Values above this threshold are considered "similar enough" to filter out
const SSIM_SIMILARITY_THRESHOLD = 0.95

// Global highlighting constants
const HIGHLIGHTING_CONFIG = {
  // File size thresholds (in KB)
  SIZE_THRESHOLDS: {
    LARGE: 500,    // Red highlighting for files >= 500KB
    MEDIUM: 100,   // Yellow highlighting for files >= 100KB  
    SMALL: 50      // Green highlighting for files <= 50KB
  },
  
  // Duration thresholds (in milliseconds)
  DURATION_THRESHOLDS: {
    SLOW: 250,     // Red highlighting for requests > 150ms
    MEDIUM: 100,    // Yellow highlighting for requests 50-150ms
    FAST: 100       // Green highlighting for requests < 50ms
  },
  
  // Server latency thresholds (in microseconds)
  SERVER_LATENCY_THRESHOLDS: {
    SLOW: 200000,   // Red highlighting for server latency > 200ms (200000 microseconds)
    MEDIUM: 50000,  // Yellow highlighting for server latency 50-200ms (50000 microseconds)
    FAST: 50000     // Green highlighting for server latency < 50ms (50000 microseconds)
  },
  
  // Queue time thresholds (in microseconds)
  QUEUE_TIME: {
    HIGH_THRESHOLD: 10000,  // 10ms - highlight in red and show analysis
    ANALYSIS_THRESHOLD: 10000  // 10ms - minimum queue time for analysis
  },
  
  // Colors
  COLORS: {
    // Status colors
    STATUS: {
      SUCCESS: '#28a745',    // 2xx
      REDIRECT: '#ffc107',   // 3xx  
      CLIENT_ERROR: '#fd7e14', // 4xx
      SERVER_ERROR: '#dc3545', // 5xx
      UNKNOWN: '#6c757d'
    },
    
    // Protocol colors
    PROTOCOL: {
      HTTP1_1: '#dc3545',    // Red
      H2: '#b8860b',         // Dark yellow
      H3: '#006400',         // Dark green
      UNKNOWN: '#6c757d'
    },
    
    // Priority colors
    PRIORITY: {
      VERY_HIGH: '#dc3545',  // Red
      HIGH: '#fd7e14',       // Orange
      MEDIUM: '#ffc107',     // Yellow
      LOW: '#28a745',        // Green
      VERY_LOW: '#6c757d',   // Gray
      UNKNOWN: '#6c757d'
    },
    
    // File size colors
    SIZE: {
      LARGE: { background: '#dc3545', color: 'white' },      // Red for 500KB+
      MEDIUM: { background: '#ffc107', color: 'black' },     // Yellow for 100-500KB
      SMALL: { background: '#28a745', color: 'white' },      // Green for under 50KB
      DEFAULT: { background: 'transparent', color: '#495057' } // Default for 50-100KB
    },
    
    // Duration colors
    DURATION: {
      SLOW: { background: '#dc3545', color: 'white' },       // Red for > 150ms
      MEDIUM: { background: '#ffc107', color: 'black' },     // Yellow for 50-150ms
      FAST: { background: '#28a745', color: 'white' },       // Green for < 50ms
      DEFAULT: { background: 'transparent', color: '#495057' } // Default
    },
    
    // Server latency colors
    SERVER_LATENCY: {
      SLOW: { background: '#dc3545', color: 'white' },       // Red for > 200ms
      MEDIUM: { background: '#ffc107', color: 'black' },     // Yellow for 50-200ms
      FAST: { background: '#28a745', color: 'white' },       // Green for < 50ms
      DEFAULT: { background: 'transparent', color: '#495057' } // Default
    }
  }
}

const getHostnameFromUrl = (url: string): string => {
  try {
    const urlObj = new URL(url)
    return urlObj.hostname
  } catch {
    return 'unknown'
  }
}

// Helper function to convert base64 image to ImageData for SSIM analysis
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}`
  })
}

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,
            screenshot: screenshotData,
            index: index++
          })
        }
      }
    }
  }

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

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.toFixed(4)}`)
      
      // If similarity is below threshold, it's different enough to keep
      if (similarity < 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.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
}

const analyzeCDN = (request: HTTPRequest): CDNAnalysis => {
  const hostname = request.hostname
  const headers = request.responseHeaders || []
  const headerMap = new Map(headers.map(h => [h.name.toLowerCase(), h.value.toLowerCase()]))
  
  let provider: CDNAnalysis['provider'] = 'unknown'
  let isEdge = false
  let cacheStatus: CDNAnalysis['cacheStatus'] = 'unknown'
  let edgeLocation: string | undefined
  let confidence = 0
  let detectionMethod = 'unknown'

  // Enhanced Akamai detection (check this first as it's often missed)
  if (headerMap.has('akamai-cache-status') || 
      headerMap.has('x-cache-key') ||
      headerMap.has('x-akamai-request-id') ||
      headerMap.has('x-akamai-edgescape') ||
      headerMap.get('server')?.includes('akamai') ||
      headerMap.get('server')?.includes('akamainet') ||
      headerMap.get('server')?.includes('akamainetworking') ||
      headerMap.get('x-cache')?.includes('akamai') ||
      hostname.includes('akamai') ||
      hostname.includes('akamaized') ||
      hostname.includes('akamaicdn') ||
      hostname.includes('akamai-staging') ||
      // Check for Akamai Edge hostnames patterns
      /e\d+\.a\.akamaiedge\.net/.test(hostname) ||
      // Check Via header for Akamai
      headerMap.get('via')?.includes('akamai') ||
      // Check for Akamai Image Manager server header
      (headerMap.get('server') === 'akamai image manager') ||
      // Check for typical Akamai headers
      headerMap.has('x-serial') ||
      // Additional Akamai detection patterns
      headerMap.has('x-akamai-session-info') ||
      headerMap.has('x-akamai-ssl-client-sid') ||
      headerMap.get('x-cache')?.includes('tcp_hit') ||
      headerMap.get('x-cache')?.includes('tcp_miss') ||
      // Akamai sometimes uses x-served-by with specific patterns
      (headerMap.has('x-served-by') && headerMap.get('x-served-by')?.includes('cache-'))) {
    provider = 'akamai'
    confidence = 0.95
    detectionMethod = 'enhanced akamai detection (headers/hostname/server)'
    isEdge = true
    
    const akamaiStatus = headerMap.get('akamai-cache-status')
    if (akamaiStatus) {
      if (akamaiStatus.includes('hit')) cacheStatus = 'hit'
      else if (akamaiStatus.includes('miss')) cacheStatus = 'miss'
    }
    
    // Also check x-cache for Akamai cache status
    const xCache = headerMap.get('x-cache')
    if (xCache && !akamaiStatus) {
      if (xCache.includes('hit')) cacheStatus = 'hit'
      else if (xCache.includes('miss')) cacheStatus = 'miss'
      else if (xCache.includes('tcp_hit')) cacheStatus = 'hit'
      else if (xCache.includes('tcp_miss')) cacheStatus = 'miss'
    }
  }
  
  // Cloudflare detection
  else if (headerMap.has('cf-ray') || headerMap.has('cf-cache-status') || hostname.includes('cloudflare')) {
    provider = 'cloudflare'
    confidence = 0.95
    detectionMethod = 'headers (cf-ray/cf-cache-status)'
    isEdge = true
    
    const cfCacheStatus = headerMap.get('cf-cache-status')
    if (cfCacheStatus) {
      if (cfCacheStatus.includes('hit')) cacheStatus = 'hit'
      else if (cfCacheStatus.includes('miss')) cacheStatus = 'miss'
      else if (cfCacheStatus.includes('expired')) cacheStatus = 'expired'
      else if (cfCacheStatus.includes('bypass')) cacheStatus = 'bypass'
    }
    
    edgeLocation = headerMap.get('cf-ray')?.split('-')[1]
  }
  
  // AWS CloudFront detection  
  else if (headerMap.has('x-amz-cf-id') || headerMap.has('x-amz-cf-pop') || 
           hostname.includes('cloudfront.net')) {
    provider = 'aws_cloudfront'
    confidence = 0.95
    detectionMethod = 'headers (x-amz-cf-id/x-amz-cf-pop)'
    isEdge = true
    
    const cloudfrontCache = headerMap.get('x-cache')
    if (cloudfrontCache) {
      if (cloudfrontCache.includes('hit')) cacheStatus = 'hit'
      else if (cloudfrontCache.includes('miss')) cacheStatus = 'miss'
    }
    
    edgeLocation = headerMap.get('x-amz-cf-pop')
  }
  
  // Fastly detection (moved after Akamai to avoid false positives)
  else if (headerMap.has('fastly-debug-digest') || 
           headerMap.has('fastly-debug-path') ||
           hostname.includes('fastly.com') || 
           hostname.includes('fastlylb.net') ||
           headerMap.get('via')?.includes('fastly') ||
           headerMap.get('x-cache')?.includes('fastly') ||
           // Only use x-served-by for Fastly if it has specific Fastly patterns
           (headerMap.has('x-served-by') && (
             headerMap.get('x-served-by')?.includes('fastly') ||
             headerMap.get('x-served-by')?.includes('f1') ||
             headerMap.get('x-served-by')?.includes('f2')
           ))) {
    provider = 'fastly'
    confidence = 0.85
    detectionMethod = 'headers (fastly-debug-digest/via/x-cache)'
    isEdge = true
    
    const fastlyCache = headerMap.get('x-cache')
    if (fastlyCache) {
      if (fastlyCache.includes('hit')) cacheStatus = 'hit'
      else if (fastlyCache.includes('miss')) cacheStatus = 'miss'
    }
  }
  
  // Azure CDN detection
  else if (headerMap.has('x-azure-ref') || hostname.includes('azureedge.net')) {
    provider = 'azure_cdn'
    confidence = 0.9
    detectionMethod = 'headers (x-azure-ref) or hostname'
    isEdge = true
  }
  
  // Google CDN detection
  else if (headerMap.has('x-goog-generation') || hostname.includes('googleapis.com') ||
           headerMap.get('server')?.includes('gws')) {
    provider = 'google_cdn'
    confidence = 0.8
    detectionMethod = 'headers (x-goog-generation) or server'
    isEdge = true
  }
  
  // Generic CDN patterns
  else if (hostname.includes('cdn') || hostname.includes('cache') || 
           hostname.includes('edge') || hostname.includes('static')) {
    provider = 'unknown'
    confidence = 0.3
    detectionMethod = 'hostname patterns (cdn/cache/edge/static)'
    isEdge = true
  }

  // Check for origin indicators (lower confidence for edge)
  if (hostname.includes('origin') || hostname.includes('api') || 
      headerMap.get('x-cache')?.includes('miss from origin')) {
    isEdge = false
    confidence = Math.max(0.1, confidence - 0.2)
    detectionMethod += ' + origin indicators'
  }

  return {
    provider,
    isEdge,
    cacheStatus,
    edgeLocation,
    confidence,
    detectionMethod
  }
}

const analyzeQueueReason = (request: HTTPRequest, allRequests: HTTPRequest[]): QueueAnalysis => {
  const queueTime = request.timing.queueTime || 0
  
  // If no significant queue time, no analysis needed
  if (queueTime < HIGHLIGHTING_CONFIG.QUEUE_TIME.ANALYSIS_THRESHOLD) {
    return {
      reason: 'unknown',
      description: 'No significant queueing detected',
      concurrentRequests: 0
    }
  }

  const requestStart = request.timing.start
  const requestEnd = request.timing.end || requestStart + (request.timing.duration || 0)
  
  // Find concurrent requests to the same host
  const concurrentToSameHost = allRequests.filter(other => {
    if (other.requestId === request.requestId) return false
    if (other.hostname !== request.hostname) return false
    
    const otherStart = other.timing.start
    const otherEnd = other.timing.end || otherStart + (other.timing.duration || 0)
    
    // Check if requests overlap in time
    return (otherStart <= requestEnd && otherEnd >= requestStart)
  })

  const concurrentSameProtocol = concurrentToSameHost.filter(r => r.protocol === request.protocol)
  
  // HTTP/1.1 connection limit analysis (typically 6 connections per host)
  if (request.protocol === 'http/1.1' && concurrentSameProtocol.length >= 6) {
    return {
      reason: 'connection_limit',
      description: `HTTP/1.1 connection limit reached (${concurrentSameProtocol.length} concurrent requests)`,
      concurrentRequests: concurrentSameProtocol.length,
      relatedRequests: concurrentSameProtocol.slice(0, 5).map(r => r.requestId)
    }
  }

  // H2 multiplexing but still queued - likely priority or server limits
  if (request.protocol === 'h2' && concurrentSameProtocol.length > 0) {
    // Check if lower priority requests are being processed first
    const lowerPriorityActive = concurrentSameProtocol.filter(r => {
      const priorityOrder = ['VeryLow', 'Low', 'Medium', 'High', 'VeryHigh']
      const requestPriorityIndex = priorityOrder.indexOf(request.priority || 'Medium')
      const otherPriorityIndex = priorityOrder.indexOf(r.priority || 'Medium')
      return otherPriorityIndex < requestPriorityIndex
    })

    if (lowerPriorityActive.length > 0) {
      return {
        reason: 'priority_queue',
        description: `Queued behind ${lowerPriorityActive.length} lower priority requests`,
        concurrentRequests: concurrentSameProtocol.length,
        relatedRequests: lowerPriorityActive.slice(0, 3).map(r => r.requestId)
      }
    }

    return {
      reason: 'resource_contention',
      description: `Server resource contention (${concurrentSameProtocol.length} concurrent H2 requests)`,
      concurrentRequests: concurrentSameProtocol.length,
      relatedRequests: concurrentSameProtocol.slice(0, 3).map(r => r.requestId)
    }
  }

  // General resource contention
  if (concurrentToSameHost.length > 0) {
    return {
      reason: 'resource_contention',
      description: `Resource contention with ${concurrentToSameHost.length} concurrent requests`,
      concurrentRequests: concurrentToSameHost.length,
      relatedRequests: concurrentToSameHost.slice(0, 3).map(r => r.requestId)
    }
  }

  return {
    reason: 'unknown',
    description: `Queued for ${(queueTime / 1000).toFixed(1)}ms - reason unclear`,
    concurrentRequests: 0
  }
}

interface HTTPRequestViewerProps {
  traceId: string | null
}

export default function HTTPRequestViewer({ traceId }: HTTPRequestViewerProps) {
  const { traceData, loading, error } = useDatabaseTraceData(traceId)
  const [currentPage, setCurrentPage] = useState(1)
  const [searchTerm, setSearchTerm] = useState('')
  const [resourceTypeFilter, setResourceTypeFilter] = useState<string>('all')
  const [protocolFilter, setProtocolFilter] = useState<string>('all')
  const [hostnameFilter, setHostnameFilter] = useState<string>('all')
  const [priorityFilter, setPriorityFilter] = useState<string>('all')
  const [showQueueAnalysis, setShowQueueAnalysis] = useState(false)
  const [showScreenshots, setShowScreenshots] = useState(false)
  const [show3DViewer, setShow3DViewer] = useState(false)
  const [showTimelineViewer, setShowTimelineViewer] = useState(false)
  const [ssimThreshold, setSsimThreshold] = useState(SSIM_SIMILARITY_THRESHOLD)
  const [expandedRows, setExpandedRows] = useState<Set<string>>(new Set())

  const httpRequests = useMemo(() => {
    if (!traceData) return []

    const requestsMap = new Map<string, HTTPRequest>()

    // Process all events and group by requestId
    for (const event of traceData.traceEvents) {
      const args = event.args as any
      const requestId = args?.data?.requestId

      if (!requestId) continue

      if (!requestsMap.has(requestId)) {
        requestsMap.set(requestId, {
          requestId,
          url: '',
          hostname: '',
          method: '',
          resourceType: '',
          priority: '',
          events: {},
          timing: { start: event.ts },
          fromCache: false,
          connectionReused: false
        })
      }

      const request = requestsMap.get(requestId)!

      switch (event.name) {
        case 'ResourceWillSendRequest':
          request.events.willSendRequest = event
          request.timing.start = Math.min(request.timing.start, event.ts)
          break

        case 'ResourceSendRequest':
          request.events.sendRequest = event
          request.url = args.data.url || ''
          request.hostname = getHostnameFromUrl(request.url)
          request.method = args.data.requestMethod || ''
          request.resourceType = args.data.resourceType || ''
          request.priority = args.data.priority || ''
          request.timing.start = Math.min(request.timing.start, event.ts)
          break

        case 'ResourceReceiveResponse':
          request.events.receiveResponse = event
          request.statusCode = args.data.statusCode
          request.mimeType = args.data.mimeType
          request.protocol = args.data.protocol
          request.responseHeaders = args.data.headers
          
          // Extract content-length from response headers
          if (request.responseHeaders) {
            const contentLengthHeader = request.responseHeaders.find(
              header => header.name.toLowerCase() === 'content-length'
            )
            if (contentLengthHeader) {
              request.contentLength = parseInt(contentLengthHeader.value, 10)
            }
          }
          
          request.fromCache = args.data.fromCache || false
          request.connectionReused = args.data.connectionReused || false
          request.timing.end = event.ts
          
          // Extract network timing details
          const timing = args.data.timing
          if (timing) {
            request.timing.networkDuration = timing.receiveHeadersEnd
            request.timing.dnsStart = timing.dnsStart
            request.timing.dnsEnd = timing.dnsEnd
            request.timing.connectStart = timing.connectStart
            request.timing.connectEnd = timing.connectEnd
            request.timing.sslStart = timing.sslStart
            request.timing.sslEnd = timing.sslEnd
            request.timing.sendStart = timing.sendStart
            request.timing.sendEnd = timing.sendEnd
            request.timing.receiveHeadersStart = timing.receiveHeadersStart
            request.timing.receiveHeadersEnd = timing.receiveHeadersEnd
          }
          break

        case 'ResourceReceivedData':
          if (!request.events.receivedData) request.events.receivedData = []
          request.events.receivedData.push(event)
          request.encodedDataLength = (request.encodedDataLength || 0) + (args.data.encodedDataLength || 0)
          request.timing.end = Math.max(request.timing.end || event.ts, event.ts)
          break

        case 'ResourceFinishLoading':
          request.events.finishLoading = event
          request.timing.end = event.ts
          break
      }

      // Calculate total duration
      if (request.timing.end) {
        request.timing.duration = request.timing.end - request.timing.start
      }
    }

    // Calculate queue times and filter valid requests
    const sortedRequests = Array.from(requestsMap.values())
      .filter(req => req.url && req.method) // Only include valid requests
      .map(request => {
        // Calculate queue time using multiple approaches
        if (request.events.willSendRequest && request.events.sendRequest) {
          // Primary approach: ResourceSendRequest - ResourceWillSendRequest
          request.timing.queueTime = request.events.sendRequest.ts - request.events.willSendRequest.ts
        } else if (request.events.sendRequest && request.events.receiveResponse) {
          // Fallback approach: use timing data from ResourceReceiveResponse
          const responseArgs = request.events.receiveResponse.args as any
          const timingData = responseArgs?.data?.timing
          if (timingData?.requestTime) {
            // requestTime is in seconds, convert to microseconds
            const requestTimeUs = timingData.requestTime * 1000000
            // Queue time = requestTime (when browser queued) - ResourceSendRequest timestamp (when DevTools recorded)
            // Note: requestTime is the actual browser queue time, ResourceSendRequest is the DevTools event
            request.timing.queueTime = requestTimeUs - request.events.sendRequest.ts
          }
        }
        
        // Calculate server latency (server processing time = total duration - queue time)
        if (request.timing.duration && request.timing.queueTime) {
          request.timing.serverLatency = request.timing.duration - request.timing.queueTime
          // Ensure server latency is not negative (can happen with timing irregularities)
          if (request.timing.serverLatency < 0) {
            request.timing.serverLatency = 0
          }
        }
        
        return request
      })
      .sort((a, b) => a.timing.start - b.timing.start)

    // Calculate start time offsets from the first request
    if (sortedRequests.length > 0) {
      const firstRequestTime = sortedRequests[0].timing.start
      sortedRequests.forEach(request => {
        request.timing.startOffset = request.timing.start - firstRequestTime
      })
    }

    // Add queue analysis for requests with significant queue time
    sortedRequests.forEach(request => {
      if ((request.timing.queueTime || 0) >= HIGHLIGHTING_CONFIG.QUEUE_TIME.ANALYSIS_THRESHOLD) {
        request.queueAnalysis = analyzeQueueReason(request, sortedRequests)
      }
    })

    // Add CDN analysis for all requests
    sortedRequests.forEach(request => {
      if (request.responseHeaders && request.responseHeaders.length > 0) {
        request.cdnAnalysis = analyzeCDN(request)
      }
    })

    return sortedRequests
  }, [traceData])

  // Extract and process screenshots with SSIM analysis
  const [screenshots, setScreenshots] = useState<ScreenshotEvent[]>([])
  const [screenshotsLoading, setScreenshotsLoading] = useState(false)

  useEffect(() => {
    if (!traceData) {
      setScreenshots([])
      return
    }

    const processScreenshots = async () => {
      setScreenshotsLoading(true)
      try {
        const allScreenshots = extractScreenshots(traceData.traceEvents)
        console.log('Debug: Found screenshots:', allScreenshots.length)
        console.log('Debug: Screenshot events sample:', allScreenshots.slice(0, 3))
        
        const uniqueScreenshots = await findUniqueScreenshots(allScreenshots, ssimThreshold)
        console.log('Debug: Unique screenshots after SSIM analysis:', uniqueScreenshots.length)
        
        setScreenshots(uniqueScreenshots)
      } catch (error) {
        console.error('Error processing screenshots with SSIM:', error)
        // Fallback to extracting all screenshots without SSIM filtering
        const allScreenshots = extractScreenshots(traceData.traceEvents)
        setScreenshots(allScreenshots)
      } finally {
        setScreenshotsLoading(false)
      }
    }

    processScreenshots()
  }, [traceData, ssimThreshold])

  const filteredRequests = useMemo(() => {
    let requests = httpRequests

    // Filter by resource type
    if (resourceTypeFilter !== 'all') {
      requests = requests.filter(req => req.resourceType === resourceTypeFilter)
    }

    // Filter by protocol
    if (protocolFilter !== 'all') {
      requests = requests.filter(req => req.protocol === protocolFilter)
    }

    // Filter by hostname
    if (hostnameFilter !== 'all') {
      requests = requests.filter(req => req.hostname === hostnameFilter)
    }

    // Filter by priority
    if (priorityFilter !== 'all') {
      requests = requests.filter(req => req.priority === priorityFilter)
    }

    // Filter by search term
    if (searchTerm) {
      const term = searchTerm.toLowerCase()
      requests = requests.filter(req =>
        req.url.toLowerCase().includes(term) ||
        req.method.toLowerCase().includes(term) ||
        req.resourceType.toLowerCase().includes(term) ||
        req.hostname.toLowerCase().includes(term) ||
        req.statusCode?.toString().includes(term)
      )
    }

    return requests
  }, [httpRequests, resourceTypeFilter, protocolFilter, hostnameFilter, priorityFilter, searchTerm])

  const paginatedRequests = useMemo(() => {
    const startIndex = (currentPage - 1) * ITEMS_PER_PAGE
    return filteredRequests.slice(startIndex, startIndex + ITEMS_PER_PAGE)
  }, [filteredRequests, currentPage])

  // Create timeline entries that include both HTTP requests and screenshot changes
  const timelineEntries = useMemo(() => {
    const entries: Array<{ 
      type: 'request' | 'screenshot', 
      timestamp: number, 
      data: HTTPRequest | ScreenshotEvent 
    }> = []

    // Add HTTP requests
    filteredRequests.forEach(request => {
      entries.push({
        type: 'request',
        timestamp: request.timing.start,
        data: request
      })
    })

    // Add screenshots if enabled
    if (showScreenshots && screenshots.length > 0) {
      screenshots.forEach(screenshot => {
        entries.push({
          type: 'screenshot',
          timestamp: screenshot.timestamp,
          data: screenshot
        })
      })
    }

    // Sort by timestamp
    return entries.sort((a, b) => a.timestamp - b.timestamp)
  }, [filteredRequests, screenshots, showScreenshots])

  const paginatedTimelineEntries = useMemo(() => {
    const startIndex = (currentPage - 1) * ITEMS_PER_PAGE
    return timelineEntries.slice(startIndex, startIndex + ITEMS_PER_PAGE)
  }, [timelineEntries, currentPage])

  const resourceTypes = useMemo(() => {
    const types = new Set(httpRequests.map(req => req.resourceType))
    return Array.from(types).sort()
  }, [httpRequests])

  const protocols = useMemo(() => {
    const protos = new Set(httpRequests.map(req => req.protocol).filter(Boolean))
    return Array.from(protos).sort()
  }, [httpRequests])

  const hostnames = useMemo(() => {
    const hosts = new Set(httpRequests.map(req => req.hostname).filter(h => h !== 'unknown'))
    return Array.from(hosts).sort()
  }, [httpRequests])

  const priorities = useMemo(() => {
    const prios = new Set(httpRequests.map(req => req.priority).filter(Boolean))
    return Array.from(prios).sort((a, b) => {
      // Sort priorities by importance: VeryHigh, High, Medium, Low, VeryLow
      const order = ['VeryHigh', 'High', 'Medium', 'Low', 'VeryLow']
      return order.indexOf(a) - order.indexOf(b)
    })
  }, [httpRequests])

  const totalPages = Math.ceil((showScreenshots ? timelineEntries.length : filteredRequests.length) / ITEMS_PER_PAGE)

  const formatDuration = (microseconds?: number) => {
    if (!microseconds) return '-'
    if (microseconds < 1000) return `${microseconds.toFixed(0)}μs`
    return `${(microseconds / 1000).toFixed(2)}ms`
  }

  const formatSize = (bytes?: number) => {
    if (!bytes) return '-'
    if (bytes < 1024) return `${bytes}B`
    if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)}KB`
    return `${(bytes / (1024 * 1024)).toFixed(1)}MB`
  }

  const getStatusColor = (status?: number) => {
    if (!status) return HIGHLIGHTING_CONFIG.COLORS.STATUS.UNKNOWN
    if (status < 300) return HIGHLIGHTING_CONFIG.COLORS.STATUS.SUCCESS
    if (status < 400) return HIGHLIGHTING_CONFIG.COLORS.STATUS.REDIRECT
    if (status < 500) return HIGHLIGHTING_CONFIG.COLORS.STATUS.CLIENT_ERROR
    return HIGHLIGHTING_CONFIG.COLORS.STATUS.SERVER_ERROR
  }

  const getProtocolColor = (protocol?: string) => {
    if (!protocol) return HIGHLIGHTING_CONFIG.COLORS.PROTOCOL.UNKNOWN
    if (protocol === 'http/1.1') return HIGHLIGHTING_CONFIG.COLORS.PROTOCOL.HTTP1_1
    if (protocol === 'h2') return HIGHLIGHTING_CONFIG.COLORS.PROTOCOL.H2
    if (protocol === 'h3') return HIGHLIGHTING_CONFIG.COLORS.PROTOCOL.H3
    return HIGHLIGHTING_CONFIG.COLORS.PROTOCOL.UNKNOWN
  }

  const getPriorityColor = (priority?: string) => {
    if (!priority) return HIGHLIGHTING_CONFIG.COLORS.PRIORITY.UNKNOWN
    if (priority === 'VeryHigh') return HIGHLIGHTING_CONFIG.COLORS.PRIORITY.VERY_HIGH
    if (priority === 'High') return HIGHLIGHTING_CONFIG.COLORS.PRIORITY.HIGH
    if (priority === 'Medium') return HIGHLIGHTING_CONFIG.COLORS.PRIORITY.MEDIUM
    if (priority === 'Low') return HIGHLIGHTING_CONFIG.COLORS.PRIORITY.LOW
    if (priority === 'VeryLow') return HIGHLIGHTING_CONFIG.COLORS.PRIORITY.VERY_LOW
    return HIGHLIGHTING_CONFIG.COLORS.PRIORITY.UNKNOWN
  }

  const getQueueAnalysisIcon = (analysis?: QueueAnalysis) => {
    if (!analysis) return ''
    switch (analysis.reason) {
      case 'connection_limit': return '🚫'
      case 'priority_queue': return '⏳'
      case 'resource_contention': return '⚠️'
      default: return '❓'
    }
  }

  const getSizeColor = (bytes?: number) => {
    if (!bytes) return HIGHLIGHTING_CONFIG.COLORS.SIZE.DEFAULT
    
    const sizeKB = bytes / 1024
    
    if (sizeKB >= HIGHLIGHTING_CONFIG.SIZE_THRESHOLDS.LARGE) {
      return HIGHLIGHTING_CONFIG.COLORS.SIZE.LARGE
    } else if (sizeKB >= HIGHLIGHTING_CONFIG.SIZE_THRESHOLDS.MEDIUM) {
      return HIGHLIGHTING_CONFIG.COLORS.SIZE.MEDIUM
    } else if (sizeKB <= HIGHLIGHTING_CONFIG.SIZE_THRESHOLDS.SMALL) {
      return HIGHLIGHTING_CONFIG.COLORS.SIZE.SMALL
    }
    
    return HIGHLIGHTING_CONFIG.COLORS.SIZE.DEFAULT
  }

  const getDurationColor = (microseconds?: number) => {
    if (!microseconds) return HIGHLIGHTING_CONFIG.COLORS.DURATION.DEFAULT
    
    const durationMs = microseconds / 1000
    
    if (durationMs > HIGHLIGHTING_CONFIG.DURATION_THRESHOLDS.SLOW) {
      return HIGHLIGHTING_CONFIG.COLORS.DURATION.SLOW
    } else if (durationMs >= HIGHLIGHTING_CONFIG.DURATION_THRESHOLDS.MEDIUM) {
      return HIGHLIGHTING_CONFIG.COLORS.DURATION.MEDIUM
    } else if (durationMs < HIGHLIGHTING_CONFIG.DURATION_THRESHOLDS.FAST) {
      return HIGHLIGHTING_CONFIG.COLORS.DURATION.FAST
    }
    
    return HIGHLIGHTING_CONFIG.COLORS.DURATION.DEFAULT
  }

  const getServerLatencyColor = (microseconds?: number) => {
    if (!microseconds) return HIGHLIGHTING_CONFIG.COLORS.SERVER_LATENCY.DEFAULT
    
    if (microseconds > HIGHLIGHTING_CONFIG.SERVER_LATENCY_THRESHOLDS.SLOW) {
      return HIGHLIGHTING_CONFIG.COLORS.SERVER_LATENCY.SLOW
    } else if (microseconds >= HIGHLIGHTING_CONFIG.SERVER_LATENCY_THRESHOLDS.MEDIUM) {
      return HIGHLIGHTING_CONFIG.COLORS.SERVER_LATENCY.MEDIUM
    } else if (microseconds < HIGHLIGHTING_CONFIG.SERVER_LATENCY_THRESHOLDS.FAST) {
      return HIGHLIGHTING_CONFIG.COLORS.SERVER_LATENCY.FAST
    }
    
    return HIGHLIGHTING_CONFIG.COLORS.SERVER_LATENCY.DEFAULT
  }

  const getCDNIcon = (analysis?: CDNAnalysis) => {
    if (!analysis) return ''
    
    const providerIcons = {
      cloudflare: '🟠',
      akamai: '🔵', 
      aws_cloudfront: '🟡',
      fastly: '⚡',
      azure_cdn: '🟦',
      google_cdn: '🟢',
      cdn77: '🟣',
      keycdn: '🔶',
      unknown: '📡'
    }
    
    const edgeIcon = analysis.isEdge ? '🌐' : '🏠'
    const cacheIcon = analysis.cacheStatus === 'hit' ? '✅' : 
                     analysis.cacheStatus === 'miss' ? '❌' : 
                     analysis.cacheStatus === 'expired' ? '⏰' : ''
    
    return `${providerIcons[analysis.provider]}${edgeIcon}${cacheIcon}`
  }

  const getCDNDisplayName = (provider: CDNAnalysis['provider']) => {
    const names = {
      cloudflare: 'Cloudflare',
      akamai: 'Akamai',
      aws_cloudfront: 'CloudFront',
      fastly: 'Fastly',
      azure_cdn: 'Azure CDN',
      google_cdn: 'Google CDN',
      cdn77: 'CDN77',
      keycdn: 'KeyCDN',
      unknown: 'Unknown CDN'
    }
    return names[provider]
  }

  const toggleRowExpansion = (requestId: string) => {
    const newExpanded = new Set(expandedRows)
    if (newExpanded.has(requestId)) {
      newExpanded.delete(requestId)
    } else {
      newExpanded.add(requestId)
    }
    setExpandedRows(newExpanded)
  }

  const truncateUrl = (url: string, maxLength: number = 60) => {
    if (url.length <= maxLength) return url
    return url.substring(0, maxLength) + '...'
  }

  if (loading) {
    return (
      <div style={{ 
        display: 'flex', 
        flexDirection: 'column',
        justifyContent: 'center', 
        alignItems: 'center', 
        minHeight: '400px',
        fontSize: '18px',
        color: '#6c757d'
      }}>
        <div style={{
          width: '50px',
          height: '50px',
          border: '4px solid #f3f3f3',
          borderTop: '4px solid #007bff',
          borderRadius: '50%',
          animation: 'spin 1s linear infinite',
          marginBottom: '20px'
        }} />
        <div>Loading HTTP requests...</div>
        <style>{`
          @keyframes spin {
            0% { transform: rotate(0deg); }
            100% { transform: rotate(360deg); }
          }
        `}</style>
      </div>
    )
  }

  if (error) {
    return (
      <div style={{ padding: '20px', textAlign: 'center' }}>
        <div style={{ 
          background: '#f8d7da', 
          color: '#721c24',
          padding: '15px', 
          borderRadius: '8px',
          border: '1px solid #f5c6cb'
        }}>
          <h3>Error Loading Trace Data</h3>
          <p>{error}</p>
        </div>
      </div>
    )
  }

  return (
    <div style={{ padding: '20px', fontFamily: 'system-ui, sans-serif' }}>
      <h2>HTTP Requests & Responses</h2>
      
      {/* Debug info - remove after investigation */}
      {traceData && (
        <div style={{ 
          background: '#f8f9fa', 
          padding: '10px', 
          borderRadius: '4px', 
          marginBottom: '10px',
          fontSize: '12px',
          color: '#6c757d'
        }}>
          <strong>Debug:</strong> Total events: {traceData.traceEvents.length.toLocaleString()}, 
          Screenshots found: {screenshots.length}, 
          HTTP requests: {httpRequests.length}
          <br />
          <strong>Categories sample:</strong> {Array.from(new Set(traceData.traceEvents.slice(0, 1000).map(e => e.cat))).slice(0, 10).join(', ')}
          <br />
          <strong>Event names sample:</strong> {Array.from(new Set(traceData.traceEvents.slice(0, 1000).map(e => e.name))).slice(0, 10).join(', ')}
        </div>
      )}
      
      {/* Controls */}
      <div style={{ 
        background: '#f8f9fa', 
        padding: '20px', 
        borderRadius: '8px',
        marginBottom: '20px',
        display: 'flex',
        flexWrap: 'wrap',
        gap: '15px',
        alignItems: 'center'
      }}>
        {/* Resource Type Filter */}
        <div style={{ display: 'flex', flexDirection: 'column', gap: '5px' }}>
          <label style={{ fontWeight: 'bold', fontSize: '14px' }}>Resource Type:</label>
          <select
            value={resourceTypeFilter}
            onChange={(e) => {
              setResourceTypeFilter(e.target.value)
              setCurrentPage(1)
            }}
            style={{
              padding: '8px 12px',
              border: '1px solid #ced4da',
              borderRadius: '4px',
              fontSize: '14px',
              minWidth: '150px'
            }}
          >
            <option value="all">All Types ({httpRequests.length})</option>
            {resourceTypes.map(type => (
              <option key={type} value={type}>
                {type} ({httpRequests.filter(r => r.resourceType === type).length})
              </option>
            ))}
          </select>
        </div>

        {/* Protocol Filter */}
        <div style={{ display: 'flex', flexDirection: 'column', gap: '5px' }}>
          <label style={{ fontWeight: 'bold', fontSize: '14px' }}>Protocol:</label>
          <select
            value={protocolFilter}
            onChange={(e) => {
              setProtocolFilter(e.target.value)
              setCurrentPage(1)
            }}
            style={{
              padding: '8px 12px',
              border: '1px solid #ced4da',
              borderRadius: '4px',
              fontSize: '14px',
              minWidth: '120px'
            }}
          >
            <option value="all">All Protocols</option>
            {protocols.map(protocol => (
              <option key={protocol} value={protocol}>
                {protocol} ({httpRequests.filter(r => r.protocol === protocol).length})
              </option>
            ))}
          </select>
        </div>

        {/* Hostname Filter */}
        <div style={{ display: 'flex', flexDirection: 'column', gap: '5px' }}>
          <label style={{ fontWeight: 'bold', fontSize: '14px' }}>Hostname:</label>
          <select
            value={hostnameFilter}
            onChange={(e) => {
              setHostnameFilter(e.target.value)
              setCurrentPage(1)
            }}
            style={{
              padding: '8px 12px',
              border: '1px solid #ced4da',
              borderRadius: '4px',
              fontSize: '14px',
              minWidth: '200px'
            }}
          >
            <option value="all">All Hostnames</option>
            {hostnames.map(hostname => (
              <option key={hostname} value={hostname}>
                {hostname} ({httpRequests.filter(r => r.hostname === hostname).length})
              </option>
            ))}
          </select>
        </div>

        {/* Priority Filter */}
        <div style={{ display: 'flex', flexDirection: 'column', gap: '5px' }}>
          <label style={{ fontWeight: 'bold', fontSize: '14px' }}>Priority:</label>
          <select
            value={priorityFilter}
            onChange={(e) => {
              setPriorityFilter(e.target.value)
              setCurrentPage(1)
            }}
            style={{
              padding: '8px 12px',
              border: '1px solid #ced4da',
              borderRadius: '4px',
              fontSize: '14px',
              minWidth: '130px'
            }}
          >
            <option value="all">All Priorities</option>
            {priorities.map(priority => (
              <option key={priority} value={priority}>
                {priority} ({httpRequests.filter(r => r.priority === priority).length})
              </option>
            ))}
          </select>
        </div>

        {/* Search */}
        <div style={{ display: 'flex', flexDirection: 'column', gap: '5px' }}>
          <label style={{ fontWeight: 'bold', fontSize: '14px' }}>Search:</label>
          <input
            type="text"
            placeholder="Search URL, method, type, or status..."
            value={searchTerm}
            onChange={(e) => {
              setSearchTerm(e.target.value)
              setCurrentPage(1)
            }}
            style={{
              padding: '8px 12px',
              border: '1px solid #ced4da',
              borderRadius: '4px',
              fontSize: '14px',
              minWidth: '300px'
            }}
          />
        </div>

        {/* Queue Analysis Toggle */}
        <div style={{ display: 'flex', flexDirection: 'column', gap: '5px' }}>
          <label style={{ fontWeight: 'bold', fontSize: '14px' }}>Queue Analysis:</label>
          <label style={{ display: 'flex', alignItems: 'center', gap: '8px', fontSize: '14px' }}>
            <input
              type="checkbox"
              checked={showQueueAnalysis}
              onChange={(e) => setShowQueueAnalysis(e.target.checked)}
              style={{ cursor: 'pointer' }}
            />
            Show queue analysis
          </label>
        </div>

        {/* 3D Viewer Toggle */}
        {httpRequests.length > 0 && (
          <div style={{ display: 'flex', flexDirection: 'column', gap: '5px' }}>
            <label style={{ fontWeight: 'bold', fontSize: '14px' }}>3D Visualization:</label>
            <label style={{ display: 'flex', alignItems: 'center', gap: '8px', fontSize: '14px' }}>
              <input
                type="checkbox"
                checked={show3DViewer}
                onChange={(e) => setShow3DViewer(e.target.checked)}
                style={{ cursor: 'pointer' }}
              />
              Show 3D Network View
            </label>
            <label style={{ display: 'flex', alignItems: 'center', gap: '8px', fontSize: '14px' }}>
              <input
                type="checkbox"
                checked={showTimelineViewer}
                onChange={(e) => setShowTimelineViewer(e.target.checked)}
                style={{ cursor: 'pointer' }}
              />
              Show 3D Timeline View
            </label>
          </div>
        )}

        {/* Screenshots Toggle */}
        {(screenshots.length > 0 || screenshotsLoading) && (
          <div style={{ display: 'flex', flexDirection: 'column', gap: '5px' }}>
            <label style={{ fontWeight: 'bold', fontSize: '14px' }}>Filmstrip:</label>
            <label style={{ display: 'flex', alignItems: 'center', gap: '8px', fontSize: '14px' }}>
              <input
                type="checkbox"
                checked={showScreenshots}
                onChange={(e) => setShowScreenshots(e.target.checked)}
                style={{ cursor: 'pointer' }}
                disabled={screenshotsLoading}
              />
              {screenshotsLoading ? (
                <span style={{ color: '#007bff' }}>
                  🔍 Analyzing screenshots with SSIM...
                </span>
              ) : (
                `Show screenshots (${screenshots.length} unique frames)`
              )}
            </label>
            {screenshots.length > 0 && !screenshotsLoading && (
              <div style={{ marginTop: '5px', fontSize: '12px' }}>
                <label style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>
                  <span>SSIM Similarity Threshold:</span>
                  <input
                    type="range"
                    min="0.8"
                    max="0.99"
                    step="0.01"
                    value={ssimThreshold}
                    onChange={(e) => setSsimThreshold(parseFloat(e.target.value))}
                    style={{ width: '100px' }}
                  />
                  <span>{ssimThreshold.toFixed(2)}</span>
                </label>
                <div style={{ fontSize: '10px', color: '#6c757d', marginTop: '2px' }}>
                  Lower values = more screenshots kept (more sensitive to changes)
                </div>
              </div>
            )}
          </div>
        )}

        {/* Results count */}
        <div style={{ 
          marginLeft: 'auto', 
          fontSize: '14px', 
          color: '#6c757d',
          fontWeight: 'bold'
        }}>
          {showScreenshots ? 
            `${timelineEntries.length.toLocaleString()} timeline entries` :
            `${filteredRequests.length.toLocaleString()} requests found`}
        </div>
      </div>

      {/* Pagination Controls */}
      {totalPages > 1 && (
        <div style={{ 
          display: 'flex', 
          justifyContent: 'center', 
          alignItems: 'center',
          gap: '10px',
          marginBottom: '20px'
        }}>
          <button
            onClick={() => setCurrentPage(Math.max(1, currentPage - 1))}
            disabled={currentPage === 1}
            style={{
              padding: '8px 16px',
              border: '1px solid #ced4da',
              borderRadius: '4px',
              background: currentPage === 1 ? '#e9ecef' : '#fff',
              cursor: currentPage === 1 ? 'not-allowed' : 'pointer'
            }}
          >
            Previous
          </button>
          
          <span style={{ margin: '0 15px', fontSize: '14px' }}>
            Page {currentPage} of {totalPages}
          </span>
          
          <button
            onClick={() => setCurrentPage(Math.min(totalPages, currentPage + 1))}
            disabled={currentPage === totalPages}
            style={{
              padding: '8px 16px',
              border: '1px solid #ced4da',
              borderRadius: '4px',
              background: currentPage === totalPages ? '#e9ecef' : '#fff',
              cursor: currentPage === totalPages ? 'not-allowed' : 'pointer'
            }}
          >
            Next
          </button>
        </div>
      )}

      {/* 3D Network Visualization Modal */}
      {show3DViewer && (
        <div style={{
          position: 'fixed',
          top: 0,
          left: 0,
          width: '100vw',
          height: '100vh',
          backgroundColor: 'rgba(0, 0, 0, 0.8)',
          display: 'flex',
          justifyContent: 'center',
          alignItems: 'center',
          zIndex: 1000
        }}>
          <div style={{
            width: '90vw',
            height: '90vh',
            background: 'white',
            borderRadius: '12px',
            display: 'flex',
            flexDirection: 'column',
            boxShadow: '0 20px 60px rgba(0, 0, 0, 0.5)'
          }}>
            <div style={{
              display: 'flex',
              alignItems: 'center',
              justifyContent: 'space-between',
              padding: '15px 20px',
              borderBottom: '1px solid #dee2e6',
              borderRadius: '12px 12px 0 0'
            }}>
              <h3 style={{ margin: '0', color: '#495057', fontSize: '18px' }}>
                3D Network Visualization ({filteredRequests.length} requests)
              </h3>
              <button
                onClick={() => setShow3DViewer(false)}
                style={{
                  background: 'transparent',
                  border: '1px solid #6c757d',
                  color: '#6c757d',
                  padding: '8px 12px',
                  borderRadius: '6px',
                  cursor: 'pointer',
                  fontSize: '14px'
                }}
              >
                ✕ Close
              </button>
            </div>
            <div style={{ flex: 1, padding: '10px' }}>
              <BabylonViewer httpRequests={filteredRequests} width={window.innerWidth * 0.9} height={window.innerHeight * 0.9 - 100} />
            </div>
            <div style={{
              padding: '15px 20px',
              fontSize: '12px',
              color: '#6c757d',
              display: 'grid',
              gridTemplateColumns: 'repeat(auto-fit, minmax(200px, 1fr))',
              gap: '10px',
              borderTop: '1px solid #dee2e6',
              borderRadius: '0 0 12px 12px',
              backgroundColor: '#f8f9fa'
            }}>
              <div><strong>Legend:</strong></div>
              <div>⬛→⬜ Gray gradient: 2xx Success (darker=lower, lighter=higher)</div>
              <div>🟡 Yellow: 3xx Redirects</div>
              <div>🟠 Orange: 4xx Client Errors</div>
              <div>🔴 Red: 5xx Server Errors</div>
              <div><strong>Layout:</strong></div>
              <div>🔵 Central sphere: Origin</div>
              <div>🏷️ Hostname labels: At 12m radius</div>
              <div>📦 Request boxes: Start → end timeline</div>
              <div>📏 Front face: Request start time</div>
              <div>📐 Height: 0.1m-5m (content-length)</div>
              <div>📊 Depth: Request duration</div>
              <div>📚 Overlapping requests stack vertically</div>
              <div>🔗 Connection lines to center</div>
              <div>👁️ Labels always face camera</div>
            </div>
          </div>
        </div>
      )}

      {/* 3D Timeline Visualization Modal */}
      {showTimelineViewer && (
        <div style={{
          position: 'fixed',
          top: 0,
          left: 0,
          width: '100vw',
          height: '100vh',
          backgroundColor: 'rgba(0, 0, 0, 0.8)',
          display: 'flex',
          justifyContent: 'center',
          alignItems: 'center',
          zIndex: 1000
        }}>
          <div style={{
            width: '90vw',
            height: '90vh',
            background: 'white',
            borderRadius: '12px',
            display: 'flex',
            flexDirection: 'column',
            boxShadow: '0 20px 60px rgba(0, 0, 0, 0.5)'
          }}>
            <div style={{
              display: 'flex',
              alignItems: 'center',
              justifyContent: 'space-between',
              padding: '15px 20px',
              borderBottom: '1px solid #dee2e6',
              borderRadius: '12px 12px 0 0'
            }}>
              <h3 style={{ margin: '0', color: '#495057', fontSize: '18px' }}>
                3D Timeline Visualization ({filteredRequests.length} requests)
              </h3>
              <button
                onClick={() => setShowTimelineViewer(false)}
                style={{
                  background: 'transparent',
                  border: '1px solid #6c757d',
                  color: '#6c757d',
                  padding: '8px 12px',
                  borderRadius: '6px',
                  cursor: 'pointer',
                  fontSize: '14px'
                }}
              >
                ✕ Close
              </button>
            </div>
            <div style={{ flex: 1, padding: '10px' }}>
              <BabylonTimelineViewer httpRequests={filteredRequests} width={window.innerWidth * 0.9} height={window.innerHeight * 0.9 - 100} />
            </div>
            <div style={{
              padding: '15px 20px',
              fontSize: '12px',
              color: '#6c757d',
              display: 'grid',
              gridTemplateColumns: 'repeat(auto-fit, minmax(200px, 1fr))',
              gap: '10px',
              borderTop: '1px solid #dee2e6',
              borderRadius: '0 0 12px 12px',
              backgroundColor: '#f8f9fa'
            }}>
              <div><strong>Legend:</strong></div>
              <div>⬛→⬜ Gray gradient: 2xx Success (darker=lower, lighter=higher)</div>
              <div>🟡 Yellow: 3xx Redirects</div>
              <div>🟠 Orange: 4xx Client Errors</div>
              <div>🔴 Red: 5xx Server Errors</div>
              <div><strong>Timeline Layout:</strong></div>
              <div>🔵 Central sphere: Timeline origin</div>
              <div>🏷️ Hostname labels: At 12m radius</div>
              <div>📦 Request boxes: Chronological timeline</div>
              <div>📏 Distance from center: Start time</div>
              <div>📐 Height: 0.1m-5m (content-length)</div>
              <div>📊 Depth: Request duration</div>
              <div>📚 Overlapping requests stack vertically</div>
              <div>🔗 Connection lines to center</div>
              <div>👁️ Labels face origin (180° rotated)</div>
            </div>
          </div>
        </div>
      )}

      {/* Requests Table */}
      <div style={{ 
        background: 'white', 
        border: '1px solid #dee2e6', 
        borderRadius: '8px',
        overflow: 'hidden'
      }}>
        <table style={{ width: '100%', borderCollapse: 'collapse' }}>
          <thead>
            <tr style={{ background: '#f8f9fa' }}>
              <th style={{ padding: '8px', textAlign: 'center', borderBottom: '1px solid #dee2e6', fontSize: '12px', width: '30px' }}>Expand</th>
              <th style={{ padding: '8px', textAlign: 'left', borderBottom: '1px solid #dee2e6', fontSize: '12px' }}>Method</th>
              <th style={{ padding: '8px', textAlign: 'center', borderBottom: '1px solid #dee2e6', fontSize: '12px' }}>Status</th>
              <th style={{ padding: '8px', textAlign: 'left', borderBottom: '1px solid #dee2e6', fontSize: '12px' }}>Type</th>
              <th style={{ padding: '8px', textAlign: 'center', borderBottom: '1px solid #dee2e6', fontSize: '12px' }}>Priority</th>
              <th style={{ padding: '8px', textAlign: 'right', borderBottom: '1px solid #dee2e6', fontSize: '12px' }}>Start Time</th>
              <th style={{ padding: '8px', textAlign: 'right', borderBottom: '1px solid #dee2e6', fontSize: '12px' }}>Queue Time</th>
              <th style={{ padding: '8px', textAlign: 'right', borderBottom: '1px solid #dee2e6', fontSize: '12px' }}>Server Latency</th>
              <th style={{ padding: '8px', textAlign: 'left', borderBottom: '1px solid #dee2e6', fontSize: '12px' }}>URL</th>
              <th style={{ padding: '8px', textAlign: 'right', borderBottom: '1px solid #dee2e6', fontSize: '12px' }}>Duration</th>
              <th style={{ padding: '8px', textAlign: 'right', borderBottom: '1px solid #dee2e6', fontSize: '12px' }}>Size</th>
              <th style={{ padding: '8px', textAlign: 'right', borderBottom: '1px solid #dee2e6', fontSize: '12px' }}>Content-Length</th>
              <th style={{ padding: '8px', textAlign: 'center', borderBottom: '1px solid #dee2e6', fontSize: '12px' }}>Protocol</th>
              <th style={{ padding: '8px', textAlign: 'center', borderBottom: '1px solid #dee2e6', fontSize: '12px' }}>CDN</th>
              <th style={{ padding: '8px', textAlign: 'center', borderBottom: '1px solid #dee2e6', fontSize: '12px' }}>Cache</th>
            </tr>
          </thead>
          <tbody>
            {(showScreenshots ? paginatedTimelineEntries : paginatedRequests.map(req => ({ type: 'request' as const, timestamp: req.timing.start, data: req }))).map((entry, entryIndex) => {
              if (entry.type === 'screenshot') {
                const screenshot = entry.data as ScreenshotEvent
                const firstRequestTime = httpRequests.length > 0 ? httpRequests[0].timing.start : 0
                const timeOffset = screenshot.timestamp - firstRequestTime
                
                return (
                  <tr key={`screenshot-${screenshot.index}`} style={{
                    backgroundColor: '#f0f8ff',
                    borderBottom: '2px solid #007bff'
                  }}>
                    <td colSpan={13} style={{ padding: '15px' }}>
                      <div style={{ display: 'flex', alignItems: 'center', gap: '15px' }}>
                        <div style={{
                          fontSize: '14px',
                          fontWeight: 'bold',
                          color: '#007bff',
                          minWidth: '120px'
                        }}>
                          📸 Screenshot
                        </div>
                        <div style={{
                          fontSize: '12px',
                          color: '#495057',
                          fontFamily: 'monospace'
                        }}>
                          <strong>Time:</strong> {formatDuration(timeOffset)}
                        </div>
                        <img
                          src={screenshot.screenshot}
                          alt={`Screenshot at ${formatDuration(timeOffset)}`}
                          style={{
                            maxWidth: '200px',
                            maxHeight: '150px',
                            border: '2px solid #007bff',
                            borderRadius: '4px',
                            cursor: 'pointer'
                          }}
                          onClick={() => {
                            // Open screenshot in new window for full size viewing
                            const newWindow = window.open('', '_blank')
                            if (newWindow) {
                              newWindow.document.write(`
                                <html>
                                  <head><title>Screenshot at ${formatDuration(timeOffset)}</title></head>
                                  <body style="margin:0;padding:20px;background:#000;display:flex;justify-content:center;align-items:center;min-height:100vh;">
                                    <img src="${screenshot.screenshot}" style="max-width:100%;max-height:100vh;border-radius:4px;box-shadow:0 4px 20px rgba(0,0,0,0.5);" alt="Full size screenshot" />
                                  </body>
                                </html>
                              `)
                            }
                          }}
                        />
                        <div style={{
                          fontSize: '11px',
                          color: '#6c757d',
                          fontStyle: 'italic'
                        }}>
                          Click to view full size
                        </div>
                      </div>
                    </td>
                  </tr>
                )
              }
              
              const request = entry.data as HTTPRequest
              const isExpanded = expandedRows.has(request.requestId)
              
              return (
                <>
                  <tr key={request.requestId} style={{ 
                    borderBottom: '1px solid #f1f3f4',
                    cursor: 'pointer'
                  }}
                  onClick={() => toggleRowExpansion(request.requestId)}
                  >
                    <td style={{ 
                      padding: '8px', 
                      textAlign: 'center',
                      fontSize: '12px',
                      color: '#007bff',
                      fontWeight: 'bold'
                    }}>
                      {isExpanded ? '−' : '+'}
                    </td>
                    <td style={{ 
                      padding: '8px', 
                      fontSize: '12px', 
                      fontFamily: 'monospace',
                      fontWeight: 'bold',
                      color: request.method === 'GET' ? '#28a745' : '#007bff'
                    }}>
                      {request.method}
                    </td>
                    <td style={{ 
                      padding: '8px', 
                      fontSize: '12px', 
                      textAlign: 'center',
                      fontFamily: 'monospace',
                      fontWeight: 'bold',
                      color: getStatusColor(request.statusCode)
                    }}>
                      {request.statusCode || '-'}
                    </td>
                    <td style={{ padding: '8px', fontSize: '12px', color: '#6c757d' }}>
                      {request.resourceType}
                    </td>
                    <td style={{ 
                      padding: '8px', 
                      fontSize: '12px', 
                      textAlign: 'center',
                      fontFamily: 'monospace',
                      color: getPriorityColor(request.priority),
                      fontWeight: 'bold'
                    }}>
                      {request.priority || '-'}
                    </td>
                    <td style={{ padding: '8px', fontSize: '12px', textAlign: 'right', fontFamily: 'monospace', color: '#495057' }}>
                      {formatDuration(request.timing.startOffset)}
                    </td>
                    <td style={{ 
                      padding: '8px', 
                      fontSize: '12px', 
                      textAlign: 'right', 
                      fontFamily: 'monospace',
                      color: request.timing.queueTime && request.timing.queueTime > HIGHLIGHTING_CONFIG.QUEUE_TIME.HIGH_THRESHOLD ? HIGHLIGHTING_CONFIG.COLORS.STATUS.SERVER_ERROR : '#495057',
                      fontWeight: request.timing.queueTime && request.timing.queueTime > HIGHLIGHTING_CONFIG.QUEUE_TIME.HIGH_THRESHOLD ? 'bold' : 'normal'
                    }}>
                      <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'flex-end', gap: '4px' }}>
                        {formatDuration(request.timing.queueTime)}
                        {showQueueAnalysis && request.queueAnalysis && (
                          <span 
                            title={request.queueAnalysis.description}
                            style={{ cursor: 'help', fontSize: '14px' }}
                          >
                            {getQueueAnalysisIcon(request.queueAnalysis)}
                          </span>
                        )}
                      </div>
                    </td>
                    <td style={{ 
                      padding: '8px', 
                      fontSize: '12px', 
                      textAlign: 'right', 
                      fontFamily: 'monospace',
                      ...getServerLatencyColor(request.timing.serverLatency),
                      borderRadius: '4px',
                      fontWeight: 'bold'
                    }}>
                      {formatDuration(request.timing.serverLatency)}
                    </td>
                    <td style={{ padding: '8px', fontSize: '11px', maxWidth: '400px', overflow: 'hidden', textOverflow: 'ellipsis' }}>
                      <a href={request.url} target="_blank" rel="noopener noreferrer" style={{ color: '#007bff', textDecoration: 'none' }}>
                        {truncateUrl(request.url)}
                      </a>
                    </td>
                    <td style={{ 
                      padding: '8px', 
                      fontSize: '12px', 
                      textAlign: 'right', 
                      fontFamily: 'monospace',
                      ...getDurationColor(request.timing.duration),
                      borderRadius: '4px',
                      fontWeight: 'bold'
                    }}>
                      {formatDuration(request.timing.duration)}
                    </td>
                    <td style={{ 
                      padding: '8px', 
                      fontSize: '12px', 
                      textAlign: 'right', 
                      fontFamily: 'monospace',
                      ...getSizeColor(request.encodedDataLength),
                      borderRadius: '4px',
                      fontWeight: 'bold'
                    }}>
                      {formatSize(request.encodedDataLength)}
                    </td>
                    <td style={{ 
                      padding: '8px', 
                      fontSize: '12px', 
                      textAlign: 'right', 
                      fontFamily: 'monospace',
                      ...getSizeColor(request.contentLength),
                      borderRadius: '4px',
                      fontWeight: 'bold'
                    }}>
                      {request.contentLength ? formatSize(request.contentLength) : '-'}
                    </td>
                    <td style={{ 
                      padding: '8px', 
                      fontSize: '12px', 
                      textAlign: 'center', 
                      fontFamily: 'monospace',
                      color: getProtocolColor(request.protocol),
                      fontWeight: 'bold'
                    }}>
                      {request.protocol || '-'}
                    </td>
                    <td style={{ 
                      padding: '8px', 
                      fontSize: '12px', 
                      textAlign: 'center',
                      cursor: request.cdnAnalysis ? 'help' : 'default'
                    }}
                    title={request.cdnAnalysis ? 
                      `${getCDNDisplayName(request.cdnAnalysis.provider)} ${request.cdnAnalysis.isEdge ? '(Edge)' : '(Origin)'} - ${request.cdnAnalysis.detectionMethod}` : 
                      'No CDN detected'}
                    >
                      {request.cdnAnalysis ? getCDNIcon(request.cdnAnalysis) : '-'}
                    </td>
                    <td style={{ padding: '8px', fontSize: '12px', textAlign: 'center' }}>
                      {request.fromCache ? '💾' : request.connectionReused ? '🔄' : '🌐'}
                    </td>
                  </tr>
                  
                  {/* Expanded Row Details */}
                  {isExpanded && (
                    <tr key={`${request.requestId}-expanded`}>
                      <td colSpan={13} style={{ 
                        padding: '15px', 
                        background: '#f8f9fa',
                        border: '1px solid #e9ecef'
                      }}>
                        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(300px, 1fr))', gap: '15px' }}>
                          
                          {/* Request Details */}
                          <div style={{ background: 'white', padding: '10px', borderRadius: '4px', border: '1px solid #dee2e6' }}>
                            <h4 style={{ margin: '0 0 8px 0', color: '#495057', fontSize: '14px' }}>Request Details</h4>
                            <div style={{ fontSize: '12px', display: 'flex', flexDirection: 'column', gap: '4px' }}>
                              <div><strong>Request ID:</strong> {request.requestId}</div>
                              <div><strong>Method:</strong> {request.method}</div>
                              <div><strong>Priority:</strong> {request.priority}</div>
                              <div><strong>MIME Type:</strong> {request.mimeType || '-'}</div>
                              <div><strong>Content-Length:</strong> {request.contentLength ? formatSize(request.contentLength) : '-'}</div>
                              <div><strong>From Cache:</strong> {request.fromCache ? 'Yes' : 'No'}</div>
                              <div><strong>Connection Reused:</strong> {request.connectionReused ? 'Yes' : 'No'}</div>
                            </div>
                          </div>

                          {/* Network Timing */}
                          <div style={{ background: 'white', padding: '10px', borderRadius: '4px', border: '1px solid #dee2e6' }}>
                            <h4 style={{ margin: '0 0 8px 0', color: '#495057', fontSize: '14px' }}>Network Timing</h4>
                            <div style={{ fontSize: '12px', display: 'flex', flexDirection: 'column', gap: '4px' }}>
                              <div><strong>Start Time:</strong> {formatDuration(request.timing.startOffset)}</div>
                              <div style={{ display: 'flex', alignItems: 'center', gap: '4px' }}>
                                <strong>Queue Time:</strong> {formatDuration(request.timing.queueTime)}
                                {request.queueAnalysis && (
                                  <span title={request.queueAnalysis.description} style={{ cursor: 'help' }}>
                                    {getQueueAnalysisIcon(request.queueAnalysis)}
                                  </span>
                                )}
                              </div>
                              <div><strong>Server Latency:</strong> {formatDuration(request.timing.serverLatency)}</div>
                              <div><strong>Total Duration:</strong> {formatDuration(request.timing.duration)}</div>
                              <div><strong>Network Duration:</strong> {formatDuration(request.timing.networkDuration)}</div>
                              {request.timing.dnsStart !== -1 && request.timing.dnsEnd !== -1 && (
                                <div><strong>DNS:</strong> {formatDuration((request.timing.dnsEnd || 0) - (request.timing.dnsStart || 0))}</div>
                              )}
                              {request.timing.connectStart !== -1 && request.timing.connectEnd !== -1 && (
                                <div><strong>Connect:</strong> {formatDuration((request.timing.connectEnd || 0) - (request.timing.connectStart || 0))}</div>
                              )}
                              {request.timing.sslStart !== -1 && request.timing.sslEnd !== -1 && (
                                <div><strong>SSL:</strong> {formatDuration((request.timing.sslEnd || 0) - (request.timing.sslStart || 0))}</div>
                              )}
                              {request.timing.sendStart !== -1 && request.timing.sendEnd !== -1 && (
                                <div><strong>Send:</strong> {formatDuration((request.timing.sendEnd || 0) - (request.timing.sendStart || 0))}</div>
                              )}
                              {request.timing.receiveHeadersStart !== -1 && request.timing.receiveHeadersEnd !== -1 && (
                                <div><strong>Receive Headers:</strong> {formatDuration((request.timing.receiveHeadersEnd || 0) - (request.timing.receiveHeadersStart || 0))}</div>
                              )}
                            </div>
                          </div>

                          {/* Queue Analysis */}
                          {request.queueAnalysis && request.queueAnalysis.reason !== 'unknown' && (
                            <div style={{ background: 'white', padding: '10px', borderRadius: '4px', border: '1px solid #dee2e6' }}>
                              <h4 style={{ margin: '0 0 8px 0', color: '#495057', fontSize: '14px' }}>
                                Queue Analysis {getQueueAnalysisIcon(request.queueAnalysis)}
                              </h4>
                              <div style={{ fontSize: '12px', display: 'flex', flexDirection: 'column', gap: '4px' }}>
                                <div><strong>Reason:</strong> {request.queueAnalysis.description}</div>
                                <div><strong>Concurrent Requests:</strong> {request.queueAnalysis.concurrentRequests}</div>
                                {request.queueAnalysis.relatedRequests && request.queueAnalysis.relatedRequests.length > 0 && (
                                  <div>
                                    <strong>Related Request IDs:</strong>{' '}
                                    <span style={{ fontFamily: 'monospace', fontSize: '11px' }}>
                                      {request.queueAnalysis.relatedRequests.join(', ')}
                                      {request.queueAnalysis.concurrentRequests > request.queueAnalysis.relatedRequests.length && 
                                        ` (+${request.queueAnalysis.concurrentRequests - request.queueAnalysis.relatedRequests.length} more)`}
                                    </span>
                                  </div>
                                )}
                              </div>
                            </div>
                          )}

                          {/* CDN Analysis */}
                          {request.cdnAnalysis && request.cdnAnalysis.provider !== 'unknown' && (
                            <div style={{ background: 'white', padding: '10px', borderRadius: '4px', border: '1px solid #dee2e6' }}>
                              <h4 style={{ margin: '0 0 8px 0', color: '#495057', fontSize: '14px' }}>
                                CDN Analysis {getCDNIcon(request.cdnAnalysis)}
                              </h4>
                              <div style={{ fontSize: '12px', display: 'flex', flexDirection: 'column', gap: '4px' }}>
                                <div><strong>Provider:</strong> {getCDNDisplayName(request.cdnAnalysis.provider)}</div>
                                <div><strong>Source:</strong> {request.cdnAnalysis.isEdge ? 'Edge Server' : 'Origin Server'}</div>
                                {request.cdnAnalysis.cacheStatus && request.cdnAnalysis.cacheStatus !== 'unknown' && (
                                  <div><strong>Cache Status:</strong> {request.cdnAnalysis.cacheStatus.toUpperCase()}</div>
                                )}
                                {request.cdnAnalysis.edgeLocation && (
                                  <div><strong>Edge Location:</strong> {request.cdnAnalysis.edgeLocation}</div>
                                )}
                                <div><strong>Confidence:</strong> {(request.cdnAnalysis.confidence * 100).toFixed(0)}%</div>
                                <div><strong>Detection Method:</strong> {request.cdnAnalysis.detectionMethod}</div>
                                
                                {/* Debug info for canadiantire.ca requests */}
                                {request.hostname.includes('canadiantire.ca') && (
                                  <div style={{ 
                                    marginTop: '8px', 
                                    padding: '8px', 
                                    background: '#fff3cd', 
                                    border: '1px solid #ffeaa7',
                                    borderRadius: '4px' 
                                  }}>
                                    <div style={{ fontWeight: 'bold', marginBottom: '4px' }}>
                                      Debug - CDN Detection Analysis:
                                    </div>
                                    <div style={{ marginBottom: '6px', fontSize: '11px' }}>
                                      <strong>Current Detection:</strong> {request.cdnAnalysis?.provider} 
                                      (confidence: {((request.cdnAnalysis?.confidence || 0) * 100).toFixed(0)}%)
                                    </div>
                                    <div style={{ fontWeight: 'bold', fontSize: '10px', marginBottom: '2px' }}>
                                      All CDN-Related Headers:
                                    </div>
                                    {request.responseHeaders && request.responseHeaders.map((header, idx) => {
                                      const headerName = header.name.toLowerCase()
                                      // Show all potentially CDN-related headers
                                      if (headerName.includes('akamai') || 
                                          headerName.includes('fastly') || 
                                          headerName.includes('server') ||
                                          headerName.includes('via') ||
                                          headerName.includes('x-cache') ||
                                          headerName.includes('x-serial') ||
                                          headerName.includes('x-served-by') ||
                                          headerName.includes('cf-') ||
                                          headerName.includes('x-amz-cf') ||
                                          headerName.includes('azure') ||
                                          headerName.includes('x-goog') ||
                                          headerName.includes('cdn') ||
                                          headerName.includes('edge') ||
                                          headerName.includes('cache')) {
                                        const isAkamaiIndicator = headerName.includes('akamai') || 
                                                                headerName.includes('x-serial') ||
                                                                (headerName === 'x-cache' && header.value.includes('tcp_')) ||
                                                                (headerName === 'x-served-by' && header.value.includes('cache-'))
                                        return (
                                          <div key={idx} style={{ 
                                            fontSize: '9px', 
                                            fontFamily: 'monospace',
                                            backgroundColor: isAkamaiIndicator ? '#d1ecf1' : 'transparent',
                                            padding: isAkamaiIndicator ? '1px 3px' : '0',
                                            borderRadius: isAkamaiIndicator ? '2px' : '0',
                                            marginBottom: '1px'
                                          }}>
                                            <span style={{ 
                                              color: isAkamaiIndicator ? '#0c5460' : '#007bff', 
                                              fontWeight: 'bold' 
                                            }}>
                                              {header.name}:
                                            </span> {header.value}
                                            {isAkamaiIndicator && (
                                              <span style={{ color: '#0c5460', fontWeight: 'bold', marginLeft: '5px' }}>
                                                ← AKAMAI
                                              </span>
                                            )}
                                          </div>
                                        )
                                      }
                                      return null
                                    })}
                                  </div>
                                )}
                              </div>
                            </div>
                          )}

                          {/* Response Headers */}
                          {request.responseHeaders && request.responseHeaders.length > 0 && (
                            <div style={{ 
                              background: 'white', 
                              padding: '10px', 
                              borderRadius: '4px', 
                              border: '1px solid #dee2e6',
                              gridColumn: '1 / -1'
                            }}>
                              <h4 style={{ margin: '0 0 8px 0', color: '#495057', fontSize: '14px' }}>
                                Response Headers ({request.responseHeaders.length})
                              </h4>
                              <div style={{ 
                                maxHeight: '150px', 
                                overflowY: 'auto', 
                                fontSize: '11px', 
                                fontFamily: 'monospace',
                                background: '#f8f9fa',
                                padding: '8px',
                                borderRadius: '3px'
                              }}>
                                {request.responseHeaders.map((header, index) => (
                                  <div key={index} style={{ 
                                    marginBottom: '2px',
                                    display: 'grid',
                                    gridTemplateColumns: '150px 1fr',
                                    gap: '10px'
                                  }}>
                                    <div style={{ color: '#007bff', fontWeight: 'bold' }}>
                                      {header.name}:
                                    </div>
                                    <div style={{ color: '#495057', wordBreak: 'break-all' }}>
                                      {header.value}
                                    </div>
                                  </div>
                                ))}
                              </div>
                            </div>
                          )}

                        </div>
                      </td>
                    </tr>
                  )}
                </>
              )
            })}
          </tbody>
        </table>
      </div>

      {(showScreenshots ? paginatedTimelineEntries.length === 0 : paginatedRequests.length === 0) && (
        <div style={{ 
          textAlign: 'center', 
          padding: '40px', 
          color: '#6c757d',
          fontSize: '16px'
        }}>
          {showScreenshots ? 
            'No timeline entries found matching the current filters' : 
            'No HTTP requests found matching the current filters'}
        </div>
      )}
    </div>
  )
}