"use client"

import { useCallback, useEffect, useMemo, useState } from "react"
import type { ReactNode } from "react"
import { useMutation, 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,
  Shield,
  ShieldOff,
  ShieldQuestion,
  Lock,
  Cloud,
  RefreshCcw,
  CheckSquare,
  RotateCcw,
  AlertTriangle,
  Key,
  Eye,
  EyeOff,
  MonitorSmartphone,
  Globe,
  Apple,
  Terminal,
  Power,
  PlayCircle,
  Download,
  Plus,
  Smartphone,
  Tablet,
  Usb,
  Loader2,
  X,
  TicketCheck,
} 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 { Textarea } from "@/components/ui/textarea"
import { Spinner } from "@/components/ui/spinner"
import { Progress } from "@/components/ui/progress"
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover"
import { Checkbox } from "@/components/ui/checkbox"
import { Card, CardAction, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"
import { Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, 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 { ChartContainer } from "@/components/ui/chart"
import { cn } from "@/lib/utils"
import { DEVICE_INVENTORY_COLUMN_METADATA, type DeviceInventoryColumnConfig } from "@/lib/device-inventory-columns"
import { DEVICE_STATUS_LABELS, getDeviceStatusIndicator, resolveDeviceStatus } from "@/lib/device-status"
import { RadialBarChart, RadialBar, PolarAngleAxis } from "recharts"
import Link from "next/link"
import { useRouter } from "next/navigation"
import { useAuth } from "@/lib/auth-client"
import type { Id } from "@/convex/_generated/dataModel"
import { TicketStatusBadge } from "@/components/tickets/status-badge"
import type { TicketPriority, TicketStatus } from "@/lib/schemas/ticket"
import { DeviceCustomFieldManager } from "@/components/admin/devices/device-custom-field-manager"
import { UsbPolicyControl } from "@/components/admin/devices/usb-policy-control"
import { DatePicker } from "@/components/ui/date-picker"
import { SearchableCombobox, type SearchableComboboxOption } from "@/components/ui/searchable-combobox"

type DeviceMetrics = Record<string, unknown> | null

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

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

type NormalizedSoftwareEntry = {
  name: string
  version?: string
  publisher?: string
  installDate?: Date | null
  source?: string
}

type DeviceExportTemplate = {
  id: string
  name: string
  description?: string
  columns: DeviceInventoryColumnConfig[]
  companyId: string | null
  isDefault: boolean
  isActive?: boolean
}

const BASE_DEVICE_COLUMN_KEYS = DEVICE_INVENTORY_COLUMN_METADATA.map((meta) => meta.key)
const DEFAULT_DEVICE_COLUMN_CONFIG: DeviceInventoryColumnConfig[] = DEVICE_INVENTORY_COLUMN_METADATA.filter((meta) => meta.default !== false).map(
  (meta) => ({ key: meta.key })
)

function orderColumnConfig(
  config: DeviceInventoryColumnConfig[],
  customOrder: string[]
): DeviceInventoryColumnConfig[] {
  const order = new Map<string, number>()
  BASE_DEVICE_COLUMN_KEYS.forEach((key, index) => order.set(key, index))
  customOrder.forEach((key, idx) => {
    if (!order.has(key)) {
      order.set(key, BASE_DEVICE_COLUMN_KEYS.length + idx)
    }
  })
  const seen = new Set<string>()
  return config
    .filter(({ key }) => {
      if (!key || seen.has(key)) return false
      seen.add(key)
      return order.has(key)
    })
    .sort((a, b) => (order.get(a.key)! - order.get(b.key)!))
}

function areColumnConfigsEqual(a: DeviceInventoryColumnConfig[], b: DeviceInventoryColumnConfig[]): boolean {
  if (a.length !== b.length) return false
  return a.every((col, idx) => col.key === b[idx]?.key && (col.label ?? "") === (b[idx]?.label ?? ""))
}

function formatDeviceCustomFieldDisplay(entry?: { value?: unknown; displayValue?: string }): string {
  if (!entry) return "—"
  if (typeof entry.displayValue === "string" && entry.displayValue.trim().length > 0) {
    return entry.displayValue
  }
  const raw = entry.value
  if (raw === null || raw === undefined) return "—"
  if (Array.isArray(raw)) {
    const values = raw
      .map((item) => (item === null || item === undefined ? "" : String(item).trim()))
      .filter((item) => item.length > 0)
    return values.length > 0 ? values.join(", ") : "—"
  }
  if (typeof raw === "boolean") {
    return raw ? "Sim" : "Não"
  }
  if (typeof raw === "number") {
    return Number.isFinite(raw) ? String(raw) : "—"
  }
  const asString = String(raw).trim()
  return asString.length > 0 ? asString : "—"
}

type DeviceAlertEntry = {
  id: string
  kind: string
  message: string
  severity: string
  createdAt: number
}
type DeviceTicketSummary = {
  id: string
  reference: number
  subject: string
  status: TicketStatus
  priority: TicketPriority
  updatedAt: number
  createdAt: number
  device: { id: string | null; hostname: string | null } | null
  assignee: { name: string | null; email: string | null } | null
}

type DeviceOpenTicketsSummary = {
  totalOpen: number
  hasMore: boolean
  tickets: DeviceTicketSummary[]
}


type DetailLineProps = {
  label: string
  value?: string | number | null
  classNameValue?: string
  layout?: "spread" | "compact"
}

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 WindowsExtended = {
  software?: DeviceSoftware[]
  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
  bitLocker?: Array<Record<string, unknown>> | Record<string, unknown>
  bitlocker?: Array<Record<string, unknown>> | Record<string, unknown>
  tpm?: Record<string, unknown>
  secureBoot?: Record<string, unknown>
  deviceGuard?: Array<Record<string, unknown>> | Record<string, unknown>
  firewallProfiles?: Array<Record<string, unknown>> | Record<string, unknown>
  windowsUpdate?: Record<string, unknown>
  computerSystem?: Record<string, unknown>
  azureAdStatus?: Record<string, unknown>
}

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

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

type DeviceInventory = {
  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?: DeviceSoftware[]
  labels?: DeviceLabel[]
  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 }
}

export type DeviceRemoteAccessEntry = {
  id: string | null
  clientId: string
  provider: string | null
  identifier: string | null
  username: string | null
  password: string | null
  url: string | null
  notes: string | null
  lastVerifiedAt: number | null
  metadata: Record<string, unknown> | null
}

export type DeviceRemoteAccess = {
  provider: string | null
  identifier: string | null
  username: string | null
  password: string | null
  url: string | null
  notes: string | null
  lastVerifiedAt: number | null
  metadata: Record<string, unknown> | null
}

function collectInitials(name: string): string {
  const words = name.split(/\s+/).filter(Boolean)
  if (words.length === 0) return "?"
  if (words.length === 1) return words[0].slice(0, 2).toUpperCase()
  return (words[0][0] + words[1][0]).toUpperCase()
}

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 createRemoteAccessClientId() {
  if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") {
    return crypto.randomUUID()
  }
  return `ra-${Math.random().toString(36).slice(2, 8)}-${Date.now().toString(36)}`
}

function normalizeDeviceRemoteAccessEntry(raw: unknown): DeviceRemoteAccessEntry | null {
  if (!raw) return null
  if (typeof raw === "string") {
    const trimmed = raw.trim()
    if (!trimmed) return null
    const isUrl = /^https?:\/\//i.test(trimmed)
    return {
      id: null,
      clientId: createRemoteAccessClientId(),
      provider: null,
      identifier: isUrl ? null : trimmed,
      username: null,
      password: null,
      url: isUrl ? trimmed : null,
      notes: null,
      lastVerifiedAt: null,
      metadata: null,
    }
  }
  const record = toRecord(raw)
  if (!record) return null
  const provider = readString(record, "provider", "tool", "vendor", "name") ?? null
  const identifier =
    readString(record, "identifier", "code", "id", "accessId") ??
    readString(record, "value", "label")
  const username = readString(record, "username", "user", "login", "email", "account") ?? null
  const password = readString(record, "password", "pass", "secret", "pin") ?? null
  const url = readString(record, "url", "link", "remoteUrl", "console", "viewer") ?? null
  const notes = readString(record, "notes", "note", "description", "obs") ?? null
  const timestampCandidate =
    readNumber(record, "lastVerifiedAt", "verifiedAt", "checkedAt", "updatedAt") ??
    parseDateish(record["lastVerifiedAt"] ?? record["verifiedAt"] ?? record["checkedAt"] ?? record["updatedAt"])
  const lastVerifiedAt = timestampCandidate instanceof Date ? timestampCandidate.getTime() : timestampCandidate ?? null
  const id = readString(record, "id") ?? null
  return {
    id,
    clientId: id ?? createRemoteAccessClientId(),
    provider,
    identifier: identifier ?? url ?? null,
    username,
    password,
    url,
    notes,
    lastVerifiedAt,
    metadata: record,
  }
}

export function normalizeDeviceRemoteAccess(raw: unknown): DeviceRemoteAccess | null {
  const entry = normalizeDeviceRemoteAccessEntry(raw)
  if (!entry) return null
  const { provider, identifier, username, password, url, notes, lastVerifiedAt, metadata } = entry
  return { provider, identifier, username, password, url, notes, lastVerifiedAt, metadata }
}

export function normalizeDeviceRemoteAccessList(raw: unknown): DeviceRemoteAccessEntry[] {
  if (!raw) return []
  const source = Array.isArray(raw) ? raw : [raw]
  const seen = new Set<string>()
  const entries: DeviceRemoteAccessEntry[] = []
  for (const item of source) {
    const entry = normalizeDeviceRemoteAccessEntry(item)
    if (!entry) continue
    let clientId = entry.clientId
    while (seen.has(clientId)) {
      clientId = createRemoteAccessClientId()
    }
    seen.add(clientId)
    entries.push(clientId === entry.clientId ? entry : { ...entry, clientId })
  }
  return entries
}

function readText(record: Record<string, unknown>, ...keys: string[]): string | undefined {
  const stringValue = readString(record, ...keys)
  if (stringValue) return stringValue
  const numberValue = readNumber(record, ...keys)
  if (typeof numberValue === "number") return String(numberValue)
  return undefined
}

export function isRustDeskAccess(entry: DeviceRemoteAccessEntry | null | undefined) {
  if (!entry) return false
  const provider = (entry.provider ?? entry.metadata?.provider ?? "").toString().toLowerCase()
  if (provider.includes("rustdesk")) return true
  const url = (entry.url ?? entry.metadata?.url ?? "").toString().toLowerCase()
  return url.includes("rustdesk")
}

// Configuracao do servidor RustDesk self-hosted
const RUSTDESK_SERVER = "rust.rever.com.br"
const RUSTDESK_SERVER_KEY = "0mxocQKmK6GvTZQYKgjrG9tlNkKOqf81gKgqwAmnZuI="

export function buildRustDeskUri(entry: DeviceRemoteAccessEntry) {
  const identifier = (entry.identifier ?? "").replace(/\s+/g, "")
  if (!identifier) return null
  const params = new URLSearchParams()
  // key = chave publica do servidor RustDesk (para identificar o servidor)
  params.set("key", RUSTDESK_SERVER_KEY)
  if (entry.password) {
    // password = senha permanente do dispositivo
    params.set("password", entry.password)
  }
  const query = params.toString()
  // Formato: rustdesk://ID@SERVER?key=SERVER_KEY&password=DEVICE_PASSWORD
  return `rustdesk://${encodeURIComponent(identifier)}@${RUSTDESK_SERVER}${query ? `?${query}` : ""}`
}

function parseWindowsInstallDate(value: unknown): Date | null {
  if (!value) return null
  if (value instanceof Date) return value
  if (typeof value === "number" && Number.isFinite(value)) {
    if (value > 10_000_000_000) {
      return new Date(value)
    }
    if (value > 1_000_000_000) {
      return new Date(value * 1000)
    }
    return new Date(value * 1000)
  }
  if (typeof value !== "string") return null
  const trimmed = value.trim()
  if (!trimmed) return null

  const wmiMatch = trimmed.match(/Date\((\d+)\)/)
  if (wmiMatch) {
    const timestamp = Number(wmiMatch[1])
    return Number.isFinite(timestamp) ? new Date(timestamp) : null
  }

  const isoValue = Date.parse(trimmed)
  if (!Number.isNaN(isoValue)) return new Date(isoValue)

  const digitsOnly = trimmed.replace(/[^0-9]/g, "")
  if (digitsOnly.length >= 8) {
    const yyyy = Number(digitsOnly.slice(0, 4))
    const mm = Number(digitsOnly.slice(4, 6))
    const dd = Number(digitsOnly.slice(6, 8))
    const hh = Number(digitsOnly.slice(8, 10) || "0")
    const mi = Number(digitsOnly.slice(10, 12) || "0")
    const ss = Number(digitsOnly.slice(12, 14) || "0")
    if (yyyy > 1900 && mm >= 1 && mm <= 12 && dd >= 1 && dd <= 31) {
      const parsed = new Date(Date.UTC(yyyy, mm - 1, dd, hh, mi, ss))
      if (!Number.isNaN(parsed.getTime())) return parsed
    }
    const dd2 = Number(digitsOnly.slice(0, 2))
    const mm2 = Number(digitsOnly.slice(2, 4))
    const yyyy2 = Number(digitsOnly.slice(4, 8))
    if (yyyy2 > 1900 && mm2 >= 1 && mm2 <= 12 && dd2 >= 1 && dd2 <= 31) {
      const parsed = new Date(Date.UTC(yyyy2, mm2 - 1, dd2))
      if (!Number.isNaN(parsed.getTime())) return parsed
    }
  }

  const localMatch = trimmed.match(
    /^(\d{1,2})[\/\-](\d{1,2})[\/\-](\d{4})(?:\s+(\d{1,2}):(\d{2})(?::(\d{2}))?)?$/
  )
  if (localMatch) {
    const dd = Number(localMatch[1])
    const mm = Number(localMatch[2])
    const yyyy = Number(localMatch[3])
    const hh = Number(localMatch[4] || "0")
    const mi = Number(localMatch[5] || "0")
    const ss = Number(localMatch[6] || "0")
    if (yyyy > 1900 && mm >= 1 && mm <= 12 && dd >= 1 && dd <= 31) {
      const parsed = new Date(Date.UTC(yyyy, mm - 1, dd, hh, mi, ss))
      if (!Number.isNaN(parsed.getTime())) return parsed
    }
  }
  return null
}

type WindowsOsInfo = {
  productName?: string
  caption?: string
  editionId?: string
  displayVersion?: string
  releaseId?: string
  version?: string
  currentBuild?: string
  currentBuildNumber?: string
  licenseStatus?: number
  isActivated?: boolean
  licenseStatusText?: string
  productId?: string
  partialProductKey?: string
  computerName?: string
  registeredOwner?: string
  installDate?: Date | null
  experience?: string
}

function formatOsVersionDisplay(osName: string | null | undefined, osVersion: string | null | undefined) {
  const name = (osName ?? "").trim()
  const version = (osVersion ?? "").trim()
  if (!version) return ""
  // If Windows and version redundantly starts with the same major (e.g., "11 (26100)"), drop leading major
  const winMatch = name.match(/^windows\s+(\d+)\b/i)
  if (winMatch) {
    const major = winMatch[1]
    const re = new RegExp(`^\\s*${major}(?:\\b|\\.|-_|\\s)+(.*)$`, "i")
    const m = version.match(re)
    if (m) {
      const rest = (m[1] ?? "").trim()
      return rest
    }
  }
  return version
}

function parseWindowsOsInfo(raw: unknown): WindowsOsInfo | null {
  if (!raw) return null
  const parseRecord = (value: Record<string, unknown>) => {
    const read = (k: string, ...alts: string[]) => readString(value, k, ...alts)
    const readNum = (...keys: string[]) => readNumber(value, ...keys)
    const readFlexible = (...keys: string[]) => readText(value, ...keys)

    const family = read("Family")
    const edition = read("Edition")
    const captionRaw = readFlexible("Caption", "caption")
    const captionNormalized = captionRaw ? captionRaw.replace(/^Microsoft\s+/i, "").trim() : undefined

    let productName =
      readFlexible("ProductName", "productName", "Name", "name") ??
      (family && edition ? `${family} ${edition}` : family ?? edition ?? undefined)
    if (captionNormalized && /windows/i.test(captionNormalized)) {
      productName = captionNormalized
    }

    const editionId =
      readFlexible("EditionID", "editionId", "Edition", "edition", "SkuEdition", "skuEdition", "CompositionEditionID", "compositionEditionId") ??
      undefined

    const displayVersion = readFlexible("DisplayVersion", "displayVersion")
    const versionValue =
      readFlexible("Version", "version", "ReleaseId", "releaseId") ?? displayVersion

    const baseBuild =
      readFlexible("CurrentBuildNumber", "currentBuildNumber", "CurrentBuild", "currentBuild", "OSBuild", "osBuild", "BuildNumber", "buildNumber") ??
      undefined
    const ubrRaw = readFlexible("UBR")
    const licenseStatus = readNum("LicenseStatus", "licenseStatus")
    const licenseStatusTextRaw = readFlexible(
      "LicenseStatusDescription",
      "licenseStatusDescription",
      "StatusDescription",
      "statusDescription",
      "Status",
      "status"
    )
    const licenseStatusText = licenseStatusTextRaw ? licenseStatusTextRaw.trim() : undefined
    const currentBuildNumber =
      baseBuild && ubrRaw && /^\d+$/.test(ubrRaw) ? `${baseBuild}.${ubrRaw}` : baseBuild ?? readFlexible("BuildNumber", "buildNumber")
    const currentBuild = baseBuild

    const isActivatedRaw = value["IsActivated"] ?? value["isActivated"]
    const isLicensedRaw = value["IsLicensed"] ?? value["isLicensed"]
    const isActivated =
      typeof isActivatedRaw === "boolean"
        ? isActivatedRaw
        : typeof isActivatedRaw === "number"
          ? isActivatedRaw === 1
        : typeof isActivatedRaw === "string"
          ? isActivatedRaw.toLowerCase() === "true"
          : typeof isLicensedRaw === "boolean"
            ? isLicensedRaw
            : typeof isLicensedRaw === "number"
              ? isLicensedRaw === 1
              : typeof isLicensedRaw === "string"
                ? ["1", "true", "licensed", "license", "activated"].includes(isLicensedRaw.toLowerCase())
                : licenseStatus === 1 || Boolean(licenseStatusText && /licensed|activated|licenciado/i.test(licenseStatusText))

    const installDate =
      parseWindowsInstallDate(value["InstallDate"]) ??
      parseWindowsInstallDate(value["InstallationDate"]) ??
      parseWindowsInstallDate(value["InstallDateTime"]) ??
      parseWindowsInstallDate(value["InstalledOn"])

    const experience = (() => {
      const exp = readFlexible("Experience", "experience")
      if (exp) return exp
      const pack = readFlexible("FeatureExperiencePack", "featureExperiencePack")
      if (pack) {
        const trimmed = pack.trim()
        if (trimmed) return `Pacote de experiência ${trimmed}`
      }
      return currentBuildNumber ? `OS Build ${currentBuildNumber}` : undefined
    })()

    const productId = readFlexible("ProductID", "productID", "ProductId", "productId", "ProductKeyId", "productKeyId")
    const partialProductKey = readFlexible("PartialProductKey", "partialProductKey")
    const computerName = readFlexible("DeviceName", "deviceName", "ComputerName", "computerName", "CSName", "csName", "HostName", "hostName")
    const registeredOwner = readFlexible("RegisteredOwner", "registeredOwner", "RegisteredOrganization", "registeredOrganization")

    return {
      productName,
      editionId,
      displayVersion,
      version: versionValue,
      releaseId: read("ReleaseId", "releaseId"),
      currentBuild,
      currentBuildNumber,
      licenseStatus,
      isActivated,
      licenseStatusText,
      productId,
      partialProductKey,
      computerName,
      registeredOwner,
      installDate,
      experience,
      caption: captionNormalized ?? captionRaw ?? undefined,
    }
  }

  if (Array.isArray(raw)) {
    for (const entry of raw) {
      const record = toRecord(entry)
      if (record) {
        return parseRecord(record)
      }
    }
    return null
  }
  if (typeof raw === "string") {
    return { productName: raw }
  }
  const record = toRecord(raw)
  if (!record) return null
  return parseRecord(record)
}

function normalizeWindowsSoftwareEntry(value: unknown): NormalizedSoftwareEntry | null {
  const record = toRecord(value)
  if (!record) return null

  const name =
    readString(record, "DisplayName", "displayName", "Name", "name") ??
    readText(record, "Title", "title") ??
    ""
  if (!name) return null

  const version = readString(record, "DisplayVersion", "displayVersion", "Version", "version") ?? undefined
  const publisher = readString(record, "Publisher", "publisher", "Vendor", "vendor") ?? undefined
  const installDate =
    parseWindowsInstallDate(record["InstallDate"]) ??
    parseWindowsInstallDate(record["InstallDateUTC"]) ??
    parseWindowsInstallDate(record["InstallDateTime"]) ??
    parseWindowsInstallDate(record["InstallDateFromRegistry"]) ??
    parseWindowsInstallDate(record["InstallDateFromRegistryUTC"]) ??
    parseWindowsInstallDate(record["InstalledDate"]) ??
    parseWindowsInstallDate(record["InstalledOn"]) ??
    null

  const source = readString(record, "ParentDisplayName", "ParentKeyName", "SystemComponent") ?? undefined

  return {
    name,
    version,
    publisher,
    installDate,
    source,
  }
}

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 DevicesQueryItem = {
  id: string
  tenantId: string
  hostname: string
  displayName: string | null
  deviceType: string | null
  devicePlatform: string | null
  managementMode: string | null
  companyId: string | null
  companySlug: string | null
  companyName: 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
  isActive: boolean
  lastHeartbeatAt: number | null
  heartbeatAgeMs: number | null
  registeredBy: string | null
  createdAt: number
  updatedAt: number
  token: {
    expiresAt: number
    lastUsedAt: number | null
    usageCount: number
  } | null
  metrics: DeviceMetrics
  inventory: DeviceInventory | null
  postureAlerts?: Array<Record<string, unknown>> | null
  lastPostureAt?: number | null
  linkedUsers?: Array<{ id: string; email: string; name: string }>
  remoteAccessEntries: DeviceRemoteAccessEntry[]
  customFields?: Array<{ fieldId?: string; fieldKey: string; label: string; type?: string; value: unknown; displayValue?: string }>
  usbPolicy?: "ALLOW_ALL" | "BLOCK_ALL" | "WHITELIST" | null
  usbPolicyStatus?: "IDLE" | "PENDING" | "APPLYING" | "APPLIED" | "FAILED" | null
}

export function normalizeDeviceItem(raw: Record<string, unknown>): DevicesQueryItem {
  const { remoteAccess, ...rest } = raw as Record<string, unknown> & { remoteAccess?: unknown }
  return {
    ...(rest as DevicesQueryItem),
    remoteAccessEntries: normalizeDeviceRemoteAccessList(remoteAccess),
  }
}

function useDevicesQuery(tenantId: string): { devices: DevicesQueryItem[]; isLoading: boolean } {
  const result = useQuery(api.devices.listByTenant, {
    tenantId,
    includeMetadata: true,
  }) as Array<Record<string, unknown>> | undefined
  const devices = useMemo(() => (result ?? []).map((item) => normalizeDeviceItem(item)), [result])
  return {
    devices,
    isLoading: result === undefined,
  }
}

const DEVICE_TYPE_LABELS: Record<string, string> = {
  desktop: "Desktop",
  mobile: "Celular",
  tablet: "Tablet",
}

const DEVICE_TYPE_FILTER_OPTIONS = [
  { value: "all", label: "Todos os tipos" },
  { value: "desktop", label: DEVICE_TYPE_LABELS.desktop },
  { value: "mobile", label: DEVICE_TYPE_LABELS.mobile },
  { value: "tablet", label: DEVICE_TYPE_LABELS.tablet },
]

function formatDeviceTypeLabel(value?: string | null): string {
  if (!value) return "Desconhecido"
  const normalized = value.toLowerCase()
  return DEVICE_TYPE_LABELS[normalized] ?? value.charAt(0).toUpperCase() + value.slice(1)
}

const TICKET_PRIORITY_META: Record<string, { label: string; badgeClass: string }> = {
  LOW: { label: "Baixa", badgeClass: "border border-slate-200 bg-slate-100 text-slate-600" },
  MEDIUM: { label: "Média", badgeClass: "border border-sky-200 bg-sky-100 text-sky-700" },
  HIGH: { label: "Alta", badgeClass: "border border-amber-200 bg-amber-50 text-amber-700" },
  URGENT: { label: "Urgente", badgeClass: "border border-rose-200 bg-rose-50 text-rose-700" },
}

function getTicketPriorityMeta(priority: TicketPriority | string | null | undefined) {
  if (!priority) {
    return { label: "Sem prioridade", badgeClass: "border border-slate-200 bg-slate-100 text-neutral-600" }
  }
  const normalized = priority.toUpperCase()

  return (
    TICKET_PRIORITY_META[normalized] ?? {
      label: priority.charAt(0).toUpperCase() + priority.slice(1).toLowerCase(),
      badgeClass: "border border-slate-200 bg-slate-100 text-neutral-600",
    }
  )
}

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

const REMOTE_ACCESS_PROVIDERS = [
  { value: "TEAMVIEWER", label: "TeamViewer" },
  { value: "ANYDESK", label: "AnyDesk" },
  { value: "SUPREMO", label: "Supremo" },
  { value: "RUSTDESK", label: "RustDesk" },
  { value: "QUICKSUPPORT", label: "TeamViewer QS" },
  { value: "CHROME_REMOTE_DESKTOP", label: "Chrome Remote Desktop" },
  { value: "DW_SERVICE", label: "DWService" },
  { value: "OTHER", label: "Outro" },
] as const

type RemoteAccessProviderValue = (typeof REMOTE_ACCESS_PROVIDERS)[number]["value"]

const POSTURE_ALERT_LABELS: Record<string, string> = {
  CPU_HIGH: "CPU alta",
  SERVICE_DOWN: "Serviço indisponível",
  SMART_FAIL: "Falha SMART",
}

function formatPostureAlertKind(raw?: string | null): string {
  if (!raw) return "Alerta"
  const normalized = raw.toUpperCase()
  if (POSTURE_ALERT_LABELS[normalized]) {
    return POSTURE_ALERT_LABELS[normalized]
  }
  return raw
    .toLowerCase()
    .replace(/_/g, " ")
    .replace(/\b\w/g, (char) => char.toUpperCase())
}

function postureSeverityClass(severity?: string | null) {
  return (severity ?? "warning").toLowerCase() === "critical"
    ? "border-rose-500/20 bg-rose-500/10"
    : "border-amber-500/20 bg-amber-500/10"
}

function formatRelativeTime(date?: Date | null) {
  if (!date) return "Nunca"
  try {
    const clamped = new Date(Math.min(date.getTime(), Date.now()))
    return formatDistanceToNowStrict(clamped, { addSuffix: true, locale: ptBR })
  } catch {
    return "—"
  }
}

function formatInstallDate(date?: Date | null) {
  if (!date) return null
  return `${formatAbsoluteDateTime(date)} (${formatRelativeTime(date)})`
}

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

function formatAbsoluteDateTime(date?: Date | null) {
  if (!date) return "—"
  return new Intl.DateTimeFormat("pt-BR", {
    dateStyle: "long",
    timeStyle: "short",
  }).format(date)
}

function parseDateish(value: unknown): Date | null {
  if (!value) return null
  if (value instanceof Date && !Number.isNaN(value.getTime())) return value
  if (typeof value === "number" && Number.isFinite(value)) {
    const numeric = value > 1e12 ? value : value > 1e9 ? value * 1000 : value
    const date = new Date(numeric)
    return Number.isNaN(date.getTime()) ? null : date
  }
  if (typeof value === "string") {
    const trimmed = value.trim()
    if (!trimmed) return null
    const numericValue = Number(trimmed)
    if (Number.isFinite(numericValue)) {
      const asMs = trimmed.length >= 13 ? numericValue : numericValue * 1000
      const date = new Date(asMs)
      if (!Number.isNaN(date.getTime())) return date
    }
    const date = new Date(trimmed)
    if (!Number.isNaN(date.getTime())) return date
  }
  return null
}

function getMetricsTimestamp(metrics: DeviceMetrics): Date | null {
  if (!metrics || typeof metrics !== "object") return null
  const data = metrics as Record<string, unknown>
  const candidates = [
    data["collectedAt"],
    data["collected_at"],
    data["collected_at_iso"],
    data["collected_at_ms"],
    data["timestamp"],
    data["updatedAt"],
    data["updated_at"],
    data["createdAt"],
    data["created_at"],
  ]
  for (const candidate of candidates) {
    const parsed = parseDateish(candidate)
    if (parsed) return parsed
  }
  return null
}

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)}%`
}

const BADGE_POSITIVE = "gap-1 border-emerald-500/20 bg-emerald-500/15 text-emerald-700"
const BADGE_WARNING = "gap-1 border-amber-500/20 bg-amber-100 text-amber-700"
const BADGE_NEUTRAL = "gap-1 border-slate-300 bg-slate-100 text-slate-600"

function parseBooleanLike(value: unknown): boolean | undefined {
  if (typeof value === "boolean") return value
  if (typeof value === "number") {
    if (value === 1) return true
    if (value === 0) return false
  }
  if (typeof value === "string") {
    const normalized = value.trim().toLowerCase()
    if (["yes", "sim", "true", "enabled", "on", "ativo", "active", "y", "1"].includes(normalized)) return true
    if (["no", "não", "nao", "false", "disabled", "off", "inativo", "not joined", "n", "0"].includes(normalized)) return false
  }
  return undefined
}

function toNumberArray(value: unknown): number[] {
  if (!value) return []
  if (Array.isArray(value)) {
    return value
      .map((item) => {
        if (typeof item === "number") return item
        if (typeof item === "string") {
          const parsed = Number(item)
          return Number.isNaN(parsed) ? null : parsed
        }
        return null
      })
      .filter((item): item is number => item !== null)
  }
  if (typeof value === "number") return [value]
  if (typeof value === "string" && value.trim().length > 0) {
    return value
      .replace(/[^\d,]/g, " ")
      .split(/[,\s]+/)
      .map((part) => Number(part))
      .filter((num) => !Number.isNaN(num))
  }
  return []
}

function describeDomainRole(role?: number | null): string | null {
  if (role === null || role === undefined) return null
  const map: Record<number, string> = {
    0: "Estação isolada",
    1: "Estação em domínio",
    2: "Servidor isolado",
    3: "Servidor em domínio",
    4: "Controlador de domínio (backup)",
    5: "Controlador de domínio (primário)",
  }
  return map[role] ?? `Função ${role}`
}

function describePcSystemType(code?: number | null): string | null {
  if (code === null || code === undefined) return null
  const map: Record<number, string> = {
    0: "Não especificado",
    1: "Desktop",
    2: "Portátil / Laptop",
    3: "Workstation",
    4: "Servidor corporativo",
    5: "Servidor SOHO",
    8: "Tablet / Slate",
    9: "Conversível",
    10: "Sistema baseado em detecção",
  }
  return map[code] ?? `Tipo ${code}`
}

function describeDeviceGuardService(code: number): string {
  const map: Record<number, string> = {
    1: "Credential Guard",
    2: "HVCI (Kernel Integrity)",
    3: "Secure Boot com DMA",
    4: "Hypervisor com Device Guard",
    5: "Aplicação protegida",
  }
  return map[code] ?? `Serviço ${code}`
}

function describeVbsStatus(code?: number | null): string | null {
  switch (code) {
    case 0:
      return "VBS desabilitado"
    case 1:
      return "VBS habilitado (inativo)"
    case 2:
      return "VBS ativo (sem serviços)"
    case 3:
      return "VBS ativo com proteções"
    default:
      return code != null ? `VBS status ${code}` : null
  }
}

function describeAuOption(value?: number | null): string | null {
  switch (value ?? -1) {
    case 1:
      return "Não configurado"
    case 2:
      return "Notificar antes de baixar"
    case 3:
      return "Baixar automático e notificar"
    case 4:
      return "Baixar e instalar automaticamente"
    case 5:
      return "Administrador local define"
    default:
      return value != null ? `Opção ${value}` : null
  }
}

function describeScheduledDay(value?: number | null): string | null {
  if (value === null || value === undefined) return null
  if (value === 0) return "Todos os dias"
  const map = ["Domingo", "Segunda", "Terça", "Quarta", "Quinta", "Sexta", "Sábado"]
  return map[value - 1] ?? `Dia ${value}`
}

function getStatusVariant(status?: string | null) {
  if (!status) return { label: DEVICE_STATUS_LABELS.unknown, className: statusClasses.unknown }
  const normalized = status.toLowerCase()
  return {
    label: DEVICE_STATUS_LABELS[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-neutral-500" />
  if (name.includes("linux")) return <Terminal className="size-4 text-neutral-500" />
  // fallback para Windows/outros como monitor genérico
  return <Monitor className="size-4 text-neutral-500" />
}

export function AdminDevicesOverview({
  tenantId,
  initialCompanyFilterSlug = "all",
  autoOpenCreateDevice = false,
}: {
  tenantId: string
  initialCompanyFilterSlug?: string
  autoOpenCreateDevice?: boolean
}) {
  const { devices, isLoading } = useDevicesQuery(tenantId)
  const [q, setQ] = useState("")
  const [statusFilter, setStatusFilter] = useState<string>("all")
  const [deviceTypeFilter, setDeviceTypeFilter] = useState<string>("all")
  const [companyFilterSlug, setCompanyFilterSlug] = useState<string>(initialCompanyFilterSlug)
  const [companySearch, setCompanySearch] = useState<string>("")
  const [isCompanyPopoverOpen, setIsCompanyPopoverOpen] = useState(false)
  const [onlyAlerts, setOnlyAlerts] = useState<boolean>(false)
  const [isExportDialogOpen, setIsExportDialogOpen] = useState(false)
  const [exportSelection, setExportSelection] = useState<string[]>([])
  const [isExporting, setIsExporting] = useState(false)
  const [exportProgress, setExportProgress] = useState(0)
  const [exportError, setExportError] = useState<string | null>(null)
  const [columnConfig, setColumnConfig] = useState<DeviceInventoryColumnConfig[]>(DEFAULT_DEVICE_COLUMN_CONFIG)
  const [selectedTemplateId, setSelectedTemplateId] = useState<string | null>(null)
  const [hasManualColumns, setHasManualColumns] = useState(false)
  const [isTemplateDialogOpen, setIsTemplateDialogOpen] = useState(false)
  const [templateName, setTemplateName] = useState("")
  const [templateForCompany, setTemplateForCompany] = useState(false)
  const [templateAsDefault, setTemplateAsDefault] = useState(false)
  const [isSavingTemplate, setIsSavingTemplate] = useState(false)
  const [isUsbPolicyDialogOpen, setIsUsbPolicyDialogOpen] = useState(false)
  const [selectedUsbPolicy, setSelectedUsbPolicy] = useState<"ALLOW" | "BLOCK_ALL" | "READONLY">("ALLOW")
  const [isApplyingUsbPolicy, setIsApplyingUsbPolicy] = useState(false)
  const [usbPolicySelection, setUsbPolicySelection] = useState<string[]>([])
  const [usbCompanyFilter, setUsbCompanyFilter] = useState<string>("all")
  const [isCreateDeviceOpen, setIsCreateDeviceOpen] = useState(false)
  const [createDeviceLoading, setCreateDeviceLoading] = useState(false)
  const [newDeviceName, setNewDeviceName] = useState("")
  const [newDeviceIdentifier, setNewDeviceIdentifier] = useState("")
  const [newDeviceType, setNewDeviceType] = useState("mobile")
  const [newDevicePlatform, setNewDevicePlatform] = useState("")
  const [newDeviceCompanySlug, setNewDeviceCompanySlug] = useState<string | null>(
    initialCompanyFilterSlug !== "all" ? initialCompanyFilterSlug : null
  )
  const [newDeviceSerials, setNewDeviceSerials] = useState("")
  const [newDeviceNotes, setNewDeviceNotes] = useState("")
  const [newDeviceActive, setNewDeviceActive] = useState(true)
  const { convexUserId } = useAuth()
  const companies = useQuery(
    api.companies.list,
    convexUserId ? { tenantId, viewerId: convexUserId as Id<"users"> } : "skip"
  ) as Array<{ id: string; name: string; slug?: string }> | undefined
  const companyNameBySlug = useMemo(() => {
    const map = new Map<string, string>()
    devices.forEach((m) => {
      if (m.companySlug && m.companyName) {
        map.set(m.companySlug, m.companyName)
      }
    })
    ;(companies ?? []).forEach((c) => {
      if (c.slug) {
        map.set(c.slug, c.name)
      }
    })
    return map
  }, [devices, companies])

  const selectedCompany = useMemo(() => {
    if (companyFilterSlug === "all") return null
    return (companies ?? []).find((company) => (company.slug ?? company.id) === companyFilterSlug) ?? null
  }, [companies, companyFilterSlug])

  const companyOptions = useMemo(() => {
    if (companies && companies.length > 0) {
      return companies
        .map((c) => ({ slug: c.slug ?? c.id, name: c.name }))
        .sort((a, b) => a.name.localeCompare(b.name, "pt-BR"))
    }
    const fallback = new Map<string, string>()
    devices.forEach((m) => {
      if (m.companySlug) {
        fallback.set(m.companySlug, m.companyName ?? m.companySlug)
      }
    })
    return Array.from(fallback.entries())
      .map(([slug, name]) => ({ slug, name }))
      .sort((a, b) => a.name.localeCompare(b.name, "pt-BR"))
  }, [companies, devices])

  const companyComboboxOptions = useMemo<SearchableComboboxOption[]>(() => {
    return companyOptions.map((company) => ({
      value: company.slug,
      label: company.name,
    }))
  }, [companyOptions])

  const deviceFields = useQuery(
    api.deviceFields.listForTenant,
    convexUserId ? { tenantId, viewerId: convexUserId as Id<"users"> } : "skip"
  ) as Array<{ id: string; key: string; label: string }> | undefined

  const exportTemplates = useQuery(
    api.deviceExportTemplates.listForTenant,
    convexUserId ? { tenantId, viewerId: convexUserId as Id<"users"> } : "skip"
  ) as DeviceExportTemplate[] | undefined

  const customFieldOptions = useMemo(() => {
    const map = new Map<string, { key: string; label: string }>()
    ;(deviceFields ?? []).forEach((field) => {
      map.set(field.key, { key: field.key, label: field.label })
    })
    devices.forEach((device) => {
      ;(device.customFields ?? []).forEach((field) => {
        if (!map.has(field.fieldKey)) {
          map.set(field.fieldKey, { key: field.fieldKey, label: field.label })
        }
      })
    })
    return Array.from(map.values()).sort((a, b) => a.label.localeCompare(b.label, "pt-BR"))
  }, [deviceFields, devices])

  const customColumnOrder = useMemo(() => customFieldOptions.map((field) => `custom:${field.key}`), [customFieldOptions])

  useEffect(() => {
    setColumnConfig((prev) => orderColumnConfig(prev, customColumnOrder))
  }, [customColumnOrder])

  const customColumnOptions = useMemo(
    () => customFieldOptions.map((field) => ({ key: `custom:${field.key}`, label: field.label })),
    [customFieldOptions]
  )

  const baseColumnOptions = useMemo(
    () => DEVICE_INVENTORY_COLUMN_METADATA.map((meta) => ({ key: meta.key, label: meta.label })),
    []
  )

  useEffect(() => {
    if (!exportTemplates || exportTemplates.length === 0) return
    if (hasManualColumns || selectedTemplateId) return
    const companyTemplate = selectedCompany
      ? exportTemplates.find((tpl) => tpl.companyId === selectedCompany.id && tpl.isDefault)
      : null
    const fallbackTemplate = exportTemplates.find((tpl) => tpl.isDefault && !tpl.companyId)
    const templateToApply = companyTemplate ?? fallbackTemplate
    if (!templateToApply) return
    const normalized = orderColumnConfig(
      (templateToApply.columns ?? []).map((col) => ({ key: col.key, label: col.label ?? undefined })),
      customColumnOrder
    )
    if (normalized.length === 0 || areColumnConfigsEqual(normalized, columnConfig)) return
    setColumnConfig(normalized)
    setSelectedTemplateId(templateToApply.id)
    setHasManualColumns(false)
  }, [exportTemplates, selectedCompany, customColumnOrder, hasManualColumns, selectedTemplateId, columnConfig])

  const createTemplate = useMutation(api.deviceExportTemplates.create)
  const saveDeviceProfileMutation = useMutation(api.devices.saveDeviceProfile)
  const bulkSetUsbPolicyMutation = useMutation(api.usbPolicy.bulkSetUsbPolicy)

  useEffect(() => {
    if (!selectedCompany && templateForCompany) {
      setTemplateForCompany(false)
    }
  }, [selectedCompany, templateForCompany])

  const templateOptions = useMemo(() => {
    return (exportTemplates ?? []).slice().sort((a, b) => a.name.localeCompare(b.name, "pt-BR"))
  }, [exportTemplates])

  const selectedTemplate = useMemo(
    () => templateOptions.find((tpl) => tpl.id === selectedTemplateId) ?? null,
    [templateOptions, selectedTemplateId]
  )

  const handleTemplateSelection = useCallback(
    (value: string) => {
      if (value === "custom") {
        setSelectedTemplateId(null)
        setHasManualColumns(true)
        return
      }
      const template = templateOptions.find((tpl) => tpl.id === value)
      if (!template) {
        toast.error("Template não encontrado.")
        return
      }
      const normalized = orderColumnConfig(
        (template.columns ?? []).map((col) => ({ key: col.key, label: col.label ?? undefined })),
        customColumnOrder
      )
      if (normalized.length === 0) {
        toast.error("Template sem colunas válidas.")
        return
      }
      setColumnConfig(normalized)
      setSelectedTemplateId(template.id)
      setHasManualColumns(false)
    },
    [templateOptions, customColumnOrder]
  )

  const handleToggleColumn = useCallback(
    (key: string, checked: boolean, label?: string) => {
      setColumnConfig((prev) => {
        const filtered = prev.filter((col) => col.key !== key)
        if (checked) {
          return orderColumnConfig([...filtered, { key, label }], customColumnOrder)
        }
        return filtered
      })
      setSelectedTemplateId(null)
      setHasManualColumns(true)
    },
    [customColumnOrder]
  )

  const handleResetColumns = useCallback(() => {
    setColumnConfig(orderColumnConfig([...DEFAULT_DEVICE_COLUMN_CONFIG], customColumnOrder))
    setSelectedTemplateId(null)
    setHasManualColumns(false)
  }, [customColumnOrder])

  const handleSelectAllColumns = useCallback(() => {
    const allColumns: DeviceInventoryColumnConfig[] = [
      ...baseColumnOptions.map((col) => ({ key: col.key })),
      ...customColumnOptions.map((col) => ({ key: col.key, label: col.label })),
    ]
    setColumnConfig(orderColumnConfig(allColumns, customColumnOrder))
    setSelectedTemplateId(null)
    setHasManualColumns(true)
  }, [baseColumnOptions, customColumnOptions, customColumnOrder])

  const handleOpenTemplateDialog = useCallback(() => {
    setTemplateName("")
    setTemplateForCompany(Boolean(selectedCompany))
    setTemplateAsDefault(false)
    setIsTemplateDialogOpen(true)
  }, [selectedCompany])

  const handleSaveTemplate = useCallback(async () => {
    if (!convexUserId) {
      toast.error("Sincronize a sessão para salvar templates.")
      return
    }
    const normalized = orderColumnConfig(columnConfig, customColumnOrder)
    if (normalized.length === 0) {
      toast.error("Selecione ao menos uma coluna para salvar o template.")
      return
    }
    const name = templateName.trim()
    if (name.length < 3) {
      toast.error("Informe um nome para o template (mínimo 3 caracteres).")
      return
    }
    try {
      setIsSavingTemplate(true)
      const response = await createTemplate({
        tenantId,
        actorId: convexUserId as Id<"users">,
        name,
        columns: normalized,
        companyId: templateForCompany && selectedCompany ? (selectedCompany.id as Id<"companies">) : undefined,
        isDefault: templateAsDefault,
        isActive: true,
      })
      setIsTemplateDialogOpen(false)
      setTemplateName("")
      setTemplateForCompany(false)
      setTemplateAsDefault(false)
      const newTemplateId = typeof response === "string" ? response : response ? String(response) : null
      if (newTemplateId) {
        setSelectedTemplateId(newTemplateId)
        setHasManualColumns(false)
      }
      toast.success("Template salvo com sucesso.")
    } catch (error) {
      console.error("Failed to save template", error)
      toast.error("Não foi possível salvar o template.")
    } finally {
      setIsSavingTemplate(false)
    }
  }, [columnConfig, createTemplate, customColumnOrder, convexUserId, selectedCompany, templateAsDefault, templateForCompany, templateName, tenantId])

  const handleOpenCreateDevice = useCallback(() => {
    const initialCompany = selectedCompany
      ? selectedCompany.slug ?? selectedCompany.id
      : companyFilterSlug !== "all"
        ? companyFilterSlug
        : null
    setNewDeviceName("")
    setNewDeviceIdentifier("")
    setNewDeviceType("mobile")
    setNewDevicePlatform("")
    setNewDeviceSerials("")
    setNewDeviceNotes("")
    setNewDeviceActive(true)
    setNewDeviceCompanySlug(initialCompany)
    setIsCreateDeviceOpen(true)
  }, [selectedCompany, companyFilterSlug])

  useEffect(() => {
    if (autoOpenCreateDevice) {
      handleOpenCreateDevice()
    }
  }, [autoOpenCreateDevice, handleOpenCreateDevice])

  useEffect(() => {
    if (typeof window === "undefined") return
    const handler = () => {
      handleOpenCreateDevice()
    }
    window.addEventListener("quick-open-device", handler)
    return () => window.removeEventListener("quick-open-device", handler)
  }, [handleOpenCreateDevice])

  const handleCreateDevice = useCallback(async () => {
    if (!convexUserId) {
      toast.error("Sincronize a sessão antes de criar dispositivos.")
      return
    }
    const name = newDeviceName.trim()
    if (name.length < 3) {
      toast.error("Informe um nome com ao menos 3 caracteres.")
      return
    }
    const identifier = (newDeviceIdentifier.trim() || name).trim()
    const platform = newDevicePlatform.trim()
    const serials = newDeviceSerials
      .split(/\r?\n|,|;/)
      .map((value) => value.trim())
      .filter(Boolean)
    const targetCompany = newDeviceCompanySlug
      ? (companies ?? []).find((company) => (company.slug ?? company.id) === newDeviceCompanySlug) ?? null
      : null
    try {
      setCreateDeviceLoading(true)
      await saveDeviceProfileMutation({
        tenantId,
        actorId: convexUserId as Id<"users">,
        displayName: name,
        hostname: identifier,
        deviceType: newDeviceType,
        devicePlatform: platform || undefined,
        osName: platform || undefined,
        serialNumbers: serials.length > 0 ? serials : undefined,
        companyId: targetCompany ? (targetCompany.id as Id<"companies">) : undefined,
        companySlug: targetCompany?.slug ?? undefined,
        status: "unknown",
        isActive: newDeviceActive,
        profile: newDeviceNotes.trim() ? { notes: newDeviceNotes.trim() } : undefined,
      })
      toast.success("Dispositivo criado com sucesso.")
      setIsCreateDeviceOpen(false)
      setNewDeviceName("")
      setNewDeviceIdentifier("")
      setNewDevicePlatform("")
      setNewDeviceSerials("")
      setNewDeviceNotes("")
      setNewDeviceActive(true)
      if (targetCompany?.slug) {
        setCompanyFilterSlug(targetCompany.slug)
      }
    } catch (error) {
      console.error("Failed to create device", error)
      toast.error("Não foi possível criar o dispositivo.")
    } finally {
      setCreateDeviceLoading(false)
    }
  }, [companies, convexUserId, newDeviceActive, newDeviceCompanySlug, newDeviceIdentifier, newDeviceName, newDeviceNotes, newDevicePlatform, newDeviceSerials, newDeviceType, saveDeviceProfileMutation, tenantId])

  const filteredDevices = useMemo(() => {
    const text = q.trim().toLowerCase()
    return devices.filter((m) => {
      if (onlyAlerts && !(Array.isArray(m.postureAlerts) && m.postureAlerts.length > 0)) return false
      if (statusFilter !== "all") {
        const s = resolveDeviceStatus(m).toLowerCase()
        if (s !== statusFilter) return false
      }
      if (deviceTypeFilter !== "all") {
        const type = (m.deviceType ?? "desktop").toLowerCase()
        if (type !== deviceTypeFilter) return false
      }
      if (companyFilterSlug !== "all" && (m.companySlug ?? "") !== companyFilterSlug) return false
      if (!text) return true
      const hay = [
        m.hostname,
        m.authEmail ?? "",
        (m.macAddresses ?? []).join(" "),
        (m.serialNumbers ?? []).join(" "),
      ]
        .join(" ")
        .toLowerCase()
      return hay.includes(text)
    })
  }, [devices, q, statusFilter, companyFilterSlug, onlyAlerts, deviceTypeFilter])
  const handleOpenExportDialog = useCallback(() => {
    if (filteredDevices.length === 0) {
      toast.info("Não há dispositivos para exportar com os filtros atuais.")
      return
    }
    setExportSelection(filteredDevices.map((m) => m.id))
    setExportProgress(0)
    setExportError(null)
    setIsExporting(false)
    setIsExportDialogOpen(true)
  }, [filteredDevices])

  const handleExportDialogOpenChange = useCallback((open: boolean) => {
    if (!open && isExporting) return
    setIsExportDialogOpen(open)
  }, [isExporting])

  useEffect(() => {
    if (!isExportDialogOpen) {
      setExportSelection([])
      setExportProgress(0)
      setExportError(null)
      setIsExporting(false)
    }
  }, [isExportDialogOpen])

  useEffect(() => {
    if (!isExportDialogOpen) return
    const allowed = new Set(filteredDevices.map((m) => m.id))
    setExportSelection((prev) => {
      const next = prev.filter((id) => allowed.has(id))
      return next.length === prev.length ? prev : next
    })
  }, [filteredDevices, isExportDialogOpen])

  const handleToggleDeviceSelection = useCallback((deviceId: string, checked: boolean) => {
    setExportSelection((prev) => {
      if (checked) {
        if (prev.includes(deviceId)) return prev
        return [...prev, deviceId]
      }
      return prev.filter((id) => id !== deviceId)
    })
  }, [])

  const handleSelectAllDevices = useCallback((checked: boolean) => {
    if (checked) {
      setExportSelection(filteredDevices.map((m) => m.id))
    } else {
      setExportSelection([])
    }
  }, [filteredDevices])

  const handleOpenUsbPolicyDialog = useCallback(() => {
    const windowsDevices = filteredDevices.filter(
      (m) => (m.devicePlatform ?? "").toLowerCase() === "windows"
    )
    if (windowsDevices.length === 0) {
      toast.info("Não há dispositivos Windows para aplicar política USB.")
      return
    }
    setUsbPolicySelection(windowsDevices.map((m) => m.id))
    setSelectedUsbPolicy("ALLOW")
    setIsApplyingUsbPolicy(false)
    setIsUsbPolicyDialogOpen(true)
  }, [filteredDevices])

  const handleUsbPolicyDialogOpenChange = useCallback((open: boolean) => {
    if (!open && isApplyingUsbPolicy) return
    setIsUsbPolicyDialogOpen(open)
  }, [isApplyingUsbPolicy])

  const handleToggleUsbDeviceSelection = useCallback((deviceId: string, checked: boolean) => {
    setUsbPolicySelection((prev) => {
      if (checked) {
        if (prev.includes(deviceId)) return prev
        return [...prev, deviceId]
      }
      return prev.filter((id) => id !== deviceId)
    })
  }, [])

  const handleSelectAllUsbDevices = useCallback((checked: boolean) => {
    const allWindowsDevices = filteredDevices.filter(
      (m) => (m.devicePlatform ?? "").toLowerCase() === "windows"
    )
    const windowsDevices = usbCompanyFilter === "all"
      ? allWindowsDevices
      : allWindowsDevices.filter((m) => (m.companySlug ?? "") === usbCompanyFilter)
    if (checked) {
      setUsbPolicySelection(windowsDevices.map((m) => m.id))
    } else {
      setUsbPolicySelection([])
    }
  }, [filteredDevices, usbCompanyFilter])

  const handleApplyBulkUsbPolicy = useCallback(async () => {
    if (usbPolicySelection.length === 0) {
      toast.info("Selecione ao menos um dispositivo.")
      return
    }

    setIsApplyingUsbPolicy(true)
    try {
      const result = await bulkSetUsbPolicyMutation({
        machineIds: usbPolicySelection.map((id) => id as Id<"machines">),
        policy: selectedUsbPolicy,
        actorId: convexUserId ? (convexUserId as Id<"users">) : undefined,
      })
      toast.success(`Política USB aplicada a ${result.successful} de ${result.total} dispositivos.`)
      setIsUsbPolicyDialogOpen(false)
    } catch (error) {
      console.error("[usb-policy] Falha ao aplicar política em massa", error)
      toast.error("Falha ao aplicar política USB. Tente novamente.")
    } finally {
      setIsApplyingUsbPolicy(false)
    }
  }, [usbPolicySelection, selectedUsbPolicy, convexUserId, bulkSetUsbPolicyMutation])

  const handleConfirmExport = useCallback(async () => {
    const orderedSelection = filteredDevices.map((m) => m.id).filter((id) => exportSelection.includes(id))
    if (orderedSelection.length === 0) {
      toast.info("Selecione ao menos um dispositivo para exportar.")
      return
    }
    const normalizedColumns = orderColumnConfig(columnConfig, customColumnOrder)
    if (normalizedColumns.length === 0) {
      toast.info("Selecione ao menos uma coluna para exportar.")
      return
    }

    setIsExporting(true)
    setExportError(null)
    setExportProgress(5)

    try {
      const params = new URLSearchParams()
      if (companyFilterSlug !== "all") {
        params.set("companyId", companyFilterSlug)
      }
      orderedSelection.forEach((id) => params.append("machineId", id))
      params.set("columns", JSON.stringify(normalizedColumns))
      if (selectedTemplateId) {
        params.set("templateId", selectedTemplateId)
      }
      const qs = params.toString()
      const url = `/api/reports/machines-inventory.xlsx${qs ? `?${qs}` : ""}`

      const response = await fetch(url)
      if (!response.ok) {
        throw new Error(`Export failed with status ${response.status}`)
      }

      const contentLengthHeader = response.headers.get("Content-Length")
      const totalBytes = contentLengthHeader ? parseInt(contentLengthHeader, 10) : Number.NaN
      const hasLength = Number.isFinite(totalBytes) && totalBytes > 0
      const disposition = response.headers.get("Content-Disposition")
      const filenameMatch = disposition?.match(/filename="?([^";]+)"?/i)
      const filename = filenameMatch?.[1] ?? `devices-inventory-${new Date().toISOString().slice(0, 10)}.xlsx`

      let blob: Blob
      if (!response.body || typeof response.body.getReader !== "function") {
        blob = await response.blob()
        setExportProgress(100)
      } else {
        const reader = response.body.getReader()
        const chunks: ArrayBuffer[] = []
        let received = 0

        while (true) {
          const { value, done } = await reader.read()
          if (done) break
          if (value) {
            chunks.push(value.buffer.slice(value.byteOffset, value.byteOffset + value.byteLength))
            received += value.length
            if (hasLength) {
              const percent = Math.min(99, Math.round((received / totalBytes) * 100))
              setExportProgress(percent)
            } else {
              setExportProgress((prev) => (prev >= 95 ? prev : prev + 5))
            }
          }
        }

        blob = new Blob(chunks, { type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" })
        setExportProgress(100)
      }

      const downloadUrl = window.URL.createObjectURL(blob)
      const link = document.createElement("a")
      link.href = downloadUrl
      link.download = filename
      document.body.appendChild(link)
      link.click()
      link.remove()
      window.URL.revokeObjectURL(downloadUrl)

      toast.success(`Exportação gerada para ${orderedSelection.length} dispositivo${orderedSelection.length === 1 ? "" : "s"}.`)
      setIsExporting(false)
      setIsExportDialogOpen(false)
    } catch (error) {
      console.error("Failed to export devices inventory", error)
      setIsExporting(false)
      setExportProgress(0)
      setExportError("Não foi possível gerar o arquivo. Tente novamente.")
    }
  }, [companyFilterSlug, exportSelection, filteredDevices, columnConfig, customColumnOrder, selectedTemplateId])

  const exportableCount = filteredDevices.length
  const selectedCount = exportSelection.length
  const selectAllState: boolean | "indeterminate" = exportableCount === 0
    ? false
    : selectedCount === exportableCount
      ? true
      : selectedCount > 0
        ? "indeterminate"
        : false



  return (
    <div className="grid gap-6">
      <Card className="border-slate-200">
        <CardHeader className="flex flex-col gap-3 md:flex-row md:items-start md:justify-between">
          <div>
            <CardTitle>Dispositivos registrados</CardTitle>
            <CardDescription>Sincronizadas via agente local instalado nas máquinas.</CardDescription>
          </div>
          <div className="flex flex-wrap items-center gap-2">
            <Button size="sm" onClick={handleOpenCreateDevice}>
              <Plus className="size-4" />
              Novo dispositivo
            </Button>
          </div>
        </CardHeader>
        <CardContent className="overflow-hidden">
          <div className="mb-3 flex flex-col gap-3">
            <div className="flex flex-wrap gap-3">
              <label className="flex min-w-[260px] flex-1 flex-col gap-1 text-xs font-semibold uppercase tracking-wide text-neutral-500">
                Buscar hostname, e-mail, MAC, serial...
                <Input value={q} onChange={(e) => setQ(e.target.value)} placeholder="Digite para filtrar" />
              </label>
              <label className="flex w-auto min-w-[170px] max-w-[220px] flex-col gap-1 text-xs font-semibold uppercase tracking-wide text-neutral-500">
                Todos status
                <Select value={statusFilter} onValueChange={setStatusFilter}>
                  <SelectTrigger className="justify-between text-sm">
                    <SelectValue placeholder="Status" />
                  </SelectTrigger>
                  <SelectContent>
                    <SelectItem value="all">Todos status</SelectItem>
                    <SelectItem value="online">Online</SelectItem>
                    <SelectItem value="offline">Offline</SelectItem>
                    <SelectItem value="stale">Sem sinal</SelectItem>
                    <SelectItem value="unknown">Desconhecido</SelectItem>
                  </SelectContent>
                </Select>
              </label>
              <label className="flex w-auto min-w-[180px] max-w-[240px] flex-col gap-1 text-xs font-semibold uppercase tracking-wide text-neutral-500">
                Todos os tipos
                <Select value={deviceTypeFilter} onValueChange={setDeviceTypeFilter}>
                  <SelectTrigger className="justify-between text-sm">
                    <SelectValue placeholder="Tipo de dispositivo" />
                  </SelectTrigger>
                  <SelectContent>
                    {DEVICE_TYPE_FILTER_OPTIONS.map((option) => (
                      <SelectItem key={option.value} value={option.value}>
                        {option.label}
                      </SelectItem>
                    ))}
                  </SelectContent>
                </Select>
              </label>
            </div>
            <div className="flex flex-wrap items-center gap-3">
              <Popover open={isCompanyPopoverOpen} onOpenChange={setIsCompanyPopoverOpen}>
                <PopoverTrigger asChild>
                  <Button variant="outline" className="min-w-56 justify-between">
                    {(() => {
                      if (companyFilterSlug === "all") return "Todas empresas"
                      const found = companyOptions.find((c) => c.slug === companyFilterSlug)
                      return found?.name ?? companyFilterSlug
                    })()}
                    <span className="ml-2 text-slate-400">▾</span>
                  </Button>
                </PopoverTrigger>
                <PopoverContent className="w-72 p-2" align="start">
                  <div className="space-y-2">
                    <Input
                      value={companySearch}
                      onChange={(e) => setCompanySearch(e.target.value)}
                      placeholder="Buscar empresa..."
                    />
                    <div className="max-h-64 overflow-auto rounded-md border border-slate-200">
                      <button
                        type="button"
                        onClick={() => {
                          setCompanyFilterSlug("all")
                          setCompanySearch("")
                          setIsCompanyPopoverOpen(false)
                        }}
                        className="block w-full px-3 py-2 text-left text-sm hover:bg-slate-100"
                      >
                        Todas empresas
                      </button>
                      {companyOptions
                        .filter((c) => c.name.toLowerCase().includes(companySearch.toLowerCase()))
                        .map((c) => (
                          <button
                            key={c.slug}
                            type="button"
                            onClick={() => {
                              setCompanyFilterSlug(c.slug)
                              setCompanySearch("")
                              setIsCompanyPopoverOpen(false)
                            }}
                            className="block w-full px-3 py-2 text-left text-sm hover:bg-slate-100"
                          >
                            {c.name}
                          </button>
                        ))}
                    </div>
                  </div>
                </PopoverContent>
              </Popover>
              <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")
                  setCompanyFilterSlug("all")
                  setCompanySearch("")
                  setOnlyAlerts(false)
                  setIsCompanyPopoverOpen(false)
                }}
              >
                Limpar
              </Button>
              <Button size="sm" variant="outline" className="gap-2" onClick={handleOpenExportDialog}>
                <Download className="size-4" />
                Exportar XLSX
              </Button>
              <Button size="sm" variant="outline" className="gap-2" onClick={handleOpenUsbPolicyDialog}>
                <Usb className="size-4" />
                Controle USB
              </Button>
            </div>
          </div>
          {isLoading ? (
            <LoadingState />
          ) : devices.length === 0 ? (
            <EmptyState />
          ) : (
            <DevicesGrid devices={filteredDevices} companyNameBySlug={companyNameBySlug} />
          )}
        </CardContent>
      </Card>
      <Dialog open={isExportDialogOpen} onOpenChange={handleExportDialogOpenChange}>
        <DialogContent className="max-w-3xl space-y-5">
          <DialogHeader>
            <DialogTitle>Exportar inventário</DialogTitle>
            <DialogDescription>Revise os dispositivos antes de gerar o XLSX.</DialogDescription>
          </DialogHeader>
          {filteredDevices.length === 0 ? (
            <div className="rounded-md border border-dashed border-slate-200 px-4 py-8 text-center text-sm text-muted-foreground">
              Nenhum dispositivo disponível para exportar com os filtros atuais.
            </div>
          ) : (
            <div className="space-y-3">
              <div className="flex items-center justify-between rounded-md border border-slate-200 bg-slate-50 px-3 py-2 text-xs text-slate-600">
                <span>
                  {selectedCount} de {filteredDevices.length} selecionadas
                </span>
                <label className="inline-flex items-center gap-2 font-medium text-slate-600">
                  <Checkbox
                    checked={selectAllState}
                    onCheckedChange={(value) => handleSelectAllDevices(value === true || value === "indeterminate")}
                    disabled={isExporting}
                  />
                  <span>Selecionar todas</span>
                </label>
              </div>
              <div className="max-h-80 overflow-y-auto rounded-md border border-slate-200">
                <ul className="divide-y divide-slate-100">
                  {filteredDevices.map((device) => {
                    const statusKey = resolveDeviceStatus(device)
                    const statusLabel = DEVICE_STATUS_LABELS[statusKey] ?? statusKey
                    const isChecked = exportSelection.includes(device.id)
                    const osParts = [device.osName ?? "", device.osVersion ?? ""].filter(Boolean)
                    const osLabel = osParts.join(" ")
                    return (
                      <li key={device.id}>
                        <label className="flex cursor-pointer items-start gap-3 px-3 py-3 hover:bg-slate-50">
                          <Checkbox
                            checked={isChecked}
                            onCheckedChange={(value) => handleToggleDeviceSelection(device.id, value === true || value === "indeterminate")}
                            disabled={isExporting}
                          />
                          <div className="flex flex-col gap-1 text-sm">
                            <div className="flex flex-wrap items-center gap-2">
                              <span className="font-medium text-slate-900">
                                {device.displayName ?? device.hostname ?? device.authEmail ?? "Dispositivo"}
                              </span>
                              <Badge variant="outline" className="text-[11px] font-medium uppercase tracking-wide">
                                {statusLabel}
                              </Badge>
                            </div>
                            <div className="flex flex-wrap items-center gap-2 text-xs text-slate-500">
                              <span>{device.companyName ?? "Sem empresa"}</span>
                              {osLabel ? (
                                <>
                                  <span className="text-slate-300">•</span>
                                  <span>{osLabel}</span>
                                </>
                              ) : null}
                              {device.architecture ? (
                                <>
                                  <span className="text-slate-300">•</span>
                                  <span>{device.architecture}</span>
                                </>
                              ) : null}
                            </div>
                          </div>
                        </label>
                      </li>
                    )
                  })}
                </ul>
              </div>
            </div>
          )}
          {filteredDevices.length > 0 ? (
            <div className="space-y-4 rounded-md border border-slate-200 bg-white p-4">
              <div className="flex flex-col gap-3">
                <div className="flex flex-wrap items-center justify-between gap-3">
                  <div className="space-y-1">
                    <p className="text-sm font-semibold text-slate-900">Template de exportação</p>
                    <p className="text-xs text-slate-500">Salve combinações de colunas para reutilizar mais tarde.</p>
                  </div>
                  <div className="flex items-center gap-2">
                    <Select value={selectedTemplateId ?? "custom"} onValueChange={handleTemplateSelection}>
                      <SelectTrigger className="w-60">
                        <SelectValue placeholder="Selecionar template" />
                      </SelectTrigger>
                      <SelectContent>
                        <SelectItem value="custom">Personalizado</SelectItem>
                        {templateOptions.map((tpl) => (
                          <SelectItem key={tpl.id} value={tpl.id}>
                            {tpl.name}
                            {tpl.isDefault ? " • padrão" : ""}
                          </SelectItem>
                        ))}
                      </SelectContent>
                    </Select>
                    <Button type="button" variant="outline" size="sm" onClick={handleOpenTemplateDialog} disabled={isExporting}>
                      Salvar template
                    </Button>
                  </div>
                </div>
                {selectedTemplate ? (
                  <p className="text-xs text-slate-500">
                    Aplicando <span className="font-semibold text-slate-700">{selectedTemplate.name}</span>
                    {selectedTemplate.companyId ? " (empresa)" : ""}
                    {selectedTemplate.isDefault ? " • padrão" : ""}
                  </p>
                ) : null}
              </div>
              <div className="space-y-3">
                <div className="flex flex-wrap items-center justify-between gap-2">
                  <p className="text-sm font-semibold text-slate-900">Colunas</p>
                  <div className="flex items-center gap-2">
                    <Button type="button" variant="ghost" size="sm" onClick={handleSelectAllColumns} disabled={isExporting} className="gap-2">
                      <CheckSquare className="size-4" />
                      Selecionar todas
                    </Button>
                    <Separator orientation="vertical" className="h-4" />
                    <Button type="button" variant="ghost" size="sm" onClick={handleResetColumns} disabled={isExporting} className="gap-2">
                      <RotateCcw className="size-4" />
                      Restaurar padrão
                    </Button>
                  </div>
                </div>
                <div className="grid gap-3 sm:grid-cols-2">
                  {baseColumnOptions.map((column) => {
                    const checked = columnConfig.some((col) => col.key === column.key)
                    return (
                      <label key={column.key} className="flex items-center gap-2 text-sm text-slate-700">
                        <Checkbox
                          checked={checked}
                          onCheckedChange={(value) =>
                            handleToggleColumn(column.key, value === true || value === "indeterminate")
                          }
                          disabled={isExporting}
                        />
                        <span>{column.label}</span>
                      </label>
                    )
                  })}
                </div>
                {customColumnOptions.length > 0 ? (
                  <div className="space-y-2">
                    <p className="text-xs font-semibold uppercase text-slate-500">Campos personalizados</p>
                    <div className="grid gap-3 sm:grid-cols-2">
                      {customColumnOptions.map((column) => {
                        const checked = columnConfig.some((col) => col.key === column.key)
                        return (
                          <label key={column.key} className="flex items-center gap-2 text-sm text-slate-700">
                            <Checkbox
                              checked={checked}
                              onCheckedChange={(value) =>
                                handleToggleColumn(column.key, value === true || value === "indeterminate", column.label)
                              }
                              disabled={isExporting}
                            />
                            <span>{column.label}</span>
                          </label>
                        )
                      })}
                    </div>
                  </div>
                ) : null}
                <p className="text-xs text-slate-500">
                  {columnConfig.length} coluna{columnConfig.length === 1 ? "" : "s"} selecionada{columnConfig.length === 1 ? "" : "s"}.
                </p>
              </div>
            </div>
          ) : null}
          {isExporting ? (
            <div className="space-y-2 rounded-md border border-slate-200 bg-slate-50 px-4 py-3">
              <div className="flex items-center justify-between text-sm font-medium text-slate-700">
                <span>Gerando planilha...</span>
                <span>{Math.min(100, Math.max(0, Math.round(exportProgress)))}%</span>
              </div>
              <Progress value={exportProgress} className="h-2" />
            </div>
          ) : null}
          {exportError ? <p className="text-sm text-destructive">{exportError}</p> : null}
          <DialogFooter className="gap-2 sm:gap-2">
            <Button type="button" variant="outline" onClick={() => handleExportDialogOpenChange(false)} disabled={isExporting}>
              Cancelar
            </Button>
            <Button type="button" onClick={handleConfirmExport} disabled={isExporting || selectedCount === 0} className="gap-2">
              {isExporting ? (
                <>
                  <Spinner className="mr-2 size-4" />
                  Exportando...
                </>
              ) : (
                <>
                  <Download className="size-4" />
                  Exportar{selectedCount > 0 ? ` (${selectedCount})` : ""}
                </>
              )}
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>
      <Dialog open={isUsbPolicyDialogOpen} onOpenChange={handleUsbPolicyDialogOpenChange}>
        <DialogContent className="max-w-2xl space-y-5">
          <DialogHeader>
            <DialogTitle className="flex items-center gap-2">
              <Usb className="size-5" />
              Controle USB em massa
            </DialogTitle>
            <DialogDescription>
              Aplique uma política de armazenamento USB a todos os dispositivos Windows selecionados.
            </DialogDescription>
          </DialogHeader>
          {(() => {
            const allWindowsDevices = filteredDevices.filter(
              (m) => (m.devicePlatform ?? "").toLowerCase() === "windows"
            )
            const windowsDevices = usbCompanyFilter === "all"
              ? allWindowsDevices
              : allWindowsDevices.filter((m) => (m.companySlug ?? "") === usbCompanyFilter)
            const usbCompanyOptions = Array.from(
              new Map(
                allWindowsDevices
                  .filter((m) => m.companySlug)
                  .map((m) => [m.companySlug, m.companyName ?? m.companySlug])
              )
            ).sort((a, b) => (a[1] ?? "").localeCompare(b[1] ?? "", "pt-BR"))
            if (allWindowsDevices.length === 0) {
              return (
                <div className="rounded-md border border-dashed border-slate-200 px-4 py-8 text-center text-sm text-muted-foreground">
                  Nenhum dispositivo Windows disponível com os filtros atuais.
                </div>
              )
            }
            const allSelected = windowsDevices.length > 0 && usbPolicySelection.length === windowsDevices.length
            const someSelected = usbPolicySelection.length > 0 && usbPolicySelection.length < windowsDevices.length
            return (
              <div className="space-y-4">
                <div className="space-y-2">
                  <label className="text-sm font-medium text-slate-700">Filtrar por empresa</label>
                  <Select
                    value={usbCompanyFilter}
                    onValueChange={(value) => {
                      setUsbCompanyFilter(value)
                      setUsbPolicySelection([])
                    }}
                    disabled={isApplyingUsbPolicy}
                  >
                    <SelectTrigger>
                      <SelectValue placeholder="Selecione uma empresa" />
                    </SelectTrigger>
                    <SelectContent>
                      <SelectItem value="all">
                        <span>Todas as empresas</span>
                      </SelectItem>
                      {usbCompanyOptions.map(([slug, name]) => (
                        <SelectItem key={slug} value={slug ?? ""}>
                          <span>{name}</span>
                        </SelectItem>
                      ))}
                    </SelectContent>
                  </Select>
                </div>
                <div className="flex items-center justify-between rounded-md border border-slate-200 bg-slate-50 px-3 py-2 text-xs text-slate-600">
                  <span>
                    {usbPolicySelection.length} de {windowsDevices.length} dispositivos Windows selecionados
                  </span>
                  <Checkbox
                    checked={allSelected ? true : someSelected ? "indeterminate" : false}
                    onCheckedChange={(value) => handleSelectAllUsbDevices(value === true || value === "indeterminate")}
                    disabled={isApplyingUsbPolicy || windowsDevices.length === 0}
                  />
                </div>
                {windowsDevices.length === 0 ? (
                  <div className="rounded-md border border-dashed border-slate-200 px-4 py-6 text-center text-sm text-muted-foreground">
                    Nenhum dispositivo Windows nesta empresa.
                  </div>
                ) : (
                <div className="max-h-48 space-y-1 overflow-y-auto rounded-md border border-slate-200 p-2">
                  {windowsDevices.map((device) => {
                    const checked = usbPolicySelection.includes(device.id)
                    const policyLabels: Record<string, string> = {
                      ALLOW: "Permitido",
                      BLOCK_ALL: "Bloqueado",
                      READONLY: "Leitura",
                    }
                    const currentPolicy = device.usbPolicy ? policyLabels[device.usbPolicy] ?? device.usbPolicy : null
                    const isPending = device.usbPolicyStatus === "PENDING"
                    const isFailed = device.usbPolicyStatus === "FAILED"
                    return (
                      <label
                        key={device.id}
                        className={cn(
                          "flex cursor-pointer items-center gap-3 rounded-md px-2 py-1.5 text-sm transition hover:bg-slate-100",
                          checked && "bg-slate-100"
                        )}
                      >
                        <Checkbox
                          checked={checked}
                          onCheckedChange={(value) => handleToggleUsbDeviceSelection(device.id, value === true)}
                          disabled={isApplyingUsbPolicy}
                        />
                        <span className="flex-1 truncate">
                          {device.displayName ?? device.hostname}
                        </span>
                        {currentPolicy && (
                          <span className={cn(
                            "rounded-full px-1.5 py-0.5 text-[10px] font-medium",
                            isFailed ? "bg-red-100 text-red-700" :
                            isPending ? "bg-amber-100 text-amber-700" :
                            "bg-slate-100 text-slate-600"
                          )}>
                            {currentPolicy}{isPending ? " ..." : isFailed ? " !" : ""}
                          </span>
                        )}
                        <span className="text-xs text-muted-foreground">
                          {device.companyName ?? "—"}
                        </span>
                      </label>
                    )
                  })}
                </div>
                )}
                <div className="space-y-2">
                  <label className="text-sm font-medium text-slate-700">Política USB</label>
                  <Select
                    value={selectedUsbPolicy}
                    onValueChange={(value) => setSelectedUsbPolicy(value as "ALLOW" | "BLOCK_ALL" | "READONLY")}
                    disabled={isApplyingUsbPolicy}
                  >
                    <SelectTrigger>
                      <SelectValue placeholder="Selecione uma política" />
                    </SelectTrigger>
                    <SelectContent>
                      <SelectItem value="ALLOW">
                        <div className="flex items-center gap-2">
                          <Shield className="size-4 text-emerald-600" />
                          <span>Permitido</span>
                        </div>
                      </SelectItem>
                      <SelectItem value="BLOCK_ALL">
                        <div className="flex items-center gap-2">
                          <ShieldOff className="size-4 text-red-600" />
                          <span>Bloqueado</span>
                        </div>
                      </SelectItem>
                      <SelectItem value="READONLY">
                        <div className="flex items-center gap-2">
                          <ShieldAlert className="size-4 text-amber-600" />
                          <span>Somente leitura</span>
                        </div>
                      </SelectItem>
                    </SelectContent>
                  </Select>
                  <p className="text-xs text-muted-foreground">
                    {selectedUsbPolicy === "ALLOW" && "Acesso total a dispositivos USB de armazenamento."}
                    {selectedUsbPolicy === "BLOCK_ALL" && "Nenhum acesso a dispositivos USB de armazenamento."}
                    {selectedUsbPolicy === "READONLY" && "Permite leitura, bloqueia escrita em dispositivos USB."}
                  </p>
                </div>
              </div>
            )
          })()}
          <DialogFooter className="gap-2 sm:gap-2">
            <Button
              type="button"
              variant="outline"
              onClick={() => handleUsbPolicyDialogOpenChange(false)}
              disabled={isApplyingUsbPolicy}
            >
              Cancelar
            </Button>
            <Button
              type="button"
              onClick={handleApplyBulkUsbPolicy}
              disabled={isApplyingUsbPolicy || usbPolicySelection.length === 0}
              className="gap-2"
            >
              {isApplyingUsbPolicy ? (
                <>
                  <Loader2 className="size-4 animate-spin" />
                  Aplicando...
                </>
              ) : (
                <>
                  <Usb className="size-4" />
                  Aplicar política{usbPolicySelection.length > 0 ? ` (${usbPolicySelection.length})` : ""}
                </>
              )}
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>
      <Dialog open={isTemplateDialogOpen} onOpenChange={(open) => setIsTemplateDialogOpen(open)}>
        <DialogContent className="max-w-md space-y-4">
          <DialogHeader>
            <DialogTitle>Salvar template</DialogTitle>
            <DialogDescription>Guarde esta seleção de colunas para reutilizar em futuras exportações.</DialogDescription>
          </DialogHeader>
          <div className="space-y-4">
            <div className="space-y-2">
              <label htmlFor="template-name" className="text-sm font-medium text-slate-700">
                Nome do template
              </label>
              <Input
                id="template-name"
                autoFocus
                value={templateName}
                onChange={(event) => setTemplateName(event.target.value)}
                placeholder="Inventário padrão"
                disabled={isSavingTemplate}
              />
            </div>
            <div className="space-y-2">
              <p className="text-sm font-medium text-slate-700">Escopo</p>
              <div className="space-y-2">
                <label className="flex items-center gap-2 text-sm text-slate-700">
                  <Checkbox
                    checked={templateForCompany && Boolean(selectedCompany)}
                    onCheckedChange={(value) => setTemplateForCompany(value === true || value === "indeterminate")}
                    disabled={!selectedCompany || isSavingTemplate}
                  />
                  <span>
                    Associar à empresa
                    {selectedCompany ? ` ${selectedCompany.name}` : " (selecione uma empresa na filtragem)"}
                  </span>
                </label>
                <label className="flex items-center gap-2 text-sm text-slate-700">
                  <Checkbox
                    checked={templateAsDefault}
                    onCheckedChange={(value) => setTemplateAsDefault(value === true || value === "indeterminate")}
                    disabled={isSavingTemplate}
                  />
                  <span>Definir como padrão</span>
                </label>
              </div>
            </div>
            <p className="text-xs text-slate-500">
              {columnConfig.length} coluna{columnConfig.length === 1 ? "" : "s"} será{columnConfig.length === 1 ? "" : "o"} salva{columnConfig.length === 1 ? "" : "s"} neste template.
            </p>
          </div>
          <DialogFooter className="gap-2 sm:gap-2">
            <Button type="button" variant="outline" onClick={() => setIsTemplateDialogOpen(false)} disabled={isSavingTemplate}>
              Cancelar
            </Button>
            <Button
              type="button"
              onClick={handleSaveTemplate}
              disabled={
                isSavingTemplate || columnConfig.length === 0 || templateName.trim().length < 3 || !convexUserId
              }
              className="gap-2"
            >
              {isSavingTemplate ? (
                <>
                  <Spinner className="size-4" />
                  Salvando...
                </>
              ) : (
                "Salvar template"
              )}
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>
      <Dialog open={isCreateDeviceOpen} onOpenChange={(open) => (!createDeviceLoading ? setIsCreateDeviceOpen(open) : null)}>
        <DialogContent className="max-w-lg space-y-4">
          <DialogHeader>
            <DialogTitle>Novo dispositivo</DialogTitle>
            <DialogDescription>Cadastre equipamentos sem agente instalado, como celulares e tablets.</DialogDescription>
          </DialogHeader>
          <div className="grid gap-4">
            <div className="grid gap-2">
              <label htmlFor="device-name" className="text-sm font-medium text-slate-700">
                Nome do dispositivo
              </label>
              <Input
                id="device-name"
                autoFocus
                value={newDeviceName}
                onChange={(event) => setNewDeviceName(event.target.value)}
                placeholder="iPhone da Ana"
                disabled={createDeviceLoading}
              />
            </div>
            <div className="grid gap-2">
              <label htmlFor="device-identifier" className="text-sm font-medium text-slate-700">
                Identificador (hostname)
              </label>
              <Input
                id="device-identifier"
                value={newDeviceIdentifier}
                onChange={(event) => setNewDeviceIdentifier(event.target.value)}
                placeholder="ana-iphone"
                disabled={createDeviceLoading}
              />
              <p className="text-xs text-slate-500">Caso vazio, usaremos o nome como identificador.</p>
            </div>
            <div className="grid gap-2 sm:grid-cols-2 sm:gap-4">
              <div className="grid gap-2">
                <label className="text-sm font-medium text-slate-700">Tipo</label>
                <Select value={newDeviceType} onValueChange={setNewDeviceType} disabled={createDeviceLoading}>
                  <SelectTrigger>
                    <SelectValue />
                  </SelectTrigger>
                  <SelectContent>
                    <SelectItem value="mobile">Celular</SelectItem>
                    <SelectItem value="desktop">Desktop</SelectItem>
                    <SelectItem value="tablet">Tablet</SelectItem>
                  </SelectContent>
                </Select>
              </div>
              <div className="grid gap-2">
                <label htmlFor="device-platform" className="text-sm font-medium text-slate-700">
                  Plataforma
                </label>
                <Input
                  id="device-platform"
                  value={newDevicePlatform}
                  onChange={(event) => setNewDevicePlatform(event.target.value)}
                  placeholder="iOS 18, Android 15, Windows 11"
                  disabled={createDeviceLoading}
                />
              </div>
            </div>
            <div className="grid gap-2">
              <label className="text-sm font-medium text-slate-700">Empresa</label>
              <SearchableCombobox
                value={newDeviceCompanySlug}
                onValueChange={setNewDeviceCompanySlug}
                options={companyComboboxOptions}
                placeholder="Sem empresa"
                searchPlaceholder="Buscar empresa..."
                emptyText="Nenhuma empresa encontrada."
                allowClear
                clearLabel="Sem empresa"
                disabled={createDeviceLoading}
              />
            </div>
            <div className="grid gap-2">
              <label htmlFor="device-serials" className="text-sm font-medium text-slate-700">
                Seriais / IMEI
              </label>
              <Textarea
                id="device-serials"
                value={newDeviceSerials}
                onChange={(event) => setNewDeviceSerials(event.target.value)}
                placeholder="Separe múltiplos valores com quebra de linha"
                disabled={createDeviceLoading}
              />
            </div>
            <div className="grid gap-2">
              <label htmlFor="device-notes" className="text-sm font-medium text-slate-700">
                Observações
              </label>
              <Textarea
                id="device-notes"
                value={newDeviceNotes}
                onChange={(event) => setNewDeviceNotes(event.target.value)}
                placeholder="Informações adicionais para a equipe"
                disabled={createDeviceLoading}
              />
            </div>
            <label className="flex items-center gap-2 text-sm text-slate-700">
              <Checkbox
                checked={newDeviceActive}
                onCheckedChange={(value) => setNewDeviceActive(value === true || value === "indeterminate")}
                disabled={createDeviceLoading}
              />
              <span>Ativo</span>
            </label>
          </div>
          <DialogFooter className="gap-2 sm:gap-2">
            <Button
              type="button"
              variant="outline"
              onClick={() => !createDeviceLoading && setIsCreateDeviceOpen(false)}
              disabled={createDeviceLoading}
            >
              Cancelar
            </Button>
            <Button
              type="button"
              onClick={handleCreateDevice}
              disabled={createDeviceLoading || newDeviceName.trim().length < 3}
              className="gap-2"
            >
              {createDeviceLoading ? (
                <>
                  <Spinner className="size-4" />
                  Salvando...
                </>
              ) : (
                "Cadastrar dispositivo"
              )}
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>
    </div>
  )
}

function DeviceStatusBadge({ status }: { status?: string | null }) {
  const { label, className } = getStatusVariant(status)
  const { dotClass, ringClass, isPinging } = getDeviceStatusIndicator(status)
  return (
    <Badge
      variant="outline"
      className={cn(
        "inline-flex items-center gap-2 rounded-lg border border-slate-200 bg-white px-3 py-1 text-xs font-semibold text-neutral-600 shadow-sm sm:text-sm",
        className
      )}
    >
      <span className="relative inline-flex size-4 items-center justify-center">
        <span className={cn("size-2.5 rounded-full", dotClass)} />
        {isPinging ? (
          <span
            className={cn(
              "absolute left-1/2 top-1/2 size-5 -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">Nenhum dispositivo registrado ainda</p>
        <p className="text-sm text-muted-foreground">
          Execute o agente local ou o webhook do Fleet para registrar os dispositivos do tenant.
        </p>
      </div>
    </div>
  )
}

function LoadingState() {
  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">
      <div className="inline-flex size-12 items-center justify-center rounded-full border border-slate-200 bg-white shadow-sm">
        <Spinner className="size-6 text-slate-500" />
      </div>
      <div className="space-y-1">
        <p className="text-sm font-semibold text-slate-600">Carregando dispositivos...</p>
        <p className="text-sm text-muted-foreground">
          Sincronizando o inventário em tempo real. Isso leva apenas alguns instantes.
        </p>
      </div>
    </div>
  )
}

type DeviceDetailsProps = {
  device: DevicesQueryItem | null
}

export function DeviceDetails({ device }: DeviceDetailsProps) {
  const router = useRouter()
  const { role: viewerRole } = useAuth()
  const normalizedViewerRole = (viewerRole ?? "").toLowerCase()
  const canManageRemoteAccess = normalizedViewerRole === "admin" || normalizedViewerRole === "agent"
  const canManageFieldCatalog = normalizedViewerRole === "admin"
  const effectiveStatus = device ? resolveDeviceStatus(device) : "unknown"
  const [isActiveLocal, setIsActiveLocal] = useState<boolean>(device?.isActive ?? true)
  const isDeactivated = !isActiveLocal || effectiveStatus === "deactivated"
  const isManualMobile =
    (device?.managementMode ?? "").toLowerCase() === "manual" &&
    (device?.deviceType ?? "").toLowerCase() === "mobile"
  const alertsHistory = useQuery(
    api.devices.listAlerts,
    device ? { machineId: device.id as Id<"machines">, limit: 50 } : "skip"
  ) as DeviceAlertEntry[] | undefined
  const deviceAlertsHistory = alertsHistory ?? []
  const openTickets = useQuery(
    api.devices.listOpenTickets,
    device ? { machineId: device.id as Id<"machines">, limit: 6 } : "skip"
  ) as DeviceOpenTicketsSummary | undefined
  const deviceTickets = openTickets?.tickets ?? []
  const totalOpenTickets = openTickets?.totalOpen ?? deviceTickets.length
  const displayLimit = 3
  const displayedDeviceTickets = deviceTickets.slice(0, displayLimit)
  const hasAdditionalOpenTickets = totalOpenTickets > displayedDeviceTickets.length
  const deviceTicketsHref = device ? `/admin/devices/${device.id}/tickets` : null
  const metadata = device?.inventory ?? null
  const metrics = device?.metrics ?? null
  const metricsCapturedAt = useMemo(() => getMetricsTimestamp(metrics), [metrics])
  // Live refresh the relative time label every second when we have a capture timestamp
  const [, setRelativeTick] = useState(0)
  useEffect(() => {
    if (!metricsCapturedAt) return
    const id = setInterval(() => setRelativeTick((t) => t + 1), 1000)
    return () => clearInterval(id)
  }, [metricsCapturedAt])
  const lastUpdateRelative = metricsCapturedAt ? formatRelativeTime(metricsCapturedAt) : 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 windowsOsInfo = parseWindowsOsInfo(windowsExt?.osInfo)
  const windowsActivationStatus = windowsOsInfo?.isActivated ?? (typeof windowsOsInfo?.licenseStatus === "number" ? windowsOsInfo.licenseStatus === 1 : null)
  const windowsMemoryModulesRaw = windowsExt?.memoryModules
  const windowsVideoControllersRaw = windowsExt?.videoControllers
  const windowsDiskEntriesRaw = windowsExt?.disks
  const windowsServicesRaw = windowsExt?.services
  const windowsSoftwareRaw = windowsExt?.software
  const windowsBaseboardRaw = windowsExt?.baseboard
  const windowsBaseboard = Array.isArray(windowsBaseboardRaw)
    ? windowsBaseboardRaw[0]
    : windowsBaseboardRaw && typeof windowsBaseboardRaw === "object"
      ? windowsBaseboardRaw
      : null
  const windowsSerialNumber = windowsBaseboard ? readString(toRecord(windowsBaseboard) ?? {}, "SerialNumber", "serialNumber") : undefined
  const windowsMemoryModules = useMemo(() => {
    if (Array.isArray(windowsMemoryModulesRaw)) return windowsMemoryModulesRaw
    if (windowsMemoryModulesRaw && typeof windowsMemoryModulesRaw === "object") return [windowsMemoryModulesRaw]
    return []
  }, [windowsMemoryModulesRaw])
  const windowsVideoControllers = useMemo(() => {
    if (Array.isArray(windowsVideoControllersRaw)) return windowsVideoControllersRaw
    if (windowsVideoControllersRaw && typeof windowsVideoControllersRaw === "object") return [windowsVideoControllersRaw]
    return []
  }, [windowsVideoControllersRaw])
  const windowsDiskEntries = useMemo(() => {
    if (Array.isArray(windowsDiskEntriesRaw)) return windowsDiskEntriesRaw
    if (windowsDiskEntriesRaw && typeof windowsDiskEntriesRaw === "object") return [windowsDiskEntriesRaw]
    return []
  }, [windowsDiskEntriesRaw])
  const windowsServices = useMemo(() => {
    if (Array.isArray(windowsServicesRaw)) return windowsServicesRaw
    if (windowsServicesRaw && typeof windowsServicesRaw === "object") return [windowsServicesRaw]
    return []
  }, [windowsServicesRaw])
  const windowsSoftware = useMemo(() => {
    if (Array.isArray(windowsSoftwareRaw)) return windowsSoftwareRaw
    if (windowsSoftwareRaw && typeof windowsSoftwareRaw === "object") return [windowsSoftwareRaw]
    return []
  }, [windowsSoftwareRaw])
  const normalizedWindowsSoftware = useMemo(() => {
    return windowsSoftware
      .map((item) => normalizeWindowsSoftwareEntry(item))
      .filter((entry): entry is NormalizedSoftwareEntry => Boolean(entry))
      .sort((a, b) => {
        const aTime = a.installDate ? a.installDate.getTime() : 0
        const bTime = b.installDate ? b.installDate.getTime() : 0
        if (aTime !== bTime) return bTime - aTime
        return a.name.localeCompare(b.name, "pt-BR")
      })
  }, [windowsSoftware])
  const windowsEditionLabel = useMemo(() => {
    const raw =
      windowsOsInfo?.productName ??
      windowsOsInfo?.caption ??
      windowsOsInfo?.editionId ??
      null
    if (!raw) return null
    return raw.replace(/^Microsoft\s+/i, "").trim()
  }, [windowsOsInfo?.productName, windowsOsInfo?.caption, windowsOsInfo?.editionId])
  const windowsVersionLabel = windowsOsInfo?.displayVersion ?? windowsOsInfo?.version ?? windowsOsInfo?.releaseId ?? null
  const windowsBuildLabel = windowsOsInfo?.currentBuildNumber ?? windowsOsInfo?.currentBuild ?? null
  const windowsInstallDateLabel = windowsOsInfo?.installDate ? formatAbsoluteDateTime(windowsOsInfo.installDate) : null
  const windowsExperienceLabel = windowsOsInfo?.experience ?? null
  const windowsProductId = windowsOsInfo?.productId ?? null
  const windowsPartialProductKey = windowsOsInfo?.partialProductKey ?? null
  const windowsComputerName = windowsOsInfo?.computerName ?? hardware?.model ?? device?.hostname ?? null
  const windowsRegisteredOwner = windowsOsInfo?.registeredOwner ?? null
  const windowsLicenseStatusLabel = (() => {
    if (windowsOsInfo?.licenseStatusText) {
      return windowsOsInfo.licenseStatusText
    }
    switch (windowsOsInfo?.licenseStatus) {
      case 0:
        return "Sem licença"
      case 1:
        return "Licenciado"
      case 2:
        return "Período inicial (OOB Grace)"
      case 3:
        return "Período exposto (OOT Grace)"
      case 4:
        return "Período não genuíno"
      case 5:
        return "Notificação"
      case 6:
        return "Período estendido"
      default:
        return null
    }
  })()
  const windowsBitLockerRaw = windowsExt?.bitLocker ?? windowsExt?.bitlocker ?? null
  const windowsBitLockerVolumes = useMemo(() => {
    if (Array.isArray(windowsBitLockerRaw)) return windowsBitLockerRaw
    if (windowsBitLockerRaw && typeof windowsBitLockerRaw === "object") return [windowsBitLockerRaw]
    return []
  }, [windowsBitLockerRaw])
  const windowsBitLockerSummary = useMemo(() => {
    if (windowsBitLockerVolumes.length === 0) return null
    let protectedCount = 0
    let lockedCount = 0
    windowsBitLockerVolumes.forEach((volume) => {
      const record = toRecord(volume) ?? {}
      const protection = readString(record, "ProtectionStatus", "protectionStatus")?.toLowerCase()
      if (protection && (protection.includes("on") || protection.includes("ativo"))) {
        protectedCount += 1
      }
      const lockStatus = readString(record, "LockStatus", "lockStatus")?.toLowerCase()
      if (lockStatus && (lockStatus.includes("locked") || lockStatus.includes("bloqueado"))) {
        lockedCount += 1
      }
    })
    return { total: windowsBitLockerVolumes.length, protectedCount, lockedCount }
  }, [windowsBitLockerVolumes])
  const windowsTpm = toRecord(windowsExt?.tpm ?? (windowsExt as Record<string, unknown> | undefined)?.["TPM"])
  const windowsSecureBoot = toRecord(windowsExt?.secureBoot ?? (windowsExt as Record<string, unknown> | undefined)?.["secureboot"])
  const windowsDeviceGuardRaw = windowsExt?.deviceGuard ?? (windowsExt as Record<string, unknown> | undefined)?.["deviceguard"] ?? null
  const windowsDeviceGuard = useMemo(() => {
    if (Array.isArray(windowsDeviceGuardRaw)) return windowsDeviceGuardRaw
    if (windowsDeviceGuardRaw && typeof windowsDeviceGuardRaw === "object") return [windowsDeviceGuardRaw]
    return []
  }, [windowsDeviceGuardRaw])
  const windowsDeviceGuardDetails = useMemo(() => {
    if (!windowsDeviceGuard.length) return null
    const primary = toRecord(windowsDeviceGuard[0]) ?? {}
    const configured = toNumberArray(primary?.["SecurityServicesConfigured"])
    const running = toNumberArray(primary?.["SecurityServicesRunning"])
    const required = toNumberArray(primary?.["RequiredSecurityProperties"])
    const available = toNumberArray(primary?.["AvailableSecurityProperties"])
    const vbsRaw = primary?.["VirtualizationBasedSecurityStatus"]
    const vbs =
      typeof vbsRaw === "number"
        ? vbsRaw
        : typeof vbsRaw === "string" && vbsRaw.trim().length > 0
          ? Number(vbsRaw)
          : undefined
    return { primary, configured, running, required, available, vbs }
  }, [windowsDeviceGuard])
  const deviceGuardConfiguredLabels = windowsDeviceGuardDetails?.configured?.map((code) => describeDeviceGuardService(code)) ?? []
  const deviceGuardRunningLabels = windowsDeviceGuardDetails?.running?.map((code) => describeDeviceGuardService(code)) ?? []
  const windowsFirewallProfilesRaw =
    windowsExt?.firewallProfiles ?? (windowsExt as Record<string, unknown> | undefined)?.["firewallprofiles"] ?? null
  const windowsFirewallProfiles = useMemo(() => {
    if (Array.isArray(windowsFirewallProfilesRaw)) return windowsFirewallProfilesRaw
    if (windowsFirewallProfilesRaw && typeof windowsFirewallProfilesRaw === "object") return [windowsFirewallProfilesRaw]
    return []
  }, [windowsFirewallProfilesRaw])
  const windowsUpdateSettings = toRecord(windowsExt?.windowsUpdate ?? (windowsExt as Record<string, unknown> | undefined)?.["windowsupdate"])
  const windowsUpdateLastSuccess = useMemo(() => {
    if (!windowsUpdateSettings) return null
    const candidates = [
      windowsUpdateSettings["LastSuccessTime"],
      windowsUpdateSettings["lastSuccessTime"],
      windowsUpdateSettings["LastSuccessTimeUtc"],
      windowsUpdateSettings["lastSuccessTimeUtc"],
    ]
    for (const candidate of candidates) {
      const parsed = parseDateish(candidate)
      if (parsed) return parsed
      if (typeof candidate === "string" && candidate.trim().length > 0) {
        const parsedIso = new Date(candidate)
        if (!Number.isNaN(parsedIso.getTime())) return parsedIso
      }
    }
    return null
  }, [windowsUpdateSettings])
  const windowsUpdateLastSuccessLabel = windowsUpdateLastSuccess ? formatAbsoluteDateTime(windowsUpdateLastSuccess) : null
  const windowsComputerSystem = toRecord(
    windowsExt?.computerSystem ?? (windowsExt as Record<string, unknown> | undefined)?.["computersystem"]
  )
  const windowsAzureAdStatusRaw = toRecord(
    windowsExt?.azureAdStatus ?? (windowsExt as Record<string, unknown> | undefined)?.["azureadstatus"]
  )
  const windowsAzureAdStatus = useMemo(() => {
    if (!windowsAzureAdStatusRaw) return null
    return Object.entries(windowsAzureAdStatusRaw).reduce<Record<string, Record<string, unknown>>>((acc, [section, value]) => {
      acc[section] = toRecord(value) ?? {}
      return acc
    }, {})
  }, [windowsAzureAdStatusRaw])
  const secureBootSupported = windowsSecureBoot
    ? parseBooleanLike(windowsSecureBoot["Supported"] ?? windowsSecureBoot["supported"])
    : undefined
  const secureBootEnabled = windowsSecureBoot
    ? parseBooleanLike(windowsSecureBoot["Enabled"] ?? windowsSecureBoot["enabled"])
    : undefined
  const secureBootError = windowsSecureBoot ? readString(windowsSecureBoot, "Error", "error") : undefined
  const tpmPresent = windowsTpm ? parseBooleanLike(windowsTpm["TpmPresent"] ?? windowsTpm["tpmPresent"]) : undefined
  const tpmReady = windowsTpm ? parseBooleanLike(windowsTpm["TpmReady"] ?? windowsTpm["tpmReady"]) : undefined
  const tpmEnabled = windowsTpm ? parseBooleanLike(windowsTpm["TpmEnabled"] ?? windowsTpm["tpmEnabled"]) : undefined
  const tpmActivated = windowsTpm ? parseBooleanLike(windowsTpm["TpmActivated"] ?? windowsTpm["tpmActivated"]) : undefined
  const tpmManufacturer =
    windowsTpm ? readString(windowsTpm, "ManufacturerIdTxt", "manufacturerIdTxt", "ManufacturerId", "manufacturerId") : undefined
  const tpmVersion =
    windowsTpm
      ? readString(windowsTpm, "ManufacturerVersionFull20", "manufacturerVersionFull20", "ManufacturerVersion", "manufacturerVersion", "SpecVersion")
      : undefined
  const windowsFirewallNormalized = useMemo(() => {
    return windowsFirewallProfiles.map((profile) => {
      const record = toRecord(profile) ?? {}
      return {
        name: readString(record, "Name", "name") ?? "Perfil",
        enabled: parseBooleanLike(record["Enabled"] ?? record["enabled"]),
        inboundAction: readString(record, "DefaultInboundAction", "defaultInboundAction"),
        outboundAction: readString(record, "DefaultOutboundAction", "defaultOutboundAction"),
        notifyOnListen: parseBooleanLike(record["NotifyOnListen"] ?? record["notifyOnListen"]),
      }
    })
  }, [windowsFirewallProfiles])
  const firewallEnabledCount = windowsFirewallNormalized.filter((profile) => profile.enabled !== false).length
  const windowsUpdateMode = windowsUpdateSettings ? describeAuOption(readNumber(windowsUpdateSettings, "AUOptions", "auOptions")) : null
  const windowsUpdateDay = windowsUpdateSettings
    ? describeScheduledDay(readNumber(windowsUpdateSettings, "ScheduledInstallDay", "scheduledInstallDay"))
    : null
  const windowsUpdateHourRaw = windowsUpdateSettings
    ? readNumber(windowsUpdateSettings, "ScheduledInstallTime", "scheduledInstallTime")
    : undefined
  const windowsUpdateHour =
    windowsUpdateHourRaw != null ? `${windowsUpdateHourRaw.toString().padStart(2, "0")}h` : null
  const windowsUpdateDisabled = windowsUpdateSettings
    ? parseBooleanLike(windowsUpdateSettings["NoAutoUpdate"] ?? windowsUpdateSettings["noAutoUpdate"])
    : undefined
  const windowsUpdateDetectionEnabled = windowsUpdateSettings
    ? parseBooleanLike(
          windowsUpdateSettings["DetectionFrequency"] ??
            windowsUpdateSettings["DetectionFrequencyEnabled"] ??
            windowsUpdateSettings["detectionFrequencyEnabled"],
      )
    : undefined
  const windowsUpdateScheduleLabel =
    windowsUpdateDay || windowsUpdateHour
      ? `${windowsUpdateDay ?? ""}${windowsUpdateDay && windowsUpdateHour ? ` · ${windowsUpdateHour}` : windowsUpdateHour ?? ""}`.trim()
      : null
  const computerDomain = windowsComputerSystem ? readString(windowsComputerSystem, "Domain", "domain") : undefined
  const computerWorkgroup = windowsComputerSystem ? readString(windowsComputerSystem, "Workgroup", "workgroup") : undefined
  const computerPartOfDomain = windowsComputerSystem
    ? parseBooleanLike(windowsComputerSystem["PartOfDomain"] ?? windowsComputerSystem["partOfDomain"])
    : undefined
  const computerDomainRole = windowsComputerSystem
    ? readNumber(windowsComputerSystem, "DomainRole", "domainRole")
    : undefined
  const computerManufacturer = windowsComputerSystem
    ? readString(windowsComputerSystem, "Manufacturer", "manufacturer")
    : undefined
  const computerModel = windowsComputerSystem ? readString(windowsComputerSystem, "Model", "model") : undefined
  const computerPcType = windowsComputerSystem
    ? readNumber(windowsComputerSystem, "PCSystemType", "pcSystemType", "PCSystemTypeEx", "pcSystemTypeEx")
    : undefined
  const computerTotalMemory = windowsComputerSystem
    ? readNumber(windowsComputerSystem, "TotalPhysicalMemory", "totalPhysicalMemory")
    : undefined
  const computerDomainRoleLabel = describeDomainRole(computerDomainRole)
  const computerPcTypeLabel = describePcSystemType(computerPcType)
  const computerTotalMemoryLabel = typeof computerTotalMemory === "number" ? formatBytes(computerTotalMemory) : null
  const azureDeviceState = windowsAzureAdStatus ? windowsAzureAdStatus["Device State"] ?? null : null
  const azureTenantDetails = windowsAzureAdStatus ? windowsAzureAdStatus["Tenant Details"] ?? null : null
  const azureUserState = windowsAzureAdStatus ? windowsAzureAdStatus["User State"] ?? null : null
  const azureAdJoined = azureDeviceState ? parseBooleanLike(azureDeviceState["AzureAdJoined"]) : undefined
  const azureDomainJoined = azureDeviceState ? parseBooleanLike(azureDeviceState["DomainJoined"]) : undefined
  const azureEnterpriseJoined = azureDeviceState ? parseBooleanLike(azureDeviceState["EnterpriseJoined"]) : undefined
  const azureTenantName =
    (azureDeviceState ? readString(azureDeviceState, "TenantName") : undefined) ??
    (azureTenantDetails ? readString(azureTenantDetails, "TenantName") : undefined)
  const azureDeviceId =
    (azureDeviceState ? readString(azureDeviceState, "DeviceId") : undefined) ??
    (azureTenantDetails ? readString(azureTenantDetails, "DeviceId") : undefined)
  const azureUserSso = azureUserState
    ? readString(azureUserState, "AzureAdPrt") ??
      (azureUserState["AzureAdPrt"] ? String(azureUserState["AzureAdPrt"]) : undefined)
    : undefined
  const windowsDefender = windowsExt?.defender ?? null
  const defenderAntivirus = windowsDefender
    ? parseBooleanLike(windowsDefender["AntivirusEnabled"] ?? windowsDefender["antivirusEnabled"])
    : undefined
  const defenderRealtime = windowsDefender
    ? parseBooleanLike(windowsDefender["RealTimeProtectionEnabled"] ?? windowsDefender["realTimeProtectionEnabled"])
    : undefined
  const defenderMode = windowsDefender ? readString(windowsDefender, "AMRunningMode", "amRunningMode") : undefined
  const windowsHotfixes = useMemo(() => {
    if (!Array.isArray(windowsExt?.hotfix)) return []
    return windowsExt.hotfix
      .map((entry) => {
        const record = toRecord(entry) ?? {}
        const id =
          readString(record, "HotFixID", "hotFixId", "HotfixId", "Id", "id") ??
          "Atualização"
        const installedAt = parseDateish(record["InstalledOn"] ?? record["installedOn"])
        const installedLabel = installedAt
          ? formatAbsoluteDateTime(installedAt)
          : readString(record, "InstalledOn", "installedOn") ?? "—"
        return { id, installedAt, installedLabel }
      })
      .sort((a, b) => {
        if (a.installedAt && b.installedAt) {
          return b.installedAt.getTime() - a.installedAt.getTime()
        }
        if (a.installedAt) return -1
        if (b.installedAt) return 1
        return a.id.localeCompare(b.id)
      })
  }, [windowsExt?.hotfix])
  const osNameDisplay = useMemo(() => {
    const base = device?.osName?.trim()
    const edition = windowsEditionLabel?.trim()
    if (edition) {
      if (!base) return edition
      const baseLower = base.toLowerCase()
      const editionLower = edition.toLowerCase()
      if (editionLower.includes(baseLower) || baseLower.includes(editionLower)) {
        return edition
      }
      if (baseLower.startsWith("windows") && editionLower.startsWith("windows")) {
        return edition
      }
      return `${base} ${edition}`.replace(/\s+/g, " ").trim()
    }
    return base ?? ""
  }, [device?.osName, windowsEditionLabel])
  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 winDiskStats = windowsDiskEntries.length > 0
    ? {
        count: windowsDiskEntries.length,
        total: windowsDiskEntries.reduce((acc, disk) => acc + (parseBytesLike(disk?.Size) ?? 0), 0),
      }
    : { count: 0, total: 0 }

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

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

  // collaborator (from device assignment or metadata)
  type Collaborator = { email?: string; name?: string; role?: string }
  const collaborator: Collaborator | null = useMemo(() => {
    if (device?.assignedUserEmail) {
      return {
        email: device.assignedUserEmail ?? undefined,
        name: device.assignedUserName ?? undefined,
        role: device.persona ?? device.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
  }, [device?.assignedUserEmail, device?.assignedUserName, device?.persona, device?.assignedUserRole, metadata])

  const primaryLinkedUser: Collaborator | null = useMemo(() => {
    const firstLinked = device?.linkedUsers?.find((user) => typeof user?.email === "string" && user.email.trim().length > 0)
    if (firstLinked) {
      return {
        email: firstLinked.email,
        name: firstLinked.name ?? undefined,
        role: collaborator?.role ?? device?.persona ?? undefined,
      }
    }
    if (collaborator?.email) {
      return collaborator
    }
    if (device?.authEmail) {
      return {
        email: device.authEmail ?? undefined,
        name: undefined,
        role: device?.persona ?? undefined,
      }
    }
    return null
  }, [collaborator, device?.authEmail, device?.linkedUsers, device?.persona])

  const personaRole = (primaryLinkedUser?.role ?? collaborator?.role ?? device?.persona ?? "").toLowerCase()
  const personaLabel = personaRole === "manager" ? "Gestor" : "Colaborador"

  const remoteAccessEntries = useMemo(() => device?.remoteAccessEntries ?? [], [device?.remoteAccessEntries])
  const hasRemoteAccess = remoteAccessEntries.length > 0

  const summaryChips = useMemo(() => {
    const chips: Array<{ key: string; label: string; value: string; icon: ReactNode; tone?: "warning" | "muted"; onClick?: () => void; statusBadge?: { text: string; variant: "default" | "success" | "warning" | "error" } }> = []
    const osName = osNameDisplay || "Sistema desconhecido"
    const osVersionRaw = device?.osVersion ?? windowsVersionLabel ?? ""
    const osVersion = formatOsVersionDisplay(osNameDisplay, osVersionRaw)
    chips.push({
      key: "os",
      label: "Sistema",
      value: [osName, osVersion].filter(Boolean).join(" ").trim(),
      icon: <OsIcon osName={device?.osName} />,
    })
    if (device?.architecture) {
      chips.push({
        key: "arch",
        label: "Arquitetura",
        value: device.architecture.toUpperCase(),
        icon: <Cpu className="size-4 text-neutral-500" />,
      })
    }
    if (windowsActivationStatus !== null && windowsActivationStatus !== undefined) {
      chips.push({
        key: "activation",
        label: "Licença",
        value: windowsActivationStatus ? "Ativada" : "Não ativada",
        icon: windowsActivationStatus ? <ShieldCheck className="size-4 text-neutral-500" /> : <ShieldAlert className="size-4 text-amber-500" />,
        tone: windowsActivationStatus ? undefined : "warning",
      })
    }
    if (primaryLinkedUser?.email) {
      const collaboratorValue = primaryLinkedUser.name ? `${primaryLinkedUser.name} · ${primaryLinkedUser.email}` : primaryLinkedUser.email
      chips.push({
        key: "collaborator",
        label: personaLabel,
        value: collaboratorValue,
        icon: <ShieldCheck className="size-4 text-neutral-500" />,
      })
    }
    const primaryRemoteAccess = remoteAccessEntries[0]
    if (primaryRemoteAccess && (primaryRemoteAccess.identifier || primaryRemoteAccess.url)) {
      const value = primaryRemoteAccess.identifier ?? primaryRemoteAccess.url ?? "—"
      const label = primaryRemoteAccess.provider ? `Acesso (${primaryRemoteAccess.provider})` : "Acesso remoto"
      chips.push({
        key: "remote-access",
        label,
        value,
        icon: <Key className="size-4 text-neutral-500" />,
      })
    }
    const isWindowsDevice = (device?.osName ?? "").toLowerCase().includes("windows")
    if (isWindowsDevice) {
      const policyLabels: Record<string, string> = {
        ALLOW: "Permitido",
        BLOCK_ALL: "Bloqueado",
        READONLY: "Somente leitura",
      }
      const statusLabels: Record<string, string> = {
        PENDING: "Pendente",
        APPLYING: "Aplicando",
        APPLIED: "Aplicado",
        FAILED: "Falhou",
      }
      const statusBadgeVariants: Record<string, "default" | "success" | "warning" | "error"> = {
        PENDING: "warning",
        APPLYING: "warning",
        APPLIED: "success",
        FAILED: "error",
      }
      const currentPolicy = device?.usbPolicy ?? "ALLOW"
      const policyLabel = policyLabels[currentPolicy] ?? currentPolicy
      const isPending = device?.usbPolicyStatus === "PENDING"
      const isApplying = device?.usbPolicyStatus === "APPLYING"
      const isFailed = device?.usbPolicyStatus === "FAILED"
      const statusBadge = device?.usbPolicyStatus
        ? {
            text: statusLabels[device.usbPolicyStatus] ?? device.usbPolicyStatus,
            variant: statusBadgeVariants[device.usbPolicyStatus] ?? "default" as const,
          }
        : undefined
      chips.push({
        key: "usb-policy",
        label: "USB",
        value: policyLabel,
        icon: <Usb className={`size-4 ${isFailed ? "text-red-500" : isPending || isApplying ? "text-amber-500" : "text-neutral-500"}`} />,
        tone: isFailed ? "warning" : isPending || isApplying ? "warning" : undefined,
        statusBadge,
      })
    }
    return chips
  }, [
    osNameDisplay,
    device?.osVersion,
    device?.architecture,
    windowsVersionLabel,
    windowsActivationStatus,
    primaryLinkedUser?.email,
    primaryLinkedUser?.name,
    personaLabel,
    device?.osName,
    remoteAccessEntries,
    device?.usbPolicy,
    device?.usbPolicyStatus,
  ])

  const companyName = device?.companyName ?? device?.companySlug ?? null

  const [renaming, setRenaming] = useState(false)
  const [newName, setNewName] = useState<string>(device?.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>("")
  const [accessName, setAccessName] = useState<string>(primaryLinkedUser?.name ?? "")
  const [accessRole, setAccessRole] = useState<"collaborator" | "manager">(personaRole === "manager" ? "manager" : "collaborator")
  const [savingAccess, setSavingAccess] = useState(false)
  const [remoteAccessDialog, setRemoteAccessDialog] = useState(false)
  const [editingRemoteAccessClientId, setEditingRemoteAccessClientId] = useState<string | null>(null)
  const [remoteAccessProviderOption, setRemoteAccessProviderOption] = useState<RemoteAccessProviderValue>(
    REMOTE_ACCESS_PROVIDERS[0].value,
  )
  const [remoteAccessCustomProvider, setRemoteAccessCustomProvider] = useState("")
  const [remoteAccessIdentifierInput, setRemoteAccessIdentifierInput] = useState("")
  const [remoteAccessUsernameInput, setRemoteAccessUsernameInput] = useState("")
  const [remoteAccessPasswordInput, setRemoteAccessPasswordInput] = useState("")
  const [remoteAccessUrlInput, setRemoteAccessUrlInput] = useState("")
  const [remoteAccessNotesInput, setRemoteAccessNotesInput] = useState("")
  const [remoteAccessSaving, setRemoteAccessSaving] = useState(false)
  const [visibleRemoteSecrets, setVisibleRemoteSecrets] = useState<Record<string, boolean>>({})
  const editingRemoteAccess = useMemo(
    () => remoteAccessEntries.find((entry) => entry.clientId === editingRemoteAccessClientId) ?? null,
    [editingRemoteAccessClientId, remoteAccessEntries]
  )
  const [togglingActive, setTogglingActive] = useState(false)
  const [isResettingAgent, setIsResettingAgent] = useState(false)
  const [showAllWindowsSoftware, setShowAllWindowsSoftware] = useState(false)
  const [isUsbModalOpen, setIsUsbModalOpen] = useState(false)
  const jsonText = useMemo(() => {
    const payload = {
      id: device?.id,
      hostname: device?.hostname,
      status: device?.status,
      lastHeartbeatAt: device?.lastHeartbeatAt,
      metrics,
      inventory: metadata,
      postureAlerts: device?.postureAlerts ?? null,
      lastPostureAt: device?.lastPostureAt ?? null,
    }
    return JSON.stringify(payload, null, 2)
  }, [device, metrics, metadata])
  const handleDownloadInventoryJson = useCallback(() => {
    if (!device) return
    const baseName = device.displayName ?? device.hostname ?? "dispositivo"
    const safeHostname = baseName.replace(/[^a-z0-9_-]/gi, "-").replace(/-{2,}/g, "-").toLowerCase()
    const fileName = `${safeHostname || "device"}_${device.id}.json`
    const blob = new Blob([jsonText], { type: "application/json" })
    const url = URL.createObjectURL(blob)
    const link = document.createElement("a")
    link.href = url
    link.download = fileName
    document.body.appendChild(link)
    link.click()
    document.body.removeChild(link)
    URL.revokeObjectURL(url)
  }, [jsonText, device])

  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("")
  }, [device?.id])

  useEffect(() => {
    setAccessName(primaryLinkedUser?.name ?? "")
    setAccessRole(personaRole === "manager" ? "manager" : "collaborator")
  }, [device?.id, primaryLinkedUser?.name, personaRole])

  useEffect(() => {
    setIsActiveLocal(device?.isActive ?? true)
  }, [device?.isActive])

  useEffect(() => {
    if (!remoteAccessDialog) return
    const providerName = editingRemoteAccess?.provider ?? ""
    const matched = REMOTE_ACCESS_PROVIDERS.find(
      (option) => option.value !== "OTHER" && option.label.toLowerCase() === providerName.toLowerCase(),
    )
    if (matched) {
      setRemoteAccessProviderOption(matched.value)
      setRemoteAccessCustomProvider("")
    } else {
      setRemoteAccessProviderOption(providerName ? "OTHER" : REMOTE_ACCESS_PROVIDERS[0].value)
      setRemoteAccessCustomProvider(providerName ?? "")
    }
    setRemoteAccessIdentifierInput(editingRemoteAccess?.identifier ?? "")
    setRemoteAccessUsernameInput(editingRemoteAccess?.username ?? "")
    setRemoteAccessPasswordInput(editingRemoteAccess?.password ?? "")
    setRemoteAccessUrlInput(editingRemoteAccess?.url ?? "")
    setRemoteAccessNotesInput(editingRemoteAccess?.notes ?? "")
  }, [remoteAccessDialog, editingRemoteAccess])

  useEffect(() => {
    if (remoteAccessDialog) return
    if (!editingRemoteAccessClientId) {
      setRemoteAccessProviderOption(REMOTE_ACCESS_PROVIDERS[0].value)
      setRemoteAccessCustomProvider("")
      setRemoteAccessIdentifierInput("")
      setRemoteAccessUsernameInput("")
      setRemoteAccessPasswordInput("")
      setRemoteAccessUrlInput("")
      setRemoteAccessNotesInput("")
    }
  }, [editingRemoteAccessClientId, remoteAccessDialog])

  useEffect(() => {
    setShowAllWindowsSoftware(false)
    setVisibleRemoteSecrets({})
  }, [device?.id])

  const displayedWindowsSoftware = useMemo(
    () => (showAllWindowsSoftware ? normalizedWindowsSoftware : normalizedWindowsSoftware.slice(0, 12)),
    [showAllWindowsSoftware, normalizedWindowsSoftware]
  )

  const handleSaveAccess = async () => {
    if (!device) return
    if (!accessEmail.trim()) {
      toast.error("Informe o e-mail do colaborador ou gestor.")
      return
    }
    setSavingAccess(true)
    try {
      const response = await fetch("/api/admin/devices/access", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          machineId: device.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 o acesso do dispositivo.")
    } finally {
      setSavingAccess(false)
    }
  }

  const handleSaveRemoteAccess = useCallback(async () => {
    if (!device) return
    if (!canManageRemoteAccess) {
      toast.error("Você não tem permissão para ajustar o acesso remoto deste dispositivo.")
      return
    }

    const providerOption = REMOTE_ACCESS_PROVIDERS.find((option) => option.value === remoteAccessProviderOption)
    const providerName =
      remoteAccessProviderOption === "OTHER"
        ? remoteAccessCustomProvider.trim()
        : providerOption?.label ?? ""

    if (!providerName) {
      toast.error("Informe a ferramenta de acesso remoto.")
      return
    }

    const identifier = remoteAccessIdentifierInput.trim()
    if (!identifier) {
      toast.error("Informe o ID ou código do acesso remoto.")
      return
    }

    const username = remoteAccessUsernameInput.trim()
    const password = remoteAccessPasswordInput.trim()
    let normalizedUrl: string | undefined
    const rawUrl = remoteAccessUrlInput.trim()
    if (rawUrl.length > 0) {
      const candidate = /^https?:\/\//i.test(rawUrl) ? rawUrl : `https://${rawUrl}`
      try {
        new URL(candidate)
        normalizedUrl = candidate
      } catch {
        toast.error("Informe uma URL válida (ex: https://example.com).")
        return
      }
    }

    const notes = remoteAccessNotesInput.trim()

    toast.dismiss("remote-access")
    toast.loading("Salvando acesso remoto...", { id: "remote-access" })
    setRemoteAccessSaving(true)

    try {
      if (editingRemoteAccess && !editingRemoteAccess.id) {
        const cleanupPayload: Record<string, unknown> = {
          machineId: device.id,
          action: "delete",
        }
        if (editingRemoteAccess.provider) cleanupPayload.provider = editingRemoteAccess.provider
        if (editingRemoteAccess.identifier) cleanupPayload.identifier = editingRemoteAccess.identifier
        if (editingRemoteAccess.clientId) cleanupPayload.entryId = editingRemoteAccess.clientId
        await fetch("/api/admin/devices/remote-access", {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify(cleanupPayload),
        }).catch(() => null)
      }

      const response = await fetch("/api/admin/devices/remote-access", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          machineId: device.id,
          provider: providerName,
          identifier,
          username,
          password,
          url: normalizedUrl,
          notes: notes.length ? notes : undefined,
          action: "upsert",
          entryId: editingRemoteAccess?.id ?? undefined,
        }),
      })

      const responsePayload = await response.json().catch(() => null)
      if (!response.ok) {
        const message = typeof responsePayload?.error === "string" ? responsePayload.error : "Falha ao atualizar acesso remoto."
        const detailMessage = typeof responsePayload?.detail === "string" ? responsePayload.detail : null
        throw new Error(detailMessage ? `${message}. ${detailMessage}` : message)
      }

      toast.success("Acesso remoto atualizado.", { id: "remote-access" })
      setRemoteAccessDialog(false)
      setEditingRemoteAccessClientId(null)
    } catch (error) {
      const message = error instanceof Error ? error.message : "Falha ao atualizar acesso remoto."
      toast.error(message, { id: "remote-access" })
    } finally {
      setRemoteAccessSaving(false)
    }
  }, [
    device,
    canManageRemoteAccess,
    remoteAccessProviderOption,
    remoteAccessCustomProvider,
    remoteAccessIdentifierInput,
    remoteAccessUsernameInput,
    remoteAccessPasswordInput,
    remoteAccessUrlInput,
    remoteAccessNotesInput,
    editingRemoteAccess,
  ])

  const handleRemoveRemoteAccess = useCallback(async (entry: DeviceRemoteAccessEntry) => {
    if (!device) return
    if (!canManageRemoteAccess) {
      toast.error("Você não tem permissão para ajustar o acesso remoto deste dispositivo.")
      return
    }
    toast.dismiss("remote-access")
    toast.loading("Removendo acesso remoto...", { id: "remote-access" })
    setRemoteAccessSaving(true)
    try {
      const requestPayload: Record<string, unknown> = {
        machineId: device.id,
        action: "delete",
      }
      if (entry.id) {
        requestPayload.entryId = entry.id
      } else if (entry.clientId) {
        requestPayload.entryId = entry.clientId
      }
      if (entry.provider) {
        requestPayload.provider = entry.provider
      }
      if (entry.identifier) {
        requestPayload.identifier = entry.identifier
      }
      const response = await fetch("/api/admin/devices/remote-access", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify(requestPayload),
      })
      const responsePayload = await response.json().catch(() => null)
      if (!response.ok) {
        const message = typeof responsePayload?.error === "string" ? responsePayload.error : "Falha ao remover acesso remoto."
        const detailMessage = typeof responsePayload?.detail === "string" ? responsePayload.detail : null
        throw new Error(detailMessage ? `${message}. ${detailMessage}` : message)
      }
      toast.success("Acesso remoto removido.", { id: "remote-access" })
      setRemoteAccessDialog(false)
      setEditingRemoteAccessClientId(null)
    } catch (error) {
      const message = error instanceof Error ? error.message : "Falha ao remover acesso remoto."
      toast.error(message, { id: "remote-access" })
    } finally {
      setRemoteAccessSaving(false)
    }
  }, [device, canManageRemoteAccess])

  const handleToggleActive = async () => {
    if (!device) return
    const nextActive = !isActiveLocal
    setIsActiveLocal(nextActive)
    setTogglingActive(true)
    try {
      const response = await fetch("/api/admin/devices/toggle-active", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ machineId: device.id, active: nextActive }),
        credentials: "include",
      })
      if (!response.ok) {
        const payload = (await response.json().catch(() => ({}))) as { error?: string }
        throw new Error(payload?.error ?? "Falha ao atualizar status")
      }
      toast.success(nextActive ? "Dispositivo reativada" : "Dispositivo desativada")
    } catch (error) {
      console.error(error)
      setIsActiveLocal(!nextActive)
      toast.error("Não foi possível atualizar o status do dispositivo.")
    } finally {
      setTogglingActive(false)
    }
  }

  const handleResetAgent = useCallback(async () => {
    if (!device) return
    toast.dismiss("device-reset")
    toast.loading("Resetando agente...", { id: "device-reset" })
    setIsResettingAgent(true)
    try {
      const response = await fetch("/api/admin/devices/reset-agent", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        credentials: "include",
        body: JSON.stringify({ machineId: device.id }),
      })
      const payload = (await response.json().catch(() => null)) as { error?: string; revoked?: number } | null
      if (!response.ok) {
        const message = payload?.error ?? "Falha ao resetar agente."
        throw new Error(message)
      }
      const revokedLabel = typeof payload?.revoked === "number" && payload.revoked > 0 ? ` (${payload.revoked} token(s) revogados)` : ""
      toast.success(`Agente resetado${revokedLabel}. Reprovisione o agente no dispositivo.`, { id: "device-reset" })
      router.refresh()
    } catch (error) {
      const message = error instanceof Error ? error.message : "Falha ao resetar agente."
      toast.error(message, { id: "device-reset" })
    } finally {
      setIsResettingAgent(false)
    }
  }, [device, router])

  const handleCopyRemoteIdentifier = useCallback(async (identifier: string | null | undefined) => {
    if (!identifier) return
    try {
      await navigator.clipboard.writeText(identifier)
      toast.success("Identificador de acesso remoto copiado.")
    } catch (error) {
      console.error(error)
      toast.error("Não foi possível copiar o identificador.")
    }
  }, [])

  const handleCopyRemoteCredential = useCallback(async (value: string | null | undefined, label: string) => {
    if (!value) return
    try {
      await navigator.clipboard.writeText(value)
      toast.success(`${label} copiado.`)
    } catch (error) {
      console.error(error)
      toast.error(`Não foi possível copiar ${label.toLowerCase()}.`)
    }
  }, [])

  const toggleRemoteSecret = useCallback((clientId: string) => {
    setVisibleRemoteSecrets((prev) => ({ ...prev, [clientId]: !prev[clientId] }))
  }, [])

  const handleRustDeskConnect = useCallback((entry: DeviceRemoteAccessEntry) => {
    if (!entry) return
    const link = buildRustDeskUri(entry)
    if (!link) {
      toast.error("Não foi possível montar o link do RustDesk (ID ou senha ausentes).")
      return
    }
    if (typeof window === "undefined") {
      toast.error("A conexão direta só funciona no navegador.")
      return
    }
    try {
      // Alguns navegadores bloqueiam location.href para protocolos custom; use anchor + click como fallback.
      const anchor = document.createElement("a")
      anchor.href = link
      anchor.rel = "noreferrer"
      anchor.target = "_self"
      document.body.appendChild(anchor)
      anchor.click()
      document.body.removeChild(anchor)
      toast.success("Abrindo o RustDesk...")
    } catch (error) {
      console.error(error)
      try {
        window.open(link, "_blank", "noreferrer")
      } catch {}
      toast.error("Não foi possível acionar o RustDesk neste dispositivo.")
    }
  }, [])

  // Exportação individual (colunas personalizadas)
  const [isSingleExportOpen, setIsSingleExportOpen] = useState(false)
  const [singleExporting, setSingleExporting] = useState(false)
  const [singleExportError, setSingleExportError] = useState<string | null>(null)
  const [singleColumns, setSingleColumns] = useState<DeviceInventoryColumnConfig[]>([...DEFAULT_DEVICE_COLUMN_CONFIG])
  const { convexUserId } = useAuth()
  const deviceFieldDefs = useQuery(
    api.deviceFields.listForTenant,
    convexUserId && device
      ? { tenantId: device.tenantId, viewerId: convexUserId as Id<"users">, scope: (device.deviceType ?? "all") as string }
      : "skip"
  ) as Array<{ id: string; key: string; label: string; type?: string; options?: Array<{ value: string; label: string }>; required?: boolean }> | undefined

  const baseColumnOptionsSingle = useMemo(
    () => DEVICE_INVENTORY_COLUMN_METADATA.map((meta) => ({ key: meta.key, label: meta.label })),
    []
  )
  const customColumnOptionsSingle = useMemo(() => {
    const map = new Map<string, { key: string; label: string }>()
    ;(deviceFieldDefs ?? []).forEach((field) => map.set(field.key, { key: field.key, label: field.label }))
    ;(device?.customFields ?? []).forEach((field) => {
      if (!map.has(field.fieldKey)) map.set(field.fieldKey, { key: field.fieldKey, label: field.label })
    })
    return Array.from(map.values())
      .map((f) => ({ key: `custom:${f.key}`, label: f.label }))
      .sort((a, b) => a.label.localeCompare(b.label, "pt-BR"))
  }, [deviceFieldDefs, device?.customFields])

  const singleCustomOrder = useMemo(() => customColumnOptionsSingle.map((c) => c.key), [customColumnOptionsSingle])

  useEffect(() => {
    setSingleColumns((prev) => orderColumnConfig(prev, singleCustomOrder))
  }, [singleCustomOrder])

  const toggleSingleColumn = useCallback((key: string, checked: boolean, label?: string) => {
    setSingleColumns((prev) => {
      const filtered = prev.filter((col) => col.key !== key)
      if (checked) return orderColumnConfig([...filtered, { key, label }], singleCustomOrder)
      return filtered
    })
  }, [singleCustomOrder])

  const resetSingleColumns = useCallback(() => {
    setSingleColumns(orderColumnConfig([...DEFAULT_DEVICE_COLUMN_CONFIG], singleCustomOrder))
  }, [singleCustomOrder])

  const selectAllSingleColumns = useCallback(() => {
    const all: DeviceInventoryColumnConfig[] = [
      ...baseColumnOptionsSingle.map((c) => ({ key: c.key })),
      ...customColumnOptionsSingle.map((c) => ({ key: c.key, label: c.label })),
    ]
    setSingleColumns(orderColumnConfig(all, singleCustomOrder))
  }, [baseColumnOptionsSingle, customColumnOptionsSingle, singleCustomOrder])

  const handleExportSingle = useCallback(async () => {
    if (!device) return
    const normalized = orderColumnConfig(singleColumns, singleCustomOrder)
    if (normalized.length === 0) {
      toast.info("Selecione ao menos uma coluna para exportar.")
      return
    }
    setSingleExporting(true)
    setSingleExportError(null)
    try {
      const params = new URLSearchParams()
      params.append("machineId", device.id)
      params.set("columns", JSON.stringify(normalized))
      const url = `/api/reports/machines-inventory.xlsx?${params.toString()}`
      const response = await fetch(url)
      if (!response.ok) throw new Error(`HTTP ${response.status}`)
      const disposition = response.headers.get("Content-Disposition")
      const filenameMatch = disposition?.match(/filename="?([^";]+)"?/i)
      const filename = filenameMatch?.[1] ?? `machine-inventory-${device.hostname}.xlsx`
      const blob = await response.blob()
      const downloadUrl = window.URL.createObjectURL(blob)
      const a = document.createElement("a")
      a.href = downloadUrl
      a.download = filename
      document.body.appendChild(a)
      a.click()
      a.remove()
      window.URL.revokeObjectURL(downloadUrl)
      setIsSingleExportOpen(false)
    } catch (err) {
      console.error("Falha na exportação individual", err)
      setSingleExportError("Não foi possível gerar a planilha. Tente novamente.")
    } finally {
      setSingleExporting(false)
    }
  }, [device, singleColumns, singleCustomOrder])

  // Editor de campos personalizados
  const [customFieldsEditorOpen, setCustomFieldsEditorOpen] = useState(false)
  const [customFieldValues, setCustomFieldValues] = useState<Record<string, unknown>>({})
  const saveCustomFields = useMutation(api.devices.saveDeviceCustomFields)
  const createDeviceField = useMutation(api.deviceFields.create)

  useEffect(() => {
    const current: Record<string, unknown> = {}
    ;(device?.customFields ?? []).forEach((f) => {
      current[String((f as { fieldId?: string }).fieldId ?? f.fieldKey)] = f.value ?? f.displayValue ?? null
    })
    setCustomFieldValues(current)
  }, [device?.customFields])

  const editableFields = useMemo(
    () => (deviceFieldDefs ?? []).map((f) => ({ id: f.id, key: f.key, label: f.label, type: f.type ?? "text", options: f.options ?? [] })),
    [deviceFieldDefs]
  )

  const displayCustomFields = useMemo(() => {
    const definitions = deviceFieldDefs ?? []
    const values = device?.customFields ?? []
    const result: Array<{ key: string; label: string; value: string }> = []
    const valueMap = new Map<string, (typeof values)[number]>()

    values.forEach((field) => {
      if (field.fieldId) {
        valueMap.set(String(field.fieldId), field)
      }
      if (field.fieldKey) {
        valueMap.set(field.fieldKey, field)
      }
    })

    const used = new Set<string>()
    definitions.forEach((definition) => {
      const idKey = String(definition.id)
      const valueEntry = valueMap.get(idKey) ?? valueMap.get(definition.key)
      used.add(idKey)
      result.push({
        key: idKey,
        label: definition.label,
        value: formatDeviceCustomFieldDisplay(valueEntry),
      })
    })

    values.forEach((field) => {
      const idKey = field.fieldId ? String(field.fieldId) : undefined
      const keyKey = field.fieldKey ?? field.label
      const compositeKey = idKey ?? keyKey
      if (!compositeKey || used.has(compositeKey)) return
      used.add(compositeKey)
      result.push({
        key: compositeKey,
        label: field.label,
        value: formatDeviceCustomFieldDisplay(field),
      })
    })

    return result
  }, [deviceFieldDefs, device?.customFields])

  const handleSaveCustomFields = useCallback(async () => {
    if (!device || !convexUserId) return
    try {
      const fields = editableFields
        .map((def) => {
          const value = customFieldValues[def.id] ?? customFieldValues[def.key]
          return { fieldId: def.id as Id<"deviceFields">, value }
        })
        .filter((entry) => entry.value !== undefined) as Array<{ fieldId: Id<"deviceFields">; value: unknown }>
      await saveCustomFields({ tenantId: device.tenantId, actorId: convexUserId as Id<"users">, machineId: device.id as Id<"machines">, fields })
      toast.success("Campos salvos com sucesso.")
      try {
        router.refresh()
      } catch {
        // ignore refresh errors (e.g., when not in a routed context)
      }
      setCustomFieldsEditorOpen(false)
    } catch (error) {
      console.error(error)
      toast.error("Não foi possível salvar os campos.")
    }
  }, [device, convexUserId, editableFields, customFieldValues, saveCustomFields, router])

  const [newFieldOpen, setNewFieldOpen] = useState(false)
  const [newFieldLabel, setNewFieldLabel] = useState("")
  const [newFieldType, setNewFieldType] = useState<string>("text")
  const [newFieldOptions, setNewFieldOptions] = useState<Array<{ label: string; value: string }>>([])

  const handleCreateNewField = useCallback(async () => {
    if (!device || !convexUserId) return
    const label = newFieldLabel.trim()
    if (label.length < 2) {
      toast.error("Informe o rótulo do campo")
      return
    }
    try {
      await createDeviceField({
        tenantId: device.tenantId,
        actorId: convexUserId as Id<"users">,
        label,
        type: newFieldType,
        required: false,
        options: (newFieldType === "select" || newFieldType === "multiselect") ? newFieldOptions : undefined,
        scope: (device.deviceType ?? "all") as string,
        companyId: device.companyId ? (device.companyId as Id<"companies">) : undefined,
      })
      toast.success("Campo criado")
      setNewFieldLabel("")
      setNewFieldOptions([])
      setNewFieldOpen(false)
    } catch (error) {
      console.error(error)
      toast.error("Não foi possível criar o campo")
    }
  }, [device, convexUserId, newFieldLabel, newFieldType, newFieldOptions, createDeviceField])

  return (
    <Card className="border-slate-200">
      <CardHeader className="gap-1">
        {device ? (
          <>
            <CardTitle className="flex items-center gap-2">
              <span className="break-words text-2xl font-semibold text-neutral-900">
                {device.displayName ?? device.hostname ?? "Dispositivo"}
              </span>
              {isManualMobile ? (
                <span className="rounded-full border border-slate-200 bg-slate-50 px-2 py-0.5 text-xs font-semibold uppercase tracking-wide text-neutral-600">
                  Identificação interna
                </span>
              ) : null}
              <Button
                size="icon"
                variant="ghost"
                className="size-7"
                onClick={() => {
                  setNewName(device.displayName ?? device.hostname ?? "")
                  setRenaming(true)
                }}
              >
                <Pencil className="size-4" />
                <span className="sr-only">Renomear dispositivo</span>
              </Button>
            </CardTitle>
            <CardAction>
              <div className="flex flex-wrap items-center justify-end gap-2 text-xs sm:text-sm">
                {companyName ? (
                  <div className="max-w-[200px] truncate rounded-lg border border-slate-200 bg-white px-3 py-1 font-semibold text-neutral-600 shadow-sm" title={companyName}>
                    {companyName}
                  </div>
                ) : null}
                {!isDeactivated ? <DeviceStatusBadge status={effectiveStatus} /> : null}
                {!isActiveLocal ? (
                  <Badge variant="outline" className="h-7 border-rose-200 bg-rose-50 px-3 font-semibold uppercase text-rose-700">
                    Dispositivo desativado
                  </Badge>
                ) : null}
              </div>
            </CardAction>
          </>
        ) : (
          <CardTitle>Detalhes</CardTitle>
        )}
      </CardHeader>
      <CardContent className="space-y-6">
        {!device ? (
          <p className="text-sm text-muted-foreground">Selecione um dispositivo para visualizar detalhes.</p>
        ) : (
          <div className="space-y-6">
            <section className="space-y-3">
              <div className="grid gap-3 sm:grid-cols-2 xl:grid-cols-3">
                {summaryChips.map((chip) => (
                  <InfoChip
                    key={chip.key}
                    label={chip.label}
                    value={chip.value}
                    icon={chip.icon}
                    tone={chip.tone}
                    statusBadge={chip.statusBadge}
                  />
                ))}
              </div>

              {/* Modal de Controle USB */}
              <Dialog open={isUsbModalOpen} onOpenChange={setIsUsbModalOpen}>
                <DialogContent className="max-w-xl">
                  <DialogClose className="absolute right-4 top-4 p-1.5 rounded-md text-muted-foreground transition-colors hover:bg-accent hover:text-accent-foreground focus:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2">
                    <X className="size-4" />
                    <span className="sr-only">Fechar</span>
                  </DialogClose>
                  <DialogHeader className="pb-4">
                    <DialogTitle className="flex items-center gap-2">
                      <Usb className="size-5" />
                      Controle de USB - {device.displayName ?? device.hostname}
                    </DialogTitle>
                    <DialogDescription>
                      Gerencie as políticas de acesso a dispositivos USB de armazenamento
                    </DialogDescription>
                  </DialogHeader>
                  <UsbPolicyControl
                    machineId={device.id}
                    machineName={device.displayName ?? device.hostname}
                    actorEmail={primaryLinkedUser?.email}
                    actorName={primaryLinkedUser?.name}
                    disabled={isDeactivated}
                    variant="inline"
                  />
                </DialogContent>
              </Dialog>

              <div className="rounded-2xl border border-slate-200 bg-white/80 px-4 py-4 shadow-sm">
                <div className="flex flex-wrap items-center justify-between gap-3">
                  <p className="text-xs font-semibold uppercase tracking-wide text-slate-500">Atalhos</p>
                  <span className="text-xs font-medium text-slate-500">
                    {device.registeredBy === "desktop-agent" ? (
                      <span className="text-slate-800">Agente na máquina</span>
                    ) : (
                      <span className="text-slate-800">Manual</span>
                    )}
                  </span>
                </div>
                <div className="mt-3 flex flex-wrap gap-2">
                  {deviceTicketsHref ? (
                    <Button size="sm" variant="outline" className="gap-2 border-dashed" asChild>
                      <Link href={deviceTicketsHref}>
                        <TicketCheck className="size-4" />
                        Tickets
                        {totalOpenTickets > 0 ? (
                          <Badge variant="secondary" className="ml-1 rounded-full px-2 py-0 text-[10px] font-semibold">
                            {totalOpenTickets}
                          </Badge>
                        ) : null}
                      </Link>
                    </Button>
                  ) : null}
                  <Button size="sm" variant="outline" className="gap-2 border-dashed" onClick={() => { setAccessDialog(true) }}>
                    <ShieldCheck className="size-4" />
                    Acesso
                  </Button>
                  {!isManualMobile ? (
                    <>
                      <Button
                        size="sm"
                        variant="outline"
                        className="gap-2 border-dashed"
                        onClick={handleResetAgent}
                        disabled={isResettingAgent}
                      >
                        <RefreshCcw className={cn("size-4", isResettingAgent && "animate-spin")} />
                        {isResettingAgent ? "Resetando..." : "Resetar"}
                      </Button>
                      <Button
                        size="sm"
                        variant={isActiveLocal ? "outline" : "default"}
                        className={cn(
                          "gap-2 border-dashed",
                          !isActiveLocal && "bg-emerald-600 text-white hover:bg-emerald-600/90"
                        )}
                        onClick={handleToggleActive}
                        disabled={togglingActive}
                      >
                        {isActiveLocal ? <Power className="size-4" /> : <PlayCircle className="size-4" />}
                        {isActiveLocal ? (togglingActive ? "Desativando..." : "Desativar") : togglingActive ? "Reativando..." : "Reativar"}
                      </Button>
                    </>
                  ) : null}
                  {canManageRemoteAccess && (device?.osName ?? "").toLowerCase().includes("windows") && (
                    <Button
                      size="sm"
                      variant="outline"
                      className="gap-2 border-dashed"
                      onClick={() => setIsUsbModalOpen(true)}
                      disabled={isDeactivated}
                    >
                      <Usb className="size-4" />
                      Controle USB
                    </Button>
                  )}
                </div>
              </div>

              {/* Acesso remoto */}
              <div className="space-y-3 border-t border-slate-100 pt-5">
                <div className="flex flex-wrap items-center justify-between gap-2">
                  <div className="flex flex-wrap items-center gap-2">
                    <h4 className="text-sm font-semibold">Acesso remoto</h4>
                    {hasRemoteAccess ? (
                      <Badge variant="outline" className="rounded-full px-2.5 py-0.5 text-[11px] font-semibold">
                        {remoteAccessEntries.length === 1 ? "1 acesso" : `${remoteAccessEntries.length} acessos`}
                      </Badge>
                    ) : null}
                  </div>
                  {canManageRemoteAccess ? (
                    <Button
                      size="sm"
                      variant="outline"
                      className="gap-2 border-dashed"
                      onClick={() => {
                        setEditingRemoteAccessClientId(null)
                        setRemoteAccessDialog(true)
                      }}
                    >
                      <Key className="size-4" />
                      {hasRemoteAccess ? "Adicionar acesso" : "Cadastrar acesso"}
                    </Button>
                  ) : null}
                </div>
                {hasRemoteAccess ? (
                  <div className="space-y-3">
                    {remoteAccessEntries.map((entry) => {
                      const lastVerifiedDate =
                        entry.lastVerifiedAt && Number.isFinite(entry.lastVerifiedAt)
                          ? new Date(entry.lastVerifiedAt)
                          : null
                      const isRustDesk = isRustDeskAccess(entry)
                      const secretVisible = Boolean(visibleRemoteSecrets[entry.clientId])
                      return (
                        <div key={entry.clientId} className="rounded-lg border border-slate-200 bg-slate-50 px-4 py-3 text-xs sm:text-sm text-slate-700">
                          <div className="flex flex-col gap-3 sm:flex-row sm:items-start sm:justify-between">
                            <div className="space-y-2">
                              <div className="flex flex-wrap items-center gap-2">
                                <span className="text-xs font-semibold uppercase tracking-wide text-slate-500">ID</span>
                                {entry.identifier ? (
                                  <code className="rounded-md border border-slate-200 bg-white px-2.5 py-1 font-mono text-sm font-semibold text-neutral-800">
                                    {entry.identifier}
                                  </code>
                                ) : null}
                                {entry.identifier ? (
                                  <Button
                                    variant="ghost"
                                    size="sm"
                                    className="h-7 border border-transparent px-2 text-slate-600 transition-colors hover:border-slate-300 hover:bg-slate-100 hover:text-slate-900"
                                    onClick={() => handleCopyRemoteIdentifier(entry.identifier)}
                                    aria-label="Copiar ID"
                                  >
                                    <ClipboardCopy className="size-3.5" />
                                  </Button>
                                ) : null}
                              </div>
                              {entry.username || entry.password ? (
                                <div className="flex flex-col gap-1">
                                  {entry.username ? (
                                    <div className="inline-flex flex-wrap items-center gap-2">
                                      <span className="text-[11px] font-semibold uppercase tracking-wide text-slate-500">Usuário</span>
                                      <code className="rounded-md border border-slate-200 bg-white px-2 py-0.5 font-mono text-xs text-slate-700">
                                        {entry.username}
                                      </code>
                                      <Button
                                        variant="ghost"
                                        size="sm"
                                        className="h-7 border border-transparent px-2 text-slate-600 hover:border-slate-300 hover:bg-slate-100 hover:text-slate-900"
                                        onClick={() => handleCopyRemoteCredential(entry.username, "Usuário do acesso remoto")}
                                        aria-label="Copiar usuário"
                                      >
                                        <ClipboardCopy className="size-3.5" />
                                      </Button>
                                    </div>
                                  ) : null}
                                  {entry.password ? (
                                    <div className="inline-flex flex-wrap items-center gap-2">
                                      <span className="text-xs font-semibold uppercase tracking-wide text-slate-500">Senha</span>
                                      <code className="rounded-md border border-slate-200 bg-white px-2.5 py-1 font-mono text-sm font-semibold text-neutral-800">
                                        {secretVisible ? entry.password : "••••••••"}
                                      </code>
                                      <Button
                                        variant="ghost"
                                        size="sm"
                                        className="h-7 border border-transparent px-2 text-slate-600 hover:border-slate-300 hover:bg-slate-100 hover:text-slate-900"
                                        onClick={() => toggleRemoteSecret(entry.clientId)}
                                        aria-label={secretVisible ? "Ocultar senha" : "Mostrar senha"}
                                      >
                                        {secretVisible ? <EyeOff className="size-3.5" /> : <Eye className="size-3.5" />}
                                      </Button>
                                      <Button
                                        variant="ghost"
                                        size="sm"
                                        className="h-7 border border-transparent px-2 text-slate-600 hover:border-slate-300 hover:bg-slate-100 hover:text-slate-900"
                                        onClick={() => handleCopyRemoteCredential(entry.password, "Senha do acesso remoto")}
                                        aria-label="Copiar senha"
                                      >
                                        <ClipboardCopy className="size-3.5" />
                                      </Button>
                                    </div>
                                  ) : null}
                                </div>
                              ) : null}
                              {entry.url && !isRustDesk ? (
                                <a
                                  href={entry.url}
                                  target="_blank"
                                  rel="noreferrer"
                                  className="inline-flex items-center gap-2 text-slate-600 underline-offset-4 hover:text-slate-900 hover:underline"
                                >
                                  Abrir console remoto
                                </a>
                              ) : null}
                            </div>
                            <div className="flex flex-col items-end gap-1 text-right">
                              {entry.notes ? (
                                <p className="whitespace-pre-wrap text-xs text-slate-600">{entry.notes}</p>
                              ) : null}
                              {lastVerifiedDate ? (
                                <p className="text-xs text-slate-500">
                                  Atualizado {formatRelativeTime(lastVerifiedDate)}{" "}
                                  <span className="text-slate-400">({formatAbsoluteDateTime(lastVerifiedDate)})</span>
                                </p>
                              ) : null}
                            </div>
                          </div>
                          <div className="flex flex-wrap items-center justify-between gap-2 border-t border-slate-200 pt-3 mt-3">
                            <div>
                              {isRustDesk && (entry.identifier || entry.password) ? (
                                <Button
                                  variant="outline"
                                  size="sm"
                                  className="inline-flex items-center gap-2 border-slate-300 bg-white text-slate-800 shadow-sm transition-colors hover:border-slate-400 hover:bg-slate-50 hover:text-slate-900 focus-visible:border-slate-400 focus-visible:ring-slate-200"
                                  onClick={() => handleRustDeskConnect(entry)}
                                >
                                  <MonitorSmartphone className="size-4 text-[#4b5563]" /> Conectar via RustDesk
                                </Button>
                              ) : null}
                            </div>
                            <div className="flex items-center gap-2">
                              {entry.provider ? (
                                <Button variant="outline" size="sm" className="gap-2 border-slate-300 cursor-default hover:bg-white">
                                  {entry.provider}
                                </Button>
                              ) : null}
                              {canManageRemoteAccess ? (
                                <>
                                  <Button
                                    size="sm"
                                    variant="outline"
                                    className="gap-2 border-slate-300"
                                    onClick={() => {
                                      setEditingRemoteAccessClientId(entry.clientId)
                                      setRemoteAccessDialog(true)
                                    }}
                                  >
                                    <Pencil className="size-3.5" /> Editar
                                  </Button>
                                  <Button
                                    size="sm"
                                    variant="ghost"
                                    className="gap-2 text-rose-600 hover:border-rose-200 hover:bg-rose-50 hover:text-rose-700"
                                    onClick={() => void handleRemoveRemoteAccess(entry)}
                                    disabled={remoteAccessSaving}
                                  >
                                    <ShieldOff className="size-3.5" /> Remover
                                  </Button>
                                </>
                              ) : null}
                            </div>
                          </div>
                        </div>
                      )
                    })}
                  </div>
                ) : (
                  <div className="rounded-lg border border-dashed border-slate-200 bg-slate-50 px-4 py-3 text-xs sm:text-sm text-slate-600">
                    Nenhum identificador de acesso remoto cadastrado. Registre o ID do TeamViewer, AnyDesk ou outra ferramenta para agilizar o suporte.
                  </div>
                )}
              </div>

              {/* Campos personalizados */}
              <div className="space-y-3 border-t border-slate-100 pt-5">
                <div className="flex flex-wrap items-start justify-between gap-3">
                  <div className="flex flex-col gap-1">
                    <div className="flex items-center gap-2">
                      <h4 className="text-sm font-semibold text-neutral-900">Campos personalizados</h4>
                      <Badge variant="outline" className="rounded-full px-2.5 py-0.5 text-[11px] font-semibold">
                        {displayCustomFields.length}
                      </Badge>
                    </div>
                    {displayCustomFields.length === 0 ? (
                      <p className="text-xs text-neutral-500">Nenhum campo personalizado definido para este dispositivo.</p>
                    ) : null}
                  </div>
                  <div className="flex items-center gap-2">
                    <Button size="sm" variant="outline" className="gap-2" onClick={() => setCustomFieldsEditorOpen(true)}>
                      <Pencil className="size-4" />
                      Editar
                    </Button>
                    {canManageFieldCatalog && device ? (
                      <DeviceCustomFieldManager
                        tenantId={device.tenantId}
                        defaultScope={device.deviceType ?? "all"}
                        defaultCompanyId={device.companyId ?? null}
                      />
                    ) : null}
                  </div>
                </div>
                {displayCustomFields.length > 0 ? (
                  <div className="grid gap-2 sm:grid-cols-2">
                    {displayCustomFields.map((field) => (
                      <div key={field.key} className="rounded-lg border border-slate-200 bg-white p-3 text-sm">
                        <p className="text-xs font-semibold uppercase tracking-wide text-neutral-500">{field.label}</p>
                        <p className="mt-1 text-neutral-800">{field.value}</p>
                      </div>
                    ))}
                  </div>
                ) : null}
              </div>
            </section>

            <section className="space-y-3 border-t border-slate-100 pt-6">
              <h4 className="text-sm font-semibold">Usuários vinculados</h4>
              <div className="space-y-2">
                {primaryLinkedUser?.email ? (
                  <div className="flex flex-wrap items-center gap-2 rounded-md border border-slate-200 bg-slate-50/80 px-3 py-2 text-sm">
                    <ShieldCheck className="size-4 text-slate-500" />
                    <span className="font-medium text-neutral-800">{primaryLinkedUser.name || primaryLinkedUser.email}</span>
                    <span className="text-neutral-500">{primaryLinkedUser.name ? `· ${primaryLinkedUser.email}` : ""}</span>
                    <span className="ml-2 rounded-full border border-slate-200 bg-white px-2 py-0.5 text-[10px] font-semibold uppercase tracking-wide text-slate-600">Principal</span>
                  </div>
                ) : null}
                {Array.isArray(device.linkedUsers) && device.linkedUsers.length > 0 ? (
                  <ul className="divide-y divide-slate-200 overflow-hidden rounded-md border border-slate-200 bg-slate-50/60">
                    {device.linkedUsers.map((u) => (
                      <li key={`lu-${u.id}`} className="flex items-center gap-2 px-3 py-2 text-sm">
                        <span className="font-medium text-neutral-800">{u.name || u.email}</span>
                        <span className="text-neutral-500">{u.name ? `· ${u.email}` : ''}</span>
                        <div className="ml-auto flex items-center gap-2">
                          <Button
                            variant="outline"
                            size="sm"
                            className="border-rose-200 text-rose-600 hover:bg-rose-50 hover:text-rose-700"
                            onClick={async () => {
                              try {
                                const res = await fetch(`/api/admin/devices/links?machineId=${device.id}&userId=${u.id}`, { method: 'DELETE', credentials: 'include' })
                                if (!res.ok) throw new Error('HTTP ' + res.status)
                                toast.success('Vínculo removido')
                              } catch (e) {
                                console.error(e)
                                toast.error('Falha ao remover vínculo')
                              }
                            }}
                          >
                            Remover
                          </Button>
                        </div>
                      </li>
                    ))}
                  </ul>
                ) : null}
                {!primaryLinkedUser?.email && (!device.linkedUsers || device.linkedUsers.length === 0) ? (
                  <p className="text-xs text-neutral-500">Nenhum usuário vinculado.</p>
                ) : null}
                <div className="mt-2 flex flex-wrap items-center gap-2">
                  <Input
                    value={accessEmail}
                    onChange={(e) => setAccessEmail(e.target.value)}
                    placeholder="e-mail do usuário para vincular"
                    className="max-w-xs"
                    type="email"
                  />
                  <Button
                    variant="outline"
                    onClick={async () => {
                      if (!accessEmail.trim()) {
                        toast.error('Informe um e-mail para vincular')
                        return
                      }
                      try {
                        const res = await fetch('/api/admin/devices/links', {
                          method: 'POST',
                          headers: { 'Content-Type': 'application/json' },
                          credentials: 'include',
                          body: JSON.stringify({ machineId: device.id, email: accessEmail.trim() }),
                        })
                        if (!res.ok) throw new Error('HTTP ' + res.status)
                        toast.success('Usuário vinculado')
                        setAccessEmail('')
                      } catch (e) {
                        console.error(e)
                        toast.error('Falha ao vincular usuário')
                      }
                    }}
                  >
                    Adicionar vínculo
                  </Button>
                  <span className="text-xs text-neutral-500">Somente colaboradores/gestores.</span>
                  <Link href="/admin/users" className="text-xs underline underline-offset-4">Gerenciar usuários</Link>
                </div>
              </div>
            </section>

{/* Renomear dispositivo */}
            <Dialog open={renaming} onOpenChange={setRenaming}>
              <DialogContent>
                <DialogHeader>
                  <DialogTitle>Renomear dispositivo</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 (!device) return
                        const name = (newName ?? "").trim()
                        if (name.length < 2) {
                          toast.error("Informe um nome válido")
                          return
                        }
                        try {
                          const res = await fetch("/api/admin/devices/rename", {
                            method: "POST",
                            headers: { "Content-Type": "application/json" },
                            body: JSON.stringify({ machineId: device.id, hostname: name }),
                          })
                          if (!res.ok) throw new Error(`HTTP ${res.status}`)
                          toast.success("Dispositivo renomeada")
                          setRenaming(false)
                        } catch (err) {
                          console.error(err)
                          toast.error("Falha ao renomear dispositivo")
                        }
                      }}
                    >
                      Salvar
                    </Button>
                  </div>
                </div>
              </DialogContent>
            </Dialog>

            <Dialog open={accessDialog} onOpenChange={setAccessDialog}>
              <DialogContent>
                <DialogHeader>
                  <DialogTitle>Ajustar acesso do dispositivo</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>

            <Dialog
              open={remoteAccessDialog}
              onOpenChange={(open) => {
                setRemoteAccessDialog(open)
                if (!open) {
                  setRemoteAccessSaving(false)
                  setEditingRemoteAccessClientId(null)
                }
              }}
            >
              <DialogContent className="max-w-lg">
                <DialogHeader>
                  <DialogTitle>{editingRemoteAccess ? "Editar acesso remoto" : "Adicionar acesso remoto"}</DialogTitle>
                  <DialogDescription>
                    Registre os detalhes do acesso remoto utilizado por este dispositivo.
                  </DialogDescription>
                </DialogHeader>
                <form
                  onSubmit={(event) => {
                    event.preventDefault()
                    void handleSaveRemoteAccess()
                  }}
                  className="space-y-4"
                >
                  <div className="grid gap-2">
                    <label className="text-sm font-medium">Ferramenta</label>
                    <Select
                      value={remoteAccessProviderOption}
                      onValueChange={(value) => setRemoteAccessProviderOption(value as RemoteAccessProviderValue)}
                    >
                      <SelectTrigger>
                        <SelectValue placeholder="Selecione o provedor" />
                      </SelectTrigger>
                      <SelectContent>
                        {REMOTE_ACCESS_PROVIDERS.map((option) => (
                          <SelectItem key={option.value} value={option.value}>
                            {option.label}
                          </SelectItem>
                        ))}
                      </SelectContent>
                    </Select>
                  </div>
                  {remoteAccessProviderOption === "OTHER" ? (
                    <div className="grid gap-2">
                      <label className="text-sm font-medium">Nome da ferramenta</label>
                      <Input
                        value={remoteAccessCustomProvider}
                        onChange={(event) => setRemoteAccessCustomProvider(event.target.value)}
                        placeholder="Ex: Supremo, Zoho Assist..."
                        autoFocus
                      />
                    </div>
                  ) : null}
                  <div className="grid gap-2">
                    <label className="text-sm font-medium">ID / código</label>
                    <Input
                      value={remoteAccessIdentifierInput}
                      onChange={(event) => setRemoteAccessIdentifierInput(event.target.value)}
                      placeholder="Ex: 123 456 789"
                      required
                    />
                  </div>
                  <div className="grid gap-2">
                    <label className="text-sm font-medium">Usuário (opcional)</label>
                    <Input
                      value={remoteAccessUsernameInput}
                      onChange={(event) => setRemoteAccessUsernameInput(event.target.value)}
                      placeholder="Ex: suporte@cliente.com"
                      autoComplete="username"
                    />
                  </div>
                  <div className="grid gap-2">
                    <label className="text-sm font-medium">Senha / PIN (opcional)</label>
                    <Input
                      type="password"
                      value={remoteAccessPasswordInput}
                      onChange={(event) => setRemoteAccessPasswordInput(event.target.value)}
                      placeholder="Senha permanente do RustDesk ou PIN"
                      autoComplete="current-password"
                    />
                    <p className="text-xs text-muted-foreground">
                      Esse valor ficará disponível para os administradores do painel. Limpe o campo para remover a senha salva.
                    </p>
                  </div>
                  <div className="grid gap-2">
                    <label className="text-sm font-medium">Link (opcional)</label>
                    <Input
                      value={remoteAccessUrlInput}
                      onChange={(event) => setRemoteAccessUrlInput(event.target.value)}
                      placeholder="https://"
                    />
                  </div>
                  <div className="grid gap-2">
                    <label className="text-sm font-medium">Observações</label>
                    <Textarea
                      value={remoteAccessNotesInput}
                      onChange={(event) => setRemoteAccessNotesInput(event.target.value)}
                      rows={3}
                      placeholder="Credencial compartilhada, PIN adicional, instruções..."
                    />
                  </div>
                  <DialogFooter className="flex flex-wrap items-center justify-between gap-2">
                    {editingRemoteAccess ? (
                      <Button
                        type="button"
                        variant="outline"
                        className="border-rose-200 text-rose-600 hover:bg-rose-50 hover:text-rose-700"
                        onClick={() => editingRemoteAccess && void handleRemoveRemoteAccess(editingRemoteAccess)}
                        disabled={remoteAccessSaving}
                      >
                        Remover acesso
                      </Button>
                    ) : (
                      <span />
                    )}
                    <div className="flex items-center gap-2">
                      <Button
                        type="button"
                        variant="ghost"
                        onClick={() => setRemoteAccessDialog(false)}
                        disabled={remoteAccessSaving}
                      >
                        Cancelar
                      </Button>
                      <Button type="submit" disabled={remoteAccessSaving}>
                        {remoteAccessSaving ? "Salvando..." : editingRemoteAccess ? "Atualizar" : "Salvar"}
                      </Button>
                    </div>
                  </DialogFooter>
                </form>
              </DialogContent>
            </Dialog>

            {!isManualMobile ? (
              <section className="space-y-3 border-t border-slate-100 pt-6">
                <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(device.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(device.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">{device.token?.usageCount ?? 0} trocas</span>
                  </div>
                </div>
              </section>
            ) : null}

            {!isManualMobile ? (
              <section className="space-y-3 border-t border-slate-100 pt-6">
                <div className="flex flex-wrap items-center gap-2">
                  <h4 className="text-sm font-semibold">Métricas recentes</h4>
                  {lastUpdateRelative ? (
                    <span className="text-xs font-medium text-muted-foreground">
                      Última atualização {lastUpdateRelative}
                    </span>
                  ) : null}
                </div>
                <MetricsGrid metrics={metrics} hardware={hardware} disks={disks} />
              </section>
            ) : null}

            {!isManualMobile && (hardware || network || (labels && labels.length > 0)) ? (
              <section className="space-y-4 border-t border-slate-100 pt-6">
                <div>
                  <h4 className="text-sm font-semibold">Inventário</h4>
                  <p className="text-xs text-muted-foreground">
                    Informações coletadas automaticamente do dispositivo.
                  </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)} VRAM</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(", ")
                              : device?.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-3 border-t border-slate-100 pt-6">
                <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-4 border-t border-slate-100 pt-6">
                <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-4">
                    {/* Cards resumidos: CPU / RAM / GPU / Discos */}
                    <div className="grid gap-3 sm:grid-cols-2 xl:grid-cols-5">
                      <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">
                          <Terminal className="size-5 text-slate-500" />
                          <div className="min-w-0 space-y-0.5">
                            <p className="text-xs text-muted-foreground">Windows</p>
                            <p className="break-words text-sm font-semibold text-foreground">
                              {windowsEditionLabel ?? device?.osName ?? "—"}
                            </p>
                            <p className="break-words text-xs text-muted-foreground">
                              {windowsVersionLabel ?? windowsBuildLabel ?? "Versão desconhecida"}
                            </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 space-y-0.5">
                            <p className="text-xs text-muted-foreground">GPU</p>
                            <p className="break-words 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>
                    <div className="grid gap-3 lg:grid-cols-2">
                      <Card className="border-slate-200">
                        <CardHeader className="pb-2">
                          <CardTitle className="flex items-center gap-2 text-sm font-semibold">
                            <Monitor className="size-4 text-slate-500" />
                            Sistema operacional
                          </CardTitle>
                          <CardDescription>Build, licença e data de instalação</CardDescription>
                        </CardHeader>
                        <CardContent className="space-y-3 text-sm">
                          <div className="flex flex-wrap gap-2">
                            {windowsVersionLabel ? (
                              <Badge className={BADGE_NEUTRAL}>
                                <RefreshCcw className="size-3" />
                                {windowsVersionLabel}
                              </Badge>
                            ) : null}
                            {windowsBuildLabel ? (
                              <Badge className={BADGE_NEUTRAL}>Build {windowsBuildLabel}</Badge>
                            ) : null}
                            {windowsLicenseStatusLabel ? (
                              <Badge className={windowsActivationStatus ? BADGE_POSITIVE : BADGE_WARNING}>
                                {windowsActivationStatus ? <ShieldCheck className="size-3" /> : <ShieldAlert className="size-3" />}
                                {windowsLicenseStatusLabel}
                              </Badge>
                            ) : null}
                          </div>
                          <div className="grid gap-2">
                            <DetailLine label="Nome do dispositivo" value={windowsComputerName ?? device?.hostname ?? "—"} classNameValue="break-words" />
                            <DetailLine label="Edição" value={windowsEditionLabel ?? windowsOsInfo?.productName ?? "—"} classNameValue="break-words" />
                            <DetailLine label="Experiência" value={windowsExperienceLabel ?? "—"} />
                            <DetailLine label="Instalação" value={windowsInstallDateLabel ?? "—"} />
                            <DetailLine label="ID do produto" value={windowsProductId ?? "—"} classNameValue="break-words" />
                            <DetailLine label="Chave parcial" value={windowsPartialProductKey ?? "—"} classNameValue="break-words" />
                            <DetailLine label="Proprietário registrado" value={windowsRegisteredOwner ?? "—"} classNameValue="break-words" />
                            <DetailLine label="Número de série" value={windowsSerialNumber ?? "—"} />
                          </div>
                        </CardContent>
                      </Card>

                      <Card className="border-slate-200">
                        <CardHeader className="pb-2">
                          <CardTitle className="flex items-center gap-2 text-sm font-semibold">
                            <Globe className="size-4 text-slate-500" />
                            Identidade e dispositivo
                          </CardTitle>
                          <CardDescription>Associação a domínio, Azure AD e detalhes físicos</CardDescription>
                        </CardHeader>
                        <CardContent className="space-y-3 text-sm">
                          <div className="grid gap-2">
                            <DetailLine label="Fabricante" value={computerManufacturer ?? "—"} />
                            <DetailLine label="Modelo" value={computerModel ?? "—"} />
                            <DetailLine label="Tipo de sistema" value={computerPcTypeLabel ?? "—"} />
                            <DetailLine label="Domínio" value={computerDomain ?? "—"} />
                            <DetailLine label="Workgroup" value={computerWorkgroup ?? "—"} />
                            <DetailLine label="Função" value={computerDomainRoleLabel ?? "—"} />
                            <DetailLine label="Memória física" value={computerTotalMemoryLabel ?? "—"} />
                          </div>
                          <div className="flex flex-wrap gap-2 text-xs">
                            {computerPartOfDomain !== undefined ? (
                              <Badge className={computerPartOfDomain ? BADGE_POSITIVE : BADGE_WARNING}>
                                {computerPartOfDomain ? <ShieldCheck className="size-3" /> : <ShieldQuestion className="size-3" />}
                                {computerPartOfDomain ? `Domínio ativo${computerDomain ? ` (${computerDomain})` : ""}` : "Fora de domínio"}
                              </Badge>
                            ) : null}
                            {azureAdJoined !== undefined ? (
                              <Badge className={azureAdJoined ? BADGE_POSITIVE : BADGE_NEUTRAL}>
                                <Cloud className="size-3" />
                                {azureAdJoined ? "Azure AD conectado" : "Azure AD não conectado"}
                              </Badge>
                            ) : null}
                            {azureDomainJoined !== undefined ? (
                              <Badge className={BADGE_NEUTRAL}>
                                <ShieldQuestion className="size-3" />
                                Domínio local: {azureDomainJoined ? "Sim" : "Não"}
                              </Badge>
                            ) : null}
                            {azureEnterpriseJoined !== undefined ? (
                              <Badge className={BADGE_NEUTRAL}>
                                <ShieldQuestion className="size-3" />
                                Enterprise: {azureEnterpriseJoined ? "Sim" : "Não"}
                              </Badge>
                            ) : null}
                          </div>
                          {azureTenantName ? (
                            <p className="text-xs text-muted-foreground">Tenant: {azureTenantName}</p>
                          ) : null}
                          {azureDeviceId ? (
                            <p className="break-words text-xs text-muted-foreground">Device ID: {azureDeviceId}</p>
                          ) : null}
                          {azureUserSso ? (
                            <p className="text-xs text-muted-foreground">Usuário SSO: {azureUserSso}</p>
                          ) : null}
                        </CardContent>
                      </Card>

                      <Card className="border-slate-200 lg:col-span-2">
                        <CardHeader className="pb-2">
                          <CardTitle className="flex items-center gap-2 text-sm font-semibold">
                            <RefreshCcw className="size-4 text-slate-500" />
                            Atualizações do Windows
                          </CardTitle>
                          <CardDescription>Configurações automáticas e histórico recente</CardDescription>
                        </CardHeader>
                        <CardContent className="flex flex-col gap-4 text-sm lg:flex-row lg:items-start lg:gap-8">
                          <div className="flex-1 space-y-3">
                            <div className="flex flex-wrap gap-2 text-xs">
                              {windowsUpdateDisabled !== undefined ? (
                                <Badge className={windowsUpdateDisabled ? BADGE_WARNING : BADGE_POSITIVE}>
                                  {windowsUpdateDisabled ? <ShieldOff className="size-3" /> : <ShieldCheck className="size-3" />}
                                  {windowsUpdateDisabled ? "Atualizações desativadas" : "Atualizações automáticas"}
                                </Badge>
                              ) : null}
                              {windowsUpdateDetectionEnabled === false ? (
                                <Badge className={BADGE_WARNING}>
                                  <AlertTriangle className="size-3" />
                                  Sem detecção automática
                                </Badge>
                              ) : null}
                            </div>
                            <div className="grid gap-2">
                              <DetailLine label="Modo" value={windowsUpdateMode ?? "—"} layout="compact" />
                              <DetailLine label="Agendamento" value={windowsUpdateScheduleLabel ?? "—"} layout="compact" />
                              <DetailLine label="Último sucesso" value={windowsUpdateLastSuccessLabel ?? "—"} layout="compact" />
                            </div>
                          </div>
                          {windowsHotfixes.length > 0 ? (
                            <div className="w-full rounded-md border border-slate-200 bg-slate-50/80 p-3 lg:ml-auto lg:w-[320px] lg:basis-[320px] lg:flex-shrink-0 lg:self-stretch">
                              <p className="text-xs font-semibold uppercase text-slate-500">Atualizações recentes</p>
                              <ul className="mt-2 space-y-1 text-xs text-muted-foreground">
                                {windowsHotfixes.slice(0, 3).map((fix) => (
                                  <li key={fix.id} className="flex flex-col gap-1 border-b border-slate-200 pb-1 last:border-b-0 last:pb-0">
                                    <span className="font-medium text-foreground">{fix.id}</span>
                                    <span className="text-[11px] uppercase tracking-wide text-slate-500">{fix.installedLabel}</span>
                                  </li>
                                ))}
                              </ul>
                            </div>
                          ) : null}
                        </CardContent>
                      </Card>

                      <Card className="border-slate-200 lg:col-span-2">
                        <CardHeader className="pb-2">
                          <CardTitle className="flex items-center gap-2 text-sm font-semibold">
                            <Shield className="size-4 text-slate-500" />
                            Segurança do dispositivo
                          </CardTitle>
                          <CardDescription>Proteções do Windows, criptografia e firewall</CardDescription>
                        </CardHeader>
                        <CardContent className="space-y-4 text-sm">
                          <div className="flex flex-wrap gap-2 text-xs">
                            {windowsActivationStatus !== null && windowsActivationStatus !== undefined ? (
                              <Badge className={windowsActivationStatus ? BADGE_POSITIVE : BADGE_WARNING}>
                                {windowsActivationStatus ? <ShieldCheck className="size-3" /> : <ShieldAlert className="size-3" />}
                                {windowsActivationStatus ? "Licença ativada" : "Licença pendente"}
                              </Badge>
                            ) : null}
                            {defenderAntivirus !== undefined ? (
                              <Badge className={defenderAntivirus ? BADGE_POSITIVE : BADGE_WARNING}>
                                {defenderAntivirus ? <ShieldCheck className="size-3" /> : <ShieldAlert className="size-3" />}
                                Antivírus {defenderAntivirus ? "ativo" : "inativo"}
                              </Badge>
                            ) : null}
                            {defenderRealtime !== undefined ? (
                              <Badge className={defenderRealtime ? BADGE_POSITIVE : BADGE_WARNING}>
                                {defenderRealtime ? <ShieldCheck className="size-3" /> : <ShieldAlert className="size-3" />}
                                Tempo real {defenderRealtime ? "ativo" : "inativo"}
                              </Badge>
                            ) : null}
                            {secureBootSupported !== undefined ? (
                              <Badge
                                className={
                                  secureBootEnabled === true
                                    ? BADGE_POSITIVE
                                    : secureBootSupported
                                      ? BADGE_WARNING
                                      : BADGE_NEUTRAL
                                }
                              >
                                {secureBootEnabled
                                  ? <Shield className="size-3" />
                                  : secureBootSupported
                                    ? <ShieldQuestion className="size-3" />
                                    : <ShieldOff className="size-3" />}
                                {secureBootSupported
                                  ? secureBootEnabled === true
                                    ? "Secure Boot ativo"
                                    : "Secure Boot desabilitado"
                                  : "Secure Boot não suportado"}
                              </Badge>
                            ) : null}
                            {windowsBitLockerSummary ? (
                              <Badge
                                className={
                                  windowsBitLockerSummary.protectedCount === windowsBitLockerSummary.total
                                    ? BADGE_POSITIVE
                                    : BADGE_WARNING
                                }
                              >
                                <Lock className="size-3" />
                                {windowsBitLockerSummary.protectedCount}/{windowsBitLockerSummary.total} BitLocker
                              </Badge>
                            ) : null}
                            {tpmPresent !== undefined ? (
                              <Badge className={tpmPresent ? BADGE_POSITIVE : BADGE_WARNING}>
                                <Key className="size-3" />
                                {tpmPresent ? (tpmReady ? "TPM pronto" : "TPM detectado") : "TPM ausente"}
                              </Badge>
                            ) : null}
                            {windowsDeviceGuardDetails ? (
                              <Badge className={windowsDeviceGuardDetails.vbs === 3 ? BADGE_POSITIVE : BADGE_NEUTRAL}>
                                <ShieldQuestion className="size-3" />
                                {describeVbsStatus(windowsDeviceGuardDetails.vbs) ?? "VBS desconhecido"}
                              </Badge>
                            ) : null}
                            {windowsFirewallNormalized.length > 0 ? (
                              <Badge
                                className={
                                  firewallEnabledCount === windowsFirewallNormalized.length ? BADGE_POSITIVE : BADGE_WARNING
                                }
                              >
                                <Shield className="size-3" />
                                Firewall {firewallEnabledCount}/{windowsFirewallNormalized.length}
                              </Badge>
                            ) : null}
                          </div>

                          {windowsDefender ? (
                            <div>
                              <p className="text-xs font-semibold uppercase text-slate-500">Defender</p>
                              <div className="mt-1 grid gap-1 text-xs text-muted-foreground">
                                <span>Modo: {defenderMode ?? "—"}</span>
                                <span>
                                  Antivírus: {defenderAntivirus === undefined ? "—" : defenderAntivirus ? "Ativo" : "Inativo"}
                                </span>
                                <span>
                                  Tempo real: {defenderRealtime === undefined ? "—" : defenderRealtime ? "Ativo" : "Inativo"}
                                </span>
                              </div>
                            </div>
                          ) : null}

                          {secureBootError ? (
                            <div className="flex items-start gap-2 rounded-md border border-amber-200 bg-amber-50 p-3 text-xs text-amber-700">
                              <AlertTriangle className="mt-0.5 size-3 shrink-0" />
                              <span>{secureBootError}</span>
                            </div>
                          ) : null}

                          {windowsBitLockerVolumes.length > 0 ? (
                            <div>
                              <div className="flex items-center justify-between gap-2">
                                <p className="text-xs font-semibold uppercase text-slate-500">BitLocker</p>
                                <Badge variant="outline" className="text-[11px] text-slate-600">
                                  {windowsBitLockerSummary
                                    ? `${windowsBitLockerSummary.protectedCount}/${windowsBitLockerSummary.total} protegidos`
                                    : `${windowsBitLockerVolumes.length} volumes`}
                                </Badge>
                              </div>
                              <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">Volume</TableHead>
                                      <TableHead className="text-xs text-slate-500">Proteção</TableHead>
                                      <TableHead className="text-xs text-slate-500">Bloqueio</TableHead>
                                      <TableHead className="text-xs text-slate-500">Método</TableHead>
                                      <TableHead className="text-xs text-slate-500">% Cript.</TableHead>
                                    </TableRow>
                                  </TableHeader>
                                  <TableBody>
                                    {windowsBitLockerVolumes.map((volume, idx) => {
                                      const record = toRecord(volume) ?? {}
                                      const mount = readString(record, "MountPoint", "mountPoint") ?? "—"
                                      const protection = readString(record, "ProtectionStatus", "protectionStatus") ?? "—"
                                      const lock = readString(record, "LockStatus", "lockStatus") ?? "—"
                                      const method = readString(record, "EncryptionMethod", "encryptionMethod") ?? "—"
                                      const percent = readNumber(record, "EncryptionPercentage", "encryptionPercentage")
                                      return (
                                        <TableRow key={`bit-${idx}`} className="border-slate-100">
                                          <TableCell className="text-sm">{mount}</TableCell>
                                          <TableCell className="text-sm text-muted-foreground">{protection}</TableCell>
                                          <TableCell className="text-sm text-muted-foreground">{lock}</TableCell>
                                          <TableCell className="text-sm text-muted-foreground">{method}</TableCell>
                                          <TableCell className="text-sm text-muted-foreground">
                                            {percent != null ? formatPercent(percent) : "—"}
                                          </TableCell>
                                        </TableRow>
                                      )
                                    })}
                                  </TableBody>
                                </Table>
                              </div>
                            </div>
                          ) : null}

                          {windowsTpm ? (
                            <div className="grid gap-1 text-xs text-muted-foreground">
                              <p className="text-xs font-semibold uppercase text-slate-500">TPM</p>
                              <span>Fabricante: {tpmManufacturer ?? "—"}</span>
                              <span>Versão: {tpmVersion ?? "—"}</span>
                              <span>
                                Status:{" "}
                                {tpmPresent === undefined
                                  ? "—"
                                  : [
                                      tpmPresent ? "Presente" : "Ausente",
                                      tpmEnabled ? "Habilitado" : "Desabilitado",
                                      tpmReady ? "Pronto" : "Não pronto",
                                      tpmActivated ? "Ativado" : "Inativo",
                                    ].join(" · ")}
                              </span>
                            </div>
                          ) : (
                            <p className="text-xs text-muted-foreground">
                              TPM: não foi possível coletar informações (requer privilégios administrativos no dispositivo).
                            </p>
                          )}

                          {windowsDeviceGuardDetails ? (
                            <div className="grid gap-1 text-xs text-muted-foreground">
                              <p className="text-xs font-semibold uppercase text-slate-500">Device Guard</p>
                              <span>{describeVbsStatus(windowsDeviceGuardDetails.vbs) ?? "—"}</span>
                              {deviceGuardConfiguredLabels.length > 0 ? (
                                <span>Configurado: {deviceGuardConfiguredLabels.join(", ")}</span>
                              ) : null}
                              {deviceGuardRunningLabels.length > 0 ? (
                                <span>Em execução: {deviceGuardRunningLabels.join(", ")}</span>
                              ) : null}
                            </div>
                          ) : null}

                          {windowsFirewallNormalized.length > 0 ? (
                            <div>
                              <div className="flex items-center justify-between gap-2">
                                <p className="text-xs font-semibold uppercase text-slate-500">Perfis de firewall</p>
                                <Badge variant="outline" className="text-[11px] text-slate-600">
                                  {firewallEnabledCount}/{windowsFirewallNormalized.length} ativos
                                </Badge>
                              </div>
                              <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">Perfil</TableHead>
                                      <TableHead className="text-xs text-slate-500">Entrada</TableHead>
                                      <TableHead className="text-xs text-slate-500">Saída</TableHead>
                                    </TableRow>
                                  </TableHeader>
                                  <TableBody>
                                    {windowsFirewallNormalized.map((profile, idx) => (
                                      <TableRow key={`fw-${idx}`} className="border-slate-100">
                                        <TableCell className="text-sm">{profile.name}</TableCell>
                                        <TableCell className="text-sm text-muted-foreground">
                                          {profile.inboundAction ?? "—"}
                                        </TableCell>
                                        <TableCell className="text-sm text-muted-foreground">
                                          {profile.outboundAction ?? "—"}
                                        </TableCell>
                                      </TableRow>
                                    ))}
                                  </TableBody>
                                </Table>
                              </div>
                            </div>
                          ) : null}
                        </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}

                    {normalizedWindowsSoftware.length > 0 ? (
                      <div className="rounded-md border border-slate-200 bg-slate-50/60 p-3">
                        <div className="flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-between">
                          <p className="text-xs font-semibold uppercase text-slate-500">Aplicativos instalados</p>
                          {normalizedWindowsSoftware.length > 12 ? (
                            <Button
                              type="button"
                              variant="ghost"
                              size="sm"
                              className="h-7 px-2 text-xs text-slate-600 hover:bg-slate-200/60"
                              onClick={() => setShowAllWindowsSoftware((prev) => !prev)}
                            >
                              {showAllWindowsSoftware ? "Mostrar menos" : `Ver todos (${normalizedWindowsSoftware.length})`}
                            </Button>
                          ) : null}
                        </div>
                        <ul className="mt-2 space-y-2">
                          {displayedWindowsSoftware.map((softwareItem, index) => {
                            const initials = collectInitials(softwareItem.name)
                            const installedAt = formatInstallDate(softwareItem.installDate)
                            return (
                              <li key={`sw-${index}`} className="flex items-start gap-3 rounded-md border border-slate-200 bg-white px-3 py-2">
                                <span className="mt-0.5 flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-slate-200 text-xs font-semibold uppercase text-slate-700">
                                  {initials}
                                </span>
                                <div className="flex-1 space-y-1">
                                  <div className="flex flex-wrap items-center gap-2">
                                    <span className="text-sm font-semibold text-foreground">{softwareItem.name}</span>
                                    {softwareItem.version ? (
                                      <Badge variant="outline" className="border-slate-300 bg-slate-100 text-[11px] text-slate-700">
                                        {softwareItem.version}
                                      </Badge>
                                    ) : null}
                                  </div>
                                  <div className="flex flex-wrap gap-2 text-xs text-muted-foreground">
                                    {softwareItem.publisher ? <span>{softwareItem.publisher}</span> : null}
                                    {installedAt ? <span>Instalado em {installedAt}</span> : null}
                                  </div>
                                </div>
                              </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}

                  </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(device?.postureAlerts) && device?.postureAlerts?.length ? (
              <section className="space-y-2">
                <h4 className="text-sm font-semibold">Alertas de postura</h4>
                <div className="space-y-2">
                  {device?.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",
                        postureSeverityClass(a?.severity)
                      )}
                    >
                      <span className="font-medium text-foreground">{a?.message ?? formatPostureAlertKind(a?.kind)}</span>
                      <Badge variant="outline">{formatPostureAlertKind(a?.kind)}</Badge>
                    </div>
                  ))}
                </div>
                <p className="text-xs text-muted-foreground">
                  Última avaliação: {device?.lastPostureAt ? formatRelativeTime(new Date(device.lastPostureAt)) : "—"}
                </p>
              </section>
            ) : null}

            {!isManualMobile ? (
              <section className="space-y-2">
                <div className="flex items-center justify-between">
                  <h4 className="text-sm font-semibold">Histórico de alertas</h4>
                  {deviceAlertsHistory.length > 0 ? (
                    <span className="text-xs text-muted-foreground">
                      Últimos {deviceAlertsHistory.length} {deviceAlertsHistory.length === 1 ? "evento" : "eventos"}
                    </span>
                  ) : null}
                </div>
                {deviceAlertsHistory.length > 0 ? (
                  <div className="relative max-h-64 overflow-y-auto pr-2">
                    <div className="absolute left-3 top-3 bottom-3 w-px bg-slate-200" />
                    <ol className="space-y-3 pl-6">
                      {deviceAlertsHistory.map((alert) => {
                        const date = new Date(alert.createdAt)
                        return (
                          <li key={alert.id} className="relative rounded-md border border-slate-200/80 bg-white px-3 py-2 text-xs shadow-sm">
                            <span className="absolute -left-5 top-3 inline-flex size-3 items-center justify-center rounded-full border border-white bg-slate-200 ring-2 ring-white" />
                            <div className={cn("flex items-center justify-between", postureSeverityClass(alert.severity))}>
                              <span className="text-xs font-medium uppercase tracking-wide text-slate-600">{formatPostureAlertKind(alert.kind)}</span>
                              <span className="text-xs text-slate-500">{formatRelativeTime(date)}</span>
                            </div>
                            <p className="mt-1 text-sm text-foreground">{alert.message ?? formatPostureAlertKind(alert.kind)}</p>
                            <p className="mt-1 text-[11px] text-muted-foreground">{format(date, "dd/MM/yyyy HH:mm:ss")}</p>
                          </li>
                        )
                      })}
                    </ol>
                  </div>
                ) : (
                  <p className="text-xs text-muted-foreground">Nenhum alerta registrado para este dispositivo.</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}

            {device ? (
              <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 o dispositivo revoga o token atual e remove os dados de inventário sincronizados.
                  </p>
                </div>
                <Button variant="destructive" size="sm" onClick={() => setDeleteDialog(true)}>Excluir dispositivo</Button>
              </section>
            ) : null}

            <Dialog open={openDialog} onOpenChange={setOpenDialog}>
              <div className="flex flex-wrap items-center justify-end gap-2">
              {device ? (
                <Button size="sm" variant="outline" className="inline-flex items-center gap-2" onClick={() => setIsSingleExportOpen(true)}>
                  <Download className="size-4" /> Exportar planilha
                </Button>
              ) : null}
                <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 — {device.displayName ?? device.hostname ?? "Dispositivo"}</DialogTitle>
                </DialogHeader>
                <div className="space-y-2">
                  <div className="flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-between">
                    <Input
                      placeholder="Buscar no JSON"
                      value={dialogQuery}
                      onChange={(e) => setDialogQuery(e.target.value)}
                      className="sm:flex-1"
                    />
                    <div className="flex flex-col gap-2 sm:flex-row sm:items-center sm:gap-3">
                      <Button
                        type="button"
                        variant="outline"
                        size="sm"
                        onClick={handleDownloadInventoryJson}
                        className="inline-flex items-center gap-2"
                      >
                        <Download className="size-4" /> Baixar JSON
                      </Button>
                      {device ? (
                        <Button type="button" variant="outline" size="sm" asChild className="inline-flex items-center gap-2">
                          <a href={`/api/admin/devices/${device.id}/inventory.xlsx`} download>
                            <Download className="size-4" /> Baixar planilha
                          </a>
                        </Button>
                      ) : null}
                    </div>
                  </div>
                  <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>

            {/* Exportação individual: seleção de colunas */}
            <Dialog open={isSingleExportOpen} onOpenChange={(open) => (!singleExporting ? setIsSingleExportOpen(open) : null)}>
              <DialogContent className="max-w-2xl space-y-4">
                <DialogHeader>
                  <DialogTitle>Exportar planilha — {device.displayName ?? device.hostname ?? "Dispositivo"}</DialogTitle>
                  <DialogDescription>Escolha as colunas a incluir na exportação.</DialogDescription>
                </DialogHeader>
                <div className="space-y-3">
                  <div className="flex items-center justify-between">
                    <p className="text-sm font-semibold text-slate-900">Colunas</p>
                    <div className="flex items-center gap-2">
                      <Button type="button" variant="ghost" size="sm" onClick={selectAllSingleColumns} disabled={singleExporting} className="gap-2">
                        <CheckSquare className="size-4" /> Selecionar todas
                      </Button>
                      <Separator orientation="vertical" className="h-4" />
                      <Button type="button" variant="ghost" size="sm" onClick={resetSingleColumns} disabled={singleExporting} className="gap-2">
                        <RotateCcw className="size-4" /> Restaurar padrão
                      </Button>
                    </div>
                  </div>
                  <div className="grid gap-3 sm:grid-cols-2">
                    {baseColumnOptionsSingle.map((col) => {
                      const checked = singleColumns.some((c) => c.key === col.key)
                      return (
                        <label key={col.key} className="flex items-center gap-2 text-sm text-slate-700">
                          <Checkbox
                            checked={checked}
                            onCheckedChange={(value) => toggleSingleColumn(col.key, value === true || value === "indeterminate")}
                            disabled={singleExporting}
                          />
                          <span>{col.label}</span>
                        </label>
                      )
                    })}
                  </div>
                  {customColumnOptionsSingle.length > 0 ? (
                    <div className="space-y-2">
                      <p className="text-xs font-semibold uppercase text-slate-500">Campos personalizados</p>
                      <div className="grid gap-3 sm:grid-cols-2">
                        {customColumnOptionsSingle.map((col) => {
                          const checked = singleColumns.some((c) => c.key === col.key)
                          return (
                            <label key={col.key} className="flex items-center gap-2 text-sm text-slate-700">
                              <Checkbox
                                checked={checked}
                                onCheckedChange={(value) => toggleSingleColumn(col.key, value === true || value === "indeterminate", col.label)}
                                disabled={singleExporting}
                              />
                              <span>{col.label}</span>
                            </label>
                          )
                        })}
                      </div>
                    </div>
                  ) : null}
                  <p className="text-xs text-slate-500">{singleColumns.length} coluna{singleColumns.length === 1 ? "" : "s"} selecionada{singleColumns.length === 1 ? "" : "s"}.</p>
                </div>
                {singleExportError ? <p className="text-sm text-destructive">{singleExportError}</p> : null}
                <DialogFooter className="gap-2 sm:gap-2">
                  <Button type="button" variant="outline" onClick={() => setIsSingleExportOpen(false)} disabled={singleExporting}>
                    Cancelar
                  </Button>
                  <Button type="button" onClick={handleExportSingle} disabled={singleExporting} className="gap-2">
                    {singleExporting ? (
                      <>
                        <Spinner className="mr-2 size-4" /> Exportando...
                      </>
                    ) : (
                      <>
                        <Download className="size-4" /> Exportar
                      </>
                    )}
                  </Button>
                </DialogFooter>
              </DialogContent>
            </Dialog>

            {/* Editor de campos personalizados */}
            <Dialog open={customFieldsEditorOpen} onOpenChange={(open) => setCustomFieldsEditorOpen(open)}>
              <DialogContent className="max-w-2xl space-y-4">
                <DialogHeader>
                  <DialogTitle>Campos personalizados — {device.displayName ?? device.hostname ?? "Dispositivo"}</DialogTitle>
                  <DialogDescription>Adicione e ajuste informações complementares deste dispositivo.</DialogDescription>
                </DialogHeader>
                <div className="space-y-3">
                  <div className="flex items-center justify-between">
                    <p className="text-sm font-semibold text-slate-900">Valores</p>
                    <div className="flex items-center gap-2">
                      <Button size="sm" variant="outline" onClick={() => setNewFieldOpen((v) => !v)}>
                        {newFieldOpen ? "Cancelar" : "Novo campo"}
                      </Button>
                    </div>
                  </div>
                  {newFieldOpen ? (
                    <div className="space-y-3 rounded-lg border border-slate-200 p-3">
                      <div className="grid gap-2 sm:grid-cols-[1fr_160px] sm:gap-3">
                        <div className="space-y-1">
                          <label className="text-xs font-medium text-slate-700">Rótulo</label>
                          <Input value={newFieldLabel} onChange={(e) => setNewFieldLabel(e.target.value)} placeholder="Ex.: Patrimônio" />
                        </div>
                        <div className="space-y-1">
                          <label className="text-xs font-medium text-slate-700">Tipo</label>
                          <Select value={newFieldType} onValueChange={setNewFieldType}>
                            <SelectTrigger><SelectValue placeholder="Selecione" /></SelectTrigger>
                            <SelectContent>
                              <SelectItem value="text">Texto</SelectItem>
                              <SelectItem value="number">Número</SelectItem>
                              <SelectItem value="date">Data</SelectItem>
                              <SelectItem value="boolean">Verdadeiro/Falso</SelectItem>
                              <SelectItem value="select">Seleção</SelectItem>
                              <SelectItem value="multiselect">Seleção múltipla</SelectItem>
                            </SelectContent>
                          </Select>
                        </div>
                      </div>
                      {(newFieldType === "select" || newFieldType === "multiselect") ? (
                        <div className="space-y-2">
                          <label className="text-xs font-medium text-slate-700">Opções</label>
                          <div className="space-y-2">
                            {newFieldOptions.map((opt, idx) => (
                              <div key={idx} className="grid gap-2 sm:grid-cols-2">
                                <Input
                                  placeholder="Rótulo"
                                  value={opt.label}
                                  onChange={(e) => setNewFieldOptions((prev) => prev.map((o, i) => i === idx ? { ...o, label: e.target.value } : o))}
                                />
                                <Input
                                  placeholder="Valor"
                                  value={opt.value}
                                  onChange={(e) => setNewFieldOptions((prev) => prev.map((o, i) => i === idx ? { ...o, value: e.target.value } : o))}
                                />
                              </div>
                            ))}
                          </div>
                          <div className="flex items-center gap-2">
                            <Button type="button" size="sm" variant="outline" onClick={() => setNewFieldOptions((prev) => [...prev, { label: "", value: "" }])}>Adicionar opção</Button>
                            {newFieldOptions.length > 0 ? (
                              <Button type="button" size="sm" variant="ghost" onClick={() => setNewFieldOptions((prev) => prev.slice(0, -1))}>Remover última</Button>
                            ) : null}
                          </div>
                        </div>
                      ) : null}
                      <div className="flex justify-end gap-2">
                        <Button type="button" size="sm" onClick={handleCreateNewField}>Criar</Button>
                      </div>
                    </div>
                  ) : null}

                  {editableFields.length === 0 ? (
                    <div className="rounded-md border border-dashed border-slate-200 p-4 text-sm text-muted-foreground">Nenhum campo disponível para este tipo de dispositivo.</div>
                  ) : (
                    <div className="grid gap-3">
                      {editableFields.map((field) => {
                        const value = customFieldValues[field.id] ?? customFieldValues[field.key] ?? null
                        const setValue = (v: unknown) => setCustomFieldValues((prev) => ({ ...prev, [field.id]: v }))
                        return (
                          <div key={field.id} className="grid gap-1">
                            <label className="text-xs font-semibold uppercase tracking-wide text-neutral-500">{field.label}</label>
                            {field.type === "text" ? (
                              <Input value={(value as string) ?? ""} onChange={(e) => setValue(e.target.value)} />
                            ) : field.type === "number" ? (
                              <Input type="number" value={value == null ? "" : String(value)} onChange={(e) => setValue(e.target.value === "" ? null : Number(e.target.value))} />
                            ) : field.type === "date" ? (
                              <DatePicker
                                value={value ? String(value).slice(0, 10) : null}
                                onChange={(next) => setValue(next ?? null)}
                                placeholder="Selecionar data"
                              />
                            ) : field.type === "boolean" ? (
                              <label className="inline-flex items-center gap-2 text-sm text-slate-700">
                                <Checkbox checked={Boolean(value)} onCheckedChange={(v) => setValue(Boolean(v))} />
                                <span>Ativo</span>
                              </label>
                            ) : field.type === "select" ? (
                              <Select value={value ? String(value) : undefined} onValueChange={(v) => setValue(v)}>
                                <SelectTrigger><SelectValue placeholder="Selecionar" /></SelectTrigger>
                                <SelectContent>
                                  {field.options?.map((opt: { value: string; label: string }) => (
                                    <SelectItem key={opt.value} value={opt.value}>{opt.label}</SelectItem>
                                  ))}
                                </SelectContent>
                              </Select>
                            ) : field.type === "multiselect" ? (
                              <div className="grid gap-1 sm:grid-cols-2">
                                {field.options?.map((opt: { value: string; label: string }) => {
                                  const arr = Array.isArray(value) ? (value as unknown[]) : []
                                  const checked = arr.some((v) => String(v) === opt.value)
                                  return (
                                    <label key={opt.value} className="flex items-center gap-2 text-sm text-slate-700">
                                      <Checkbox
                                        checked={checked}
                                        onCheckedChange={(c) => {
                                          const base = Array.isArray(value) ? [...(value as unknown[])] : []
                                          if (c) {
                                            if (!base.some((v) => String(v) === opt.value)) base.push(opt.value)
                                          } else {
                                            const idx = base.findIndex((v) => String(v) === opt.value)
                                            if (idx >= 0) base.splice(idx, 1)
                                          }
                                          setValue(base)
                                        }}
                                      />
                                      <span>{opt.label}</span>
                                    </label>
                                  )
                                })}
                              </div>
                            ) : null}
                          </div>
                        )
                      })}
                    </div>
                  )}
                </div>
                <DialogFooter>
                  <Button type="button" variant="outline" onClick={() => setCustomFieldsEditorOpen(false)}>Cancelar</Button>
                  <Button type="button" onClick={handleSaveCustomFields}>Salvar</Button>
                </DialogFooter>
              </DialogContent>
            </Dialog>

            <Dialog open={deleteDialog} onOpenChange={(open) => { if (!open) setDeleting(false); setDeleteDialog(open) }}>
              <DialogContent>
                <DialogHeader>
                  <DialogTitle>Excluir dispositivo</DialogTitle>
                </DialogHeader>
                <div className="space-y-3 text-sm text-muted-foreground">
                  <p>Tem certeza que deseja excluir <span className="font-semibold text-foreground">{device?.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 (!device) return
                        setDeleting(true)
                        try {
                          const res = await fetch("/api/admin/devices/delete", {
                            method: "POST",
                            headers: { "Content-Type": "application/json" },
                            body: JSON.stringify({ machineId: device.id }),
                            credentials: "include",
                          })
                          if (!res.ok) throw new Error(`HTTP ${res.status}`)
                          toast.success("Dispositivo excluída")
                          setDeleteDialog(false)
                          router.push("/admin/devices")
                        } catch (err) {
                          console.error(err)
                          toast.error("Falha ao excluir dispositivo")
                        } finally {
                          setDeleting(false)
                        }
                      }}
                    >
                      {deleting ? "Excluindo..." : "Excluir dispositivo"}
                    </Button>
                  </div>
                </div>
              </DialogContent>
            </Dialog>
          </div>
        )}
        </CardContent>
      </Card>
    );
}

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

function DeviceCard({ device, companyName }: { device: DevicesQueryItem; companyName?: string | null }) {
  const router = useRouter()
  const effectiveStatus = resolveDeviceStatus(device)
  const statusIndicator = getDeviceStatusIndicator(effectiveStatus)
  const isActive = device.isActive
  const lastHeartbeat = device.lastHeartbeatAt ? new Date(device.lastHeartbeatAt) : null
  const deviceType = (device.deviceType ?? "desktop").toLowerCase()
  const DeviceIcon = deviceType === "mobile" ? Smartphone : deviceType === "tablet" ? Tablet : Monitor
  const deviceTypeLabel = formatDeviceTypeLabel(device.deviceType)
  const deviceLabel = device.displayName ?? device.hostname ?? "Dispositivo"
  type AgentMetrics = {
    memoryUsedBytes?: number
    memoryTotalBytes?: number
    memoryUsedPercent?: number
    cpuUsagePercent?: number
  }
  const mm = (device.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 (device.assignedUserEmail) {
      return {
        email: device.assignedUserEmail ?? undefined,
        name: device.assignedUserName ?? undefined,
        role: device.persona ?? device.assignedUserRole ?? undefined,
      }
    }
    const inv = device.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 ?? device.companySlug ?? null

  return (
    <Link href={`/admin/devices/${device.id}`} className="group">
      <Card className={cn("relative h-full overflow-hidden border-slate-200 transition-colors hover:border-slate-300", !isActive && "border-slate-300 bg-slate-50") }>
        <div className="absolute right-2 top-2">
          <span
            aria-hidden
            className={cn("relative block size-2 rounded-full border border-white shadow-sm", statusIndicator.dotClass)}
          />
          {statusIndicator.isPinging ? (
            <span
              className={cn(
                "absolute left-1/2 top-1/2 -z-10 size-4 -translate-x-1/2 -translate-y-1/2 rounded-full animate-ping",
                statusIndicator.ringClass
              )}
            />
          ) : null}
        </div>
        <CardHeader className="pb-2">
          <CardTitle className="flex items-center gap-2 text-base font-semibold">
            <DeviceIcon className="size-4 text-slate-500" />
            <span className="line-clamp-1">{deviceLabel}</span>
          </CardTitle>
          <div className="flex flex-col gap-1">
            <div className="flex flex-wrap items-center gap-2 text-xs text-slate-500">
              <span>{deviceTypeLabel}</span>
              {device.devicePlatform ? (
                <>
                  <span className="text-slate-300">•</span>
                  <span>{device.devicePlatform}</span>
                </>
              ) : null}
              {device.authEmail ? (
                <>
                  <span className="text-slate-300">•</span>
                  <span className="truncate max-w-[140px]" title={device.authEmail}>
                    {device.authEmail}
                  </span>
                </>
              ) : null}
            </div>
            {collaborator?.email ? (
              <div className="mt-3 flex flex-col gap-2 text-xs text-slate-600">
                <div className="flex flex-col rounded-lg border border-slate-200 bg-slate-50 px-3 py-1.5">
                  <span className="text-[11px] uppercase text-slate-400">Usuário vinculado</span>
                  <span className="line-clamp-1 text-sm font-medium text-slate-800" title={collaborator.name ?? collaborator.email}>
                    {collaborator.name ?? "Usuário"}
                  </span>
                  <span className="text-[11px] text-slate-500 line-clamp-1" title={collaborator.email}>
                    {collaborator.email}
                  </span>
                </div>
                <button
                  type="button"
                  className="self-start text-[11px] font-semibold text-slate-500 underline underline-offset-4 hover:text-slate-800"
                  onClick={(event) => {
                    event.preventDefault()
                    event.stopPropagation()
                    router.push("/admin/users")
                  }}
                >
                  Gerenciar usuários
                </button>
              </div>
            ) : null}
          </div>
          {!isActive ? (
            <Badge variant="outline" className="mt-2 w-fit border-rose-200 bg-rose-50 text-[10px] font-semibold uppercase tracking-wide text-rose-700">
              Desativado
            </Badge>
          ) : null}
        </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">
              {(() => {
                const name = device.osName ?? "SO"
                const ver = formatOsVersionDisplay(device.osName, device.osVersion)
                return [name, ver].filter(Boolean).join(" ").trim()
              })()}
            </Badge>
            {device.architecture ? (
              <Badge variant="outline" className="border-slate-300 bg-slate-100 text-xs font-medium text-slate-700">
                {device.architecture.toUpperCase()}
              </Badge>
            ) : null}
          </div>
          <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">
              {deviceTypeLabel}
            </Badge>
            {companyLabel ? (
              <Badge variant="outline" className="border-slate-300 bg-slate-100 text-xs font-medium text-slate-700">
                {companyLabel}
              </Badge>
            ) : null}
          </div>
          <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(device.inventory?.disks) ? `${device.inventory?.disks?.length ?? 0} discos` : "—"}
            </span>
            <span>
              {lastHeartbeat ? formatRelativeTime(lastHeartbeat) : "Sem heartbeat"}
            </span>
          </div>
        </CardContent>
      </Card>
    </Link>
  )
}

function DetailLine({ label, value, classNameValue, layout = "spread" }: DetailLineProps) {
  if (value === null || value === undefined) return null
  if (typeof value === "string" && (value.trim() === "" || value === "undefined" || value === "null")) {
    return null
  }
  return (
    <div
      className={cn(
        "items-center",
        layout === "compact"
          ? "grid grid-cols-[auto_minmax(0,1fr)] gap-3"
          : "flex justify-between gap-4"
      )}
    >
      <span>{label}</span>
      <span
        className={cn(
          "font-medium text-foreground",
          layout === "compact" ? "text-left" : "text-right",
          classNameValue
        )}
      >
        {value}
      </span>
    </div>
  )
}

function InfoChip({ label, value, icon, tone = "default", onClick, statusBadge }: { label: string; value: string; icon?: ReactNode; tone?: "default" | "warning" | "muted"; onClick?: () => void; statusBadge?: { text: string; variant: "default" | "success" | "warning" | "error" } }) {
  const toneClasses =
    tone === "warning"
      ? "border-amber-200 bg-amber-50 text-amber-700"
      : tone === "muted"
        ? "border-slate-200 bg-slate-50 text-neutral-600"
        : "border-slate-200 bg-white text-neutral-800"

  const clickableClasses = onClick ? "cursor-pointer hover:ring-2 hover:ring-blue-200 transition-all" : ""

  const badgeVariantClasses = {
    default: "border-slate-300 text-slate-500",
    success: "border-emerald-500 text-emerald-600",
    warning: "border-amber-500 text-amber-600",
    error: "border-red-500 text-red-600",
  }

  return (
    <div
      className={cn("flex items-center gap-3 rounded-xl border px-3 py-2 shadow-sm", toneClasses, clickableClasses)}
      onClick={onClick}
      role={onClick ? "button" : undefined}
      tabIndex={onClick ? 0 : undefined}
      onKeyDown={onClick ? (e) => { if (e.key === "Enter" || e.key === " ") onClick() } : undefined}
    >
      {icon ? <span className="text-neutral-500">{icon}</span> : null}
      <div className="min-w-0 leading-tight">
        <p className="text-xs uppercase text-neutral-500">{label}</p>
        <div className="flex items-center gap-2">
          <p className="truncate text-sm font-semibold">{value}</p>
          {statusBadge && (
            <span className={cn("inline-flex rounded-full border px-2 py-0.5 text-[11px] font-semibold", badgeVariantClasses[statusBadge.variant])}>
              {statusBadge.text}
            </span>
          )}
        </div>
      </div>
    </div>
  )
}

function clampPercent(raw: number): number {
  if (!Number.isFinite(raw)) return 0
  const normalized = raw > 1 && raw <= 100 ? raw : raw <= 1 ? raw * 100 : raw
  return Math.max(0, Math.min(100, normalized))
}

function deriveUsageMetrics({
  metrics,
  hardware,
  disks,
}: {
  metrics: DeviceMetrics
  hardware?: DeviceInventory["hardware"]
  disks?: DeviceInventory["disks"]
}) {
  const data = (metrics ?? {}) as Record<string, unknown>

  const cpuRaw = Number(
    data.cpuUsagePercent ?? data.cpuUsage ?? data.cpu_percent ?? data.cpu ?? NaN
  )
  const cpuPercent = Number.isFinite(cpuRaw) ? clampPercent(cpuRaw) : null

  const totalCandidates = [
    data.memoryTotalBytes,
    data.memory_total,
    data.memoryTotal,
    hardware?.memoryBytes,
    hardware?.memory,
  ]
  let memoryTotalBytes: number | null = null
  for (const candidate of totalCandidates) {
    const parsed = parseBytesLike(candidate)
    if (parsed && Number.isFinite(parsed) && parsed > 0) {
      memoryTotalBytes = parsed
      break
    }
    const numeric = Number(candidate)
    if (Number.isFinite(numeric) && numeric > 0) {
      memoryTotalBytes = numeric
      break
    }
  }

  const usedCandidates = [
    data.memoryUsedBytes,
    data.memoryBytes,
    data.memory_used,
    data.memory,
  ]
  let memoryUsedBytes: number | null = null
  for (const candidate of usedCandidates) {
    const parsed = parseBytesLike(candidate)
    if (parsed !== undefined && Number.isFinite(parsed)) {
      memoryUsedBytes = parsed
      break
    }
    const numeric = Number(candidate)
    if (Number.isFinite(numeric)) {
      memoryUsedBytes = numeric
      break
    }
  }

  const memoryPercentRaw = Number(data.memoryUsedPercent ?? data.memory_percent ?? NaN)
  let memoryPercent = Number.isFinite(memoryPercentRaw) ? clampPercent(memoryPercentRaw) : null
  if (memoryTotalBytes && memoryUsedBytes === null && memoryPercent !== null) {
    memoryUsedBytes = (memoryPercent / 100) * memoryTotalBytes
  } else if (memoryTotalBytes && memoryUsedBytes !== null) {
    memoryPercent = clampPercent((memoryUsedBytes / memoryTotalBytes) * 100)
  }

  let diskTotalBytes: number | null = null
  let diskUsedBytes: number | null = null
  let diskPercent: number | null = null
  if (Array.isArray(disks) && disks.length > 0) {
    let total = 0
    let available = 0
    disks.forEach((disk) => {
      const totalParsed = parseBytesLike(disk?.totalBytes)
      if (typeof totalParsed === "number" && Number.isFinite(totalParsed) && totalParsed > 0) {
        total += totalParsed
      }
      const availableParsed = parseBytesLike(disk?.availableBytes)
      if (typeof availableParsed === "number" && Number.isFinite(availableParsed) && availableParsed >= 0) {
        available += availableParsed
      }
    })
    if (total > 0) {
      diskTotalBytes = total
      const used = Math.max(0, total - available)
      diskUsedBytes = used
      diskPercent = clampPercent((used / total) * 100)
    }
  }
  if (diskPercent === null) {
    const diskMetric = Number(
      data.diskUsage ?? data.disk ?? data.diskUsedPercent ?? data.storageUsedPercent ?? NaN
    )
    if (Number.isFinite(diskMetric)) {
      diskPercent = clampPercent(diskMetric)
    }
  }

  const gpuMetric = Number(
    data.gpuUsagePercent ?? data.gpuUsage ?? data.gpu_percent ?? data.gpu ?? NaN
  )
  const gpuPercent = Number.isFinite(gpuMetric) ? clampPercent(gpuMetric) : null

  return {
    cpuPercent,
    memoryUsedBytes,
    memoryTotalBytes,
    memoryPercent,
    diskPercent,
    diskUsedBytes,
    diskTotalBytes,
    gpuPercent,
  }
}

function MetricsGrid({ metrics, hardware, disks }: { metrics: DeviceMetrics; hardware?: DeviceInventory["hardware"]; disks?: DeviceInventory["disks"] }) {
  const derived = useMemo(
    () => deriveUsageMetrics({ metrics, hardware, disks }),
    [metrics, hardware, disks]
  )

  const cards = [
    {
      key: "cpu",
      label: "CPU",
      percent: derived.cpuPercent,
      primaryText: derived.cpuPercent !== null ? formatPercent(derived.cpuPercent) : "Sem dados",
      secondaryText: derived.cpuPercent !== null ? "Uso instantâneo" : "Sem leituras recentes",
      icon: <Cpu className="size-4 text-neutral-500" />,
      color: "var(--chart-1)",
    },
    {
      key: "memory",
      label: "Memória",
      percent: derived.memoryPercent,
      primaryText:
        derived.memoryUsedBytes !== null && derived.memoryTotalBytes !== null
          ? `${formatBytes(derived.memoryUsedBytes)} / ${formatBytes(derived.memoryTotalBytes)}`
          : derived.memoryPercent !== null
            ? formatPercent(derived.memoryPercent)
            : "Sem dados",
      secondaryText: derived.memoryPercent !== null ? `${Math.round(derived.memoryPercent)}% em uso` : null,
      icon: <MemoryStick className="size-4 text-neutral-500" />,
      color: "var(--chart-2)",
    },
    {
      key: "disk",
      label: "Disco",
      percent: derived.diskPercent,
      primaryText:
        derived.diskUsedBytes !== null && derived.diskTotalBytes !== null
          ? `${formatBytes(derived.diskUsedBytes)} / ${formatBytes(derived.diskTotalBytes)}`
          : derived.diskPercent !== null
            ? formatPercent(derived.diskPercent)
            : "Sem dados",
      secondaryText: derived.diskPercent !== null ? `${Math.round(derived.diskPercent)}% utilizado` : null,
      icon: <HardDrive className="size-4 text-neutral-500" />,
      color: "var(--chart-3)",
    },
  ] as Array<{ key: string; label: string; percent: number | null; primaryText: string; secondaryText?: string | null; icon: ReactNode; color: string }>

  if (derived.gpuPercent !== null) {
    cards.push({
      key: "gpu",
      label: "GPU",
      percent: derived.gpuPercent,
      primaryText: formatPercent(derived.gpuPercent),
      secondaryText: null,
      icon: <Monitor className="size-4 text-neutral-500" />,
      color: "var(--chart-4)",
    })
  }

  return (
    <div className="grid gap-3 md:grid-cols-2 xl:grid-cols-3">
      {cards.map((card) => {
        const percentValue = Number.isFinite(card.percent ?? NaN) ? Math.max(0, Math.min(100, card.percent ?? 0)) : 0
        const percentLabel = card.percent !== null ? `${Math.round(card.percent)}%` : "—"
        return (
          <div key={card.key} className="flex items-center gap-4 rounded-xl border border-slate-200 bg-white px-4 py-3 shadow-sm">
            <div className="relative h-24 w-24">
              <ChartContainer
                config={{ usage: { label: card.label, color: card.color } }}
                className="h-24 w-24 aspect-square"
              >
                <RadialBarChart
                  data={[{ name: card.label, value: percentValue }]}
                  innerRadius="68%"
                  outerRadius="100%"
                  startAngle={90}
                  endAngle={-270}
                >
                  <PolarAngleAxis type="number" domain={[0, 100]} tick={false} />
                  <RadialBar dataKey="value" cornerRadius={10} fill="var(--color-usage)" background />
                </RadialBarChart>
              </ChartContainer>
              <div className="pointer-events-none absolute inset-[18%] flex items-center justify-center rounded-full bg-white/70 text-sm font-semibold text-neutral-900">
                {percentLabel}
              </div>
            </div>
            <div className="flex min-w-0 flex-1 flex-col gap-1">
              <div className="flex items-center gap-2 text-sm font-semibold text-neutral-900">
                {card.icon}
                {card.label}
              </div>
              <div className="text-sm text-neutral-700">{card.primaryText}</div>
              {card.secondaryText ? (
                <div className="text-xs text-neutral-500">{card.secondaryText}</div>
              ) : null}
            </div>
          </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)
}
