"use client"

import * as React from "react"
import { NavMain, type NavGroup } from "@/components/nav-main"
import { AppSwitcher } from "@/components/app-switcher"
import { NavUser } from "@/components/nav-user"
import {
  Sidebar,
  SidebarContent,
  SidebarFooter,
  SidebarHeader,
} from "@/components/ui/sidebar"
import {
  LayoutDashboardIcon,
  ActivityIcon,
  MapIcon,
  HeartPulseIcon,
  GlobeIcon,
  NetworkIcon,
  LayersIcon,
  TagIcon,
  ServerIcon,
  FilterIcon,
  ShieldIcon,
  HardDriveIcon,
  RouteIcon,
  GitForkIcon,
  GitMergeIcon,
  TerminalIcon,
  SettingsIcon,
  DatabaseIcon,
  CableIcon,
  ScanLineIcon,
  BellIcon,
  ShieldCheckIcon,
  BoxIcon,
  BadgeCheckIcon,
  UsersIcon,
} from "lucide-react"
import { useDataSource } from "@/lib/data-source"
import { useEvoBGP } from "@/lib/evobgp-context"
import { requestJson } from "@/shared/api/http-client"
import {
  formatSidebarBadgeCount,
  mockSidebarBadgesByUrl,
  type SidebarCountsDto,
} from "@/lib/sidebar-badges"

type NavItemBase = { title: string; url: string; icon: React.ReactNode }

const navStructure: { label: string; items: NavItemBase[] }[] = [
  {
    label: "Обзор",
    items: [
      { title: "Дашборд", url: "/dashboard", icon: <LayoutDashboardIcon /> },
      { title: "Трафик", url: "/traffic", icon: <ActivityIcon /> },
      { title: "Карта сети", url: "/network-map", icon: <MapIcon /> },
      { title: "Мониторинг", url: "/uptime", icon: <HeartPulseIcon /> },
    ],
  },
  {
    label: "Данные",
    items: [
      { title: "Домены", url: "/domains", icon: <GlobeIcon /> },
      { title: "IP-диапазоны", url: "/ip-ranges", icon: <NetworkIcon /> },
      { title: "ASN", url: "/asns", icon: <LayersIcon /> },
      { title: "Communities", url: "/communities", icon: <TagIcon /> },
    ],
  },
  {
    label: "Управление",
    items: [
      { title: "Серверы", url: "/servers", icon: <ServerIcon /> },
      { title: "Пользователи", url: "/users", icon: <UsersIcon /> },
      { title: "Фильтры", url: "/filters", icon: <FilterIcon /> },
      { title: "Рекурсивные маршруты", url: "/recursive-routes", icon: <RouteIcon /> },
      { title: "Firewall", url: "/firewall", icon: <ShieldIcon /> },
      { title: "WireGuard", url: "/wireguard", icon: <ShieldCheckIcon /> },
      { title: "GRE-туннели", url: "/gre", icon: <CableIcon /> },
      { title: "VXLAN", url: "/vxlan", icon: <NetworkIcon /> },
      { title: "Контейнеры", url: "/containers", icon: <BoxIcon /> },
      { title: "Сертификаты", url: "/certificates", icon: <BadgeCheckIcon /> },
      { title: "Бэкапы", url: "/backups", icon: <HardDriveIcon /> },
    ],
  },
  {
    label: "Инструменты",
    items: [
      { title: "Оптимизатор маршрутов", url: "/route-optimizer", icon: <RouteIcon /> },
      { title: "OSPF", url: "/ospf", icon: <GitForkIcon /> },
      { title: "BGP", url: "/bgp", icon: <GitMergeIcon /> },
      { title: "Диагностика", url: "/probes", icon: <ScanLineIcon /> },
      { title: "Терминал", url: "/terminal", icon: <TerminalIcon /> },
    ],
  },
  {
    label: "Система",
    items: [
      { title: "Оповещения", url: "/alerts", icon: <BellIcon /> },
      { title: "Сбор данных", url: "/data-collection", icon: <DatabaseIcon /> },
      { title: "Релизы", url: "/releases", icon: <BadgeCheckIcon /> },
      { title: "Настройки", url: "/settings", icon: <SettingsIcon /> },
    ],
  },
]

type LiveSidebarCounts = SidebarCountsDto & { greTunnels?: number; certificates?: number; wireguard?: number; users?: number }

export function AppSidebar({ ...props }: React.ComponentProps<typeof Sidebar>) {
  const { mode, backendUrl, prefsHydrated } = useDataSource()
  const evo = useEvoBGP()
  const [mounted, setMounted] = React.useState(false)
  const [liveCounts, setLiveCounts] = React.useState<LiveSidebarCounts | null>(null)

  const mockBadges = React.useMemo(() => mockSidebarBadgesByUrl(), [])

  React.useEffect(() => {
    queueMicrotask(() => {
      setMounted(true)
    })
  }, [])

  React.useEffect(() => {
    if (!prefsHydrated || mode !== "live") {
      if (mode !== "live") setLiveCounts(null)
      return
    }
    let cancelled = false
    const load = async () => {
      try {
        const [cJson, gJson] = await Promise.all([
          requestJson<SidebarCountsDto>(backendUrl, "/api/sidebar-counts"),
          requestJson<{ tunnels?: unknown[] }>(backendUrl, "/api/filters/gre-tunnels").catch(
            () => ({ tunnels: [] as unknown[] }),
          ),
        ])
        if (cancelled) return
        setLiveCounts({ ...cJson, greTunnels: (gJson.tunnels ?? []).length })
      } catch {
        if (!cancelled) setLiveCounts(null)
      }
    }
    void load()
    const id = window.setInterval(load, 120_000)
    return () => {
      cancelled = true
      window.clearInterval(id)
    }
  }, [mode, backendUrl, prefsHydrated])

  const navGroups = React.useMemo((): NavGroup[] => {
    function badgeFor(url: string): string | undefined {
      if (mode !== "live") return mockBadges[url]

      if (url === "/domains" || url === "/ip-ranges" || url === "/asns") {
        if (!evo.enabled) return undefined
        if (!evo.snapshot) return undefined
        if (url === "/domains") return formatSidebarBadgeCount(evo.snapshot.domains.length)
        if (url === "/ip-ranges") return formatSidebarBadgeCount(evo.snapshot.ipRanges.length)
        return formatSidebarBadgeCount(evo.snapshot.asns.length)
      }

      if (!liveCounts) return undefined

      if (url === "/servers") return formatSidebarBadgeCount(liveCounts.servers)
      if (url === "/users") return formatSidebarBadgeCount(liveCounts.users ?? 0)
      if (url === "/filters") return formatSidebarBadgeCount(liveCounts.filterRules)
      if (url === "/uptime") return formatSidebarBadgeCount(liveCounts.monitoringItems)
      if (url === "/gre") return formatSidebarBadgeCount(liveCounts.greTunnels ?? 0)
      if (url === "/certificates") return formatSidebarBadgeCount(liveCounts.certificates ?? 0)
      if (url === "/wireguard") return formatSidebarBadgeCount(liveCounts.wireguard ?? 0)

      if (url === "/containers" || url === "/bgp") {
        return undefined
      }

      return undefined
    }

    return navStructure.map((g) => ({
      label: g.label,
      items: g.items.map((it) => ({
        title: it.title,
        url: it.url,
        icon: it.icon,
        badge: mounted ? badgeFor(it.url) : undefined,
      })),
    }))
  }, [mounted, mode, liveCounts, mockBadges, evo.enabled, evo.snapshot])

  return (
    <Sidebar collapsible="icon" {...props}>
      <SidebarHeader>
        <AppSwitcher />
      </SidebarHeader>
      <SidebarContent>
        <NavMain groups={navGroups} />
      </SidebarContent>
      <SidebarFooter>
        <NavUser />
      </SidebarFooter>
    </Sidebar>
  )
}
