"use client"

import { useCallback, useEffect, useMemo, useState } from "react"
import { usePathname } from "next/navigation"
import Link from "next/link"
import { PageHeader } from "@/components/page-header"
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"
import { StatusDot } from "@/components/status-dot"
import { StatusBadge } from "@/components/status-badge"
import { Sparkline } from "@/components/sparkline"
import { LatencyChart } from "@/components/dashboard/latency-chart"
import { BandwidthChart } from "@/components/dashboard/bandwidth-chart"
import {
  servers as mockServers,
  pingProbes,
  systemEvents,
  dashLatency,
  traffic,
  serverFilterRulesets,
} from "@/lib/data"
import type { PingProbe, Server, ServerStatus, ServerType } from "@/lib/data"
import { useDataSource } from "@/lib/data-source"
import { Flag } from "@/components/flag"
import { AlertCircleIcon, AlertTriangleIcon, InfoIcon, FilterIcon, DownloadIcon } from "lucide-react"
import { Button, buttonVariants } from "@/components/ui/button"
import { cn } from "@/lib/utils"
import { requestJson } from "@/shared/api/http-client"
import { buildLatencySeriesByProbeSource } from "@/lib/dashboard-latency"

function makeApiFetch(backendUrl: string) {
  return async function apiFetch<T>(path: string, init?: RequestInit): Promise<T> {
    return requestJson<T>(backendUrl, path, init)
  }
}

function StatCard({
  label, value, unit, delta, deltaDir, spark, sparkColor,
}: {
  label: string; value: string; unit?: string; delta?: string
  deltaDir?: "up" | "down"; spark?: number[]; sparkColor?: string
}) {
  return (
    <Card className="relative overflow-hidden">
      <CardContent className="pt-5 pb-4 px-5">
        <p className="text-sm font-medium text-muted-foreground">{label}</p>
        <div className="flex items-baseline gap-1.5 mt-1">
          <span className="text-3xl font-semibold tracking-tight tabular-nums">{value}</span>
          {unit && <span className="text-sm text-muted-foreground">{unit}</span>}
        </div>
        {delta && (
          <p className={`text-xs mt-1 flex items-center gap-1 ${deltaDir === "up" ? "text-[var(--status-online-fg)]" : deltaDir === "down" ? "text-[var(--status-offline-fg)]" : "text-muted-foreground"}`}>
            {delta}
          </p>
        )}
        {spark && spark.length > 1 && (
          <div className="absolute right-4 bottom-4 opacity-60">
            <Sparkline data={spark} width={80} height={32} color={sparkColor ?? "currentColor"} filled />
          </div>
        )}
      </CardContent>
    </Card>
  )
}

function formatLossPct(loss: number): string {
  if (!Number.isFinite(loss)) return "—"
  return Number.isInteger(loss) ? `${loss}%` : `${loss.toFixed(1)}%`
}

function fmtIntRu(n: number): string {
  return n.toLocaleString("ru-RU")
}

interface LiveKpiSnapshot {
  filters: { ruleTotal: number; serversWithRules: number } | null
  bgp: { prefixSum: number; establishedCount: number } | null
}

/** Синхронизируется со страницей мониторинга (mock) */
const MOCK_DASH_STARS_LS = "mm:dashboard-probe-ids"
const UPTIME_PROBES_CHANGED = "mm:uptime-probes-changed"

function readMockDashboardStarIds(): Set<string> {
  if (typeof window === "undefined") return new Set()
  try {
    const raw = localStorage.getItem(MOCK_DASH_STARS_LS)
    const arr = raw ? (JSON.parse(raw) as unknown) : []
    return new Set(Array.isArray(arr) ? arr.filter((x): x is string => typeof x === "string") : [])
  } catch {
    return new Set()
  }
}

/** Совпадает с эталоном uptime / servers */
function TypeChip({ type }: { type: ServerType }) {
  return (
    <span className={cn(
      "inline-flex items-center rounded px-1.5 py-0.5 text-[10px] font-bold border shrink-0",
      type === "home-router"
        ? "bg-emerald-500/10 text-emerald-600 dark:text-emerald-400 border-emerald-500/20"
        : type === "jump-host"
          ? "bg-violet-500/10 text-violet-600 dark:text-violet-400 border-violet-500/20"
          : "bg-sky-500/10 text-sky-600 dark:text-sky-400 border-sky-500/20",
    )}>
      {type === "jump-host" ? "JH" : type === "home-router" ? "HR" : "EN"}
    </span>
  )
}

interface BackendServerRow {
  id: number
  name: string
  host: string
  site: string
  country: string
  asn: string
  type: ServerType
  enabled: boolean
  status: "online" | "offline" | null
  latency: number | null
  os: string | null
  model: string | null
  sessions?: number
}

function mapBackendToServer(s: BackendServerRow): Server {
  return {
    id: String(s.id),
    name: s.name || s.host,
    host: s.host,
    model: s.model ?? "—",
    os: s.os ?? "—",
    site: s.site || "—",
    country: s.country || "UN",
    asn: s.asn,
    type: s.type,
    enabled: s.enabled,
    status: (s.status ?? "offline") as ServerStatus,
    latency: s.latency != null ? Math.round(s.latency) : null,
    sessions: s.sessions ?? 0,
  }
}

function ProbeSourceCell({ probe, catalog }: { probe: PingProbe; catalog: Server[] }) {
  const srv = catalog.find(s => s.id === probe.srcServerId)
  const iface = (probe.srcInterface ?? "").trim() || "auto"

  if (!srv) {
    return (
      <div className="flex items-start gap-2 min-w-0 max-w-[280px]">
        <span className="mt-1 shrink-0 inline-flex">
          <StatusDot status="offline" />
        </span>
        <div className="min-w-0">
          <p className="text-[13px] font-medium text-muted-foreground truncate">
            Сервер <span className="font-mono tabular-nums">{probe.srcServerId}</span>
          </p>
          <p className="text-[11px] font-mono text-muted-foreground truncate mt-0.5" title={iface}>
            {iface}
          </p>
        </div>
      </div>
    )
  }

  return (
    <div className="flex items-start gap-2 min-w-0 max-w-[280px]">
      <span className="mt-1 shrink-0 inline-flex">
        <StatusDot status={srv.status} pulse={srv.status === "online"} />
      </span>
      <div className="flex gap-2 min-w-0 flex-1">
        <Flag code={srv.country} size={16} className="shrink-0 mt-0.5" />
        <div className="min-w-0 flex-1">
          <div className="flex items-center gap-1.5 flex-wrap">
            <span className="text-[13px] font-medium leading-tight truncate">{srv.name}</span>
            <TypeChip type={srv.type} />
          </div>
          <p className="text-[11px] text-muted-foreground mt-0.5 truncate" title={`Интерфейс: ${iface}`}>
            <span className="font-mono tabular-nums">{iface}</span>
            {srv.site && srv.site !== "—" && (
              <span className="text-muted-foreground/90"> · {srv.site}</span>
            )}
          </p>
        </div>
      </div>
    </div>
  )
}

export default function DashboardPage() {
  const pathname = usePathname()
  const { mode, backendUrl, backendStatus } = useDataSource()
  const isLive = mode === "live" && backendStatus === true
  const apiFetch = useMemo(() => makeApiFetch(backendUrl), [backendUrl])

  const [liveProbes, setLiveProbes] = useState<PingProbe[] | null>(null)
  const [liveServersResolved, setLiveServersResolved] = useState<Server[] | null>(null)
  const [liveKpi, setLiveKpi] = useState<LiveKpiSnapshot | null>(null)
  const [probesLoading, setProbesLoading] = useState(false)
  const [probesError, setProbesError] = useState<string | null>(null)

  const probeServerCatalog = useMemo(() => {
    if (!isLive) return mockServers
    return liveServersResolved ?? []
  }, [isLive, liveServersResolved])

  const fetchProbes = useCallback(async (silent: boolean) => {
    if (!isLive) return
    if (!silent) setProbesLoading(true)
    try {
      const overview = await apiFetch<{ probes: PingProbe[] }>("/api/uptime/overview?range=1h")
      setLiveProbes(overview.probes)
      setProbesError(null)
      try {
        const backendServers = await apiFetch<BackendServerRow[]>("/api/servers")
        setLiveServersResolved(backendServers.map(mapBackendToServer))
      } catch {
        setLiveServersResolved([])
      }

      const [fr, br] = await Promise.allSettled([
        apiFetch<{ rulesets: Array<{ rules?: unknown[] }> }>("/api/filters/rules"),
        apiFetch<Array<{ state?: string; prefixesRx?: number }>>("/api/bgp/sessions"),
      ])

      let filtersPart: LiveKpiSnapshot["filters"] = null
      if (fr.status === "fulfilled") {
        const rs = fr.value.rulesets ?? []
        const ruleTotal = rs.reduce((n, x) => n + (Array.isArray(x.rules) ? x.rules.length : 0), 0)
        const serversWithRules = rs.filter((x) => Array.isArray(x.rules) && x.rules.length > 0).length
        filtersPart = { ruleTotal, serversWithRules }
      }

      let bgpPart: LiveKpiSnapshot["bgp"] = null
      if (br.status === "fulfilled") {
        let prefixSum = 0
        let establishedCount = 0
        for (const s of br.value) {
          const st = String(s.state ?? "")
          if (/established/i.test(st)) {
            establishedCount += 1
            prefixSum += Number(s.prefixesRx ?? 0)
          }
        }
        bgpPart = { prefixSum, establishedCount }
      }

      setLiveKpi({ filters: filtersPart, bgp: bgpPart })
    } catch (e) {
      const msg = e instanceof Error ? e.message : "Не удалось загрузить пробы"
      setProbesError(msg)
      setLiveKpi(null)
      if (!silent) {
        setLiveProbes(null)
        setLiveServersResolved(null)
      }
    } finally {
      if (!silent) setProbesLoading(false)
    }
  }, [apiFetch, isLive])

  useEffect(() => {
    if (!isLive) {
      queueMicrotask(() => {
        setLiveProbes(null)
        setLiveServersResolved(null)
        setLiveKpi(null)
        setProbesError(null)
      })
      return
    }
    let cancelled = false
    queueMicrotask(() => {
      if (cancelled) return
      void fetchProbes(false)
    })
    return () => { cancelled = true }
  }, [isLive, fetchProbes])

  useEffect(() => {
    if (!isLive) return
    const id = setInterval(() => {
      queueMicrotask(() => { void fetchProbes(true) })
    }, 60_000)
    return () => clearInterval(id)
  }, [isLive, fetchProbes])

  /** Live: после звезды на мониторинге данные на дашборде должны подтянуться сразу (раньше только при монтировании и раз в 60 с). */
  useEffect(() => {
    if (!isLive) return
    queueMicrotask(() => { void fetchProbes(true) })
  }, [pathname, isLive, fetchProbes])

  const [mockDashEpoch, setMockDashEpoch] = useState(0)
  useEffect(() => {
    const bumpMock = () => setMockDashEpoch((x) => x + 1)
    const onStorage = (e: StorageEvent) => {
      if (e.key === MOCK_DASH_STARS_LS) bumpMock()
    }
    const onVis = () => {
      if (document.visibilityState === "visible") bumpMock()
    }
    const onUptimeChanged = () => {
      bumpMock()
      if (isLive) void fetchProbes(true)
    }
    window.addEventListener(UPTIME_PROBES_CHANGED, onUptimeChanged)
    window.addEventListener("storage", onStorage)
    document.addEventListener("visibilitychange", onVis)
    return () => {
      window.removeEventListener(UPTIME_PROBES_CHANGED, onUptimeChanged)
      window.removeEventListener("storage", onStorage)
      document.removeEventListener("visibilitychange", onVis)
    }
  }, [isLive, fetchProbes])
  useEffect(() => {
    queueMicrotask(() => setMockDashEpoch((x) => x + 1))
  }, [pathname])

  const mockActiveProbes = useMemo(() => {
    void mockDashEpoch
    const stars = readMockDashboardStarIds()
    return pingProbes.filter(p => p.enabled && stars.has(p.id))
  }, [mockDashEpoch])

  const activeProbesTable = useMemo(() => {
    if (!isLive) return mockActiveProbes
    if (liveProbes === null && probesLoading) return []
    if (liveProbes === null) return []
    return liveProbes.filter((p) => p.enabled && p.showOnDashboard === true)
  }, [isLive, liveProbes, probesLoading, mockActiveProbes])

  const probesSubtitle = useMemo(() => {
    if (!isLive) {
      const starred = mockActiveProbes.length
      return starred > 0
        ? `${starred} на дашборде · мок-данные · отметьте звезды в мониторинге`
        : "Нет проб на дашборде · отметьте звёздочкой на странице мониторинга"
    }
    if (probesError && liveProbes === null) return probesError
    const n = activeProbesTable.length
    return n > 0
      ? `${n} на дашборде · последний час (API)`
      : "Нет проб на дашборде · отметьте звёздочкой на странице мониторинга"
  }, [isLive, mockActiveProbes.length, probesError, liveProbes, activeProbesTable.length])

  /** Карточка «Состояние серверов»: в Live — `/api/servers` (тот же запрос, что и для каталога проб). */
  const serverStatusModel = useMemo(() => {
    if (!isLive) {
      return {
        kind: "mock" as const,
        servers: mockServers.slice(0, 5),
        subtitle: `${mockServers.length} узлов MikroTik · демо`,
      }
    }
    if (liveServersResolved === null) {
      if (probesLoading) {
        return { kind: "loading" as const, subtitle: "Загрузка…" }
      }
      return {
        kind: "unavailable" as const,
        subtitle: probesError ? "Нет данных · проверьте backend" : "Нет данных о серверах",
      }
    }
    const servers = [...liveServersResolved].sort((a, b) => {
      if (a.enabled !== b.enabled) return a.enabled ? -1 : 1
      return a.name.localeCompare(b.name, "ru")
    })
    const onlineN = servers.filter((s) => s.status === "online").length
    return {
      kind: "live" as const,
      servers,
      subtitle: `${servers.length} узлов · ${onlineN} онлайн · API`,
    }
  }, [isLive, liveServersResolved, probesLoading, probesError])

  const latencyChartBlock = useMemo(() => {
    if (!isLive) {
      return {
        kind: "mock" as const,
        series: dashLatency,
        labels: undefined as Record<string, string> | undefined,
        subtitle:
          "Последние 60 минут · ping от монитора → серверы MikroTik · демо",
      }
    }
    if (liveProbes === null && probesLoading) {
      return { kind: "loading" as const }
    }
    if (!liveProbes?.length) {
      return {
        kind: "empty" as const,
        message: "Нет данных проб. Откройте мониторинг и проверьте сборщик uptime.",
      }
    }
    const catalog = liveServersResolved ?? []
    const { series, labels } = buildLatencySeriesByProbeSource(
      liveProbes,
      catalog,
      { maxServers: 8, points: 60 },
    )
    if (Object.keys(series).length === 0) {
      return {
        kind: "empty" as const,
        message:
          "Нет включённых проб с историей RTT. Включите пробы на странице «Мониторинг».",
      }
    }
    return {
      kind: "live" as const,
      series,
      labels,
      subtitle:
        "Средний RTT по источникам проб · окно 1 ч · до 8 узлов · API",
    }
  }, [isLive, liveProbes, probesLoading, liveServersResolved])

  const dashboardKpi = useMemo(() => {
    const sparkSrv = [5, 5, 6, 6, 5, 6, 6, 6, 7, 6, 6, 6, 6, 6, 6, 6, 6]
    const sparkFlt = [3, 4, 4, 5, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5]
    const sparkBgp = [7800, 7900, 8000, 8100, 8050, 8120, 8200, 8240, 8300, 8350, 8380, 8400, 8420, 8430, 8432]
    const sparkAlt = [1, 2, 2, 3, 3, 4, 5, 4, 4, 4, 3, 3, 4, 4, 4]

    if (!isLive) {
      const totalSrv = mockServers.length
      const onlineSrv = mockServers.filter((s) => s.status === "online").length
      const ruleTotal = serverFilterRulesets.reduce((n, rs) => n + rs.rules.length, 0)
      const serversWithRules = serverFilterRulesets.filter((rs) => rs.rules.length > 0).length
      const en = pingProbes.filter((p) => p.enabled)
      const down = en.filter((p) => p.status === "down").length
      const warn = en.filter((p) => p.status === "warn").length
      return {
        servers: {
          value: String(onlineSrv),
          unit: `/ ${totalSrv}`,
          delta: `${totalSrv - onlineSrv} offline`,
          deltaDir: onlineSrv < totalSrv ? ("down" as const) : ("up" as const),
          spark: sparkSrv,
          sparkColor: "var(--chart-line-1)",
        },
        filters: {
          value: String(ruleTotal),
          unit: `/ ${serverFilterRulesets.length}`,
          delta: `${serversWithRules} серверов с правилами · демо`,
          deltaDir: "up" as const,
          spark: sparkFlt,
          sparkColor: "var(--chart-line-2)",
        },
        bgp: {
          value: "8 432",
          unit: undefined as string | undefined,
          delta: "демо · не из API",
          deltaDir: "up" as const,
          spark: sparkBgp,
          sparkColor: "var(--chart-line-4)",
        },
        alerts: {
          value: String(down + warn),
          unit: undefined as string | undefined,
          delta: `${down} down · ${warn} warn`,
          deltaDir: down + warn > 0 ? ("down" as const) : ("up" as const),
          spark: sparkAlt,
          sparkColor: "var(--chart-5)",
        },
      }
    }

    const loadingBlock = probesLoading && liveProbes === null
    const srvList = liveServersResolved ?? []
    const totalSrv = srvList.length
    const onlineSrv = srvList.filter((s) => s.status === "online").length
    const offlineSrv = Math.max(0, totalSrv - onlineSrv)

    const en = liveProbes?.filter((p) => p.enabled) ?? []
    const down = en.filter((p) => p.status === "down").length
    const warn = en.filter((p) => p.status === "warn").length

    const filters = liveKpi?.filters
    const bgp = liveKpi?.bgp

    return {
      servers: {
        value: loadingBlock ? "—" : String(onlineSrv),
        unit: loadingBlock ? undefined : `/ ${totalSrv}`,
        delta: loadingBlock
          ? "Загрузка…"
          : offlineSrv > 0
            ? `${offlineSrv} offline · опрос API`
            : totalSrv > 0
              ? "Все узлы online в последнем опросе"
              : "Нет серверов в базе",
        deltaDir: offlineSrv > 0 ? ("down" as const) : ("up" as const),
        spark: undefined as number[] | undefined,
        sparkColor: "var(--chart-line-1)",
      },
      filters: {
        value: loadingBlock ? "—" : filters ? String(filters.ruleTotal) : "—",
        unit:
          filters && filters.serversWithRules > 0
            ? `на ${filters.serversWithRules} серв.`
            : undefined,
        delta: loadingBlock
          ? "Загрузка…"
          : filters
            ? `${filters.serversWithRules} серверов с правилами · /api/filters/rules`
            : "Не удалось загрузить правила",
        deltaDir: filters ? ("up" as const) : ("down" as const),
        spark: undefined as number[] | undefined,
        sparkColor: "var(--chart-line-2)",
      },
      bgp: {
        value: loadingBlock ? "—" : bgp ? fmtIntRu(bgp.prefixSum) : "—",
        unit: undefined as string | undefined,
        delta: loadingBlock
          ? "Загрузка…"
          : bgp
            ? `Σ prefixes Rx · ${bgp.establishedCount} Established · /api/bgp/sessions`
            : "Не удалось загрузить BGP",
        deltaDir: (bgp ? "up" : "down") as "up" | "down",
        spark: undefined as number[] | undefined,
        sparkColor: "var(--chart-line-4)",
      },
      alerts: {
        value: loadingBlock ? "—" : String(down + warn),
        unit: undefined as string | undefined,
        delta: loadingBlock
          ? "Загрузка…"
          : `${down} down · ${warn} warn · включённые пробы`,
        deltaDir: down + warn > 0 ? ("down" as const) : ("up" as const),
        spark: undefined as number[] | undefined,
        sparkColor: "var(--chart-5)",
      },
    }
  }, [isLive, liveServersResolved, liveKpi, liveProbes, probesLoading])

  return (
    <div className="flex flex-col h-full">
      <PageHeader
        crumbs={[{ label: "Обзор" }, { label: "Дашборд" }]}
        actions={
          <>
            <Button variant="outline" size="sm"><DownloadIcon className="size-4" />Экспорт</Button>
          </>
        }
      />

      <div className="flex-1 overflow-y-auto">
        <div className="p-6 flex flex-col gap-6">

          {/* KPI row */}
          <div className="grid grid-cols-2 lg:grid-cols-4 gap-4">
            <StatCard
              label="Серверы онлайн"
              value={dashboardKpi.servers.value}
              unit={dashboardKpi.servers.unit}
              delta={dashboardKpi.servers.delta}
              deltaDir={dashboardKpi.servers.deltaDir}
              spark={dashboardKpi.servers.spark}
              sparkColor={dashboardKpi.servers.sparkColor}
            />
            <StatCard
              label="Активные фильтры"
              value={dashboardKpi.filters.value}
              unit={dashboardKpi.filters.unit}
              delta={dashboardKpi.filters.delta}
              deltaDir={dashboardKpi.filters.deltaDir}
              spark={dashboardKpi.filters.spark}
              sparkColor={dashboardKpi.filters.sparkColor}
            />
            <StatCard
              label="BGP-префиксы"
              value={dashboardKpi.bgp.value}
              unit={dashboardKpi.bgp.unit}
              delta={dashboardKpi.bgp.delta}
              deltaDir={dashboardKpi.bgp.deltaDir}
              spark={dashboardKpi.bgp.spark}
              sparkColor={dashboardKpi.bgp.sparkColor}
            />
            <StatCard
              label="Активные алерты"
              value={dashboardKpi.alerts.value}
              unit={dashboardKpi.alerts.unit}
              delta={dashboardKpi.alerts.delta}
              deltaDir={dashboardKpi.alerts.deltaDir}
              spark={dashboardKpi.alerts.spark}
              sparkColor={dashboardKpi.alerts.sparkColor}
            />
          </div>

          {/* Latency chart + Events */}
          <div className="grid grid-cols-1 lg:grid-cols-[2fr_1fr] gap-4">
            <Card>
              <CardHeader className="pb-2">
                <div className="flex items-center justify-between">
                  <div>
                    <CardTitle className="text-base">Задержка до серверов</CardTitle>
                    <p className="text-sm text-muted-foreground mt-0.5">
                      {latencyChartBlock.kind === "mock" && latencyChartBlock.subtitle}
                      {latencyChartBlock.kind === "live" && latencyChartBlock.subtitle}
                      {latencyChartBlock.kind === "loading" && "Загрузка…"}
                      {latencyChartBlock.kind === "empty" && "Нет серии RTT для графика"}
                    </p>
                  </div>
                </div>
              </CardHeader>
              <CardContent className="pt-0 px-3">
                {latencyChartBlock.kind === "loading" && (
                  <div
                    className="w-full rounded-md bg-muted/50 animate-pulse"
                    style={{ height: 220 }}
                  />
                )}
                {latencyChartBlock.kind === "empty" && (
                  <p className="text-sm text-muted-foreground py-10 text-center px-4">
                    {latencyChartBlock.message}
                  </p>
                )}
                {(latencyChartBlock.kind === "mock" || latencyChartBlock.kind === "live") && (
                  <LatencyChart
                    series={latencyChartBlock.series}
                    labels={latencyChartBlock.labels}
                  />
                )}
              </CardContent>
            </Card>

            <Card>
              <CardHeader className="pb-2">
                <div className="flex items-center justify-between">
                  <CardTitle className="text-base">Последние события</CardTitle>
                  <Button variant="ghost" size="sm" className="text-xs h-7">Все →</Button>
                </div>
                <p className="text-sm text-muted-foreground">Система и BGP-активность</p>
              </CardHeader>
              <CardContent className="pt-0 px-0">
                <div className="divide-y divide-border">
                  {systemEvents.map((e) => (
                    <div key={e.id} className="grid grid-cols-[20px_1fr_auto] gap-3 px-5 py-3 items-start">
                      <div className="mt-0.5">
                        {e.sev === "destructive" && <AlertCircleIcon className="size-4 text-destructive" />}
                        {e.sev === "warning"     && <AlertTriangleIcon className="size-4 text-[var(--status-degraded)]" />}
                        {e.sev === "info"        && <InfoIcon className="size-4 text-[var(--chart-1)]" />}
                      </div>
                      <div>
                        <p className="text-[13px] font-medium leading-tight">{e.title}</p>
                        <p className="text-xs text-muted-foreground mt-0.5 leading-snug">{e.message}</p>
                      </div>
                      <span className="text-[11px] font-mono text-muted-foreground">{e.when}</span>
                    </div>
                  ))}
                </div>
              </CardContent>
            </Card>
          </div>

          {/* Bandwidth + Server status */}
          <div className="grid grid-cols-1 lg:grid-cols-[3fr_2fr] gap-4">
            <Card>
              <CardHeader className="pb-2">
                <div className="flex items-center justify-between">
                  <div>
                    <CardTitle className="text-base">Пропускная способность</CardTitle>
                    <p className="text-sm text-muted-foreground mt-0.5">Суммарный RX / TX по всем серверам</p>
                  </div>
                  <div className="flex items-center gap-3 text-xs">
                    <span className="flex items-center gap-1.5"><span className="w-3 h-0.5 bg-foreground/80 rounded inline-block" />RX 318 Мбит/с</span>
                    <span className="flex items-center gap-1.5"><span className="w-3 h-0.5 bg-[var(--chart-tx)] rounded inline-block" />TX 244 Мбит/с</span>
                  </div>
                </div>
              </CardHeader>
              <CardContent className="pt-0 px-3">
                <BandwidthChart rx={traffic.rx} tx={traffic.tx} />
              </CardContent>
            </Card>

            <Card>
              <CardHeader className="pb-2">
                <div className="flex items-center justify-between gap-2">
                  <div className="min-w-0">
                    <CardTitle className="text-base">Состояние серверов</CardTitle>
                    <p className="text-sm text-muted-foreground mt-0.5 truncate" title={serverStatusModel.subtitle}>
                      {serverStatusModel.subtitle}
                    </p>
                  </div>
                  <Link
                    href="/servers"
                    className={cn(buttonVariants({ variant: "outline", size: "sm" }), "h-7 text-xs shrink-0")}
                  >
                    Управление →
                  </Link>
                </div>
              </CardHeader>
              <CardContent className="pt-0 px-0">
                <div className="divide-y divide-border">
                  {serverStatusModel.kind === "loading" && (
                    <>
                      {Array.from({ length: 5 }, (_, i) => (
                        <div key={i} className="grid grid-cols-[10px_1fr_auto_auto] gap-3 px-5 py-2.5 items-center">
                          <div className="size-2 rounded-full bg-muted animate-pulse" />
                          <div className="space-y-2 min-w-0">
                            <div className="h-4 rounded bg-muted/80 animate-pulse max-w-[180px]" />
                            <div className="h-3 rounded bg-muted/60 animate-pulse max-w-[240px]" />
                          </div>
                          <div className="h-4 w-12 rounded bg-muted/60 animate-pulse" />
                          <div className="h-5 w-16 rounded bg-muted/60 animate-pulse justify-self-end" />
                        </div>
                      ))}
                    </>
                  )}
                  {serverStatusModel.kind === "unavailable" && (
                    <div className="px-5 py-8 text-center text-sm text-muted-foreground">
                      {serverStatusModel.subtitle}
                    </div>
                  )}
                  {(serverStatusModel.kind === "mock" || serverStatusModel.kind === "live") && serverStatusModel.servers.length === 0 && (
                    <div className="px-5 py-8 text-center text-sm text-muted-foreground">
                      Нет серверов в базе. Добавьте узел на странице «Серверы».
                    </div>
                  )}
                  {(serverStatusModel.kind === "mock" || serverStatusModel.kind === "live") && serverStatusModel.servers.map((s) => (
                    <div
                      key={s.id}
                      className={cn(
                        "grid grid-cols-[10px_1fr_auto_auto] gap-3 px-5 py-2.5 items-center",
                        !s.enabled && "opacity-60",
                      )}
                    >
                      <StatusDot status={s.status} pulse={s.status === "online"} />
                      <div className="min-w-0">
                        <p className="text-[13px] font-medium leading-tight truncate">{s.name}</p>
                        <p className="text-[11px] font-mono text-muted-foreground flex items-center gap-1 truncate">
                          <Flag code={s.country} className="not-mono shrink-0" />
                          <span className="truncate">{s.host} · {s.site} · {s.asn}</span>
                        </p>
                      </div>
                      <span className={`text-xs font-mono tabular-nums shrink-0 ${s.latency == null ? "text-[var(--status-offline-fg)]" : s.latency > 60 ? "text-[var(--status-degraded-fg)]" : "text-muted-foreground"}`}>
                        {s.latency == null ? "недоступен" : `${s.latency}мс`}
                      </span>
                      <StatusBadge status={s.status} />
                    </div>
                  ))}
                </div>
              </CardContent>
            </Card>
          </div>

          {/* Ping probes table */}
          <Card>
            <CardHeader className="pb-2">
              <div className="flex items-center justify-between">
                <div>
                  <CardTitle className="text-base">Активные пробы</CardTitle>
                  <p className={cn(
                    "text-sm mt-0.5",
                    probesError && isLive ? "text-destructive" : "text-muted-foreground",
                  )}
                  >
                    {probesSubtitle}
                  </p>
                </div>
                <Link
                  href="/uptime"
                  className={cn(buttonVariants({ variant: "outline", size: "sm" }), "h-7 text-xs")}
                >
                  Открыть монитор →
                </Link>
              </div>
            </CardHeader>
            <CardContent className="pt-0 px-0">
              <div className="overflow-x-auto">
                <table className="w-full text-sm">
                  <thead>
                    <tr className="border-b border-border text-xs text-muted-foreground">
                      <th className="text-left font-medium px-5 py-2.5 w-[min(280px,32vw)]">Источник</th>
                      <th className="text-left font-medium px-4 py-2.5">Проба</th>
                      <th className="text-left font-medium px-4 py-2.5">Цель</th>
                      <th className="text-left font-medium px-4 py-2.5">Фильтр</th>
                      <th className="text-right font-medium px-4 py-2.5">RTT</th>
                      <th className="text-right font-medium px-4 py-2.5">Потери</th>
                      <th className="text-left font-medium px-4 py-2.5 w-36">60с</th>
                      <th className="text-left font-medium px-4 py-2.5">Статус</th>
                    </tr>
                  </thead>
                  <tbody className="divide-y divide-border">
                    {isLive && probesLoading && liveProbes === null && (
                      <tr>
                        <td colSpan={8} className="px-5 py-6">
                          <div className="h-10 rounded-md bg-muted/50 animate-pulse max-w-md mx-auto" />
                        </td>
                      </tr>
                    )}
                    {!(isLive && probesLoading && liveProbes === null) && activeProbesTable.map((p) => {
                      const sparkColor = p.status === "down" ? "hsl(0 84% 60%)" : p.status === "warn" ? "hsl(32 94% 44%)" : "hsl(142 76% 36%)"
                      return (
                        <tr key={p.id} className="hover:bg-muted/40 transition-colors">
                          <td className="px-5 py-2.5 align-top">
                            <ProbeSourceCell probe={p} catalog={probeServerCatalog} />
                          </td>
                          <td className="px-4 py-2.5 font-medium">{p.name}</td>
                          <td className="px-4 py-2.5 font-mono text-xs text-muted-foreground">{p.target}</td>
                          <td className="px-4 py-2.5">
                            <span className="inline-flex items-center gap-1 text-xs border border-border rounded px-2 py-0.5">
                              <FilterIcon className="size-3 text-muted-foreground" />{p.filter}
                            </span>
                          </td>
                          <td className="px-4 py-2.5 font-mono text-right">{p.rtt == null ? "—" : `${p.rtt} мс`}</td>
                          <td className={`px-4 py-2.5 font-mono text-right ${p.loss > 5 ? "text-red-500" : p.loss > 0 ? "text-amber-500" : "text-muted-foreground"}`}>
                            {formatLossPct(p.loss)}
                          </td>
                          <td className="px-4 py-2.5">
                            <Sparkline data={p.series} width={120} height={24} color={sparkColor} />
                          </td>
                          <td className="px-4 py-2.5">
                            <StatusBadge status={p.status === "up" ? "online" : p.status === "warn" ? "degraded" : "offline"} />
                          </td>
                        </tr>
                      )
                    })}
                    {!(isLive && probesLoading && liveProbes === null) && activeProbesTable.length === 0 && (
                      <tr>
                        <td colSpan={8} className="px-5 py-8 text-center text-sm text-muted-foreground">
                          {isLive && probesError
                            ? "Нет данных о пробах. Проверьте сборщик uptime и настройки проб на странице мониторинга."
                            : "Нет проб с звездой на дашборде. Включите пробу и отметьте ★ в разделе «Мониторинг»."}
                        </td>
                      </tr>
                    )}
                  </tbody>
                </table>
              </div>
            </CardContent>
          </Card>

        </div>
      </div>
    </div>
  )
}
