import { query } from '../../utils/db'

export default defineEventHandler(async (event) => {
  const SLOPE_THRESHOLD = 0.5
  const MIN_SAMPLES = 10
  const WINDOW_MINUTES = 30
  
  const servers = await query<any>(`
    SELECT target_id, server_name 
    FROM server_targets 
    WHERE is_active = 1 
    ORDER BY server_name
  `)
  
  const anomalies: any[] = []
  const serverResults: any[] = []
  
  for (const server of servers) {
    const snapshots = await query<any>(`
      SELECT cpu_percent, memory_percent, collected_at,
             EXTRACT(EPOCH FROM (NOW() - collected_at::timestamp)) / 60 as minutes_ago
      FROM server_snapshots
      WHERE target_id = $1 AND is_online = 1
        AND collected_at::timestamp >= NOW() - INTERVAL '${WINDOW_MINUTES} minutes'
      ORDER BY collected_at ASC
    `, [server.target_id])
    
    if (snapshots.length < MIN_SAMPLES) {
      serverResults.push({
        target_id: server.target_id,
        server_name: server.server_name,
        cpu_current: snapshots.length > 0 ? snapshots[snapshots.length - 1].cpu_percent : null,
        mem_current: snapshots.length > 0 ? snapshots[snapshots.length - 1].memory_percent : null,
        cpu_slope: null,
        mem_slope: null,
        cpu_trend: null,
        mem_trend: null,
        sample_count: snapshots.length,
        status: 'insufficient'
      })
      continue
    }

    const n = snapshots.length
    const current = snapshots[n - 1]
    const currCpu = Number(current.cpu_percent) || 0
    const currMem = Number(current.memory_percent) || 0
    
    const cpuPoints = snapshots.map((s: any, i: number) => ({ x: i, y: Number(s.cpu_percent) || 0 }))
    const memPoints = snapshots.map((s: any, i: number) => ({ x: i, y: Number(s.memory_percent) || 0 }))
    
    function linearRegression(points: { x: number, y: number }[]): { slope: number, intercept: number, r2: number } {
      const n = points.length
      let sumX = 0, sumY = 0, sumXY = 0, sumX2 = 0
      
      for (const p of points) {
        sumX += p.x
        sumY += p.y
        sumXY += p.x * p.y
        sumX2 += p.x * p.x
      }
      
      const slope = (n * sumXY - sumX * sumY) / (n * sumX2 - sumX * sumX)
      const intercept = (sumY - slope * sumX) / n
      
      const yMean = sumY / n
      let ssTotal = 0, ssResidual = 0
      for (const p of points) {
        const yPred = slope * p.x + intercept
        ssTotal += Math.pow(p.y - yMean, 2)
        ssResidual += Math.pow(p.y - yPred, 2)
      }
      const r2 = ssTotal > 0 ? 1 - (ssResidual / ssTotal) : 0
      
      return { slope, intercept, r2 }
    }
    
    const cpuReg = linearRegression(cpuPoints)
    const memReg = linearRegression(memPoints)
    
    const cpuSlopePerMin = (cpuReg.slope * n) / WINDOW_MINUTES
    const memSlopePerMin = (memReg.slope * n) / WINDOW_MINUTES
    
    function getTrend(slope: number, r2: number): string {
      if (r2 < 0.3) return 'unstable'
      if (slope >= SLOPE_THRESHOLD) return 'rising'
      if (slope <= -SLOPE_THRESHOLD) return 'falling'
      return 'stable'
    }
    
    const cpuTrend = getTrend(cpuSlopePerMin, cpuReg.r2)
    const memTrend = getTrend(memSlopePerMin, memReg.r2)

    let status = 'normal'
    if (cpuTrend === 'rising' || memTrend === 'rising') status = 'warning'
    if (cpuSlopePerMin >= 1.0 || memSlopePerMin >= 1.0) status = 'danger'
    
    serverResults.push({
      target_id: server.target_id,
      server_name: server.server_name,
      cpu_current: currCpu,
      mem_current: currMem,
      cpu_slope: cpuSlopePerMin,
      mem_slope: memSlopePerMin,
      cpu_trend: cpuTrend,
      mem_trend: memTrend,
      cpu_r2: cpuReg.r2,
      mem_r2: memReg.r2,
      sample_count: snapshots.length,
      status
    })
    
    if (cpuTrend === 'rising' && cpuReg.r2 >= 0.3) {
      const level = cpuSlopePerMin >= 1.0 ? 'danger' : 'warning'
      anomalies.push({
        target_id: server.target_id,
        server_name: server.server_name,
        metric: 'CPU',
        current: currCpu,
        slope: cpuSlopePerMin,
        r2: cpuReg.r2,
        trend: cpuTrend,
        level
      })
    }
    
    if (memTrend === 'rising' && memReg.r2 >= 0.3) {
      const level = memSlopePerMin >= 1.0 ? 'danger' : 'warning'
      anomalies.push({
        target_id: server.target_id,
        server_name: server.server_name,
        metric: 'Memory',
        current: currMem,
        slope: memSlopePerMin,
        r2: memReg.r2,
        trend: memTrend,
        level
      })
    }
  }
  
  anomalies.sort((a, b) => b.slope - a.slope)
  
  return {
    anomalies,
    servers: serverResults,
    config: {
      slope_threshold: SLOPE_THRESHOLD,
      window_minutes: WINDOW_MINUTES,
      min_samples: MIN_SAMPLES
    },
    timestamp: new Date().toISOString()
  }
})
