/**
 * Layer 3: AI Semantic Analysis
 *
 * Uses Claude to perform deep security analysis including:
 * - Taint analysis (data flow from sources to sinks)
 * - Business logic flaw detection
 * - Missing authorization checks
 * - Cryptography validation
 * - Data exposure detection
 * - Framework-specific deep analysis
 *
 * Also provides high-context validation for Layer 1/2 findings.
 */

import type { Vulnerability, ScanFile } from '../shared/types'
import type { ContextEngineResult } from '../model/taint-types'
import type { ProjectContext } from '../model/project-context'
import { buildProjectContext } from '../model/project-context'
import type { ValidationStats, AIValidationResult, Layer3Context, AIFinding } from './types'
import { createInitialStats } from './types'
import { getAnthropicClient } from './clients'
import { parseAIResponse, getLineContent, validateSeverity, validateCategory } from './utils/response-parser'
import { buildAuthContextForPrompt, SECURITY_ANALYSIS_PROMPT } from './prompts/semantic-analysis'
import { validateWithOpenAI } from './providers/openai'
import { validateWithAnthropic } from './providers/anthropic'

// Re-export types and functions for backward compatibility
export type { ValidationStats, AIValidationResult, Layer3Context } from './types'
export { applyAutoDismissRules } from '../score/auto-dismiss'

// ============================================================================
// Layer 3: Deep AI Analysis
// ============================================================================

/**
 * Analyze a single file using AI for deep security analysis (Layer 3)
 */
export async function analyzeWithAI(
  file: ScanFile,
  context?: Layer3Context
): Promise<Vulnerability[]> {
  const client = getAnthropicClient()

  // Prepare the code with line numbers for reference
  const numberedCode = file.content
    .split('\n')
    .map((line, i) => `${i + 1}: ${line}`)
    .join('\n')

  // Build auth context for the prompt
  const authContext = buildAuthContextForPrompt(context)

  const userMessage = `Analyze this ${file.language} file for security vulnerabilities:

File: ${file.path}${authContext}

\`\`\`${file.language}
${numberedCode}
\`\`\`

Return ONLY a JSON array of findings.`

  try {
    const response = await client.messages.create({
      model: 'claude-3-5-haiku-20241022',
      max_tokens: 4096,
      system: SECURITY_ANALYSIS_PROMPT,
      messages: [
        {
          role: 'user',
          content: userMessage,
        },
      ],
    })

    // Extract text content from response
    const textContent = response.content.find((block: { type: string }) => block.type === 'text')
    if (!textContent || textContent.type !== 'text') {
      console.error('No text content in AI response')
      return []
    }

    // Parse the JSON response
    const findings = parseAIResponse(textContent.text)

    // Convert to Vulnerability format
    return findings.map((finding, index) => ({
      id: `ai-${file.path}-${finding.lineNumber}-${index}`,
      filePath: file.path,
      lineNumber: finding.lineNumber,
      lineContent: getLineContent(file.content, finding.lineNumber),
      severity: finding.severity,
      category: finding.category,
      title: finding.title,
      description: finding.description,
      suggestedFix: finding.suggestedFix,
      confidence: 'high' as const,
      layer: 3 as const,
    }))
  } catch (error) {
    console.error('AI analysis error:', error)
    return []
  }
}

/**
 * Batch analyze multiple files using AI (Layer 3)
 * Processes files in batches to avoid rate limits
 */
export async function batchAnalyzeWithAI(
  files: ScanFile[],
  context?: Layer3Context,
  maxConcurrent: number = 3
): Promise<Vulnerability[]> {
  const vulnerabilities: Vulnerability[] = []

  // Process files in batches to avoid rate limits
  for (let i = 0; i < files.length; i += maxConcurrent) {
    const batch = files.slice(i, i + maxConcurrent)
    const results = await Promise.all(
      batch.map(file => analyzeWithAI(file, context).catch(err => {
        console.error(`AI analysis failed for ${file.path}:`, err)
        return []
      }))
    )
    vulnerabilities.push(...results.flat())

    // Small delay between batches to avoid rate limits
    if (i + maxConcurrent < files.length) {
      await new Promise(resolve => setTimeout(resolve, 500))
    }
  }

  return vulnerabilities
}

// ============================================================================
// Layer 2.5: High-Context Validation
// ============================================================================

/**
 * Validate Layer 1/2 findings using AI with HIGH-CONTEXT validation
 *
 * Key improvements over previous version:
 * 1. Sends FULL FILE CONTENT (not just snippets) for better context
 * 2. Includes PROJECT CONTEXT (auth patterns, data access, etc.)
 * 3. Uses generalised rules from Section 3 of the security model
 */
export async function validateFindingsWithAI(
  findings: Vulnerability[],
  files: ScanFile[],
  ceResult?: ContextEngineResult,
  onProgress?: (progress: { filesProcessed: number; totalFiles: number; status: string }) => void
): Promise<AIValidationResult> {
  // Initialize stats tracking
  const stats: ValidationStats = createInitialStats(findings.length)

  if (findings.length === 0) {
    return { vulnerabilities: [], stats }
  }

  // Check for provider override (GPT-5-mini is default for 47% cost savings)
  const aiProvider = process.env.AI_PROVIDER || 'openai'
  if (aiProvider === 'anthropic') {
    console.log('[AI Validation] Using Anthropic provider (Claude 3.5 Haiku)')
    return validateWithAnthropic(findings, files, ceResult, stats, onProgress)
  } else {
    console.log('[AI Validation] Using OpenAI provider (GPT-5-mini)')
    return validateWithOpenAI(findings, files, ceResult, stats)
  }
}
