"use client"

import { useEffect, useMemo, useState } from "react"
import { useQuery } from "convex/react"
import { format, formatDistanceToNowStrict } from "date-fns"
import { ptBR } from "date-fns/locale"
import { toast } from "sonner"
import { ClipboardCopy, ServerCog } from "lucide-react"

import { api } from "@/convex/_generated/api"
import { Badge } from "@/components/ui/badge"
import { Button } from "@/components/ui/button"
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from "@/components/ui/table"
import { Separator } from "@/components/ui/separator"
import { cn } from "@/lib/utils"

type MachineMetrics = Record<string, unknown> | null

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

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

type MachineInventory = {
  hardware?: {
    vendor?: string
    model?: string
    serial?: string
    cpuType?: string
    physicalCores?: number
    logicalCores?: number
    memoryBytes?: number
    memory?: number
  }
  network?: {
    primaryIp?: string
    publicIp?: string
    macAddresses?: string[]
  }
  software?: MachineSoftware[]
  labels?: MachineLabel[]
  fleet?: {
    id?: number | string
    teamId?: number | string
    detailUpdatedAt?: string
    osqueryVersion?: string
  }
}

type MachinesQueryItem = {
  id: string
  tenantId: string
  hostname: string
  companyId: string | null
  companySlug: string | null
  osName: string | null
  osVersion: string | null
  architecture: string | null
  macAddresses: string[]
  serialNumbers: string[]
  authUserId: string | null
  authEmail: string | null
  status: string | null
  lastHeartbeatAt: number | null
  heartbeatAgeMs: number | null
  registeredBy: string | null
  createdAt: number
  updatedAt: number
  token: {
    expiresAt: number
    lastUsedAt: number | null
    usageCount: number
  } | null
  metrics: MachineMetrics
  inventory: MachineInventory | null
}

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

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

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

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

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

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

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

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

export function AdminMachinesOverview({ tenantId }: { tenantId: string }) {
  const machines = useMachinesQuery(tenantId)
  const [selectedId, setSelectedId] = useState<string | null>(null)

  useEffect(() => {
    if (machines.length === 0) {
      setSelectedId(null)
      return
    }
    if (!selectedId) {
      setSelectedId(machines[0]?.id ?? null)
    } else if (!machines.some((machine) => machine.id === selectedId)) {
      setSelectedId(machines[0]?.id ?? null)
    }
  }, [machines, selectedId])

  const selectedMachine = useMemo(() => machines.find((item) => item.id === selectedId) ?? null, [machines, selectedId])

  return (
    <div className="grid gap-6 xl:grid-cols-[minmax(0,1fr)_minmax(0,400px)]">
      <Card className="border-slate-200">
        <CardHeader>
          <CardTitle>Máquinas registradas</CardTitle>
          <CardDescription>Sincronizadas via agente local ou Fleet. Atualiza em tempo real.</CardDescription>
        </CardHeader>
        <CardContent className="overflow-hidden">
          {machines.length === 0 ? (
            <EmptyState />
          ) : (
            <div className="overflow-x-auto max-h-[70vh] overflow-y-auto rounded-md border border-slate-200">
              <Table className="">
                <TableHeader className="sticky top-0 z-10 bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/60">
                  <TableRow className="border-slate-200">
                    <TableHead>Hostname</TableHead>
                    <TableHead>Status</TableHead>
                    <TableHead>Último heartbeat</TableHead>
                    <TableHead>Empresa</TableHead>
                    <TableHead>Plataforma</TableHead>
                  </TableRow>
                </TableHeader>
                <TableBody>
                  {machines.map((machine: MachinesQueryItem) => (
                    <TableRow
                      key={machine.id}
                      onClick={() => setSelectedId(machine.id)}
                      className={cn(
                        "cursor-pointer transition-colors hover:bg-muted/50",
                        selectedId === machine.id ? "bg-muted/60" : undefined
                      )}
                    >
                      <TableCell>
                        <div className="font-medium">{machine.hostname}</div>
                        <p className="text-xs text-muted-foreground">{machine.authEmail ?? "—"}</p>
                      </TableCell>
                      <TableCell className="align-middle">
                        <div className="flex items-center">
                          <MachineStatusBadge status={machine.status} />
                        </div>
                      </TableCell>
                      <TableCell>
                        <p className="text-sm text-muted-foreground">
                          {formatRelativeTime(machine.lastHeartbeatAt ? new Date(machine.lastHeartbeatAt) : null)}
                        </p>
                      </TableCell>
                      <TableCell>
                        <p className="text-sm font-medium text-muted-foreground">{machine.companySlug ?? "—"}</p>
                      </TableCell>
                      <TableCell>
                        <p className="text-sm font-medium">
                          {machine.osName ?? "—"}
                          {machine.osVersion ? ` ${machine.osVersion}` : ""}
                        </p>
                        <p className="text-xs text-muted-foreground">
                          {machine.architecture ? machine.architecture.toUpperCase() : "—"}
                        </p>
                      </TableCell>
                    </TableRow>
                  ))}
                </TableBody>
              </Table>
            </div>
          )}
        </CardContent>
      </Card>

      <MachineDetails machine={selectedMachine ?? null} />
    </div>
  )
}

function MachineStatusBadge({ status }: { status?: string | null }) {
  const { label, className } = getStatusVariant(status)
  return <Badge className={cn("border", className)}>{label}</Badge>
}

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

type MachineDetailsProps = {
  machine: MachinesQueryItem | null
}

function MachineDetails({ machine }: MachineDetailsProps) {
  const metadata = machine?.inventory ?? null
  const metrics = machine?.metrics ?? null
  const hardware = metadata?.hardware ?? null
  const network = metadata?.network ?? null
  const software = metadata?.software ?? null
  const labels = metadata?.labels ?? null
  const fleet = metadata?.fleet ?? null

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

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

  return (
    <Card className="border-slate-200">
      <CardHeader>
        <CardTitle>Detalhes</CardTitle>
        <CardDescription>Resumo da máquina selecionada.</CardDescription>
      </CardHeader>
      <CardContent className="space-y-6">
        {!machine ? (
          <p className="text-sm text-muted-foreground">Selecione uma máquina para visualizar detalhes.</p>
        ) : (
          <div className="space-y-6">
            <section className="space-y-3">
              <div className="flex items-start justify-between gap-2">
                <div className="space-y-1">
                  <p className="text-sm font-semibold text-foreground">{machine.hostname}</p>
                  <p className="text-xs text-muted-foreground">
                    {machine.authEmail ?? "E-mail não definido"}
                  </p>
                  {machine.companySlug ? (
                    <p className="text-xs text-muted-foreground">
                      Empresa vinculada: <span className="font-medium text-foreground">{machine.companySlug}</span>
                    </p>
                  ) : null}
                </div>
                <MachineStatusBadge status={machine.status} />
              </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">
                  {machine.osName ?? "SO desconhecido"} {machine.osVersion ?? ""}
                </Badge>
                <Badge variant="outline" className="border-slate-300 bg-slate-100 text-xs font-medium text-slate-700">
                  {machine.architecture?.toUpperCase() ?? "Arquitetura indefinida"}
                </Badge>
              </div>
                <div className="flex flex-wrap gap-2">
                  {machine.authEmail ? (
                    <Button size="sm" variant="outline" onClick={copyEmail} className="gap-2">
                      <ClipboardCopy className="size-4" />
                      Copiar e-mail
                  </Button>
                ) : null}
                {machine.registeredBy ? (
                  <Badge variant="outline">Registrada via {machine.registeredBy}</Badge>
                ) : null}
              </div>
            </section>

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

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

            {hardware || network || (labels && labels.length > 0) ? (
              <section className="space-y-3">
                <div>
                  <h4 className="text-sm font-semibold">Inventário</h4>
                  <p className="text-xs text-muted-foreground">
                    Dados sincronizados via agente ou Fleet.
                  </p>
                </div>
                <div className="space-y-3 text-sm text-muted-foreground">
                  {hardware ? (
                    <div className="rounded-md border border-slate-200 bg-slate-50/60 p-3">
                      <p className="text-xs font-semibold uppercase text-slate-500">Hardware</p>
                      <div className="mt-2 grid gap-1">
                        <DetailLine label="Fabricante" value={hardware.vendor} />
                        <DetailLine label="Modelo" value={hardware.model} />
                        <DetailLine label="Número de série" value={hardware.serial} />
                        <DetailLine label="CPU" value={hardware.cpuType} />
                        <DetailLine
                          label="Núcleos"
                          value={`${hardware.physicalCores ?? "?"} físicos / ${hardware.logicalCores ?? "?"} lógicos`}
                        />
                        <DetailLine label="Memória" value={formatBytes(Number(hardware.memoryBytes ?? hardware.memory))} />
                      </div>
                    </div>
                  ) : null}

                  {network ? (
                    <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={network.primaryIp} />
                        <DetailLine label="IP público" value={network.publicIp} />
                        <DetailLine
                          label="MAC addresses"
                          value={
                            Array.isArray(network.macAddresses)
                              ? (network.macAddresses as string[]).join(", ")
                              : machine?.macAddresses.join(", ")
                          }
                        />
                      </div>
                    </div>
                  ) : null}

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

            {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}
          </div>
        )}
      </CardContent>
    </Card>
  )
}

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

function MetricsGrid({ metrics }: { metrics: MachineMetrics }) {
  const data = (metrics ?? {}) as Record<string, unknown>
  const cpu = Number(data.cpuUsage ?? data.cpu ?? data.cpu_percent ?? NaN)
  const memory = Number(data.memoryBytes ?? data.memory ?? data.memory_used ?? NaN)
  const disk = Number(data.diskUsage ?? data.disk ?? NaN)

  return (
    <div className="grid gap-2 rounded-md border border-slate-200 bg-slate-50/60 p-3 text-sm text-muted-foreground sm:grid-cols-3">
      <div>
        <p className="text-xs uppercase text-slate-500">CPU</p>
        <p className="text-sm font-semibold text-foreground">{formatPercent(cpu)}</p>
      </div>
      <div>
        <p className="text-xs uppercase text-slate-500">Memória</p>
        <p className="text-sm font-semibold text-foreground">{formatBytes(memory)}</p>
      </div>
      <div>
        <p className="text-xs uppercase text-slate-500">Disco</p>
        <p className="text-sm font-semibold text-foreground">
          {Number.isNaN(disk) ? "—" : `${formatPercent(disk)}`}
        </p>
      </div>
    </div>
  )
}
