import React, { useMemo } from 'react'
import type { HTTPRequest } from './types/httpRequest'
import styles from './InitiatorChain.module.css'

interface InitiatorChainProps {
  requests: HTTPRequest[]
  selectedRequest: HTTPRequest
}

interface ChainNode {
  request: HTTPRequest
  level: number
  children: ChainNode[]
  isSelected: boolean
}

const InitiatorChain: React.FC<InitiatorChainProps> = ({ requests, selectedRequest }) => {
  // Build the initiator chain tree
  const chainTree = useMemo(() => {
    const buildChain = (request: HTTPRequest, level: number = 0, visited: Set<string> = new Set()): ChainNode => {
      // Prevent infinite loops
      if (visited.has(request.requestId)) {
        return {
          request,
          level,
          children: [],
          isSelected: request.requestId === selectedRequest.requestId
        }
      }

      visited.add(request.requestId)

      // Find requests initiated by this request
      const children = requests
        .filter(r => {
          if (!r.initiator || r.requestId === request.requestId) return false
          
          // Check if this request was initiated by the current request
          if (r.initiator.type === 'script' && r.initiator.stack) {
            // Look for the current request's URL in the call stack
            return r.initiator.stack.callFrames.some(frame => 
              frame.url === request.url || 
              frame.url.includes(new URL(request.url).pathname)
            )
          }
          
          if (r.initiator.type === 'parser' && r.initiator.url) {
            return r.initiator.url === request.url
          }
          
          return false
        })
        .map(r => buildChain(r, level + 1, new Set(visited)))

      return {
        request,
        level,
        children,
        isSelected: request.requestId === selectedRequest.requestId
      }
    }

    // Find the root requests (those without initiators or with external initiators)
    const rootRequests = requests.filter(r => {
      if (!r.initiator) return true
      if (r.initiator.type === 'parser' && r.initiator.url) {
        // Check if the initiator URL is in our request list
        return !requests.some(req => req.url === r.initiator!.url)
      }
      return r.initiator.type === 'other' || r.initiator.type === 'preload'
    })

    // Build chains for each root
    const chains = rootRequests.map(root => buildChain(root))
    
    // If the selected request is not in any chain, add it as a standalone chain
    const selectedInChains = chains.some(chain => 
      findNodeInChain(chain, selectedRequest.requestId)
    )
    
    if (!selectedInChains) {
      chains.push(buildChain(selectedRequest))
    }

    return chains
  }, [requests, selectedRequest])

  const findNodeInChain = (node: ChainNode, requestId: string): boolean => {
    if (node.request.requestId === requestId) return true
    return node.children.some(child => findNodeInChain(child, requestId))
  }

  const getResourceTypeIcon = (resourceType: string) => {
    switch (resourceType.toLowerCase()) {
      case 'document': return '📄'
      case 'script': return '📜'
      case 'stylesheet': return '🎨'
      case 'image': return '🖼️'
      case 'font': return '🔤'
      case 'xhr': return '📡'
      case 'fetch': return '📤'
      default: return '📋'
    }
  }

  const truncateUrl = (url: string, maxLength: number = 50) => {
    if (url.length <= maxLength) return url
    const start = url.substring(0, 20)
    const end = url.substring(url.length - 25)
    return `${start}...${end}`
  }

  const renderChainNode = (node: ChainNode) => {
    const { request, level, children, isSelected } = node
    const indentation = level * 20

    return (
      <div key={request.requestId} className={styles.chainNodeContainer}>
        <div 
          className={`${styles.chainNode} ${isSelected ? styles.selected : ''}`}
          style={{ marginLeft: `${indentation}px` }}
        >
          <div className={styles.nodeConnector}>
            {level > 0 && (
              <>
                <div className={styles.verticalLine} />
                <div className={styles.horizontalLine} />
              </>
            )}
          </div>
          
          <div className={styles.nodeContent}>
            <div className={styles.nodeIcon}>
              {getResourceTypeIcon(request.resourceType)}
            </div>
            
            <div className={styles.nodeDetails}>
              <div className={styles.nodeUrl} title={request.url}>
                {truncateUrl(request.url)}
              </div>
              <div className={styles.nodeInfo}>
                <span className={styles.resourceType}>{request.resourceType}</span>
                {request.initiator && (
                  <span className={styles.initiatorType}>
                    via {request.initiator.type}
                    {request.initiator.fetchType && ` (${request.initiator.fetchType})`}
                  </span>
                )}
              </div>
            </div>
            
            {isSelected && (
              <div className={styles.selectedIndicator}>
                📍 Selected
              </div>
            )}
          </div>
        </div>
        
        {children.map(child => renderChainNode(child))}
      </div>
    )
  }

  if (chainTree.length === 0) {
    return (
      <div className={styles.noChain}>
        No initiator chain information available
      </div>
    )
  }

  return (
    <div className={styles.chainContainer}>
      <div className={styles.chainHeader}>
        <h4 className={styles.chainTitle}>🔗 Request Initiator Chain</h4>
        <div className={styles.chainDescription}>
          Shows how requests are initiated by other requests or by the browser
        </div>
      </div>
      
      <div className={styles.chainTree}>
        {chainTree.map(rootNode => renderChainNode(rootNode))}
      </div>
    </div>
  )
}

export default InitiatorChain