import { useState, useMemo } from 'react'
import { useDatabaseTraceData } from '../hooks/useDatabaseTraceData'
import type { TraceEventPhase } from '../../types/trace'

interface ExtendedTraceEvent {
  args: Record<string, unknown>
  cat: string
  name: string
  ph: TraceEventPhase
  pid: number
  tid: number
  ts: number
  tts?: number
  dur?: number
  tdur?: number
}

const PHASE_DESCRIPTIONS: Record<string, string> = {
  'M': 'Metadata',
  'X': 'Complete Events',
  'I': 'Instant Events',
  'B': 'Begin Events',
  'E': 'End Events',
  'D': 'Deprecated',
  'b': 'Nestable Start',
  'e': 'Nestable End',
  'n': 'Nestable Instant',
  'S': 'Async Start',
  'T': 'Async Instant',
  'F': 'Async End',
  'P': 'Sample',
  'C': 'Counter',
  'R': 'Mark'
}

const ITEMS_PER_PAGE = 50

// Helper functions to extract valuable fields
const getURL = (event: ExtendedTraceEvent): string | null => {
  const args = event.args as any
  return args?.url || args?.beginData?.url || args?.data?.frames?.[0]?.url || null
}

const getStackTrace = (event: ExtendedTraceEvent): any[] | null => {
  const args = event.args as any
  return args?.beginData?.stackTrace || null
}


const getScriptInfo = (event: ExtendedTraceEvent): { contextId?: number, scriptId?: number } => {
  const args = event.args as any
  return {
    contextId: args?.data?.executionContextId,
    scriptId: args?.data?.scriptId
  }
}

const getLayoutInfo = (event: ExtendedTraceEvent): { dirtyObjects?: number, totalObjects?: number, elementCount?: number } => {
  const args = event.args as any
  return {
    dirtyObjects: args?.beginData?.dirtyObjects,
    totalObjects: args?.beginData?.totalObjects,
    elementCount: args?.elementCount
  }
}

const getSampleTraceId = (event: ExtendedTraceEvent): number | null => {
  const args = event.args as any
  return args?.beginData?.sampleTraceId || null
}

interface PhaseViewerProps {
  traceId: string | null
}

export default function PhaseViewer({ traceId }: PhaseViewerProps) {
  const { traceData, loading, error, stats } = useDatabaseTraceData(traceId)
  const [selectedPhase, setSelectedPhase] = useState<string>('all')
  const [currentPage, setCurrentPage] = useState(1)
  const [searchTerm, setSearchTerm] = useState('')
  const [expandedRows, setExpandedRows] = useState<Set<string>>(new Set())

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

    let events = traceData.traceEvents

    // Filter by phase
    if (selectedPhase !== 'all') {
      events = events.filter(event => event.ph === selectedPhase)
    }

    // Filter by search term
    if (searchTerm) {
      const term = searchTerm.toLowerCase()
      events = events.filter(event => 
        event.name.toLowerCase().includes(term) ||
        event.cat.toLowerCase().includes(term) ||
        event.pid.toString().includes(term) ||
        event.tid.toString().includes(term)
      )
    }

    return events
  }, [traceData, selectedPhase, searchTerm])

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

  const totalPages = Math.ceil(filteredEvents.length / ITEMS_PER_PAGE)

  const formatTimestamp = (ts: number) => {
    return (ts / 1000).toFixed(3) + 'ms'
  }

  const formatDuration = (dur?: number) => {
    if (!dur) return '-'
    return (dur / 1000).toFixed(3) + 'ms'
  }

  const formatThreadTime = (tts?: number) => {
    if (!tts) return '-'
    return (tts / 1000).toFixed(3) + 'ms'
  }

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

  const truncateText = (text: string, maxLength: number = 50) => {
    if (text.length <= maxLength) return text
    return text.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 trace events...</div>
      </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>
    )
  }

  if (!traceData || !stats) {
    return <div style={{ padding: '20px', textAlign: 'center' }}>No trace data available</div>
  }

  const phaseOptions = Object.keys(stats.eventsByPhase).sort()

  return (
    <div style={{ padding: '20px', fontFamily: 'system-ui, sans-serif' }}>
      <h2>Phase Event Viewer</h2>
      
      {/* Controls */}
      <div style={{ 
        background: '#f8f9fa', 
        padding: '20px', 
        borderRadius: '8px',
        marginBottom: '20px',
        display: 'flex',
        flexWrap: 'wrap',
        gap: '15px',
        alignItems: 'center'
      }}>
        {/* Phase Filter */}
        <div style={{ display: 'flex', flexDirection: 'column', gap: '5px' }}>
          <label style={{ fontWeight: 'bold', fontSize: '14px' }}>Filter by Phase:</label>
          <select
            value={selectedPhase}
            onChange={(e) => {
              setSelectedPhase(e.target.value)
              setCurrentPage(1)
            }}
            style={{
              padding: '8px 12px',
              border: '1px solid #ced4da',
              borderRadius: '4px',
              fontSize: '14px',
              minWidth: '200px'
            }}
          >
            <option value="all">All Phases ({stats.totalEvents.toLocaleString()})</option>
            {phaseOptions.map(phase => (
              <option key={phase} value={phase}>
                {phase} - {PHASE_DESCRIPTIONS[phase] || 'Unknown'} ({stats.eventsByPhase[phase].toLocaleString()})
              </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 by name, category, PID, or TID..."
            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>

        {/* Results count */}
        <div style={{ 
          marginLeft: 'auto', 
          fontSize: '14px', 
          color: '#6c757d',
          fontWeight: 'bold'
        }}>
          {filteredEvents.length.toLocaleString()} events 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>
      )}

      {/* Events 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: 'center', borderBottom: '1px solid #dee2e6', fontSize: '12px', width: '50px' }}>Phase</th>
              <th style={{ padding: '8px', textAlign: 'left', borderBottom: '1px solid #dee2e6', fontSize: '12px' }}>Name</th>
              <th style={{ padding: '8px', textAlign: 'left', borderBottom: '1px solid #dee2e6', fontSize: '12px' }}>Category</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' }}>Thread Time</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' }}>PID</th>
              <th style={{ padding: '8px', textAlign: 'right', borderBottom: '1px solid #dee2e6', fontSize: '12px' }}>TID</th>
            </tr>
          </thead>
          <tbody>
            {paginatedEvents.map((event, index) => {
              const eventKey = `${event.pid}-${event.tid}-${event.ts}-${index}`
              const isExpanded = expandedRows.has(eventKey)
              const url = getURL(event as ExtendedTraceEvent)
              const stackTrace = getStackTrace(event as ExtendedTraceEvent)
              const layoutInfo = getLayoutInfo(event as ExtendedTraceEvent)
              const scriptInfo = getScriptInfo(event as ExtendedTraceEvent)
              const sampleTraceId = getSampleTraceId(event as ExtendedTraceEvent)
              
              return (
                <>
                  <tr key={eventKey} style={{ 
                    borderBottom: '1px solid #f1f3f4',
                    cursor: 'pointer'
                  }}
                  onClick={() => toggleRowExpansion(eventKey)}
                  >
                    <td style={{ 
                      padding: '8px', 
                      textAlign: 'center',
                      fontSize: '12px',
                      color: '#007bff',
                      fontWeight: 'bold'
                    }}>
                      {isExpanded ? '−' : '+'}
                    </td>
                    <td style={{ 
                      padding: '8px', 
                      fontSize: '12px', 
                      fontFamily: 'monospace',
                      background: getPhaseColor(event.ph),
                      color: 'white',
                      fontWeight: 'bold',
                      textAlign: 'center'
                    }}>
                      {event.ph}
                    </td>
                    <td style={{ padding: '8px', fontSize: '12px', maxWidth: '200px', overflow: 'hidden', textOverflow: 'ellipsis' }}>
                      {event.name}
                    </td>
                    <td style={{ padding: '8px', fontSize: '12px', color: '#6c757d', maxWidth: '120px', overflow: 'hidden', textOverflow: 'ellipsis' }}>
                      {event.cat}
                    </td>
                    <td style={{ padding: '8px', fontSize: '12px', textAlign: 'right', fontFamily: 'monospace' }}>
                      {formatDuration((event as ExtendedTraceEvent).dur)}
                    </td>
                    <td style={{ padding: '8px', fontSize: '12px', textAlign: 'right', fontFamily: 'monospace' }}>
                      {formatThreadTime((event as ExtendedTraceEvent).tts)}
                    </td>
                    <td style={{ padding: '8px', fontSize: '11px', color: '#007bff', maxWidth: '200px', overflow: 'hidden', textOverflow: 'ellipsis' }}>
                      {url ? (
                        <a href={url} target="_blank" rel="noopener noreferrer" style={{ color: '#007bff', textDecoration: 'none' }}>
                          {truncateText(url, 40)}
                        </a>
                      ) : '-'}
                    </td>
                    <td style={{ padding: '8px', fontSize: '12px', textAlign: 'right', fontFamily: 'monospace' }}>
                      {event.pid}
                    </td>
                    <td style={{ padding: '8px', fontSize: '12px', textAlign: 'right', fontFamily: 'monospace' }}>
                      {event.tid}
                    </td>
                  </tr>
                  
                  {/* Expanded Row Details */}
                  {isExpanded && (
                    <tr key={`${eventKey}-expanded`}>
                      <td colSpan={9} style={{ 
                        padding: '15px', 
                        background: '#f8f9fa',
                        border: '1px solid #e9ecef'
                      }}>
                        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(300px, 1fr))', gap: '15px' }}>
                          
                          {/* Timing Information */}
                          <div style={{ background: 'white', padding: '10px', borderRadius: '4px', border: '1px solid #dee2e6' }}>
                            <h4 style={{ margin: '0 0 8px 0', color: '#495057', fontSize: '14px' }}>Timing</h4>
                            <div style={{ fontSize: '12px', display: 'flex', flexDirection: 'column', gap: '4px' }}>
                              <div><strong>Timestamp:</strong> {formatTimestamp(event.ts)}</div>
                              <div><strong>Duration:</strong> {formatDuration((event as ExtendedTraceEvent).dur)}</div>
                              <div><strong>Thread Duration:</strong> {formatDuration((event as ExtendedTraceEvent).tdur)}</div>
                              <div><strong>Thread Time:</strong> {formatThreadTime((event as ExtendedTraceEvent).tts)}</div>
                              {sampleTraceId && <div><strong>Sample Trace ID:</strong> {sampleTraceId}</div>}
                            </div>
                          </div>

                          {/* Script/Context Information */}
                          {(scriptInfo.contextId || scriptInfo.scriptId) && (
                            <div style={{ background: 'white', padding: '10px', borderRadius: '4px', border: '1px solid #dee2e6' }}>
                              <h4 style={{ margin: '0 0 8px 0', color: '#495057', fontSize: '14px' }}>Script Context</h4>
                              <div style={{ fontSize: '12px', display: 'flex', flexDirection: 'column', gap: '4px' }}>
                                {scriptInfo.contextId && <div><strong>Execution Context:</strong> {scriptInfo.contextId}</div>}
                                {scriptInfo.scriptId && <div><strong>Script ID:</strong> {scriptInfo.scriptId}</div>}
                              </div>
                            </div>
                          )}

                          {/* Layout Information */}
                          {(layoutInfo.dirtyObjects || layoutInfo.totalObjects || layoutInfo.elementCount) && (
                            <div style={{ background: 'white', padding: '10px', borderRadius: '4px', border: '1px solid #dee2e6' }}>
                              <h4 style={{ margin: '0 0 8px 0', color: '#495057', fontSize: '14px' }}>Layout Metrics</h4>
                              <div style={{ fontSize: '12px', display: 'flex', flexDirection: 'column', gap: '4px' }}>
                                {layoutInfo.dirtyObjects && <div><strong>Dirty Objects:</strong> {layoutInfo.dirtyObjects}</div>}
                                {layoutInfo.totalObjects && <div><strong>Total Objects:</strong> {layoutInfo.totalObjects}</div>}
                                {layoutInfo.elementCount && <div><strong>Element Count:</strong> {layoutInfo.elementCount}</div>}
                              </div>
                            </div>
                          )}

                          {/* Stack Trace */}
                          {stackTrace && stackTrace.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' }}>
                                Stack Trace ({stackTrace.length} frames)
                              </h4>
                              <div style={{ 
                                maxHeight: '200px', 
                                overflowY: 'auto', 
                                fontSize: '11px', 
                                fontFamily: 'monospace',
                                background: '#f8f9fa',
                                padding: '8px',
                                borderRadius: '3px'
                              }}>
                                {stackTrace.slice(0, 10).map((frame: any, frameIndex: number) => (
                                  <div key={frameIndex} style={{ 
                                    marginBottom: '4px', 
                                    paddingBottom: '4px',
                                    borderBottom: frameIndex < Math.min(stackTrace.length, 10) - 1 ? '1px solid #e9ecef' : 'none'
                                  }}>
                                    <div style={{ color: '#007bff', fontWeight: 'bold' }}>
                                      {frame.functionName || '(anonymous)'}
                                    </div>
                                    <div style={{ color: '#6c757d' }}>
                                      {frame.url ? truncateText(frame.url, 80) : 'unknown'}
                                      {frame.lineNumber && `:${frame.lineNumber}`}
                                      {frame.columnNumber && `:${frame.columnNumber}`}
                                    </div>
                                  </div>
                                ))}
                                {stackTrace.length > 10 && (
                                  <div style={{ color: '#6c757d', fontStyle: 'italic', marginTop: '8px' }}>
                                    ... and {stackTrace.length - 10} more frames
                                  </div>
                                )}
                              </div>
                            </div>
                          )}

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

      {paginatedEvents.length === 0 && (
        <div style={{ 
          textAlign: 'center', 
          padding: '40px', 
          color: '#6c757d',
          fontSize: '16px'
        }}>
          No events found matching the current filters
        </div>
      )}

      <style>{`
        @keyframes spin {
          0% { transform: rotate(0deg); }
          100% { transform: rotate(360deg); }
        }
        
        tr:hover {
          background: #f8f9fa !important;
        }
      `}</style>
    </div>
  )
}

function getPhaseColor(phase: TraceEventPhase): string {
  const colors: Record<string, string> = {
    'M': '#6c757d',  // Metadata - gray
    'X': '#007bff',  // Complete - blue
    'I': '#28a745',  // Instant - green
    'B': '#ffc107',  // Begin - yellow
    'E': '#fd7e14',  // End - orange
    'D': '#6f42c1',  // Deprecated - purple
    'b': '#20c997',  // Nestable start - teal
    'e': '#e83e8c',  // Nestable end - pink
    'n': '#17a2b8',  // Nestable instant - cyan
    'S': '#dc3545',  // Async start - red
    'T': '#ffc107',  // Async instant - warning
    'F': '#fd7e14',  // Async end - orange
    'P': '#6f42c1',  // Sample - purple
    'C': '#20c997',  // Counter - teal
    'R': '#e83e8c'   // Mark - pink
  }
  return colors[phase] || '#6c757d'
}