/**
 * Утилита для агрегации часовых данных в дневные
 */

export interface ChartDataPoint {
  timestamp: string
  value: number
  label?: string
}

/**
 * Агрегирует часовые данные в дневные на основе периода
 * @param hourlyData - Массив часовых данных
 * @param timePeriod - Период в часах ('24', '72', '168', '720')
 * @returns Агрегированные дневные данные
 */
export function aggregateChartDataByDays(
  hourlyData: ChartDataPoint[],
  timePeriod: string
): ChartDataPoint[] {
  if (!Array.isArray(hourlyData) || hourlyData.length === 0) {
    return []
  }

  // Для периода в 24 часа - возвращаем часовые данные как есть
  if (timePeriod === '24') {
    return hourlyData.map(d => ({
      ...d,
      label: d.label || new Date(d.timestamp).toLocaleTimeString('ru-RU', {
        hour: '2-digit',
        minute: '2-digit'
      })
    }))
  }

  // Для остальных периодов - агрегируем по дням
  const dailyMap = new Map<string, { sum: number; count: number; date: Date }>()

  hourlyData.forEach(point => {
    const date = new Date(point.timestamp)
    // Получаем дату в формате YYYY-MM-DD
    const dateKey = date.toISOString().split('T')[0]

    if (!dailyMap.has(dateKey)) {
      dailyMap.set(dateKey, { sum: 0, count: 0, date })
    }

    const entry = dailyMap.get(dateKey)!
    entry.sum += point.value
    entry.count += 1
  })

  // Преобразуем в массив и сортируем по дате
  const dailyData = Array.from(dailyMap.entries())
    .sort((a, b) => new Date(a[0]).getTime() - new Date(b[0]).getTime())
    .map(([dateKey, data]) => {
      const date = new Date(dateKey)
      
      // Форматируем подпись в зависимости от периода
      let label = ''
      if (timePeriod === '72') {
        // 3 дня - показываем день недели и дату
        label = date.toLocaleDateString('ru-RU', {
          weekday: 'short',
          day: '2-digit',
          month: '2-digit'
        })
      } else if (timePeriod === '168') {
        // Неделя - показываем день недели
        label = date.toLocaleDateString('ru-RU', {
          weekday: 'short',
          day: '2-digit'
        })
      } else if (timePeriod === '720') {
        // Месяц - показываем дату
        label = date.toLocaleDateString('ru-RU', {
          day: '2-digit',
          month: '2-digit'
        })
      }

      return {
        timestamp: date.toISOString(),
        value: data.sum,
        label
      }
    })

  return dailyData
}

/**
 * Получает среднее значение за день (для альтернативной агрегации)
 */
export function aggregateChartDataByDaysAverage(
  hourlyData: ChartDataPoint[],
  timePeriod: string
): ChartDataPoint[] {
  if (!Array.isArray(hourlyData) || hourlyData.length === 0) {
    return []
  }

  if (timePeriod === '24') {
    return hourlyData.map(d => ({
      ...d,
      label: d.label || new Date(d.timestamp).toLocaleTimeString('ru-RU', {
        hour: '2-digit',
        minute: '2-digit'
      })
    }))
  }

  const dailyMap = new Map<string, { sum: number; count: number; date: Date }>()

  hourlyData.forEach(point => {
    const date = new Date(point.timestamp)
    const dateKey = date.toISOString().split('T')[0]

    if (!dailyMap.has(dateKey)) {
      dailyMap.set(dateKey, { sum: 0, count: 0, date })
    }

    const entry = dailyMap.get(dateKey)!
    entry.sum += point.value
    entry.count += 1
  })

  const dailyData = Array.from(dailyMap.entries())
    .sort((a, b) => new Date(a[0]).getTime() - new Date(b[0]).getTime())
    .map(([dateKey, data]) => {
      const date = new Date(dateKey)
      
      let label = ''
      if (timePeriod === '72') {
        label = date.toLocaleDateString('ru-RU', {
          weekday: 'short',
          day: '2-digit',
          month: '2-digit'
        })
      } else if (timePeriod === '168') {
        label = date.toLocaleDateString('ru-RU', {
          weekday: 'short',
          day: '2-digit'
        })
      } else if (timePeriod === '720') {
        label = date.toLocaleDateString('ru-RU', {
          day: '2-digit',
          month: '2-digit'
        })
      }

      return {
        timestamp: date.toISOString(),
        value: Math.round(data.sum / data.count), // Среднее значение
        label
      }
    })

  return dailyData
}

/**
 * Интерфейс для данных с разделением по типам событий
 */
export interface SeverityChartDataPoint {
  timestamp: string
  critical: number
  warning: number
  label?: string
}

/**
 * Агрегирует данные тревог по дням с разделением по severity
 * @param alerts - Массив тревог с полями timestamp и severity
 * @param timePeriod - Период в часах ('24', '72', '168', '720')
 * @returns Агрегированные данные с разделением по critical/warning
 */
export function aggregateAlertsBySeverity(
  alerts: Array<{ timestamp?: string; created_at?: string; severity?: string }>,
  timePeriod: string
): SeverityChartDataPoint[] {
  if (!Array.isArray(alerts) || alerts.length === 0) {
    return []
  }

  // Группируем по дням
  const dailyMap = new Map<string, { critical: number; warning: number; date: Date }>()

  alerts.forEach(alert => {
    const timestampField = alert.timestamp || alert.created_at
    if (!timestampField) return

    const date = new Date(timestampField)
    const dateKey = date.toISOString().split('T')[0]

    if (!dailyMap.has(dateKey)) {
      dailyMap.set(dateKey, { critical: 0, warning: 0, date })
    }

    const entry = dailyMap.get(dateKey)!
    
    if (alert.severity === 'critical') {
      entry.critical += 1
    } else if (alert.severity === 'warning') {
      entry.warning += 1
    }
  })

  // Преобразуем в массив и сортируем по дате
  const dailyData = Array.from(dailyMap.entries())
    .sort((a, b) => new Date(a[0]).getTime() - new Date(b[0]).getTime())
    .map(([dateKey, data]) => {
      const date = new Date(dateKey)
      
      // Форматируем подпись в зависимости от периода
      let label = ''
      if (timePeriod === '24') {
        // День - показываем время
        label = date.toLocaleDateString('ru-RU', {
          day: '2-digit',
          month: '2-digit',
          hour: '2-digit'
        })
      } else if (timePeriod === '72') {
        // 3 дня - показываем день недели и дату
        label = date.toLocaleDateString('ru-RU', {
          weekday: 'short',
          day: '2-digit',
          month: '2-digit'
        })
      } else if (timePeriod === '168') {
        // Неделя - показываем день недели
        label = date.toLocaleDateString('ru-RU', {
          weekday: 'short',
          day: '2-digit'
        })
      } else if (timePeriod === '720') {
        // Месяц - показываем дату
        label = date.toLocaleDateString('ru-RU', {
          day: '2-digit',
          month: '2-digit'
        })
      }

      return {
        timestamp: date.toISOString(),
        critical: data.critical,
        warning: data.warning,
        label
      }
    })

  return dailyData
}
