"use client"

import { useCallback, useEffect, useMemo, useState } from "react"
import { PageHeader } from "@/components/page-header"
import { servers as mockServers } from "@/lib/data"
import type { Server } from "@/lib/data"
import { DataPageCard } from "@/components/data-page-card"
import { DataPageToolbar } from "@/components/data-page-toolbar"
import {
  WireguardDataGrid,
  type WgIfaceWithServer,
} from "@/components/data-grids/wireguard-data-grid"
import {
  WireguardPeersGrid,
  type WgPeerRow,
} from "@/components/data-grids/wireguard-peers-grid"
import { Button } from "@/components/ui/button"
import {
  Alert,
  AlertDescription,
  AlertTitle,
} from "@/components/reui/alert"
import { KpiStatGrid } from "@/components/reui-kit/kpi-stat-grid"
import { OpsPanel } from "@/components/ops-panel"
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"
import {
  AlertDialog,
  AlertDialogAction,
  AlertDialogCancel,
  AlertDialogContent,
  AlertDialogDescription,
  AlertDialogFooter,
  AlertDialogHeader,
  AlertDialogMedia,
  AlertDialogTitle,
} from "@/components/ui/alert-dialog"
import { useDataSource } from "@/lib/data-source"
import { requestJson } from "@/shared/api/http-client"
import {
  createWireGuardInterface,
  createWireGuardPeer,
  deleteWireGuardInterface,
  deleteWireGuardPeer,
  exportWireGuard,
  importWireGuard,
  listWireGuard,
  patchWireGuardInterface,
} from "@/shared/api/wireguard"
import type { WgIfaceDto } from "@mmapp/contracts/wireguard"
import { WgCreateSheet, type WgCreateFormState } from "@/components/wireguard/wg-create-sheet"
import { WgImportSheet } from "@/components/wireguard/wg-import-sheet"
import { WgExportSheet } from "@/components/wireguard/wg-export-sheet"
import { WgPeerSheet, type WgPeerFormState } from "@/components/wireguard/wg-peer-sheet"
import { ServerRailLayout, ServerRailMobileButton } from "@/components/server-rail-layout"
import {
  ALL_SERVERS_ID,
  type ServerTileItem,
} from "@/components/server-tile-rail"
import { toast } from "sonner"
import {
  ShieldCheckIcon, PlusIcon, KeyRoundIcon,
  UsersIcon, ActivityIcon, RefreshCwIcon, UploadIcon, InfoIcon,
  Trash2Icon, CodeXmlIcon, AlertCircleIcon,
} from "lucide-react"

type WgWorkspaceTab = "interfaces" | "peers" | "cli"
type WgStatusFilter = "all" | "up" | "down"
type WgFailure = { serverId: string; serverName?: string; error: string }
type PendingDelete =
  | { kind: "iface"; iface: WgIfaceWithServer }
  | { kind: "peer"; iface: WgIfaceWithServer; peerId: string }

function collectMockInterfaces(): WgIfaceWithServer[] {
  const result: WgIfaceWithServer[] = []
  for (const srv of mockServers) {
    for (const wg of srv.wireGuardIfaces ?? []) {
      result.push({
        ...wg,
        serverId: srv.id,
        serverName: srv.name,
        serverCountry: srv.country,
      })
    }
  }
  return result
}

function dtoToRow(d: WgIfaceDto): WgIfaceWithServer {
  return {
    id: d.id,
    rosId: d.rosId,
    name: d.name,
    listenPort: d.listenPort,
    mtu: d.mtu,
    publicKey: d.publicKey,
    privateKey: d.privateKey,
    address: d.address,
    peers: d.peers.map((p) => ({
      id: p.id,
      rosId: p.rosId,
      publicKey: p.publicKey,
      allowedIps: p.allowedIps,
      endpoint: p.endpoint,
      latestHandshake: p.latestHandshake,
      transferRx: p.transferRx,
      transferTx: p.transferTx,
      persistentKeepalive: p.persistentKeepalive,
      persistent: p.persistent,
      comment: p.comment,
      disabled: p.disabled,
      name: p.name,
      clientAddress: p.clientAddress,
      clientDns: p.clientDns,
      clientEndpoint: p.clientEndpoint,
    })),
    comment: d.comment,
    enabled: d.enabled,
    status: d.status,
    serverId: d.serverId,
    serverName: d.serverName,
    serverCountry: d.serverCountry ?? "UN",
  }
}

interface BackendServer {
  id: number
  name: string
  host: string
  country: string
  type?: Server["type"]
  enabled: boolean
  status?: Server["status"]
  latency?: number | null
  asn?: string
}

function mapBackendServer(s: BackendServer): Server {
  return {
    id: String(s.id),
    name: s.name || s.host,
    host: s.host,
    model: "—",
    os: "—",
    site: "",
    country: s.country || "UN",
    asn: s.asn ?? "",
    type: s.type ?? "exit-node",
    enabled: s.enabled,
    status: s.status ?? "online",
    latency: s.latency ?? null,
    sessions: 0,
  }
}

function parseEndpoint(endpoint: string): { address?: string; port?: number } {
  const t = endpoint.trim()
  if (!t) return {}
  const idx = t.lastIndexOf(":")
  if (idx <= 0) return { address: t }
  return {
    address: t.slice(0, idx),
    port: Number.parseInt(t.slice(idx + 1), 10) || undefined,
  }
}

function peerRowId(iface: WgIfaceWithServer, peer: WgIfaceWithServer["peers"][number], index: number): string {
  return peer.id ?? peer.rosId ?? `${iface.id}-${peer.publicKey}-${index}`
}

export default function WireGuardPage() {
  const { mode, backendUrl } = useDataSource()
  const isLive = mode === "live"

  const [liveIfaces, setLiveIfaces] = useState<WgIfaceWithServer[]>([])
  const [liveServers, setLiveServers] = useState<Server[]>([])
  const [failures, setFailures] = useState<WgFailure[]>([])
  const [loading, setLoading] = useState(false)
  const [busy, setBusy] = useState(false)

  const [selectedServerId, setSelectedServerId] = useState(ALL_SERVERS_ID)
  const [workspaceTab, setWorkspaceTab] = useState<WgWorkspaceTab>("interfaces")
  const [statusFilter, setStatusFilter] = useState<WgStatusFilter>("all")
  const [search, setSearch] = useState("")
  const [createOpen, setCreateOpen] = useState(false)
  const [importOpen, setImportOpen] = useState(false)
  const [exportIface, setExportIface] = useState<WgIfaceWithServer | null>(null)
  const [exportInitialTab, setExportInitialTab] = useState<"rsc" | "conf" | "peer">("rsc")
  const [exportPeerId, setExportPeerId] = useState<string | null>(null)
  const [peerIface, setPeerIface] = useState<WgIfaceWithServer | null>(null)
  const [pendingDelete, setPendingDelete] = useState<PendingDelete | null>(null)
  const [liveExport, setLiveExport] = useState<{
    rsc?: string
    conf?: string
    peerConf?: string
  } | null>(null)
  const [exportBusy, setExportBusy] = useState(false)

  const loadLive = useCallback(async () => {
    if (!isLive) return
    setLoading(true)
    try {
      const [wg, servers] = await Promise.all([
        listWireGuard(backendUrl),
        requestJson<BackendServer[]>(backendUrl, "/api/servers"),
      ])
      setLiveIfaces(wg.interfaces.map(dtoToRow))
      setLiveServers(servers.filter((s) => s.enabled).map(mapBackendServer))
      setFailures(wg.failures ?? [])
      if (wg.failures?.length) {
        toast.warning(
          `Не удалось опросить: ${wg.failures.map((f) => f.serverName ?? f.serverId).join(", ")}`,
        )
      }
    } catch (e) {
      toast.error(e instanceof Error ? e.message : "Ошибка загрузки WireGuard")
      setLiveIfaces([])
      setFailures([])
    } finally {
      setLoading(false)
    }
  }, [isLive, backendUrl])

  useEffect(() => {
    if (!isLive) {
      queueMicrotask(() => {
        setLiveIfaces([])
        setLiveServers([])
        setFailures([])
      })
      return
    }
    queueMicrotask(() => {
      void loadLive()
    })
  }, [isLive, loadLive])

  const displayIfaces = isLive ? liveIfaces : collectMockInterfaces()
  const displayServers = isLive ? liveServers : mockServers.filter((s) => s.enabled)

  const effectiveServerId =
    selectedServerId === ALL_SERVERS_ID || displayServers.some((s) => s.id === selectedServerId)
      ? selectedServerId
      : ALL_SERVERS_ID

  const scopedIfaces = useMemo(() => {
    if (effectiveServerId === ALL_SERVERS_ID) return displayIfaces
    return displayIfaces.filter((i) => i.serverId === effectiveServerId)
  }, [displayIfaces, effectiveServerId])

  const statusCounts = useMemo(() => {
    let up = 0
    let down = 0
    for (const iface of scopedIfaces) {
      if (iface.status === "up") up += 1
      else down += 1
    }
    return { all: scopedIfaces.length, up, down }
  }, [scopedIfaces])

  const statusFiltered = useMemo(() => {
    if (statusFilter === "all") return scopedIfaces
    return scopedIfaces.filter((i) => i.status === statusFilter)
  }, [scopedIfaces, statusFilter])

  const filteredIfaces = useMemo(() => {
    if (!search) return statusFiltered
    const q = search.toLowerCase()
    return statusFiltered.filter(
      (i) =>
        i.name.toLowerCase().includes(q) ||
        i.serverName.toLowerCase().includes(q) ||
        i.peers.some(
          (p) =>
            p.allowedIps.some((a) => a.includes(q)) ||
            (p.endpoint ?? "").includes(q),
        ),
    )
  }, [statusFiltered, search])

  const peerRows = useMemo<WgPeerRow[]>(() => {
    const q = search.toLowerCase()
    const rows: WgPeerRow[] = []
    for (const iface of scopedIfaces) {
      iface.peers.forEach((peer, index) => {
        const id = peerRowId(iface, peer, index)
        if (q) {
          const hay = [
            peer.publicKey,
            peer.name ?? "",
            peer.endpoint ?? "",
            peer.allowedIps.join(" "),
            iface.name,
            iface.serverName,
          ].join(" ").toLowerCase()
          if (!hay.includes(q)) return
        }
        rows.push({
          ...peer,
          id,
          ifaceId: iface.id,
          ifaceName: iface.name,
          serverId: iface.serverId,
          serverName: iface.serverName,
          serverCountry: iface.serverCountry,
        })
      })
    }
    return rows
  }, [scopedIfaces, search])

  const totalPeers = scopedIfaces.reduce((s, i) => s + i.peers.length, 0)
  const onlinePeers = scopedIfaces.reduce(
    (s, i) => s + i.peers.filter((p) => !!p.latestHandshake).length,
    0,
  )
  const upIfaces = scopedIfaces.filter((i) => i.status === "up").length
  const compactServer = effectiveServerId !== ALL_SERVERS_ID
  const sheetServerId = compactServer ? effectiveServerId : undefined

  const serverOptions = displayServers.map((s) => ({
    id: s.id,
    name: s.name,
    host: s.host,
  }))

  const railItems = useMemo<ServerTileItem[]>(() => {
    const counts = new Map<string, number>()
    for (const iface of displayIfaces) {
      counts.set(iface.serverId, (counts.get(iface.serverId) ?? 0) + 1)
    }
    return displayServers.map((s) => ({
      id: s.id,
      name: s.name,
      host: s.host,
      site: s.site,
      country: s.country,
      status: s.status,
      type: s.type,
      count: counts.get(s.id) ?? 0,
      enabled: s.enabled,
      title: [s.name, s.host, s.asn].filter(Boolean).join(" · "),
    }))
  }, [displayServers, displayIfaces])

  async function handleCreate(form: WgCreateFormState) {
    if (!isLive) {
      toast.info("Создание на роутер доступно только в live-режиме")
      return
    }
    setBusy(true)
    try {
      const ep = parseEndpoint(form.peerEndpoint)
      await createWireGuardInterface(backendUrl, {
        serverId: form.serverId,
        name: form.name.trim(),
        listenPort: Number.parseInt(form.listenPort, 10) || 13231,
        mtu: Number.parseInt(form.mtu, 10) || 1420,
        comment: form.comment || undefined,
        address: form.address.trim() || undefined,
        disabled: !form.enabled,
        peer: form.peerEnabled && form.peerPublicKey.trim()
          ? {
              publicKey: form.peerPublicKey.trim(),
              allowedAddresses: form.peerAllowedIps
                .split(",")
                .map((s) => s.trim())
                .filter(Boolean),
              endpointAddress: ep.address,
              endpointPort: ep.port,
              persistentKeepalive: Number.parseInt(form.peerKeepalive, 10) || undefined,
              comment: form.peerComment || undefined,
            }
          : undefined,
      })
      toast.success(`Интерфейс ${form.name} создан`)
      setCreateOpen(false)
      await loadLive()
    } catch (e) {
      toast.error(e instanceof Error ? e.message : "Ошибка создания")
    } finally {
      setBusy(false)
    }
  }

  async function handleImport(args: {
    serverId: string
    content: string
    format: "auto" | "rsc" | "conf"
    dryRun: boolean
  }) {
    if (!isLive) {
      toast.info("Импорт на роутер доступен только в live-режиме")
      return
    }
    setBusy(true)
    try {
      const res = await importWireGuard(backendUrl, {
        serverId: args.serverId,
        content: args.content,
        format: args.format,
        dryRun: args.dryRun,
      })
      toast.success(
        res.applied
          ? `Импортировано: ${res.applied.interfaceName} (+${res.applied.peersCreated} пиров)`
          : "Импорт выполнен",
      )
      setImportOpen(false)
      await loadLive()
    } catch (e) {
      toast.error(e instanceof Error ? e.message : "Ошибка импорта")
    } finally {
      setBusy(false)
    }
  }

  async function handleToggle(iface: WgIfaceWithServer) {
    if (!isLive || !iface.rosId) {
      toast.info("Доступно только в live-режиме")
      return
    }
    try {
      await patchWireGuardInterface(backendUrl, iface.serverId, iface.rosId, {
        disabled: iface.enabled,
      })
      toast.success(iface.enabled ? "Отключено" : "Включено")
      await loadLive()
    } catch (e) {
      toast.error(e instanceof Error ? e.message : "Ошибка")
    }
  }

  async function confirmDelete() {
    if (!pendingDelete) return
    if (!isLive) {
      toast.info("Доступно только в live-режиме")
      setPendingDelete(null)
      return
    }
    try {
      if (pendingDelete.kind === "iface") {
        if (!pendingDelete.iface.rosId) {
          toast.info("Доступно только в live-режиме")
          return
        }
        await deleteWireGuardInterface(backendUrl, pendingDelete.iface.serverId, pendingDelete.iface.rosId)
        toast.success("Удалено")
      } else {
        await deleteWireGuardPeer(backendUrl, pendingDelete.iface.serverId, pendingDelete.peerId)
        toast.success("Пир удалён")
      }
      setPendingDelete(null)
      await loadLive()
    } catch (e) {
      toast.error(e instanceof Error ? e.message : "Ошибка удаления")
    }
  }

  async function handleAddPeer(form: WgPeerFormState) {
    if (!isLive || !peerIface) {
      toast.info("Доступно только в live-режиме")
      return
    }
    setBusy(true)
    try {
      const ep = parseEndpoint(form.endpoint)
      await createWireGuardPeer(backendUrl, {
        serverId: peerIface.serverId,
        interfaceName: peerIface.name,
        publicKey: form.publicKey.trim(),
        allowedAddresses: form.allowedIps
          .split(",")
          .map((s) => s.trim())
          .filter(Boolean),
        endpointAddress: ep.address,
        endpointPort: ep.port,
        persistentKeepalive: Number.parseInt(form.keepalive, 10) || undefined,
        comment: form.comment || undefined,
      })
      toast.success("Пир добавлен")
      setPeerIface(null)
      await loadLive()
    } catch (e) {
      toast.error(e instanceof Error ? e.message : "Ошибка")
    } finally {
      setBusy(false)
    }
  }

  async function handleLiveExport(format: "rsc" | "conf" | "peer-conf") {
    if (!exportIface || !isLive) return
    setExportBusy(true)
    try {
      const res = await exportWireGuard(backendUrl, {
        serverId: exportIface.serverId,
        interfaceName: exportIface.name,
        format,
        includePrivateKey: format !== "peer-conf",
        peerId: format === "peer-conf" ? (exportPeerId ?? undefined) : undefined,
      })
      setLiveExport((prev) => ({
        ...prev,
        ...(format === "rsc"
          ? { rsc: res.content }
          : format === "conf"
            ? { conf: res.content }
            : { peerConf: res.content }),
      }))
      toast.success("Конфиг загружен с роутера")
    } catch (e) {
      toast.error(e instanceof Error ? e.message : "Ошибка экспорта")
    } finally {
      setExportBusy(false)
    }
  }

  function openExport(iface: WgIfaceWithServer, tab: "rsc" | "conf" | "peer" = "rsc", peerId?: string) {
    setLiveExport(null)
    setExportInitialTab(tab)
    setExportPeerId(peerId ?? null)
    setExportIface(iface)
  }

  const emptyCreateAction = (
    <Button size="sm" onClick={() => setCreateOpen(true)}>
      <PlusIcon className="size-4" />
      Новый интерфейс
    </Button>
  )

  return (
    <>
    <ServerRailLayout
      items={railItems}
      selectedId={effectiveServerId}
      onSelect={setSelectedServerId}
      showAll
      allCount={displayIfaces.length}
      loading={isLive && loading && displayServers.length === 0}
      header={
        <PageHeader
          crumbs={[{ label: "Управление" }, { label: "WireGuard" }]}
          actions={
            <>
              <ServerRailMobileButton />
              {isLive && (
                <Button
                  size="sm"
                  variant="outline"
                  disabled={loading}
                  onClick={() => void loadLive()}
                >
                  <RefreshCwIcon className={`size-4 ${loading ? "animate-spin" : ""}`} />
                  Обновить
                </Button>
              )}
              <Button size="sm" variant="outline" onClick={() => setImportOpen(true)}>
                <UploadIcon className="size-4" />
                Импорт
              </Button>
              <Button size="sm" onClick={() => setCreateOpen(true)}>
                <PlusIcon className="size-4" />
                Новый интерфейс
              </Button>
            </>
          }
        />
      }
    >
          <div className="flex flex-col gap-4">
            <KpiStatGrid
              aria-label="Сводка WireGuard"
              items={[
                {
                  id: "ifaces",
                  label: "Интерфейсов",
                  value: scopedIfaces.length,
                  icon: <ShieldCheckIcon className="size-4" />,
                  iconClassName: "text-muted-foreground",
                },
                {
                  id: "up",
                  label: "Активных (UP)",
                  value: upIfaces,
                  icon: <ActivityIcon className="size-4" />,
                  iconClassName: "text-success",
                },
                {
                  id: "peers",
                  label: "Всего пиров",
                  value: totalPeers,
                  icon: <UsersIcon className="size-4" />,
                  iconClassName: "text-info",
                },
                {
                  id: "online",
                  label: "Пиров онлайн",
                  value: `${onlinePeers}/${totalPeers}`,
                  icon: <KeyRoundIcon className="size-4" />,
                  iconClassName: "text-primary",
                },
              ]}
            />

            {failures.length > 0 ? (
              <Alert variant="destructive">
                <AlertCircleIcon />
                <AlertTitle>Не удалось опросить часть роутеров</AlertTitle>
                <AlertDescription>
                  {failures.map((f) => f.serverName ?? f.serverId).join(", ")}
                </AlertDescription>
              </Alert>
            ) : null}

            {!isLive ? (
              <Alert variant="info">
                <InfoIcon />
                <AlertTitle>Mock-режим</AlertTitle>
                <AlertDescription>
                  Переключитесь в live в настройках, чтобы применять изменения на MikroTik.
                </AlertDescription>
              </Alert>
            ) : null}

            <Tabs
              value={workspaceTab}
              onValueChange={(v) => setWorkspaceTab(v as WgWorkspaceTab)}
              className="gap-3"
            >
              <TabsList variant="line">
                <TabsTrigger value="interfaces" className="gap-1.5">
                  <ShieldCheckIcon className="size-3.5" />
                  Интерфейсы
                </TabsTrigger>
                <TabsTrigger value="peers" className="gap-1.5">
                  <UsersIcon className="size-3.5" />
                  Пиры
                </TabsTrigger>
                <TabsTrigger value="cli" className="gap-1.5">
                  <CodeXmlIcon className="size-3.5" />
                  CLI
                </TabsTrigger>
              </TabsList>

              <TabsContent value="interfaces" className="mt-0 outline-none">
                <DataPageCard>
                  <DataPageToolbar
                    search={search}
                    onSearchChange={setSearch}
                    searchPlaceholder="Поиск по имени, серверу, IP…"
                    countLabel={`${filteredIfaces.length} интерфейсов`}
                    segmented={{
                      value: statusFilter,
                      onChange: setStatusFilter,
                      options: [
                        { value: "all", label: "Все", count: statusCounts.all },
                        { value: "up", label: "UP", count: statusCounts.up },
                        { value: "down", label: "DOWN", count: statusCounts.down },
                      ],
                    }}
                  />
                  <WireguardDataGrid
                    interfaces={filteredIfaces}
                    compactServer={compactServer}
                    emptyAction={emptyCreateAction}
                    onExport={(iface) => openExport(iface, "rsc")}
                    onAddPeer={setPeerIface}
                    onToggle={handleToggle}
                    onDelete={(iface) => setPendingDelete({ kind: "iface", iface })}
                    onDeletePeer={(iface, peerId) => setPendingDelete({ kind: "peer", iface, peerId })}
                    onExportPeer={(iface, peerId) => openExport(iface, "peer", peerId)}
                  />
                </DataPageCard>
              </TabsContent>

              <TabsContent value="peers" className="mt-0 outline-none">
                <DataPageCard>
                  <DataPageToolbar
                    search={search}
                    onSearchChange={setSearch}
                    searchPlaceholder="Поиск по ключу, IP, endpoint…"
                    countLabel={`${peerRows.length} пиров`}
                  />
                  <WireguardPeersGrid
                    peers={peerRows}
                    compactServer={compactServer}
                    emptyAction={
                      scopedIfaces.length === 1 ? (
                        <Button size="sm" onClick={() => setPeerIface(scopedIfaces[0])}>
                          <PlusIcon className="size-4" />
                          Добавить пира
                        </Button>
                      ) : emptyCreateAction
                    }
                    onDeletePeer={(row) => {
                      const iface = scopedIfaces.find((i) => i.id === row.ifaceId)
                      if (!iface) return
                      setPendingDelete({ kind: "peer", iface, peerId: row.id })
                    }}
                    onExportPeer={(row) => {
                      const iface = scopedIfaces.find((i) => i.id === row.ifaceId)
                      if (!iface) return
                      openExport(iface, "peer", row.id)
                    }}
                  />
                </DataPageCard>
              </TabsContent>

              <TabsContent value="cli" className="mt-0 outline-none">
                <OpsPanel title="RouterOS 7 · /interface wireguard — быстрые команды" contentClassName="px-5 py-4">
                  <div className="grid grid-cols-1 gap-4 font-mono text-xs sm:grid-cols-3">
                    {[
                      {
                        title: "Создать интерфейс",
                        lines: [
                          "/interface wireguard add \\",
                          "  name=wg0 \\",
                          "  listen-port=13231 \\",
                          "  mtu=1420",
                        ],
                      },
                      {
                        title: "Добавить пира",
                        lines: [
                          "/interface wireguard peers add \\",
                          "  interface=wg0 \\",
                          '  public-key="<ключ>" \\',
                          "  allowed-address=10.0.0.2/32 \\",
                          "  endpoint-address=1.2.3.4 \\",
                          "  persistent-keepalive=25",
                        ],
                      },
                      {
                        title: "Назначить IP",
                        lines: [
                          "/ip address add \\",
                          "  address=10.210.0.1/30 \\",
                          "  interface=wg0",
                          "",
                          "# Статус:",
                          "/interface wireguard print",
                        ],
                      },
                    ].map((b) => (
                      <div key={b.title}>
                        <p className="mb-1.5 font-sans text-[11px] font-semibold uppercase tracking-wide text-foreground/80">
                          {b.title}
                        </p>
                        <pre className="overflow-x-auto rounded-md bg-muted p-2.5 text-[11px] leading-relaxed text-muted-foreground">
                          {b.lines.join("\n")}
                        </pre>
                      </div>
                    ))}
                  </div>
                </OpsPanel>
              </TabsContent>
            </Tabs>
          </div>
    </ServerRailLayout>

      <WgCreateSheet
        open={createOpen}
        onOpenChange={setCreateOpen}
        servers={serverOptions}
        defaultServerId={sheetServerId}
        busy={busy}
        onSubmit={handleCreate}
      />
      <WgImportSheet
        open={importOpen}
        onOpenChange={setImportOpen}
        servers={serverOptions}
        defaultServerId={sheetServerId}
        busy={busy}
        onImport={handleImport}
      />
      <WgPeerSheet
        open={!!peerIface}
        iface={peerIface}
        busy={busy}
        onOpenChange={(v) => { if (!v) setPeerIface(null) }}
        onSubmit={handleAddPeer}
      />
      <WgExportSheet
        open={!!exportIface}
        iface={exportIface}
        initialTab={exportInitialTab}
        peerId={exportPeerId}
        onClose={() => {
          setExportIface(null)
          setExportPeerId(null)
          setExportInitialTab("rsc")
          setLiveExport(null)
        }}
        liveContent={liveExport}
        liveBusy={exportBusy}
        onRequestLiveExport={isLive ? handleLiveExport : undefined}
      />

      <AlertDialog open={!!pendingDelete} onOpenChange={(v) => { if (!v) setPendingDelete(null) }}>
        <AlertDialogContent size="default">
          <AlertDialogHeader>
            <AlertDialogMedia className="bg-destructive/10 text-destructive">
              <Trash2Icon />
            </AlertDialogMedia>
            <AlertDialogTitle>
              {pendingDelete?.kind === "peer" ? "Удалить пира?" : "Удалить интерфейс?"}
            </AlertDialogTitle>
            <AlertDialogDescription>
              {pendingDelete?.kind === "iface"
                ? `${pendingDelete.iface.name} на ${pendingDelete.iface.serverName}. Вместе с интерфейсом будут удалены связанные пиры на роутере.`
                : pendingDelete
                  ? `Пир на ${pendingDelete.iface.name} (${pendingDelete.iface.serverName}).`
                  : null}
            </AlertDialogDescription>
          </AlertDialogHeader>
          <AlertDialogFooter>
            <AlertDialogCancel onClick={() => setPendingDelete(null)}>Отмена</AlertDialogCancel>
            <AlertDialogAction variant="destructive" onClick={() => void confirmDelete()}>
              Удалить
            </AlertDialogAction>
          </AlertDialogFooter>
        </AlertDialogContent>
      </AlertDialog>
    </>
  )
}
