/**
 * Finding Grouping Logic
 * Groups and sorts vulnerabilities for workflow-friendly output
 */

import type { Vulnerability, VulnerabilitySeverity, VulnerabilityCategory } from '../../shared/types'

/**
 * Risk themes for grouping findings
 */
export type RiskTheme =
  | 'secrets'      // Hardcoded secrets, high entropy strings
  | 'injection'    // SQL, XSS, command injection
  | 'auth'         // Missing auth, weak auth patterns
  | 'ai'           // AI-specific vulnerabilities
  | 'config'       // Insecure configuration
  | 'data'         // Data exposure, sensitive variables
  | 'other'        // Uncategorized

/**
 * Map categories to risk themes
 */
export function getRiskTheme(category: VulnerabilityCategory): RiskTheme {
  switch (category) {
    case 'hardcoded_secret':
    case 'high_entropy_string':
    case 'sensitive_url':
      return 'secrets'

    case 'sql_injection':
    case 'xss':
    case 'command_injection':
    case 'dangerous_function':
      return 'injection'

    case 'missing_auth':
    case 'security_bypass':
      return 'auth'

    case 'ai_pattern':
    case 'ai_prompt_injection':
    case 'ai_unsafe_execution':
    case 'ai_overpermissive_tool':
      return 'ai'

    case 'insecure_config':
    case 'cors_misconfiguration':
    case 'root_container':
    case 'dangerous_file':
    case 'weak_crypto':
      return 'config'

    case 'data_exposure':
    case 'sensitive_variable':
      return 'data'

    default:
      return 'other'
  }
}

/**
 * Theme display names and icons
 */
export const THEME_CONFIG: Record<RiskTheme, { name: string; icon: string; priority: number }> = {
  secrets: { name: 'Secrets & Credentials', icon: '*', priority: 1 },
  injection: { name: 'Injection Vulnerabilities', icon: '*', priority: 2 },
  auth: { name: 'Authentication Issues', icon: '*', priority: 3 },
  ai: { name: 'AI Security', icon: '*', priority: 4 },
  config: { name: 'Configuration Issues', icon: '*', priority: 5 },
  data: { name: 'Data Exposure', icon: '*', priority: 6 },
  other: { name: 'Other Issues', icon: '*', priority: 7 },
}

/**
 * Severity sort order (higher = more severe)
 */
const SEVERITY_ORDER: Record<VulnerabilitySeverity, number> = {
  critical: 5,
  high: 4,
  medium: 3,
  low: 2,
  info: 1,
}

/**
 * Grouped findings by risk theme
 */
export interface GroupedFindings {
  theme: RiskTheme
  themeName: string
  themeIcon: string
  findings: Vulnerability[]
  severityCounts: Record<VulnerabilitySeverity, number>
}

/**
 * Group vulnerabilities by risk theme
 */
export function groupByTheme(vulnerabilities: Vulnerability[]): GroupedFindings[] {
  // Group by theme
  const groups = new Map<RiskTheme, Vulnerability[]>()

  for (const vuln of vulnerabilities) {
    const theme = getRiskTheme(vuln.category)
    if (!groups.has(theme)) {
      groups.set(theme, [])
    }
    groups.get(theme)!.push(vuln)
  }

  // Convert to array and sort
  const result: GroupedFindings[] = []

  for (const [theme, findings] of groups) {
    // Sort findings within group: severity desc, then confidence desc
    findings.sort((a, b) => {
      const severityDiff = SEVERITY_ORDER[b.severity] - SEVERITY_ORDER[a.severity]
      if (severityDiff !== 0) return severityDiff

      const confidenceOrder = { high: 3, medium: 2, low: 1 }
      return confidenceOrder[b.confidence] - confidenceOrder[a.confidence]
    })

    // Count severities
    const severityCounts: Record<VulnerabilitySeverity, number> = {
      critical: 0,
      high: 0,
      medium: 0,
      low: 0,
      info: 0,
    }
    for (const f of findings) {
      severityCounts[f.severity]++
    }

    const config = THEME_CONFIG[theme]
    result.push({
      theme,
      themeName: config.name,
      themeIcon: config.icon,
      findings,
      severityCounts,
    })
  }

  // Sort groups by theme priority
  result.sort((a, b) => THEME_CONFIG[a.theme].priority - THEME_CONFIG[b.theme].priority)

  return result
}

/**
 * Limit findings per group to avoid overwhelming output
 */
export function limitPerGroup(groups: GroupedFindings[], maxPerGroup: number = 10): GroupedFindings[] {
  return groups.map(group => ({
    ...group,
    findings: group.findings.slice(0, maxPerGroup),
  }))
}

/**
 * Get findings sorted by severity across all groups
 */
export function sortBySeverity(vulnerabilities: Vulnerability[]): Vulnerability[] {
  return [...vulnerabilities].sort((a, b) => {
    const severityDiff = SEVERITY_ORDER[b.severity] - SEVERITY_ORDER[a.severity]
    if (severityDiff !== 0) return severityDiff

    const confidenceOrder = { high: 3, medium: 2, low: 1 }
    return confidenceOrder[b.confidence] - confidenceOrder[a.confidence]
  })
}

/**
 * Filter to only blocking issues (critical/high)
 */
export function getBlockingIssues(vulnerabilities: Vulnerability[]): Vulnerability[] {
  return vulnerabilities.filter(v => v.severity === 'critical' || v.severity === 'high')
}

/**
 * Filter to actionable issues (medium and above)
 */
export function getActionableIssues(vulnerabilities: Vulnerability[]): Vulnerability[] {
  return vulnerabilities.filter(v =>
    v.severity === 'critical' || v.severity === 'high' || v.severity === 'medium'
  )
}
