import type { PingProbe, Server } from "@/lib/data"

/** Длина ряда на графике дашборда (ось времени). */
export const DASH_LATENCY_POINTS = 60

/** Растягивает/сэмплирует ряд до `targetLen` (линейная интерполяция по индексам). */
export function padSeriesToLength(values: number[], targetLen: number): number[] {
  if (targetLen <= 0) return []
  if (values.length === 0) return Array(targetLen).fill(0)
  if (values.length === targetLen) return [...values]
  if (values.length > targetLen) return values.slice(values.length - targetLen)
  if (values.length === 1) return Array(targetLen).fill(values[0] ?? 0)
  const out: number[] = []
  for (let i = 0; i < targetLen; i++) {
    const t = (i / (targetLen - 1)) * (values.length - 1)
    const j = Math.floor(t)
    const f = t - j
    const a = values[j] ?? 0
    const b = values[Math.min(j + 1, values.length - 1)] ?? a
    out.push(Math.round(a + f * (b - a)))
  }
  return out
}

export interface DashboardLatencyChartInput {
  series: Record<string, number[]>
  labels: Record<string, string>
}

/**
 * Средний RTT по всем включённым пробам с одного источника (srcServerId).
 * Ключ серии — стабильный id вида `src-<numericId>`; подпись — площадка или имя сервера.
 * Ограничение числа линий — чтобы график оставался читаемым.
 */
export function buildLatencySeriesByProbeSource(
  probes: PingProbe[],
  servers: Server[],
  opts?: { maxServers?: number; points?: number },
): DashboardLatencyChartInput {
  const maxServers = opts?.maxServers ?? 8
  const points = opts?.points ?? DASH_LATENCY_POINTS

  const bySrv = new Map<string, PingProbe[]>()
  for (const p of probes) {
    if (!p.enabled || !p.series?.length) continue
    const sid = p.srcServerId
    if (!bySrv.has(sid)) bySrv.set(sid, [])
    bySrv.get(sid)!.push(p)
  }

  const sortedIds = [...bySrv.keys()].sort((a, b) => {
    const na = servers.find((s) => s.id === a)?.name ?? a
    const nb = servers.find((s) => s.id === b)?.name ?? b
    return na.localeCompare(nb, "ru")
  }).slice(0, maxServers)

  const series: Record<string, number[]> = {}
  const labels: Record<string, string> = {}

  for (const sid of sortedIds) {
    const plist = bySrv.get(sid)!
    const innerLen = plist.reduce((m, p) => Math.max(m, p.series.length), 0)
    if (innerLen === 0) continue

    const averaged = Array.from({ length: innerLen }, (_, i) => {
      const vals = plist
        .map((p) => p.series[i])
        .filter((v): v is number => typeof v === "number" && Number.isFinite(v))
      if (!vals.length) return 0
      return Math.round(vals.reduce((x, y) => x + y, 0) / vals.length)
    })

    const key = `src-${sid}`
    series[key] = padSeriesToLength(averaged, points)
    const srv = servers.find((s) => s.id === sid)
    const site = srv?.site?.trim()
    labels[key] =
      site && site !== "—"
        ? site.slice(0, 16)
        : (srv?.name ?? `#${sid}`).slice(0, 16)
  }

  return { series, labels }
}
