"use client"

import { useEffect, useMemo, useState } from "react"
import { useQuery } from "convex/react"
import { format, formatDistanceToNowStrict } from "date-fns"
import { ptBR } from "date-fns/locale"
import { toast } from "sonner"
import { ClipboardCopy, ServerCog, Cpu, MemoryStick, Monitor, HardDrive, Pencil, ShieldCheck, ShieldAlert, Apple, Terminal } from "lucide-react"

import { api } from "@/convex/_generated/api"
import { Badge } from "@/components/ui/badge"
import { Button } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"
import { Checkbox } from "@/components/ui/checkbox"
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogTrigger } from "@/components/ui/dialog"
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from "@/components/ui/table"
import { Separator } from "@/components/ui/separator"
import { cn } from "@/lib/utils"
import Link from "next/link"
import { useRouter } from "next/navigation"
import { useAuth } from "@/lib/auth-client"
import type { Id } from "@/convex/_generated/dataModel"

type MachineMetrics = Record<string, unknown> | null

type MachineLabel = {
  id?: number | string
  name?: string
}

type MachineSoftware = {
  name?: string
  version?: string
  source?: string
}

type DetailLineProps = { label: string; value?: string | number | null; classNameValue?: string }

type GpuAdapter = {
  name?: string
  vendor?: string
  driver?: string
  memoryBytes?: number
}

type LinuxLsblkEntry = {
  name?: string
  mountPoint?: string
  mountpoint?: string
  fs?: string
  fstype?: string
  sizeBytes?: number
  size?: number
}

type LinuxSmartEntry = {
  smart_status?: { passed?: boolean }
  model_name?: string
  model_family?: string
  serial_number?: string
  device?: { name?: string }
}

type LinuxExtended = {
  lsblk?: LinuxLsblkEntry[]
  lspci?: string
  lsusb?: string
  pciList?: Array<{ text: string }>
  usbList?: Array<{ text: string }>
  smart?: LinuxSmartEntry[]
}

type WindowsCpuInfo = {
  Name?: string
  Manufacturer?: string
  SocketDesignation?: string
  NumberOfCores?: number
  NumberOfLogicalProcessors?: number
  L2CacheSize?: number
  L3CacheSize?: number
  MaxClockSpeed?: number
}

type WindowsMemoryModule = {
  BankLabel?: string
  Capacity?: number
  Manufacturer?: string
  PartNumber?: string
  SerialNumber?: string
  ConfiguredClockSpeed?: number
  Speed?: number
  ConfiguredVoltage?: number
}

type WindowsVideoController = {
  Name?: string
  AdapterRAM?: number
  DriverVersion?: string
  PNPDeviceID?: string
}

type WindowsDiskEntry = {
  Model?: string
  SerialNumber?: string
  Size?: number
  InterfaceType?: string
  MediaType?: string
}

type WindowsOsInfo = {
  ProductName?: string
  CurrentBuild?: string | number
  CurrentBuildNumber?: string | number
  DisplayVersion?: string
  ReleaseId?: string
  EditionID?: string
  LicenseStatus?: number
  IsActivated?: boolean
}

type WindowsExtended = {
  software?: MachineSoftware[]
  services?: Array<{ name?: string; status?: string; displayName?: string }>
  defender?: Record<string, unknown>
  hotfix?: Array<Record<string, unknown>>
  cpu?: WindowsCpuInfo | WindowsCpuInfo[]
  baseboard?: Record<string, unknown> | Array<Record<string, unknown>>
  bios?: Record<string, unknown> | Array<Record<string, unknown>>
  memoryModules?: WindowsMemoryModule[]
  videoControllers?: WindowsVideoController[]
  disks?: WindowsDiskEntry[]
  osInfo?: WindowsOsInfo
}

type MacExtended = {
  systemProfiler?: Record<string, unknown>
  packages?: string[]
  launchctl?: string
}

type NetworkInterface = { name?: string; mac?: string; ip?: string }

type MachineInventory = {
  hardware?: {
    vendor?: string
    model?: string
    serial?: string
    cpuType?: string
    physicalCores?: number
    logicalCores?: number
    memoryBytes?: number
    memory?: number
    primaryGpu?: GpuAdapter
    gpus?: GpuAdapter[]
  }
  network?: { primaryIp?: string; publicIp?: string; macAddresses?: string[] } | NetworkInterface[]
  software?: MachineSoftware[]
  labels?: MachineLabel[]
  fleet?: {
    id?: number | string
    teamId?: number | string
    detailUpdatedAt?: string
    osqueryVersion?: string
  }
  disks?: Array<{ name?: string; mountPoint?: string; fs?: string; interface?: string | null; serial?: string | null; totalBytes?: number; availableBytes?: number }>
  extended?: { linux?: LinuxExtended; windows?: WindowsExtended; macos?: MacExtended }
  services?: Array<{ name?: string; status?: string; displayName?: string }>
  collaborator?: { email?: string; name?: string; role?: string }
}

function toRecord(value: unknown): Record<string, unknown> | null {
  if (!value || typeof value !== "object") return null
  return value as Record<string, unknown>
}

function readString(record: Record<string, unknown>, ...keys: string[]): string | undefined {
  for (const key of keys) {
    const raw = record[key]
    if (typeof raw === "string" && raw.trim().length > 0) {
      return raw
    }
  }
  return undefined
}

function readNumber(record: Record<string, unknown>, ...keys: string[]): number | undefined {
  for (const key of keys) {
    const raw = record[key]
    if (typeof raw === "number" && Number.isFinite(raw)) {
      return raw
    }
    if (typeof raw === "string") {
      const trimmed = raw.trim()
      if (!trimmed) continue
      const parsed = Number(trimmed)
      if (!Number.isNaN(parsed)) return parsed
      const digits = trimmed.replace(/[^0-9.]/g, "")
      if (digits) {
        const fallback = Number(digits)
        if (!Number.isNaN(fallback)) return fallback
      }
    }
  }
  return undefined
}

function parseBytesLike(value: unknown): number | undefined {
  if (typeof value === "number" && Number.isFinite(value)) return value
  if (typeof value === "string") {
    const trimmed = value.trim()
    if (!trimmed) return undefined
    const normalized = trimmed.replace(",", ".")
    const match = normalized.match(/^([\d.]+)\s*(ti|tb|tib|gb|gib|mb|mib|kb|kib|b)?$/i)
    if (match) {
      const amount = Number(match[1])
      if (Number.isNaN(amount)) return undefined
      const unit = match[2]?.toLowerCase()
      const base = 1024
      const unitMap: Record<string, number> = {
        b: 1,
        kb: base,
        kib: base,
        mb: base ** 2,
        mib: base ** 2,
        gb: base ** 3,
        gib: base ** 3,
        tb: base ** 4,
        tib: base ** 4,
        ti: base ** 4,
      }
      if (unit) {
        const multiplier = unitMap[unit]
        if (multiplier) {
          return amount * multiplier
        }
      }
      return amount
    }
    const digits = normalized.replace(/[^0-9.]/g, "")
    if (digits) {
      const fallback = Number(digits)
      if (!Number.isNaN(fallback)) return fallback
    }
  }
  return undefined
}

function deriveVendor(record: Record<string, unknown>): string | undefined {
  const direct = readString(record, "vendor", "Vendor", "AdapterCompatibility")
  if (direct) return direct
  const pnp = readString(record, "PNPDeviceID")
  if (!pnp) return undefined
  const match = pnp.match(/VEN_([0-9A-F]{4})/i)
  if (match) {
    const vendorCode = match[1].toUpperCase()
    const vendorMap: Record<string, string> = {
      "10DE": "NVIDIA",
      "1002": "AMD",
      "1022": "AMD",
      "8086": "Intel",
      "8087": "Intel",
      "1AF4": "Red Hat",
    }
    return vendorMap[vendorCode] ?? `VEN_${vendorCode}`
  }
  const segments = pnp.split("\\")
  const last = segments.pop()
  return last && last.trim().length > 0 ? last : pnp
}

function normalizeGpuSource(value: unknown): GpuAdapter | null {
  if (typeof value === "string") {
    const name = value.trim()
    return name ? { name } : null
  }
  const record = toRecord(value)
  if (!record) return null
  const name = readString(record, "name", "Name", "_name", "AdapterCompatibility")
  const vendor = deriveVendor(record)
  const driver = readString(record, "driver", "DriverVersion", "driverVersion")
  const memoryBytes =
    readNumber(record, "memoryBytes", "MemoryBytes", "AdapterRAM", "VRAM", "vramBytes") ??
    parseBytesLike(record["AdapterRAM"] ?? record["VRAM"] ?? record["vram"])
  if (!name && !vendor && !driver && memoryBytes === undefined) {
    return null
  }
  return { name, vendor, driver, memoryBytes }
}

function uniqueBy<T>(items: T[], keyFn: (item: T) => string): T[] {
  const seen = new Set<string>()
  const result: T[] = []
  items.forEach((item) => {
    const key = keyFn(item)
    if (key && !seen.has(key)) {
      seen.add(key)
      result.push(item)
    }
  })
  return result
}

export type MachinesQueryItem = {
  id: string
  tenantId: string
  hostname: string
  companyId: string | null
  companySlug: string | null
  osName: string | null
  osVersion: string | null
  architecture: string | null
  macAddresses: string[]
  serialNumbers: string[]
  authUserId: string | null
  authEmail: string | null
  persona: string | null
  assignedUserId: string | null
  assignedUserEmail: string | null
  assignedUserName: string | null
  assignedUserRole: string | null
  status: string | null
  lastHeartbeatAt: number | null
  heartbeatAgeMs: number | null
  registeredBy: string | null
  createdAt: number
  updatedAt: number
  token: {
    expiresAt: number
    lastUsedAt: number | null
    usageCount: number
  } | null
  metrics: MachineMetrics
  inventory: MachineInventory | null
  postureAlerts?: Array<Record<string, unknown>> | null
  lastPostureAt?: number | null
}

function useMachinesQuery(tenantId: string): MachinesQueryItem[] {
  return (
    (useQuery(api.machines.listByTenant, {
      tenantId,
      includeMetadata: true,
    }) ?? []) as MachinesQueryItem[]
  )
}

const statusLabels: Record<string, string> = {
  online: "Online",
  offline: "Offline",
  maintenance: "Manutenção",
  blocked: "Bloqueada",
  unknown: "Desconhecida",
}

const statusClasses: Record<string, string> = {
  online: "border-emerald-500/20 bg-emerald-500/15 text-emerald-600",
  offline: "border-rose-500/20 bg-rose-500/15 text-rose-600",
  maintenance: "border-amber-500/20 bg-amber-500/15 text-amber-600",
  blocked: "border-orange-500/20 bg-orange-500/15 text-orange-600",
  unknown: "border-slate-300 bg-slate-200 text-slate-700",
}

function formatRelativeTime(date?: Date | null) {
  if (!date) return "Nunca"
  try {
    return formatDistanceToNowStrict(date, { addSuffix: true, locale: ptBR })
  } catch {
    return "—"
  }
}

function formatDate(date?: Date | null) {
  if (!date) return "—"
  return format(date, "dd/MM/yyyy HH:mm")
}

function formatBytes(bytes?: number | null) {
  if (!bytes || Number.isNaN(bytes)) return "—"
  const units = ["B", "KB", "MB", "GB", "TB"]
  let value = bytes
  let unitIndex = 0
  while (value >= 1024 && unitIndex < units.length - 1) {
    value /= 1024
    unitIndex += 1
  }
  return `${value.toFixed(value >= 10 || unitIndex === 0 ? 0 : 1)} ${units[unitIndex]}`
}

function formatPercent(value?: number | null) {
  if (value === null || value === undefined || Number.isNaN(value)) return "—"
  const normalized = value > 1 ? value : value * 100
  return `${normalized.toFixed(0)}%`
}

function readBool(source: unknown, key: string): boolean | undefined {
  if (!source || typeof source !== "object") return undefined
  const value = (source as Record<string, unknown>)[key]
  return typeof value === "boolean" ? value : undefined
}

function getStatusVariant(status?: string | null) {
  if (!status) return { label: statusLabels.unknown, className: statusClasses.unknown }
  const normalized = status.toLowerCase()
  return {
    label: statusLabels[normalized] ?? status,
    className: statusClasses[normalized] ?? statusClasses.unknown,
  }
}

function OsIcon({ osName }: { osName?: string | null }) {
  const name = (osName ?? "").toLowerCase()
  if (name.includes("mac") || name.includes("darwin") || name.includes("macos")) return <Apple className="size-4 text-black" />
  if (name.includes("linux")) return <Terminal className="size-4 text-black" />
  // fallback para Windows/outros como monitor genérico
  return <Monitor className="size-4 text-black" />
}

export function AdminMachinesOverview({ tenantId }: { tenantId: string }) {
  const machines = useMachinesQuery(tenantId)
  const [q, setQ] = useState("")
  const [statusFilter, setStatusFilter] = useState<string>("all")
  const [osFilter, setOsFilter] = useState<string>("all")
  const [companyQuery, setCompanyQuery] = useState<string>("")
  const [onlyAlerts, setOnlyAlerts] = useState<boolean>(false)
  const { convexUserId } = useAuth()
  const companies = useQuery(
    convexUserId ? api.companies.list : "skip",
    convexUserId ? { tenantId, viewerId: convexUserId as Id<"users"> } : ("skip" as const)
  ) as Array<{ id: string; name: string; slug?: string }> | undefined
  const companyNameBySlug = useMemo(() => {
    const map = new Map<string, string>()
    ;(companies ?? []).forEach((c) => c.slug && map.set(c.slug, c.name))
    return map
  }, [companies])

  const osOptions = useMemo(() => {
    const set = new Set<string>()
    machines.forEach((m) => m.osName && set.add(m.osName))
    return Array.from(set).sort()
  }, [machines])

  const companyNameOptions = useMemo(() => (companies ?? []).map((c) => c.name).sort((a,b)=>a.localeCompare(b,"pt-BR")), [companies])

  const filteredMachines = useMemo(() => {
    const text = q.trim().toLowerCase()
    return machines.filter((m) => {
      if (onlyAlerts && !(Array.isArray(m.postureAlerts) && m.postureAlerts.length > 0)) return false
      if (statusFilter !== "all") {
        const s = (m.status ?? "unknown").toLowerCase()
        if (s !== statusFilter) return false
      }
      if (osFilter !== "all" && (m.osName ?? "").toLowerCase() !== osFilter.toLowerCase()) return false
      if (companyQuery && companyQuery.trim().length > 0) {
        const name = companyNameBySlug.get(m.companySlug ?? "")?.toLowerCase() ?? ""
        if (!name.includes(companyQuery.trim().toLowerCase())) return false
      }
      if (!text) return true
      const hay = [
        m.hostname,
        m.authEmail ?? "",
        (m.macAddresses ?? []).join(" "),
        (m.serialNumbers ?? []).join(" "),
      ]
        .join(" ")
        .toLowerCase()
      return hay.includes(text)
    })
  }, [machines, q, statusFilter, osFilter, companyQuery, onlyAlerts, companyNameBySlug])

  return (
    <div className="grid gap-6">
      <Card className="border-slate-200">
        <CardHeader>
          <CardTitle>Máquinas registradas</CardTitle>
          <CardDescription>Sincronizadas via agente local ou Fleet. Atualiza em tempo real.</CardDescription>
        </CardHeader>
        <CardContent className="overflow-hidden">
          <div className="mb-3 flex flex-wrap items-center gap-2">
            <div className="min-w-[220px] flex-1">
              <Input value={q} onChange={(e) => setQ(e.target.value)} placeholder="Buscar hostname, e-mail, MAC, serial..." />
            </div>
            <Select value={statusFilter} onValueChange={setStatusFilter}>
              <SelectTrigger className="min-w-36">
                <SelectValue placeholder="Status" />
              </SelectTrigger>
              <SelectContent>
                <SelectItem value="all">Todos status</SelectItem>
                <SelectItem value="online">Online</SelectItem>
                <SelectItem value="offline">Offline</SelectItem>
                <SelectItem value="unknown">Desconhecido</SelectItem>
              </SelectContent>
            </Select>
            <Select value={osFilter} onValueChange={setOsFilter}>
              <SelectTrigger className="min-w-40">
                <SelectValue placeholder="Sistema" />
              </SelectTrigger>
              <SelectContent>
                <SelectItem value="all">Todos sistemas</SelectItem>
                {osOptions.map((os) => (
                  <SelectItem key={os} value={os}>{os}</SelectItem>
                ))}
              </SelectContent>
            </Select>
            <div className="relative">
              <Input
                value={companyQuery}
                onChange={(e) => setCompanyQuery(e.target.value)}
                placeholder="Buscar empresa"
                className="min-w-[220px]"
              />
              {companyQuery && companyNameOptions.filter((c) => c.toLowerCase().includes(companyQuery.toLowerCase())).slice(0,6).length > 0 ? (
                <div className="absolute z-10 mt-1 max-h-52 w-full overflow-auto rounded-md border bg-white p-1 shadow-sm">
                  {companyNameOptions
                    .filter((c) => c.toLowerCase().includes(companyQuery.toLowerCase()))
                    .slice(0, 8)
                    .map((c) => (
                      <button
                        key={c}
                        type="button"
                        onClick={() => setCompanyQuery(c)}
                        className="w-full rounded px-2 py-1 text-left text-sm hover:bg-slate-100"
                      >
                        {c}
                      </button>
                    ))}
                </div>
              ) : null}
            </div>
            <label className="inline-flex items-center gap-2 rounded-md border border-slate-200 bg-slate-50/80 px-3 py-1.5 text-sm">
              <Checkbox checked={onlyAlerts} onCheckedChange={(v) => setOnlyAlerts(Boolean(v))} />
              <span>Somente com alertas</span>
            </label>
            <Button variant="outline" onClick={() => { setQ(""); setStatusFilter("all"); setOsFilter("all"); setCompanyQuery(""); setOnlyAlerts(false) }}>Limpar</Button>
          </div>
          {machines.length === 0 ? (
            <EmptyState />
          ) : (
            <MachinesGrid machines={filteredMachines} companyNameBySlug={companyNameBySlug} />
          )}
        </CardContent>
      </Card>
    </div>
  )
}

function MachineStatusBadge({ status }: { status?: string | null }) {
  const { label, className } = getStatusVariant(status)
  const s = String(status ?? "").toLowerCase()
  const colorClass =
    s === "online"
      ? "bg-emerald-500"
      : s === "offline"
        ? "bg-rose-500"
        : s === "maintenance"
          ? "bg-amber-500"
          : s === "blocked"
            ? "bg-orange-500"
            : "bg-slate-400"
  const ringClass =
    s === "online"
      ? "bg-emerald-400/30"
      : s === "offline"
        ? "bg-rose-400/30"
        : s === "maintenance"
          ? "bg-amber-400/30"
          : s === "blocked"
            ? "bg-orange-400/30"
            : "bg-slate-300/30"

  const isOnline = s === "online"
  return (
    <Badge className={cn("inline-flex h-9 items-center gap-5 rounded-full border border-slate-200 px-3 text-sm font-semibold", className)}>
      <span className="relative inline-flex items-center">
        <span className={cn("size-2 rounded-full", colorClass)} />
        {isOnline ? (
          <span className={cn("absolute left-1/2 top-1/2 size-4 -translate-x-1/2 -translate-y-1/2 rounded-full animate-ping [animation-duration:2s]", ringClass)} />
        ) : null}
      </span>
      {label}
    </Badge>
  )
}

function EmptyState() {
  return (
    <div className="flex flex-col items-center gap-3 rounded-lg border border-dashed border-slate-300 bg-slate-50/50 py-12 text-center">
      <ServerCog className="size-10 text-slate-400" />
      <div className="space-y-1">
        <p className="text-sm font-semibold text-slate-600">Nenhuma máquina registrada ainda</p>
        <p className="text-sm text-muted-foreground">
          Execute o agente local ou o webhook do Fleet para registrar as máquinas do tenant.
        </p>
      </div>
    </div>
  )
}

type MachineDetailsProps = {
  machine: MachinesQueryItem | null
}

export function MachineDetails({ machine }: MachineDetailsProps) {
  const { convexUserId } = useAuth()
  const router = useRouter()
  // Company name lookup (by slug)
  const companyQueryArgs = convexUserId && machine ? { tenantId: machine.tenantId, viewerId: convexUserId as Id<"users"> } : undefined
  const companies = useQuery(
    api.companies.list,
    companyQueryArgs ?? ("skip" as const)
  ) as Array<{ id: string; name: string; slug?: string }> | undefined
  const metadata = machine?.inventory ?? null
  const metrics = machine?.metrics ?? null
  const hardware = metadata?.hardware
  const network = metadata?.network ?? null
  const networkInterfaces = Array.isArray(network) ? network : null
  const networkSummary = !Array.isArray(network) && network ? network : null
  const software = metadata?.software ?? null
  const labels = metadata?.labels ?? null
  const fleet = metadata?.fleet ?? null
  const disks = Array.isArray(metadata?.disks) ? metadata.disks : []
  const extended = metadata?.extended ?? null
  const linuxExt = extended?.linux ?? null
  const windowsExt = extended?.windows ?? null
  const macosExt = extended?.macos ?? null
  const windowsMemoryModulesRaw = windowsExt?.memoryModules
  const windowsVideoControllersRaw = windowsExt?.videoControllers
  const windowsDiskEntriesRaw = windowsExt?.disks
  const windowsMemoryModules = Array.isArray(windowsMemoryModulesRaw)
    ? windowsMemoryModulesRaw
    : windowsMemoryModulesRaw && typeof windowsMemoryModulesRaw === "object"
      ? [windowsMemoryModulesRaw]
      : []
  const windowsVideoControllers = Array.isArray(windowsVideoControllersRaw)
    ? windowsVideoControllersRaw
    : windowsVideoControllersRaw && typeof windowsVideoControllersRaw === "object"
      ? [windowsVideoControllersRaw]
      : []
  const windowsDiskEntries = Array.isArray(windowsDiskEntriesRaw)
    ? windowsDiskEntriesRaw
    : windowsDiskEntriesRaw && typeof windowsDiskEntriesRaw === "object"
      ? [windowsDiskEntriesRaw]
      : []
  const linuxLsblk = linuxExt?.lsblk ?? []
  const linuxSmartEntries = linuxExt?.smart ?? []
  const normalizedHardwareGpus = Array.isArray(hardware?.gpus)
    ? hardware.gpus.map((gpu) => normalizeGpuSource(gpu)).filter((gpu): gpu is GpuAdapter => Boolean(gpu))
    : []
  const hardwarePrimaryGpu = hardware?.primaryGpu ? normalizeGpuSource(hardware.primaryGpu) : null

  const windowsCpuRaw = windowsExt?.cpu
  const winCpu = windowsCpuRaw
    ? (Array.isArray(windowsCpuRaw) ? windowsCpuRaw[0] ?? null : windowsCpuRaw)
    : null
  const winMemTotal = windowsMemoryModules.reduce((acc, module) => acc + (parseBytesLike(module?.Capacity) ?? 0), 0)
  const normalizedWindowsGpus = windowsVideoControllers
    .map((controller) => normalizeGpuSource(controller))
    .filter((gpu): gpu is GpuAdapter => Boolean(gpu))
  const combinedGpus = uniqueBy(
    [
      ...(hardwarePrimaryGpu ? [hardwarePrimaryGpu] : []),
      ...normalizedHardwareGpus,
      ...normalizedWindowsGpus,
    ],
    (gpu) => `${gpu.name ?? ""}|${gpu.vendor ?? ""}|${gpu.driver ?? ""}`
  )
  const displayGpus = [...combinedGpus].sort(
    (a, b) => (b.memoryBytes ?? 0) - (a.memoryBytes ?? 0)
  )
  const primaryGpu = hardwarePrimaryGpu ?? displayGpus[0] ?? null
  const windowsPrimaryGpu = [...normalizedWindowsGpus].sort(
    (a, b) => (b.memoryBytes ?? 0) - (a.memoryBytes ?? 0)
  )[0] ?? null
  const windowsCpuDetails = windowsCpuRaw
    ? Array.isArray(windowsCpuRaw)
      ? windowsCpuRaw
      : [windowsCpuRaw]
    : []
  const windowsServices = windowsExt?.services ?? []
  const windowsSoftware = windowsExt?.software ?? []
  const winDiskStats = windowsDiskEntries.length > 0
    ? {
        count: windowsDiskEntries.length,
        total: windowsDiskEntries.reduce((acc, disk) => acc + (parseBytesLike(disk?.Size) ?? 0), 0),
      }
    : { count: 0, total: 0 }

  const lastHeartbeatDate = machine?.lastHeartbeatAt ? new Date(machine.lastHeartbeatAt) : null
  const tokenExpiry = machine?.token?.expiresAt ? new Date(machine.token.expiresAt) : null
  const tokenLastUsed = machine?.token?.lastUsedAt ? new Date(machine.token.lastUsedAt) : null

  const copyEmail = async () => {
    if (!machine?.authEmail) return
    try {
      await navigator.clipboard.writeText(machine.authEmail)
      toast.success("E-mail da máquina copiado.")
    } catch {
      toast.error("Não foi possível copiar o e-mail da máquina.")
    }
  }

  // collaborator (from machine assignment or metadata)
  type Collaborator = { email?: string; name?: string; role?: string }
  const collaborator: Collaborator | null = useMemo(() => {
    if (machine?.assignedUserEmail) {
      return {
        email: machine.assignedUserEmail ?? undefined,
        name: machine.assignedUserName ?? undefined,
        role: machine.persona ?? machine.assignedUserRole ?? undefined,
      }
    }
    if (!metadata || typeof metadata !== "object") return null
    const inv = metadata as Record<string, unknown>
    const c = inv["collaborator"]
    if (c && typeof c === "object") {
      const base = c as Record<string, unknown>
      return {
        email: typeof base.email === "string" ? base.email : undefined,
        name: typeof base.name === "string" ? base.name : undefined,
        role: typeof base.role === "string" ? (base.role as string) : undefined,
      }
    }
    return null
  }, [machine?.assignedUserEmail, machine?.assignedUserName, machine?.persona, machine?.assignedUserRole, metadata])

  const personaLabel = collaborator?.role === "manager" ? "Gestor" : "Colaborador"

  const companyName = (() => {
    if (!companies || !machine?.companySlug) return machine?.companySlug ?? null
    const found = companies.find((c) => c.slug === machine.companySlug)
    return found?.name ?? machine.companySlug
  })()

  const [renaming, setRenaming] = useState(false)
  const [newName, setNewName] = useState<string>(machine?.hostname ?? "")

  const [openDialog, setOpenDialog] = useState(false)
  const [dialogQuery, setDialogQuery] = useState("")
  const [deleteDialog, setDeleteDialog] = useState(false)
  const [deleting, setDeleting] = useState(false)
  const [accessDialog, setAccessDialog] = useState(false)
  const [accessEmail, setAccessEmail] = useState<string>(collaborator?.email ?? "")
  const [accessName, setAccessName] = useState<string>(collaborator?.name ?? "")
  const [accessRole, setAccessRole] = useState<"collaborator" | "manager">(
    (machine?.persona === "manager" || collaborator?.role === "manager") ? "manager" : "collaborator"
  )
  const [savingAccess, setSavingAccess] = useState(false)
  const jsonText = useMemo(() => {
    const payload = {
      id: machine?.id,
      hostname: machine?.hostname,
      status: machine?.status,
      lastHeartbeatAt: machine?.lastHeartbeatAt,
      metrics,
      inventory: metadata,
      postureAlerts: machine?.postureAlerts ?? null,
      lastPostureAt: machine?.lastPostureAt ?? null,
    }
    return JSON.stringify(payload, null, 2)
  }, [machine, metrics, metadata])

  const filteredJsonHtml = useMemo(() => {
    if (!dialogQuery.trim()) return jsonText
    const q = dialogQuery.trim().toLowerCase()
    // highlight simples
    return jsonText.replace(new RegExp(q.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"), "gi"), (m) => `__HIGHLIGHT__${m}__END__`)
  }, [jsonText, dialogQuery])

  // removed copy/export inventory JSON buttons as requested
  useEffect(() => {
    setAccessEmail(collaborator?.email ?? "")
    setAccessName(collaborator?.name ?? "")
    setAccessRole((machine?.persona === "manager" || collaborator?.role === "manager") ? "manager" : "collaborator")
  }, [machine?.id, machine?.persona, collaborator?.email, collaborator?.name, collaborator?.role])

  const handleSaveAccess = async () => {
    if (!machine) return
    if (!accessEmail.trim()) {
      toast.error("Informe o e-mail do colaborador ou gestor.")
      return
    }
    setSavingAccess(true)
    try {
      const response = await fetch("/api/admin/machines/access", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          machineId: machine.id,
          persona: accessRole,
          email: accessEmail.trim(),
          name: accessName.trim() || undefined,
        }),
      })
      if (!response.ok) {
        throw new Error(await response.text())
      }
      toast.success("Perfil de acesso atualizado.")
      setAccessDialog(false)
    } catch (error) {
      console.error(error)
      toast.error("Falha ao atualizar acesso da máquina.")
    } finally {
      setSavingAccess(false)
    }
  }

  return (
    <Card className="border-slate-200">
      <CardHeader>
        <CardTitle>Detalhes</CardTitle>
        <CardDescription>Resumo da máquina selecionada.</CardDescription>
      </CardHeader>
      <CardContent className="space-y-6">
        {!machine ? (
          <p className="text-sm text-muted-foreground">Selecione uma máquina para visualizar detalhes.</p>
        ) : (
          <div className="space-y-6">
            <section className="space-y-3">
              <div className="flex items-start justify-between gap-2">
                <div className="space-y-1">
                  <div className="flex items-center gap-2">
                    <h1 className="break-words text-2xl font-semibold text-neutral-900">{machine.hostname}</h1>
                    <Button size="icon" variant="ghost" className="size-7" onClick={() => { setNewName(machine.hostname); setRenaming(true) }}>
                      <Pencil className="size-4" />
                      <span className="sr-only">Renomear máquina</span>
                    </Button>
                  </div>
                  <p className="text-xs text-muted-foreground">
                    {machine.authEmail ?? "E-mail não definido"}
                  </p>
                  {machine.companySlug ? (
                    <p className="text-xs text-muted-foreground">
                      Empresa vinculada: <span className="font-medium text-foreground">{companyName ?? machine.companySlug}</span>
                    </p>
                  ) : null}
                </div>
                <MachineStatusBadge status={machine.status} />
              </div>
              {/* ping integrado na badge de status */}
              <div className="flex flex-wrap items-center gap-2">
                <Badge variant="outline" className="h-7 border-slate-300 bg-slate-100 px-3 text-sm font-medium text-slate-700">
                  <span className="mr-2 inline-flex items-center"><OsIcon osName={machine.osName} /></span>
                  {machine.osName ?? "SO desconhecido"} {machine.osVersion ?? ""}
                </Badge>
                <Badge variant="outline" className="h-7 border-slate-300 bg-slate-100 px-3 text-sm font-medium text-slate-700">
                  {machine.architecture?.toUpperCase() ?? "Arquitetura indefinida"}
                </Badge>
                {windowsExt?.osInfo ? (
                  <Badge variant="outline" className="h-7 border-slate-300 bg-slate-100 px-3 text-sm font-medium text-slate-700">
                    Build: {String(windowsExt.osInfo?.CurrentBuildNumber ?? windowsExt.osInfo?.CurrentBuild ?? "—")}
                  </Badge>
                ) : null}
                {windowsExt?.osInfo ? (
                  <Badge variant="outline" className="h-7 border-slate-300 bg-slate-100 px-3 text-sm font-medium text-slate-700">
                    Ativado: {windowsExt.osInfo?.IsActivated === true ? "Sim" : "Não"}
                  </Badge>
                ) : null}
                {primaryGpu?.name ? (
                  <Badge variant="outline" className="h-7 border-slate-300 bg-slate-100 px-3 text-sm font-medium text-slate-700">
                    GPU: {primaryGpu.name}
                    {typeof primaryGpu.memoryBytes === "number" ? ` · ${formatBytes(primaryGpu.memoryBytes)}` : ""}
                  </Badge>
                ) : null}
                {companyName ? (
                  <Badge variant="outline" className="h-7 border-slate-300 bg-slate-100 px-3 text-sm font-medium text-slate-700">
                    Empresa: {companyName}
                  </Badge>
                ) : null}
                {collaborator?.email ? (
                  <Badge variant="outline" className="h-7 border-slate-300 bg-slate-100 px-3 text-sm font-medium text-slate-700">
                    {personaLabel}: {collaborator?.name ? `${collaborator.name} · ` : ""}{collaborator.email}
                  </Badge>
                ) : null}
              </div>
              <div className="flex flex-wrap gap-2">
                {machine.authEmail ? (
                  <Button size="sm" variant="outline" onClick={copyEmail} className="gap-2 border-dashed">
                    <ClipboardCopy className="size-4" />
                    Copiar e-mail
                  </Button>
                ) : null}
                <Button size="sm" variant="outline" className="gap-2 border-dashed" onClick={() => { setAccessDialog(true) }}>
                  <ShieldCheck className="size-4" />
                  Ajustar acesso
                </Button>
                {machine.registeredBy ? (
                  <Badge variant="outline" className="h-7 border-slate-300 bg-slate-100 px-3 text-sm font-medium text-slate-700">
                    Registrada via {machine.registeredBy}
                  </Badge>
                ) : null}
              </div>
            </section>

            {/* Renomear máquina */}
            <Dialog open={renaming} onOpenChange={setRenaming}>
              <DialogContent>
                <DialogHeader>
                  <DialogTitle>Renomear máquina</DialogTitle>
                </DialogHeader>
                <div className="grid gap-3 py-2">
                  <Input value={newName} onChange={(e) => setNewName(e.target.value)} placeholder="Novo hostname" />
                  <div className="flex justify-end gap-2">
                    <Button variant="outline" onClick={() => setRenaming(false)}>Cancelar</Button>
                    <Button
                      onClick={async () => {
                        if (!machine) return
                        const name = (newName ?? "").trim()
                        if (name.length < 2) {
                          toast.error("Informe um nome válido")
                          return
                        }
                        try {
                          const res = await fetch("/api/admin/machines/rename", {
                            method: "POST",
                            headers: { "Content-Type": "application/json" },
                            body: JSON.stringify({ machineId: machine.id, hostname: name }),
                          })
                          if (!res.ok) throw new Error(`HTTP ${res.status}`)
                          toast.success("Máquina renomeada")
                          setRenaming(false)
                        } catch (err) {
                          console.error(err)
                          toast.error("Falha ao renomear máquina")
                        }
                      }}
                    >
                      Salvar
                    </Button>
                  </div>
                </div>
              </DialogContent>
            </Dialog>

            <Dialog open={accessDialog} onOpenChange={setAccessDialog}>
              <DialogContent>
                <DialogHeader>
                  <DialogTitle>Ajustar acesso da máquina</DialogTitle>
                </DialogHeader>
                <div className="grid gap-3 py-2">
                  <div className="grid gap-2">
                    <label className="text-sm font-medium">Perfil</label>
                    <Select value={accessRole} onValueChange={(value) => setAccessRole((value as "collaborator" | "manager") ?? "collaborator")}>
                      <SelectTrigger>
                        <SelectValue placeholder="Selecione o perfil" />
                      </SelectTrigger>
                      <SelectContent>
                        <SelectItem value="collaborator">Colaborador (portal)</SelectItem>
                        <SelectItem value="manager">Gestor (painel completo)</SelectItem>
                      </SelectContent>
                    </Select>
                  </div>
                  <div className="grid gap-2">
                    <label className="text-sm font-medium">E-mail</label>
                    <Input type="email" value={accessEmail} onChange={(e) => setAccessEmail(e.target.value)} placeholder="colaborador@empresa.com" />
                  </div>
                  <div className="grid gap-2">
                    <label className="text-sm font-medium">Nome (opcional)</label>
                    <Input value={accessName} onChange={(e) => setAccessName(e.target.value)} placeholder="Nome completo" />
                  </div>
                </div>
                <div className="flex justify-end gap-2">
                  <Button variant="outline" onClick={() => setAccessDialog(false)} disabled={savingAccess}>Cancelar</Button>
                  <Button onClick={handleSaveAccess} disabled={savingAccess || !accessEmail.trim()}>
                    {savingAccess ? "Salvando..." : "Salvar"}
                  </Button>
                </div>
              </DialogContent>
            </Dialog>

            <section className="space-y-2">
              <h4 className="text-sm font-semibold">Sincronização</h4>
              <div className="grid gap-2 text-sm text-muted-foreground">
                <div className="flex justify-between gap-4">
                  <span>Último heartbeat</span>
                  <span className="text-right font-medium text-foreground">
                    {formatRelativeTime(lastHeartbeatDate)}
                  </span>
                </div>
                <div className="flex justify-between gap-4">
                  <span>Criada em</span>
                  <span className="text-right font-medium text-foreground">{formatDate(new Date(machine.createdAt))}</span>
                </div>
                <div className="flex justify-between gap-4">
                  <span>Atualizada em</span>
                  <span className="text-right font-medium text-foreground">{formatDate(new Date(machine.updatedAt))}</span>
                </div>
                <div className="flex justify-between gap-4">
                  <span>Token expira</span>
                  <span className="text-right font-medium text-foreground">
                    {tokenExpiry ? formatRelativeTime(tokenExpiry) : "—"}
                  </span>
                </div>
                <div className="flex justify-between gap-4">
                  <span>Token usado por último</span>
                  <span className="text-right font-medium text-foreground">
                    {tokenLastUsed ? formatRelativeTime(tokenLastUsed) : "—"}
                  </span>
                </div>
                <div className="flex justify-between gap-4">
                  <span>Uso do token</span>
                  <span className="text-right font-medium text-foreground">{machine.token?.usageCount ?? 0} trocas</span>
                </div>
              </div>
            </section>

            {metrics && typeof metrics === "object" ? (
            <section className="space-y-2">
              <h4 className="text-sm font-semibold">Métricas recentes</h4>
              <MetricsGrid metrics={metrics} />
            </section>
          ) : null}

            {hardware || network || (labels && labels.length > 0) ? (
              <section className="space-y-3">
                <div>
                  <h4 className="text-sm font-semibold">Inventário</h4>
                  <p className="text-xs text-muted-foreground">
                    Dados sincronizados via agente ou Fleet.
                  </p>
                </div>
                <div className="space-y-3 text-sm text-muted-foreground">
                  {hardware ? (
                    <div className="rounded-md border border-slate-200 bg-slate-50/60 p-3">
                      <p className="text-xs font-semibold uppercase text-slate-500">Hardware</p>
                      <div className="mt-2 grid gap-1">
                        <DetailLine label="Fabricante" value={hardware.vendor} />
                        <DetailLine label="Modelo" value={hardware.model} />
                        <DetailLine label="Número de série" value={hardware.serial} />
                        <DetailLine label="CPU" value={hardware.cpuType} />
                        <DetailLine
                          label="Núcleos"
                          value={`${hardware.physicalCores ?? "?"} físicos / ${hardware.logicalCores ?? "?"} lógicos`}
                        />
                        <DetailLine label="Memória" value={formatBytes(Number(hardware.memoryBytes ?? hardware.memory))} />
                        {displayGpus.length > 0 ? (
                          <div className="mt-2 space-y-1 text-xs text-muted-foreground">
                            <p className="font-semibold uppercase text-slate-500">GPUs</p>
                            <ul className="space-y-1">
                              {displayGpus.slice(0, 3).map((gpu, idx) => {
                                const { name, memoryBytes, driver, vendor } = gpu
                                return (
                                  <li key={`gpu-${idx}`}>
                                    <span className="font-medium text-foreground">{name ?? "Adaptador de vídeo"}</span>
                                    {memoryBytes ? <span className="ml-1 text-muted-foreground">{formatBytes(memoryBytes)}</span> : null}
                                    {vendor ? <span className="ml-1 text-muted-foreground">· {vendor}</span> : null}
                                    {driver ? <span className="ml-1 text-muted-foreground">· Driver {driver}</span> : null}
                                  </li>
                                )
                              })}
                              {displayGpus.length > 3 ? (
                                <li className="text-muted-foreground">+{displayGpus.length - 3} adaptadores adicionais</li>
                              ) : null}
                            </ul>
                          </div>
                        ) : null}
                      </div>
                    </div>
                  ) : null}

                  {networkInterfaces ? (
                    <div className="rounded-md border border-slate-200 bg-slate-50/60 p-3">
                      <p className="text-xs font-semibold uppercase text-slate-500">Rede (interfaces)</p>
                      <div className="mt-2 overflow-hidden rounded-md border border-slate-200">
                        <Table>
                          <TableHeader>
                            <TableRow className="border-slate-200 bg-slate-100/80">
                              <TableHead className="text-xs text-slate-500">Interface</TableHead>
                              <TableHead className="text-xs text-slate-500">MAC</TableHead>
                              <TableHead className="text-xs text-slate-500">IP</TableHead>
                            </TableRow>
                          </TableHeader>
                          <TableBody>
                            {networkInterfaces.map((iface, idx) => (
                              <TableRow key={`iface-${idx}`} className="border-slate-100">
                                <TableCell className="text-sm">{iface?.name ?? "—"}</TableCell>
                                <TableCell className="text-sm text-muted-foreground">{iface?.mac ?? "—"}</TableCell>
                                <TableCell className="text-sm text-muted-foreground">{iface?.ip ?? "—"}</TableCell>
                              </TableRow>
                            ))}
                          </TableBody>
                        </Table>
                      </div>
                    </div>
                  ) : networkSummary ? (
                    <div className="rounded-md border border-slate-200 bg-slate-50/60 p-3">
                      <p className="text-xs font-semibold uppercase text-slate-500">Rede</p>
                      <div className="mt-2 grid gap-1">
                        <DetailLine label="IP primário" value={networkSummary.primaryIp} />
                        <DetailLine label="IP público" value={networkSummary.publicIp} />
                        <DetailLine
                          label="MAC addresses"
                          value={
                            Array.isArray(networkSummary.macAddresses)
                              ? networkSummary.macAddresses.join(", ")
                              : machine?.macAddresses.join(", ")
                          }
                        />
                      </div>
                    </div>
                  ) : null}

                  {labels && labels.length > 0 ? (
                    <div className="rounded-md border border-slate-200 bg-slate-50/60 p-3">
                      <p className="text-xs font-semibold uppercase text-slate-500">Labels</p>
                      <div className="mt-2 flex flex-wrap gap-2">
                        {labels.slice(0, 12).map((label, index) => (
                          <Badge key={String(label.id ?? `${label.name ?? "label"}-${index}`)} variant="outline">
                            {label.name ?? `Label ${index + 1}`}
                          </Badge>
                        ))}
                        {labels.length > 12 ? (
                          <Badge variant="outline">+{labels.length - 12} outras</Badge>
                        ) : null}
                      </div>
                    </div>
                  ) : null}
                </div>
              </section>
            ) : null}

            {/* Discos (agente) */}
            {disks.length > 0 ? (
              <section className="space-y-2">
                <h4 className="text-sm font-semibold">Discos e partições</h4>
                <div className="rounded-md border border-slate-200 bg-slate-50/60">
                  <Table>
                    <TableHeader>
                      <TableRow className="border-slate-200 bg-slate-100/80">
                        <TableHead className="text-xs text-slate-500">Nome</TableHead>
                        <TableHead className="text-xs text-slate-500">Mount</TableHead>
                        <TableHead className="text-xs text-slate-500">FS</TableHead>
                        <TableHead className="text-xs text-slate-500">Capacidade</TableHead>
                        <TableHead className="text-xs text-slate-500">Livre</TableHead>
                      </TableRow>
                    </TableHeader>
                    <TableBody>
                      {disks.map((d, idx) => (
                        <TableRow key={`disk-${idx}`} className="border-slate-100">
                          <TableCell className="text-sm">{d.name ?? "—"}</TableCell>
                          <TableCell className="text-sm text-muted-foreground">{d.mountPoint ?? "—"}</TableCell>
                          <TableCell className="text-sm text-muted-foreground">{d.fs ?? "—"}</TableCell>
                          <TableCell className="text-sm text-foreground">{formatBytes(Number(d.totalBytes))}</TableCell>
                          <TableCell className="text-sm text-muted-foreground">{formatBytes(Number(d.availableBytes))}</TableCell>
                        </TableRow>
                      ))}
                    </TableBody>
                  </Table>
                </div>
              </section>
            ) : null}

            {/* Inventário estendido por SO */}
            {extended ? (
              <section className="space-y-3">
                <div>
                  <h4 className="text-sm font-semibold">Inventário estendido</h4>
                  <p className="text-xs text-muted-foreground">Dados ricos coletados pelo agente, variam por sistema operacional.</p>
                </div>

                {/* Linux */}
                {linuxExt ? (
                  <div className="space-y-3">
                    {linuxLsblk.length > 0 ? (
                      <div className="rounded-md border border-slate-200 bg-slate-50/60 p-3">
                        <p className="text-xs font-semibold uppercase text-slate-500">Montagens (lsblk)</p>
                        <div className="mt-2 overflow-hidden rounded-md border border-slate-200">
                          <Table>
                            <TableHeader>
                              <TableRow className="border-slate-200 bg-slate-100/80">
                                <TableHead className="text-xs text-slate-500">Nome</TableHead>
                                <TableHead className="text-xs text-slate-500">Ponto de montagem</TableHead>
                                <TableHead className="text-xs text-slate-500">FS</TableHead>
                                <TableHead className="text-xs text-slate-500">Tamanho</TableHead>
                              </TableRow>
                            </TableHeader>
                            <TableBody>
                              {linuxLsblk.slice(0, 18).map((entry, idx) => {
                                const name = entry.name ?? "—"
                                const mp = entry.mountPoint ?? entry.mountpoint ?? "—"
                                const fs = entry.fs ?? entry.fstype ?? "—"
                                const sizeRaw = typeof entry.sizeBytes === "number" ? entry.sizeBytes : entry.size
                                return (
                                  <TableRow key={`lsblk-${idx}`} className="border-slate-100">
                                    <TableCell className="text-sm text-foreground">{name}</TableCell>
                                    <TableCell className="text-sm text-muted-foreground">{mp || "—"}</TableCell>
                                    <TableCell className="text-sm text-muted-foreground">{fs || "—"}</TableCell>
                                    <TableCell className="text-sm text-muted-foreground">{typeof sizeRaw === "number" ? formatBytes(sizeRaw) : "—"}</TableCell>
                                  </TableRow>
                                )
                              })}
                            </TableBody>
                          </Table>
                        </div>
                      </div>
                    ) : null}
                    {linuxSmartEntries.length > 0 ? (
                      <div className="rounded-md border border-slate-200 bg-emerald-50/40 p-3 dark:bg-emerald-900/10">
                        <p className="text-xs font-semibold uppercase text-slate-500">SMART</p>
                        <div className="mt-2 grid gap-2">
                          {linuxSmartEntries.map((smartEntry, idx) => {
                            const ok = smartEntry.smart_status?.passed !== false
                            const model = smartEntry.model_name ?? smartEntry.model_family ?? "Disco"
                            const serial = smartEntry.serial_number ?? smartEntry.device?.name ?? "—"
                            return (
                              <div
                                key={`smart-${idx}`}
                                className={cn(
                                  "flex items-center justify-between gap-2 rounded-md border px-3 py-2 text-sm",
                                  ok
                                    ? "border-emerald-500/20 bg-emerald-500/15 text-emerald-700"
                                    : "border-rose-500/20 bg-rose-500/15 text-rose-700"
                                )}
                              >
                                <span className="font-medium text-foreground">
                                  {model} <span className="text-muted-foreground">({serial})</span>
                                </span>
                                <Badge variant="outline" className="text-xs uppercase">
                                  {ok ? "OK" : "ALERTA"}
                                </Badge>
                              </div>
                            )
                          })}
                        </div>
                      </div>
                    ) : null}

                    {linuxExt.lspci ? (
                      <div className="rounded-md border border-slate-200 bg-slate-50/60 p-3">
                        <p className="text-xs font-semibold uppercase text-slate-500">PCI</p>
                        <pre className="mt-2 whitespace-pre-wrap break-words text-xs text-muted-foreground">{linuxExt.lspci}</pre>
                      </div>
                    ) : null}
                    {linuxExt.lsusb ? (
                      <div className="rounded-md border border-slate-200 bg-slate-50/60 p-3">
                        <p className="text-xs font-semibold uppercase text-slate-500">USB</p>
                        <pre className="mt-2 whitespace-pre-wrap break-words text-xs text-muted-foreground">{linuxExt.lsusb}</pre>
                      </div>
                    ) : null}
                  </div>
                ) : null}

                {/* Windows */}
                {windowsExt ? (
                  <div className="space-y-3">
                    {/* Cards resumidos: CPU / RAM / GPU / Discos */}
                    <div className="grid gap-3 sm:grid-cols-2 xl:grid-cols-4">
                      <Card className="border-slate-200">
                        <CardContent className="flex items-center gap-3 py-3">
                          <Cpu className="size-5 text-slate-500" />
                          <div className="min-w-0">
                            <p className="text-xs text-muted-foreground">CPU</p>
                            <p className="break-words text-sm font-semibold text-foreground">{winCpu?.Name ?? "—"}</p>
                          </div>
                        </CardContent>
                      </Card>
                      <Card className="border-slate-200">
                        <CardContent className="flex items-center gap-3 py-3">
                          <MemoryStick className="size-5 text-slate-500" />
                          <div>
                            <p className="text-xs text-muted-foreground">Memória total</p>
                            <p className="text-sm font-semibold text-foreground">{formatBytes(winMemTotal)}</p>
                          </div>
                        </CardContent>
                      </Card>
                      <Card className="border-slate-200">
                        <CardContent className="flex items-center gap-3 py-3">
                          <Monitor className="size-5 text-slate-500" />
                          <div className="min-w-0">
                            <p className="truncate text-xs text-muted-foreground">GPU</p>
                            <p className="truncate text-sm font-semibold text-foreground">{(windowsPrimaryGpu ?? primaryGpu)?.name ?? "—"}</p>
                          </div>
                        </CardContent>
                      </Card>
                      <Card className="border-slate-200">
                        <CardContent className="flex items-center gap-3 py-3">
                          <HardDrive className="size-5 text-slate-500" />
                          <div>
                            <p className="text-xs text-muted-foreground">Discos</p>
                            <p className="text-sm font-semibold text-foreground">{winDiskStats.count} · {formatBytes(winDiskStats.total)}</p>
                          </div>
                        </CardContent>
                      </Card>
                    </div>
                    {windowsCpuDetails.length > 0 ? (
                      <div className="rounded-md border border-slate-200 bg-slate-50/60 p-3">
                        <p className="text-xs font-semibold uppercase text-slate-500">CPU</p>
                        {windowsCpuDetails.slice(0, 1).map((cpuRecord, idx) => (
                          <div key={`cpu-${idx}`} className="mt-2 grid gap-1 text-sm text-muted-foreground">
                            <DetailLine label="Modelo" value={cpuRecord?.Name ?? "—"} classNameValue="break-words" />
                            <DetailLine label="Fabricante" value={cpuRecord?.Manufacturer ?? "—"} />
                            <DetailLine label="Socket" value={cpuRecord?.SocketDesignation ?? "—"} />
                            <DetailLine label="Núcleos" value={cpuRecord?.NumberOfCores != null ? `${cpuRecord.NumberOfCores}` : "—"} />
                            <DetailLine label="Threads" value={cpuRecord?.NumberOfLogicalProcessors != null ? `${cpuRecord.NumberOfLogicalProcessors}` : "—"} />
                            <DetailLine label="L2" value={cpuRecord?.L2CacheSize != null ? `${cpuRecord.L2CacheSize} KB` : "—"} />
                            <DetailLine label="L3" value={cpuRecord?.L3CacheSize != null ? `${cpuRecord.L3CacheSize} KB` : "—"} />
                            <DetailLine label="Clock máx" value={cpuRecord?.MaxClockSpeed != null ? `${cpuRecord.MaxClockSpeed} MHz` : "—"} />
                          </div>
                        ))}
                      </div>
                    ) : null}

                    {windowsExt.baseboard || windowsExt.bios ? (
                      <div className="rounded-md border border-slate-200 bg-slate-50/60 p-3">
                        <p className="text-xs font-semibold uppercase text-slate-500">Placa-mãe / BIOS</p>
                        <div className="mt-2 grid gap-1 text-sm text-muted-foreground">
                          {(() => {
                            const b = Array.isArray(windowsExt.baseboard) ? windowsExt.baseboard[0] : windowsExt.baseboard
                            const bios = Array.isArray(windowsExt.bios) ? windowsExt.bios[0] : windowsExt.bios
                            return (
                              <>
                                <DetailLine label="Board" value={b ? `${String(b?.["Manufacturer"] ?? "")} ${String(b?.["Product"] ?? "")}`.trim() : "—"} />
                                <DetailLine label="Board SN" value={b ? String(b?.["SerialNumber"] ?? "—") : "—"} />
                                <DetailLine label="BIOS" value={bios ? `${String(bios?.["Manufacturer"] ?? "")} ${String(bios?.["SMBIOSBIOSVersion"] ?? "")}`.trim() : "—"} />
                              </>
                            )
                          })()}
                        </div>
                      </div>
                    ) : null}
                    {windowsServices.length > 0 ? (
                      <div className="rounded-md border border-slate-200 bg-slate-50/60 p-3">
                        <p className="text-xs font-semibold uppercase text-slate-500">Serviços</p>
                        <div className="mt-2 overflow-hidden rounded-md border border-slate-200">
                          <Table>
                            <TableHeader>
                              <TableRow className="border-slate-200 bg-slate-100/80">
                                <TableHead className="text-xs text-slate-500">Nome</TableHead>
                                <TableHead className="text-xs text-slate-500">Exibição</TableHead>
                                <TableHead className="text-xs text-slate-500">Status</TableHead>
                              </TableRow>
                            </TableHeader>
                            <TableBody>
                              {windowsServices.slice(0, 10).map((service, index) => {
                                const record = toRecord(service) ?? {}
                                const name = readString(record, "Name", "name") ?? "—"
                                const displayName = readString(record, "DisplayName", "displayName") ?? "—"
                                const status = readString(record, "Status", "status") ?? "—"
                                return (
                                  <TableRow key={`svc-${index}`} className="border-slate-100">
                                    <TableCell className="text-sm">{name}</TableCell>
                                    <TableCell className="text-sm text-muted-foreground">{displayName}</TableCell>
                                    <TableCell className="text-sm text-muted-foreground">{status}</TableCell>
                                  </TableRow>
                                )
                              })}
                            </TableBody>
                          </Table>
                        </div>
                      </div>
                    ) : null}

                    {windowsSoftware.length > 0 ? (
                      <div className="rounded-md border border-slate-200 bg-slate-50/60 p-3">
                        <p className="text-xs font-semibold uppercase text-slate-500">Softwares (amostra)</p>
                        <ul className="mt-2 grid gap-1 text-xs text-muted-foreground">
                          {windowsSoftware.slice(0, 8).map((softwareItem, index) => {
                            const record = toRecord(softwareItem) ?? {}
                            const name = readString(record, "DisplayName", "name") ?? "—"
                            const version = readString(record, "DisplayVersion", "version")
                            const publisher = readString(record, "Publisher")
                            return (
                              <li key={`sw-${index}`}>
                                <span className="font-medium text-foreground">{name}</span>
                                {version ? <span className="ml-1">{version}</span> : null}
                                {publisher ? <span className="ml-1">· {publisher}</span> : null}
                              </li>
                            )
                          })}
                        </ul>
                      </div>
                    ) : null}

                    {windowsMemoryModules.length > 0 ? (
                      <div className="rounded-md border border-slate-200 bg-slate-50/60 p-3">
                        <p className="text-xs font-semibold uppercase text-slate-500">Módulos de memória</p>
                        <div className="mt-2 overflow-hidden rounded-md border border-slate-200">
                          <Table>
                            <TableHeader>
                              <TableRow className="border-slate-200 bg-slate-100/80">
                                <TableHead className="text-xs text-slate-500">Banco</TableHead>
                                <TableHead className="text-xs text-slate-500">Capacidade</TableHead>
                                <TableHead className="text-xs text-slate-500">Fabricante</TableHead>
                                <TableHead className="text-xs text-slate-500">PartNumber</TableHead>
                                <TableHead className="text-xs text-slate-500">Clock</TableHead>
                              </TableRow>
                            </TableHeader>
                            <TableBody>
                              {windowsMemoryModules.map((module, idx) => {
                                const record = toRecord(module) ?? {}
                                const bank = readString(record, "BankLabel", "bankLabel") ?? "—"
                                const capacityBytes =
                                  parseBytesLike(record["Capacity"]) ?? parseBytesLike(record["capacity"]) ?? 0
                                const manufacturer = readString(record, "Manufacturer", "manufacturer") ?? "—"
                                const partNumber = readString(record, "PartNumber", "partNumber") ?? "—"
                                const clockValue = readNumber(
                                  record,
                                  "ConfiguredClockSpeed",
                                  "configuredClockSpeed",
                                  "Speed",
                                  "speed"
                                )
                                const clockLabel =
                                  typeof clockValue === "number" && Number.isFinite(clockValue)
                                    ? `${clockValue} MHz`
                                    : "—"
                                return (
                                  <TableRow key={`mem-${idx}`} className="border-slate-100">
                                    <TableCell className="text-sm">{bank}</TableCell>
                                    <TableCell className="text-sm text-muted-foreground">
                                      {capacityBytes > 0 ? formatBytes(capacityBytes) : "—"}
                                    </TableCell>
                                    <TableCell className="text-sm text-muted-foreground">{manufacturer}</TableCell>
                                    <TableCell className="text-sm text-muted-foreground">{partNumber}</TableCell>
                                    <TableCell className="text-sm text-muted-foreground">{clockLabel}</TableCell>
                                  </TableRow>
                                )
                              })}
                            </TableBody>
                          </Table>
                        </div>
                      </div>
                    ) : null}

                    {windowsVideoControllers.length > 0 ? (
                      <div className="rounded-md border border-slate-200 bg-slate-50/60 p-3">
                        <p className="text-xs font-semibold uppercase text-slate-500">Adaptadores de vídeo</p>
                        <ul className="mt-2 grid gap-1 text-xs text-muted-foreground">
                          {windowsVideoControllers.map((controller, idx) => {
                            const record = toRecord(controller) ?? {}
                            const normalized = normalizeGpuSource(record)
                            const name =
                              normalized?.name ??
                              readString(record, "Name", "name") ??
                              "—"
                            const ram =
                              normalized?.memoryBytes ??
                              parseBytesLike(record["AdapterRAM"]) ??
                              undefined
                            const driver = normalized?.driver ?? readString(record, "DriverVersion", "driverVersion")
                            const vendor = normalized?.vendor ?? readString(record, "AdapterCompatibility")
                            return (
                              <li key={`vid-${idx}`}>
                                <span className="font-medium text-foreground">{name}</span>
                                {typeof ram === "number" && ram > 0 ? <span className="ml-1">{formatBytes(ram)}</span> : null}
                                {vendor ? <span className="ml-1 text-muted-foreground">· {vendor}</span> : null}
                                {driver ? <span className="ml-1">· Driver {driver}</span> : null}
                              </li>
                            )
                          })}
                        </ul>
                      </div>
                    ) : null}

                    {windowsDiskEntries.length > 0 ? (
                      <div className="rounded-md border border-slate-200 bg-slate-50/60 p-3">
                        <p className="text-xs font-semibold uppercase text-slate-500">Discos físicos</p>
                        <div className="mt-2 overflow-hidden rounded-md border border-slate-200">
                          <Table>
                            <TableHeader>
                              <TableRow className="border-slate-200 bg-slate-100/80">
                                <TableHead className="text-xs text-slate-500">Modelo</TableHead>
                                <TableHead className="text-xs text-slate-500">Tamanho</TableHead>
                                <TableHead className="text-xs text-slate-500">Interface</TableHead>
                                <TableHead className="text-xs text-slate-500">Tipo</TableHead>
                                <TableHead className="text-xs text-slate-500">Serial</TableHead>
                              </TableRow>
                            </TableHeader>
                            <TableBody>
                              {windowsDiskEntries.map((disk, idx) => {
                                const record = toRecord(disk) ?? {}
                                const model = readString(record, "Model", "model")
                                const serial = readString(record, "SerialNumber", "serialNumber")
                                const size = parseBytesLike(record["Size"])
                                const iface = readString(record, "InterfaceType", "interfaceType")
                                const media = readString(record, "MediaType", "mediaType")
                                return (
                                  <TableRow key={`diskp-${idx}`} className="border-slate-100">
                                    <TableCell className="text-sm">{model ?? serial ?? "—"}</TableCell>
                                    <TableCell className="text-sm text-muted-foreground">
                                      {typeof size === "number" && size > 0 ? formatBytes(size) : "—"}
                                    </TableCell>
                                    <TableCell className="text-sm text-muted-foreground">{iface ?? "—"}</TableCell>
                                    <TableCell className="text-sm text-muted-foreground">{media ?? "—"}</TableCell>
                                    <TableCell className="text-sm text-muted-foreground">{serial ?? "—"}</TableCell>
                                  </TableRow>
                                )
                              })}
                            </TableBody>
                          </Table>
                        </div>
                      </div>
                    ) : null}

                    {windowsExt.defender ? (
                      <div className="rounded-md border border-slate-200 bg-slate-50/60 p-3">
                        <p className="text-xs font-semibold uppercase text-slate-500">Defender</p>
                        <div className="mt-2 flex flex-wrap gap-2 text-xs">
                          {readBool(windowsExt.defender, "AntivirusEnabled") === true ? (
                            <Badge className="gap-1 border-emerald-500/20 bg-emerald-500/15 text-emerald-700">
                              <ShieldCheck className="size-3" /> Antivírus: Ativo
                            </Badge>
                          ) : (
                            <Badge className="gap-1 border-rose-500/20 bg-rose-500/15 text-rose-700">
                              <ShieldAlert className="size-3" /> Antivírus: Inativo
                            </Badge>
                          )}
                          {readBool(windowsExt.defender, "RealTimeProtectionEnabled") === true ? (
                            <Badge className="gap-1 border-emerald-500/20 bg-emerald-500/15 text-emerald-700">
                              <ShieldCheck className="size-3" /> Proteção em tempo real: Ativa
                            </Badge>
                          ) : (
                            <Badge className="gap-1 border-rose-500/20 bg-rose-500/15 text-rose-700">
                              <ShieldAlert className="size-3" /> Proteção em tempo real: Inativa
                            </Badge>
                          )}
                        </div>
                      </div>
                    ) : null}
                  </div>
                ) : null}

                {/* macOS */}
                {macosExt ? (
                  <div className="space-y-3">
                    {Array.isArray(macosExt.packages) && macosExt.packages.length > 0 ? (
                      <div className="rounded-md border border-slate-200 bg-slate-50/60 p-3">
                        <p className="text-xs font-semibold uppercase text-slate-500">Pacotes</p>
                        <p className="mt-1 text-xs text-muted-foreground">{macosExt.packages.slice(0, 8).join(", ")}</p>
                      </div>
                    ) : null}
                    {macosExt.launchctl ? (
                      <div className="rounded-md border border-slate-200 bg-slate-50/60 p-3">
                        <p className="text-xs font-semibold uppercase text-slate-500">Launchctl</p>
                        <pre className="mt-2 whitespace-pre-wrap break-words text-xs text-muted-foreground">{macosExt.launchctl}</pre>
                      </div>
                    ) : null}
                  </div>
                ) : null}
              </section>
            ) : null}

            {/* Postura/Alertas */}
            {Array.isArray(machine?.postureAlerts) && machine?.postureAlerts?.length ? (
              <section className="space-y-2">
                <h4 className="text-sm font-semibold">Alertas de postura</h4>
                <div className="space-y-2">
                  {machine?.postureAlerts?.map((a: { kind?: string; message?: string; severity?: string }, i: number) => (
                    <div key={`alert-${i}`} className={cn("flex items-center justify-between rounded-md border px-3 py-2 text-sm",
                      (a?.severity ?? "warning").toLowerCase() === "critical" ? "border-rose-500/20 bg-rose-500/10" : "border-amber-500/20 bg-amber-500/10")
                    }>
                      <span className="font-medium text-foreground">{a?.message ?? a?.kind ?? "Alerta"}</span>
                      <Badge variant="outline">{String(a?.kind ?? "ALERTA")}</Badge>
                    </div>
                  ))}
                </div>
                <p className="text-xs text-muted-foreground">
                  Última avaliação: {machine?.lastPostureAt ? formatRelativeTime(new Date(machine.lastPostureAt)) : "—"}
                </p>
              </section>
            ) : null}

            <div className="flex flex-wrap gap-2 pt-2">
              {Array.isArray(software) && software.length > 0 ? (
                <Button size="sm" variant="outline" onClick={() => exportCsv(software, "softwares.csv")}>Softwares CSV</Button>
              ) : null}
              {Array.isArray(metadata?.services) && metadata.services.length > 0 ? (
                <Button size="sm" variant="outline" onClick={() => exportCsv(metadata.services as Array<Record<string, unknown>>, "servicos.csv")}>Serviços CSV</Button>
              ) : null}
            </div>
            {fleet ? (
              <section className="space-y-2 text-sm text-muted-foreground">
                <Separator />
                <div className="flex items-center justify-between">
                  <span>ID Fleet</span>
                  <span className="font-medium text-foreground">{fleet.id ?? "—"}</span>
                </div>
                <div className="flex items-center justify-between">
                  <span>Team ID</span>
                  <span className="font-medium text-foreground">{fleet.teamId ?? "—"}</span>
                </div>
                <div className="flex items-center justify-between">
                  <span>Detalhes atualizados</span>
                  <span className="font-medium text-foreground">
                    {fleet.detailUpdatedAt ? formatDate(new Date(String(fleet.detailUpdatedAt))) : "—"}
                  </span>
                </div>
                <div className="flex items-center justify-between">
                  <span>Versão osquery</span>
                  <span className="font-medium text-foreground">{fleet.osqueryVersion ?? "—"}</span>
                </div>
              </section>
            ) : null}

            {software && software.length > 0 ? (
              <section className="space-y-2">
                <h4 className="text-sm font-semibold">Softwares detectados</h4>
                <div className="rounded-md border border-slate-200 bg-slate-50/60">
                  <Table>
                    <TableHeader>
                      <TableRow className="border-slate-200 bg-slate-100/80">
                        <TableHead className="text-xs text-slate-500">Nome</TableHead>
                        <TableHead className="text-xs text-slate-500">Versão</TableHead>
                        <TableHead className="text-xs text-slate-500">Fonte</TableHead>
                      </TableRow>
                    </TableHeader>
                    <TableBody>
                      {software.slice(0, 6).map((item, index) => (
                        <TableRow key={`${item.name ?? "software"}-${index}`} className="border-slate-100">
                          <TableCell className="text-sm text-foreground">{item.name ?? "—"}</TableCell>
                          <TableCell className="text-sm text-muted-foreground">{item.version ?? "—"}</TableCell>
                          <TableCell className="text-sm text-muted-foreground">{item.source ?? "—"}</TableCell>
                        </TableRow>
                      ))}
                    </TableBody>
                  </Table>
                  {software.length > 6 ? (
                    <p className="px-3 py-2 text-xs text-muted-foreground">
                      +{software.length - 6} softwares adicionais sincronizados via Fleet.
                    </p>
                  ) : null}
                </div>
              </section>
            ) : null}

            {machine ? (
              <section className="space-y-2 rounded-md border border-rose-200 bg-rose-50/60 p-3">
                <div className="space-y-1">
                  <h4 className="text-sm font-semibold text-rose-700">Zona perigosa</h4>
                  <p className="text-xs text-rose-600">
                    Excluir a máquina revoga o token atual e remove os dados de inventário sincronizados.
                  </p>
                </div>
                <Button variant="destructive" size="sm" onClick={() => setDeleteDialog(true)}>Excluir máquina</Button>
              </section>
            ) : null}

            <Dialog open={openDialog} onOpenChange={setOpenDialog}>
              <div className="flex justify-end">
                <DialogTrigger asChild>
                  <Button size="sm" variant="outline" onClick={() => setOpenDialog(true)}>Inventário completo</Button>
                </DialogTrigger>
              </div>
              <DialogContent className="max-w-3xl">
                <DialogHeader>
                  <DialogTitle>Inventário completo — {machine.hostname}</DialogTitle>
                </DialogHeader>
                <div className="space-y-2">
                  <Input placeholder="Buscar no JSON" value={dialogQuery} onChange={(e) => setDialogQuery(e.target.value)} />
                  <div className="max-h-[60vh] overflow-auto rounded-md border border-slate-200 bg-slate-50/60 p-3 text-xs">
                    <pre className="whitespace-pre-wrap break-words text-muted-foreground" dangerouslySetInnerHTML={{ __html: filteredJsonHtml
                      .replaceAll("__HIGHLIGHT__", '<mark class="bg-yellow-200 text-foreground">')
                      .replaceAll("__END__", '</mark>')
                    }} />
                  </div>
                </div>
              </DialogContent>
            </Dialog>

            <Dialog open={deleteDialog} onOpenChange={(open) => { if (!open) setDeleting(false); setDeleteDialog(open) }}>
              <DialogContent>
                <DialogHeader>
                  <DialogTitle>Excluir máquina</DialogTitle>
                </DialogHeader>
                <div className="space-y-3 text-sm text-muted-foreground">
                  <p>Tem certeza que deseja excluir <span className="font-semibold text-foreground">{machine?.hostname}</span>? Esta ação não pode ser desfeita.</p>
                  <p>Os tokens ativos serão revogados e o inventário deixará de aparecer no painel.</p>
                  <div className="flex justify-end gap-2">
                    <Button variant="outline" onClick={() => setDeleteDialog(false)} disabled={deleting}>Cancelar</Button>
                    <Button
                      variant="destructive"
                      disabled={deleting}
                      onClick={async () => {
                        if (!machine) return
                        setDeleting(true)
                        try {
                          const res = await fetch("/api/admin/machines/delete", {
                            method: "POST",
                            headers: { "Content-Type": "application/json" },
                            body: JSON.stringify({ machineId: machine.id }),
                          })
                          if (!res.ok) throw new Error(`HTTP ${res.status}`)
                          toast.success("Máquina excluída")
                          setDeleteDialog(false)
                          router.push("/admin/machines")
                        } catch (err) {
                          console.error(err)
                          toast.error("Falha ao excluir máquina")
                        } finally {
                          setDeleting(false)
                        }
                      }}
                    >
                      {deleting ? "Excluindo..." : "Excluir máquina"}
                    </Button>
                  </div>
                </div>
              </DialogContent>
            </Dialog>
          </div>
        )}
      </CardContent>
    </Card>
  )
}

function MachinesGrid({ machines, companyNameBySlug }: { machines: MachinesQueryItem[]; companyNameBySlug: Map<string, string> }) {
  if (!machines || machines.length === 0) return <EmptyState />
  return (
    <div className="grid grid-cols-1 gap-3 [@supports(display:grid)]:grid-cols-[repeat(auto-fit,minmax(280px,1fr))]">
      {machines.map((m) => (
        <MachineCard
          key={m.id}
          machine={m}
          companyName={m.companySlug ? companyNameBySlug.get(m.companySlug) ?? m.companySlug : null}
        />
      ))}
    </div>
  )
}

function MachineCard({ machine, companyName }: { machine: MachinesQueryItem; companyName?: string | null }) {
  const { className } = getStatusVariant(machine.status)
  const lastHeartbeat = machine.lastHeartbeatAt ? new Date(machine.lastHeartbeatAt) : null
  type AgentMetrics = {
    memoryUsedBytes?: number
    memoryTotalBytes?: number
    memoryUsedPercent?: number
    cpuUsagePercent?: number
  }
  const mm = (machine.metrics ?? null) as unknown as AgentMetrics | null
  const memUsed = mm?.memoryUsedBytes ?? NaN
  const memTotal = mm?.memoryTotalBytes ?? NaN
  const memPct = mm?.memoryUsedPercent ?? (Number.isFinite(memUsed) && Number.isFinite(memTotal) ? (Number(memUsed) / Number(memTotal)) * 100 : NaN)
  const cpuPct = mm?.cpuUsagePercent ?? NaN
  const collaborator = (() => {
    if (machine.assignedUserEmail) {
      return {
        email: machine.assignedUserEmail ?? undefined,
        name: machine.assignedUserName ?? undefined,
        role: machine.persona ?? machine.assignedUserRole ?? undefined,
      }
    }
    const inv = machine.inventory as unknown
    if (!inv || typeof inv !== "object") return null
    const raw = (inv as Record<string, unknown>).collaborator
    if (!raw || typeof raw !== "object") return null
    const obj = raw as Record<string, unknown>
    const email = typeof obj.email === "string" ? obj.email : undefined
    if (!email) return null
    return {
      email,
      name: typeof obj.name === "string" ? obj.name : undefined,
      role: typeof obj.role === "string" ? (obj.role as string) : undefined,
    }
  })()
  const persona = collaborator?.role === "manager" ? "Gestor" : "Colaborador"
  const companyLabel = companyName ?? machine.companySlug ?? null

  return (
    <Link href={`/admin/machines/${machine.id}`} className="group">
      <Card className="relative h-full overflow-hidden border-slate-200 transition-colors hover:border-slate-300">
        <div className="absolute right-2 top-2">
          <span
            aria-hidden
            className={cn(
              "relative block size-2 rounded-full",
              className.includes("emerald")
                ? "bg-emerald-500"
                : className.includes("rose")
                  ? "bg-rose-500"
                  : className.includes("amber")
                    ? "bg-amber-500"
                    : "bg-slate-400"
            )}
          />
          {String(machine.status ?? "").toLowerCase() === "online" ? (
            <span className="absolute left-1/2 top-1/2 -z-10 size-4 -translate-x-1/2 -translate-y-1/2 rounded-full bg-emerald-400/30 animate-ping" />
          ) : null}
        </div>
        <CardHeader className="pb-2">
          <CardTitle className="line-clamp-1 flex items-center gap-2 text-base font-semibold">
            <Monitor className="size-4 text-slate-500" /> {machine.hostname}
          </CardTitle>
          <CardDescription className="line-clamp-1 text-xs">{machine.authEmail ?? "—"}</CardDescription>
        </CardHeader>
        <CardContent className="flex grow flex-col gap-3 text-sm">
          <div className="flex flex-wrap items-center gap-2">
            <Badge variant="outline" className="border-slate-300 bg-slate-100 text-xs font-medium text-slate-700">
              {machine.osName ?? "SO"} {machine.osVersion ?? ""}
            </Badge>
            {machine.architecture ? (
              <Badge variant="outline" className="border-slate-300 bg-slate-100 text-xs font-medium text-slate-700">
                {machine.architecture.toUpperCase()}
              </Badge>
            ) : null}
            {companyLabel ? (
              <Badge variant="outline" className="text-xs">{companyLabel}</Badge>
            ) : null}
          </div>
          {collaborator?.email ? (
            <p className="text-[11px] text-muted-foreground">
              {persona}: {collaborator.name ? `${collaborator.name} · ` : ""}
              {collaborator.email}
            </p>
          ) : null}
          <div className="grid grid-cols-2 gap-2">
            <div className="flex items-center gap-2 rounded-md border border-slate-200 bg-slate-50/80 px-2 py-1.5">
              <Cpu className="size-4 text-slate-500" />
              <span className="text-xs font-medium text-slate-800">{formatPercent(cpuPct)}</span>
            </div>
            <div className="flex items-center gap-2 rounded-md border border-slate-200 bg-slate-50/80 px-2 py-1.5">
              <MemoryStick className="size-4 text-slate-500" />
              <span className="text-xs font-medium text-slate-800">
                {Number.isFinite(memUsed) && Number.isFinite(memTotal)
                  ? `${formatBytes(memUsed)} / ${formatBytes(memTotal)}`
                  : formatPercent(memPct)}
              </span>
            </div>
          </div>
          <div className="mt-auto flex items-center justify-between text-xs text-muted-foreground">
            <span className="flex items-center gap-1.5">
              <HardDrive className="size-3.5 text-slate-500" />
              {Array.isArray(machine.inventory?.disks) ? `${machine.inventory?.disks?.length ?? 0} discos` : "—"}
            </span>
            <span>
              {lastHeartbeat ? formatRelativeTime(lastHeartbeat) : "sem heartbeat"}
            </span>
          </div>
        </CardContent>
      </Card>
    </Link>
  )
}

function DetailLine({ label, value, classNameValue }: DetailLineProps) {
  if (value === null || value === undefined) return null
  if (typeof value === "string" && (value.trim() === "" || value === "undefined" || value === "null")) {
    return null
  }
  return (
    <div className="flex items-center justify-between gap-4">
      <span>{label}</span>
      <span className={cn("text-right font-medium text-foreground", classNameValue)}>{value}</span>
    </div>
  )
}

function MetricsGrid({ metrics }: { metrics: MachineMetrics }) {
  const data = (metrics ?? {}) as Record<string, unknown>
  // Compat: aceitar chaves do agente desktop (cpuUsagePercent, memoryUsedBytes, memoryTotalBytes)
  const cpu = (() => {
    const v = Number(
      data.cpuUsage ?? data.cpu ?? data.cpu_percent ?? data.cpuUsagePercent ?? NaN
    )
    return v
  })()
  const memory = (() => {
    // valor absoluto em bytes, se disponível
    const memBytes = Number(
      data.memoryBytes ?? data.memory ?? data.memory_used ?? data.memoryUsedBytes ?? NaN
    )
    if (Number.isFinite(memBytes)) return memBytes
    // tentar derivar a partir de percentuais do agente
    const usedPct = Number(data.memoryUsedPercent ?? NaN)
    const totalBytes = Number(data.memoryTotalBytes ?? NaN)
    if (Number.isFinite(usedPct) && Number.isFinite(totalBytes)) {
      return Math.max(0, Math.min(1, usedPct > 1 ? usedPct / 100 : usedPct)) * totalBytes
    }
    return NaN
  })()
  const disk = Number(data.diskUsage ?? data.disk ?? NaN)
  const gpuUsage = Number(
    data.gpuUsage ?? data.gpu ?? data.gpuUsagePercent ?? data.gpu_percent ?? NaN
  )

  const cards: Array<{ label: string; value: string }> = [
    { label: "CPU", value: formatPercent(cpu) },
    { label: "Memória", value: formatBytes(memory) },
    { label: "Disco", value: Number.isNaN(disk) ? "—" : formatPercent(disk) },
  ]

  if (!Number.isNaN(gpuUsage)) {
    cards.push({ label: "GPU", value: formatPercent(gpuUsage) })
  }

  return (
    <div className="grid gap-2 sm:grid-cols-3 md:grid-cols-4">
      {cards.map((card) => (
        <div key={card.label} className="rounded-md border border-slate-200 bg-slate-50/60 p-3 text-sm text-muted-foreground">
          <p className="text-xs uppercase text-slate-500">{card.label}</p>
          <p className="text-sm font-semibold text-foreground">{card.value}</p>
        </div>
      ))}
    </div>
  )
}

function exportCsv(items: Array<Record<string, unknown>>, filename: string) {
  if (!Array.isArray(items) || items.length === 0) return
  const headersSet = new Set<string>()
  items.forEach((it) => Object.keys(it ?? {}).forEach((k) => headersSet.add(k)))
  const headers = Array.from(headersSet)
  const csv = [headers.join(",")]
  for (const it of items) {
    const row = headers
      .map((h) => {
        const v = (it as Record<string, unknown>)[h]
        if (v === undefined || v === null) return ""
        const s = typeof v === "string" ? v : JSON.stringify(v)
        return `"${s.replace(/"/g, '""')}"`
      })
      .join(",")
    csv.push(row)
  }
  const blob = new Blob([csv.join("\n")], { type: "text/csv;charset=utf-8;" })
  const url = URL.createObjectURL(blob)
  const a = document.createElement("a")
  a.href = url
  a.download = filename
  document.body.appendChild(a)
  a.click()
  a.remove()
  URL.revokeObjectURL(url)
}
