import type { BrainfishCollection, BrainfishRESTRequest, HTTPMethod } from '../types'

interface EndpointSummary {
  name: string
  method: HTTPMethod
  path: string
  description: string | null
  tags: string[]
  hasAuth: boolean
  hasBody: boolean
  paramCount: number
}

interface ResourceGroup {
  name: string
  endpoints: EndpointSummary[]
  operations: {
    create: number
    read: number
    update: number
    delete: number
  }
}

interface AuthSummary {
  types: string[]
  primaryMethod: string | null
}

interface APISummary {
  name: string
  description: string | null
  baseUrl: string | null
  totalEndpoints: number
  authSummary: AuthSummary
  resourceGroups: ResourceGroup[]
  commonPatterns: string[]
  suggestedUseCases: string[]
}

/**
 * Recursively collect all requests from a collection
 */
function collectAllRequests(collection: BrainfishCollection): BrainfishRESTRequest[] {
  const requests: BrainfishRESTRequest[] = [...collection.requests]
  
  for (const folder of collection.folders) {
    requests.push(...collectAllRequests(folder))
  }
  
  return requests
}

/**
 * Extract base URL from endpoints
 */
function extractBaseUrl(requests: BrainfishRESTRequest[]): string | null {
  if (requests.length === 0) return null
  
  const firstEndpoint = requests[0].endpoint
  try {
    const url = new URL(firstEndpoint)
    return `${url.protocol}//${url.host}`
  } catch {
    // Try to extract from path pattern
    const match = firstEndpoint.match(/^(https?:\/\/[^\/]+)/)
    return match ? match[1] : null
  }
}

/**
 * Analyze authentication patterns across endpoints
 */
function analyzeAuth(requests: BrainfishRESTRequest[]): AuthSummary {
  const authTypes = new Set<string>()
  const authCounts: Record<string, number> = {}
  
  for (const req of requests) {
    const type = req.auth.authType
    if (type !== 'none' && type !== 'inherit') {
      authTypes.add(type)
      authCounts[type] = (authCounts[type] || 0) + 1
    }
  }
  
  // Find primary auth method (most common)
  let primaryMethod: string | null = null
  let maxCount = 0
  for (const [type, count] of Object.entries(authCounts)) {
    if (count > maxCount) {
      maxCount = count
      primaryMethod = type
    }
  }
  
  return {
    types: Array.from(authTypes),
    primaryMethod,
  }
}

/**
 * Group endpoints by resource/tag
 */
function groupByResource(requests: BrainfishRESTRequest[]): ResourceGroup[] {
  const groups: Map<string, EndpointSummary[]> = new Map()
  
  for (const req of requests) {
    // Use first tag, or extract from path, or use "Other"
    let groupName = req.tags[0] || extractResourceFromPath(req.endpoint) || 'Other'
    groupName = groupName.charAt(0).toUpperCase() + groupName.slice(1)
    
    const summary: EndpointSummary = {
      name: req.name,
      method: req.method,
      path: req.endpoint,
      description: req.description,
      tags: req.tags,
      hasAuth: req.auth.authType !== 'none',
      hasBody: req.body.body !== null,
      paramCount: req.params.filter(p => p.active).length,
    }
    
    if (!groups.has(groupName)) {
      groups.set(groupName, [])
    }
    groups.get(groupName)!.push(summary)
  }
  
  // Convert to array and calculate operations
  return Array.from(groups.entries()).map(([name, endpoints]) => ({
    name,
    endpoints,
    operations: {
      create: endpoints.filter(e => e.method === 'POST').length,
      read: endpoints.filter(e => e.method === 'GET').length,
      update: endpoints.filter(e => e.method === 'PUT' || e.method === 'PATCH').length,
      delete: endpoints.filter(e => e.method === 'DELETE').length,
    },
  }))
}

/**
 * Extract resource name from path
 */
function extractResourceFromPath(path: string): string | null {
  // Remove base URL and extract first path segment
  const pathMatch = path.match(/\/api\/v?\d*\/?([^\/]+)/) || path.match(/\/([^\/]+)/)
  if (pathMatch) {
    return pathMatch[1].replace(/[-_]/g, ' ')
  }
  return null
}

/**
 * Detect common API patterns
 */
function detectPatterns(groups: ResourceGroup[]): string[] {
  const patterns: string[] = []
  
  // Check for RESTful CRUD patterns
  const hasCRUD = groups.some(g => 
    g.operations.create > 0 && 
    g.operations.read > 0 && 
    (g.operations.update > 0 || g.operations.delete > 0)
  )
  if (hasCRUD) {
    patterns.push('RESTful CRUD operations')
  }
  
  // Check for authentication endpoints
  const hasAuthEndpoints = groups.some(g => 
    g.name.toLowerCase().includes('auth') ||
    g.endpoints.some(e => 
      e.name.toLowerCase().includes('login') ||
      e.name.toLowerCase().includes('token') ||
      e.name.toLowerCase().includes('session')
    )
  )
  if (hasAuthEndpoints) {
    patterns.push('Authentication/Authorization flows')
  }
  
  // Check for search/filter patterns
  const hasSearch = groups.some(g =>
    g.endpoints.some(e => 
      e.name.toLowerCase().includes('search') ||
      e.name.toLowerCase().includes('filter') ||
      e.paramCount > 2
    )
  )
  if (hasSearch) {
    patterns.push('Search and filtering capabilities')
  }
  
  // Check for batch operations
  const hasBatch = groups.some(g =>
    g.endpoints.some(e => 
      e.name.toLowerCase().includes('batch') ||
      e.name.toLowerCase().includes('bulk')
    )
  )
  if (hasBatch) {
    patterns.push('Batch/bulk operations')
  }
  
  // Check for webhooks
  const hasWebhooks = groups.some(g =>
    g.name.toLowerCase().includes('webhook') ||
    g.endpoints.some(e => e.name.toLowerCase().includes('webhook'))
  )
  if (hasWebhooks) {
    patterns.push('Webhook integrations')
  }
  
  return patterns
}

/**
 * Generate suggested use cases based on resources
 */
function generateUseCases(groups: ResourceGroup[], _apiName: string): string[] {
  const useCases: string[] = []
  
  for (const group of groups.slice(0, 5)) { // Top 5 groups
    if (group.operations.create > 0) {
      useCases.push(`Create and manage ${group.name.toLowerCase()}`)
    }
    if (group.operations.read > 0 && group.endpoints.length > 1) {
      useCases.push(`List and retrieve ${group.name.toLowerCase()} data`)
    }
  }
  
  // Add generic use cases based on patterns
  const hasAuth = groups.some(g => g.name.toLowerCase().includes('auth'))
  if (hasAuth) {
    useCases.push('Implement user authentication flow')
  }
  
  return useCases.slice(0, 6) // Limit to 6 use cases
}

/**
 * Generate a comprehensive API summary from a collection
 */
export function generateAPISummary(collection: BrainfishCollection): APISummary {
  const requests = collectAllRequests(collection)
  const groups = groupByResource(requests)
  const patterns = detectPatterns(groups)
  
  return {
    name: collection.name,
    description: collection.description,
    baseUrl: extractBaseUrl(requests),
    totalEndpoints: requests.length,
    authSummary: analyzeAuth(requests),
    resourceGroups: groups,
    commonPatterns: patterns,
    suggestedUseCases: generateUseCases(groups, collection.name),
  }
}

/**
 * Format API summary as a string for the LLM system prompt
 */
export function formatAPISummaryForPrompt(summary: APISummary): string {
  const sections: string[] = []
  
  // Header
  sections.push(`# API Overview: ${summary.name}`)
  if (summary.description) {
    sections.push(summary.description)
  }
  
  // Stats
  sections.push(`\n## Quick Stats`)
  sections.push(`- Total Endpoints: ${summary.totalEndpoints}`)
  if (summary.baseUrl) {
    sections.push(`- Base URL: ${summary.baseUrl}`)
  }
  
  // Auth
  if (summary.authSummary.types.length > 0) {
    sections.push(`- Authentication: ${summary.authSummary.types.join(', ')}`)
    if (summary.authSummary.primaryMethod) {
      sections.push(`- Primary Auth Method: ${summary.authSummary.primaryMethod}`)
    }
  }
  
  // Resources
  sections.push(`\n## API Resources (${summary.resourceGroups.length} groups)`)
  for (const group of summary.resourceGroups) {
    const ops = []
    if (group.operations.create) ops.push(`${group.operations.create} create`)
    if (group.operations.read) ops.push(`${group.operations.read} read`)
    if (group.operations.update) ops.push(`${group.operations.update} update`)
    if (group.operations.delete) ops.push(`${group.operations.delete} delete`)
    
    sections.push(`\n### ${group.name} (${group.endpoints.length} endpoints)`)
    if (ops.length > 0) {
      sections.push(`Operations: ${ops.join(', ')}`)
    }
    
    // List key endpoints (up to 5 per group)
    const keyEndpoints = group.endpoints.slice(0, 5)
    for (const ep of keyEndpoints) {
      const authIndicator = ep.hasAuth ? '🔐' : ''
      sections.push(`- [${ep.method}] ${ep.name} ${authIndicator}`)
      if (ep.description) {
        sections.push(`  ${ep.description.slice(0, 100)}${ep.description.length > 100 ? '...' : ''}`)
      }
    }
    if (group.endpoints.length > 5) {
      sections.push(`  ... and ${group.endpoints.length - 5} more`)
    }
  }
  
  // Patterns
  if (summary.commonPatterns.length > 0) {
    sections.push(`\n## Common Patterns`)
    for (const pattern of summary.commonPatterns) {
      sections.push(`- ${pattern}`)
    }
  }
  
  // Use cases
  if (summary.suggestedUseCases.length > 0) {
    sections.push(`\n## Suggested Use Cases`)
    for (const useCase of summary.suggestedUseCases) {
      sections.push(`- ${useCase}`)
    }
  }
  
  return sections.join('\n')
}
