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

export default defineEventHandler(async (event) => {
  const queryParams = getQuery(event)
  
  const type = queryParams.type as string || 'short-term'
  const period = queryParams.period as string || '24h'
  
  // 기간/간격 설정
  const config = getPeriodConfig(period)
  
  // 시간 슬롯 생성 (연속된 X축)
  const timeSlots = generateTimeSlots(config)
  
  // DB에서 로그 조회
  let rows: any[] = []
  try {
    rows = await query<any>(`
      SELECT 
        to_char(detected_at::timestamp, '${config.dbFormat}') as time_slot,
        SUM(CASE WHEN level = 'warning' THEN 1 ELSE 0 END) as warning,
        SUM(CASE WHEN level = 'danger' THEN 1 ELSE 0 END) as danger
      FROM anomaly_logs
      WHERE detect_type = $1
        AND detected_at::timestamp >= NOW() - INTERVAL '${config.interval}'
      GROUP BY time_slot
      ORDER BY time_slot ASC
    `, [type])
  } catch (e) {
    rows = []
  }
  
  // 로그 데이터를 Map으로 변환
  const logMap = new Map<string, { warning: number; danger: number }>()
  for (const r of rows) {
    logMap.set(r.time_slot, {
      warning: Number(r.warning) || 0,
      danger: Number(r.danger) || 0
    })
  }
  
  // 전체 시간 슬롯에 데이터 매핑 (없으면 0)
  const data = timeSlots.map(slot => ({
    time: slot.label,
    warning: logMap.get(slot.key)?.warning || 0,
    danger: logMap.get(slot.key)?.danger || 0
  }))
  
  return {
    data,
    type,
    period,
    timestamp: new Date().toISOString()
  }
})

interface PeriodConfig {
  interval: string
  stepMinutes: number
  dbFormat: string
  labelFormat: (date: Date) => string
}

function getPeriodConfig(period: string): PeriodConfig {
  switch (period) {
    case '1h':
      return {
        interval: '1 hour',
        stepMinutes: 5,
        dbFormat: 'YYYY-MM-DD HH24:MI',
        labelFormat: (d) => `${pad(d.getHours())}:${pad(d.getMinutes())}`
      }
    case '6h':
      return {
        interval: '6 hours',
        stepMinutes: 30,
        dbFormat: 'YYYY-MM-DD HH24:MI',
        labelFormat: (d) => `${pad(d.getHours())}:${pad(d.getMinutes())}`
      }
    case '12h':
      return {
        interval: '12 hours',
        stepMinutes: 60,
        dbFormat: 'YYYY-MM-DD HH24:00',
        labelFormat: (d) => `${pad(d.getHours())}:00`
      }
    case '24h':
      return {
        interval: '24 hours',
        stepMinutes: 60,
        dbFormat: 'YYYY-MM-DD HH24:00',
        labelFormat: (d) => `${pad(d.getHours())}:00`
      }
    case '7d':
      return {
        interval: '7 days',
        stepMinutes: 360, // 6시간
        dbFormat: 'YYYY-MM-DD HH24:00',
        labelFormat: (d) => `${pad(d.getMonth()+1)}/${pad(d.getDate())} ${pad(d.getHours())}시`
      }
    case '30d':
      return {
        interval: '30 days',
        stepMinutes: 1440, // 1일
        dbFormat: 'YYYY-MM-DD',
        labelFormat: (d) => `${pad(d.getMonth()+1)}/${pad(d.getDate())}`
      }
    default:
      return {
        interval: '24 hours',
        stepMinutes: 60,
        dbFormat: 'YYYY-MM-DD HH24:00',
        labelFormat: (d) => `${pad(d.getHours())}:00`
      }
  }
}

function generateTimeSlots(config: PeriodConfig): { key: string; label: string }[] {
  const slots: { key: string; label: string }[] = []
  const now = new Date()
  
  // 현재 시간을 간격에 맞게 내림
  const roundedNow = new Date(now)
  if (config.stepMinutes >= 1440) {
    // 일 단위: 오늘 00:00
    roundedNow.setHours(0, 0, 0, 0)
  } else if (config.stepMinutes >= 60) {
    // 시간 단위: 현재 시간 00분
    roundedNow.setMinutes(0, 0, 0)
  } else {
    // 분 단위: 가장 가까운 간격
    const mins = roundedNow.getMinutes()
    const rounded = Math.floor(mins / config.stepMinutes) * config.stepMinutes
    roundedNow.setMinutes(rounded, 0, 0)
  }
  
  // interval을 밀리초로 변환
  const intervalMs = parseInterval(config.interval)
  const startTime = new Date(roundedNow.getTime() - intervalMs)
  
  // 시작부터 현재까지 슬롯 생성
  const stepMs = config.stepMinutes * 60 * 1000
  let current = new Date(startTime)
  
  while (current <= roundedNow) {
    const key = formatDbKey(current, config.dbFormat)
    const label = config.labelFormat(current)
    slots.push({ key, label })
    current = new Date(current.getTime() + stepMs)
  }
  
  return slots
}

function parseInterval(interval: string): number {
  const match = interval.match(/(\d+)\s*(hour|hours|day|days)/)
  if (!match) return 24 * 60 * 60 * 1000
  
  const num = parseInt(match[1])
  const unit = match[2]
  
  if (unit.startsWith('day')) {
    return num * 24 * 60 * 60 * 1000
  } else {
    return num * 60 * 60 * 1000
  }
}

function formatDbKey(date: Date, format: string): string {
  const y = date.getFullYear()
  const m = pad(date.getMonth() + 1)
  const d = pad(date.getDate())
  const h = pad(date.getHours())
  const mi = pad(date.getMinutes())
  
  if (format === 'YYYY-MM-DD') {
    return `${y}-${m}-${d}`
  } else if (format === 'YYYY-MM-DD HH24:00') {
    return `${y}-${m}-${d} ${h}:00`
  } else {
    return `${y}-${m}-${d} ${h}:${mi}`
  }
}

function pad(n: number): string {
  return n.toString().padStart(2, '0')
}
