"use client"

import Link from "next/link"
import { useCallback, useEffect, useMemo, useState, useTransition } from "react"
import { IconSearch, IconUserPlus, IconTrash } from "@tabler/icons-react"

import { toast } from "sonner"

import { Badge } from "@/components/ui/badge"
import { Button } from "@/components/ui/button"
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"
import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from "@/components/ui/dialog"
import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"
import { Checkbox } from "@/components/ui/checkbox"
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select"
import { Sheet, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetTitle } from "@/components/ui/sheet"
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"
import { ROLE_OPTIONS, type RoleOption } from "@/lib/authz"
import { canReactivateInvite as canReactivateInvitePolicy } from "@/lib/invite-policies"

type AdminRole = RoleOption | "machine"
const NO_COMPANY_ID = "__none__"

type AdminUser = {
  id: string
  email: string
  name: string
  role: AdminRole
  tenantId: string
  createdAt: string
  updatedAt: string | null
  companyId: string | null
  companyName: string | null
  machinePersona: string | null
}

type AdminInvite = {
  id: string
  email: string
  name: string | null
  role: RoleOption
  tenantId: string
  status: "pending" | "accepted" | "revoked" | "expired"
  token: string
  inviteUrl: string
  expiresAt: string
  createdAt: string
  createdById: string | null
  acceptedAt: string | null
  acceptedById: string | null
  revokedAt: string | null
  revokedById: string | null
  revokedReason: string | null
}

type CompanyOption = {
  id: string
  name: string
}

type Props = {
  initialUsers: AdminUser[]
  initialInvites: AdminInvite[]
  roleOptions: readonly AdminRole[]
  defaultTenantId: string
  viewerRole: string
}

const ROLE_LABELS: Record<string, string> = {
  admin: "Administrador",
  manager: "Gestor",
  agent: "Agente",
  collaborator: "Colaborador",
  machine: "Agente de máquina",
}

function formatRole(role: string) {
  const key = role?.toLowerCase?.() ?? ""
  return ROLE_LABELS[key] ?? role
}

function formatMachinePersona(persona: string | null | undefined) {
  const normalized = persona?.toLowerCase?.() ?? ""
  if (normalized === "manager") return "Gestor"
  if (normalized === "collaborator") return "Colaborador"
  return "Sem persona"
}

function machinePersonaBadgeVariant(persona: string | null | undefined) {
  const normalized = persona?.toLowerCase?.() ?? ""
  if (normalized === "manager") return "secondary" as const
  if (normalized === "collaborator") return "outline" as const
  return "outline" as const
}

function formatTenantLabel(tenantId: string, defaultTenantId: string) {
  if (!tenantId) return "Principal"
  if (tenantId === defaultTenantId) return "Principal"
  return tenantId
}

function formatDate(dateIso: string) {
  const date = new Date(dateIso)
  return new Intl.DateTimeFormat("pt-BR", {
    dateStyle: "medium",
    timeStyle: "short",
  }).format(date)
}

function formatStatus(status: AdminInvite["status"]) {
  switch (status) {
    case "pending":
      return "Pendente"
    case "accepted":
      return "Aceito"
    case "revoked":
      return "Revogado"
    case "expired":
      return "Expirado"
    default:
      return status
  }
}

function inviteStatusVariant(status: AdminInvite["status"]) {
  switch (status) {
    case "pending":
      return "secondary" as const
    case "accepted":
      return "default" as const
    case "revoked":
      return "destructive" as const
    default:
      return "outline" as const
  }
}

function sanitizeInvite(invite: AdminInvite & { events?: unknown }): AdminInvite {
  const { events: unusedEvents, ...rest } = invite
  void unusedEvents
  return rest
}

function coerceRole(role: AdminRole | string | null | undefined): RoleOption {
  const candidate = (role ?? "agent").toLowerCase()
  return (ROLE_OPTIONS as readonly string[]).includes(candidate) ? (candidate as RoleOption) : "agent"
}

function extractMachineId(email: string): string | null {
  const match = /^machine-(.+)@machines\.local$/i.exec(email.trim())
  return match ? match[1] : null
}

function isRestrictedRole(role?: string | null) {
  const normalized = (role ?? "").toLowerCase()
  return normalized === "admin" || normalized === "agent"
}

export function AdminUsersManager({ initialUsers, initialInvites, roleOptions, defaultTenantId, viewerRole }: Props) {
  const [users, setUsers] = useState<AdminUser[]>(initialUsers)
  const [invites, setInvites] = useState<AdminInvite[]>(initialInvites)
  const [companies, setCompanies] = useState<CompanyOption[]>([])

  const [email, setEmail] = useState("")
  const [name, setName] = useState("")
  const [role, setRole] = useState<RoleOption>("agent")
  const [tenantId, setTenantId] = useState(defaultTenantId)
  const [expiresInDays, setExpiresInDays] = useState("7")
  const [lastInviteLink, setLastInviteLink] = useState<string | null>(null)
  const [revokingId, setRevokingId] = useState<string | null>(null)
  const [reactivatingId, setReactivatingId] = useState<string | null>(null)
  const [isPending, startTransition] = useTransition()

  const [linkEmail, setLinkEmail] = useState("")
  const [linkCompanyId, setLinkCompanyId] = useState("")
  const [assigningCompany, setAssigningCompany] = useState(false)

  const [editUserId, setEditUserId] = useState<string | null>(null)
  const editUser = useMemo(() => users.find((user) => user.id === editUserId) ?? null, [users, editUserId])
  const [editForm, setEditForm] = useState({
    name: "",
    email: "",
    role: "agent" as RoleOption,
    tenantId: defaultTenantId,
    companyId: "",
  })
  const [isSavingUser, setIsSavingUser] = useState(false)
  const [isResettingPassword, setIsResettingPassword] = useState(false)
  const [passwordPreview, setPasswordPreview] = useState<string | null>(null)
  const [deleteUserId, setDeleteUserId] = useState<string | null>(null)
  const deleteTarget = useMemo(
    () => users.find((candidate) => candidate.id === deleteUserId) ?? null,
    [users, deleteUserId]
  )
  const [isDeletingUser, setIsDeletingUser] = useState(false)
  const [revokeDialogInviteId, setRevokeDialogInviteId] = useState<string | null>(null)
  const revokeCandidate = useMemo(
    () => invites.find((invite) => invite.id === revokeDialogInviteId) ?? null,
    [invites, revokeDialogInviteId]
  )
  const viewerRoleNormalized = viewerRole?.toLowerCase?.() ?? "agent"
  const viewerIsAdmin = viewerRoleNormalized === "admin"
  const canManageUser = useCallback((role?: string | null) => viewerIsAdmin || !isRestrictedRole(role), [viewerIsAdmin])
  const canManageInvite = useCallback((role: RoleOption) => viewerIsAdmin || !["admin", "agent"].includes(role), [viewerIsAdmin])

  const normalizedRoles = useMemo<readonly AdminRole[]>(() => {
    return (roleOptions && roleOptions.length > 0 ? roleOptions : ROLE_OPTIONS) as readonly AdminRole[]
  }, [roleOptions])
  const selectableRoles = useMemo(() => {
    const unique = new Set<RoleOption>()
    normalizedRoles.forEach((roleOption) => {
      const coerced = coerceRole(roleOption)
      if (!viewerIsAdmin && isRestrictedRole(coerced)) return
      unique.add(coerced)
    })
    return Array.from(unique)
  }, [normalizedRoles, viewerIsAdmin])
  // Split users: team (admin/agent) and people (manager/collaborator); exclude machines
  const teamUsers = useMemo(
    () => users.filter((user) => user.role !== "machine" && ["admin", "agent"].includes(coerceRole(user.role))),
    [users],
  )
  const peopleUsers = useMemo(
    () => users.filter((user) => user.role !== "machine" && ["manager", "collaborator"].includes(coerceRole(user.role))),
    [users],
  )
  const machineUsers = useMemo(() => users.filter((user) => user.role === "machine"), [users])

  const defaultCreateRole: RoleOption = selectableRoles[0] ?? "agent"
  // Equipe
  const [teamSearch, setTeamSearch] = useState("")
  const [teamRoleFilter, setTeamRoleFilter] = useState<"all" | RoleOption>("all")
  const [teamCompanyFilter, setTeamCompanyFilter] = useState<string>("all")
  const [teamTenantFilter, setTeamTenantFilter] = useState<string>("all")
  const [teamSelection, setTeamSelection] = useState<Set<string>>(new Set())
  const [isBulkDeletingTeam, setIsBulkDeletingTeam] = useState(false)
  const [bulkDeleteTeamOpen, setBulkDeleteTeamOpen] = useState(false)
  // Usuários
  const [peopleSearch, setPeopleSearch] = useState("")
  const [peopleRoleFilter, setPeopleRoleFilter] = useState<"all" | "manager" | "collaborator">("all")
  const [peopleCompanyFilter, setPeopleCompanyFilter] = useState<string>("all")
  const [peopleTenantFilter, setPeopleTenantFilter] = useState<string>("all")
  const [peopleSelection, setPeopleSelection] = useState<Set<string>>(new Set())
  const [isBulkDeletingPeople, setIsBulkDeletingPeople] = useState(false)
  const [bulkDeletePeopleOpen, setBulkDeletePeopleOpen] = useState(false)
  const [machineSearch, setMachineSearch] = useState("")
  const [machinePersonaFilter, setMachinePersonaFilter] = useState<"all" | "manager" | "collaborator" | "unassigned">("all")
  const [machineSelection, setMachineSelection] = useState<Set<string>>(new Set())
  const [isBulkDeletingMachines, setIsBulkDeletingMachines] = useState(false)
  const [bulkDeleteMachinesOpen, setBulkDeleteMachinesOpen] = useState(false)
  // Unificado (pessoas + máquinas)
  const [usersSearch, setUsersSearch] = useState("")
  const [usersTypeFilter, setUsersTypeFilter] = useState<"all" | "people" | "machines">("all")
  const [usersCompanyFilter, setUsersCompanyFilter] = useState<string>("all")
  const [usersTenantFilter, setUsersTenantFilter] = useState<string>("all")
  const [usersSelection, setUsersSelection] = useState<Set<string>>(new Set())
  const [isBulkDeletingUsersCombined, setIsBulkDeletingUsersCombined] = useState(false)
  const [bulkDeleteUsersCombinedOpen, setBulkDeleteUsersCombinedOpen] = useState(false)
  const [createDialogOpen, setCreateDialogOpen] = useState(false)
  const [createForm, setCreateForm] = useState({
    name: "",
    email: "",
    role: defaultCreateRole,
    tenantId: defaultTenantId,
    companyId: NO_COMPANY_ID,
  })
  const [isCreatingUser, setIsCreatingUser] = useState(false)
  const [createPassword, setCreatePassword] = useState<string | null>(null)

  // Options of tenants present in dataset for filtering
  const tenantOptions = useMemo(() => {
    const set = new Set<string>()
    users.forEach((u) => u.tenantId && set.add(u.tenantId))
    const list = Array.from(set)
    return list.length > 0 ? list : [defaultTenantId]
  }, [users, defaultTenantId])

  const filteredTeamUsers = useMemo(() => {
    const term = teamSearch.trim().toLowerCase()
    return teamUsers.filter((user) => {
      if (teamCompanyFilter !== "all" && user.companyId !== teamCompanyFilter) return false
      if (teamTenantFilter !== "all" && (user.tenantId ?? defaultTenantId) !== teamTenantFilter) return false
      if (teamRoleFilter !== "all" && coerceRole(user.role) !== teamRoleFilter) return false
      if (!term) return true
      const haystack = [
        user.name ?? "",
        user.email ?? "",
        user.companyName ?? "",
        formatRole(user.role),
      ]
        .join(" ")
        .toLowerCase()
      return haystack.includes(term)
    })
  }, [teamUsers, teamSearch, teamRoleFilter, teamCompanyFilter, teamTenantFilter, defaultTenantId])

  const filteredPeopleUsers = useMemo(() => {
    const term = peopleSearch.trim().toLowerCase()
    return peopleUsers.filter((user) => {
      const role = coerceRole(user.role)
      if (peopleRoleFilter !== "all" && role !== peopleRoleFilter) return false
      if (peopleCompanyFilter !== "all" && user.companyId !== peopleCompanyFilter) return false
      if (peopleTenantFilter !== "all" && (user.tenantId ?? defaultTenantId) !== peopleTenantFilter) return false
      if (!term) return true
      const haystack = [
        user.name ?? "",
        user.email ?? "",
        user.companyName ?? "",
        formatRole(user.role),
      ]
        .join(" ")
        .toLowerCase()
      return haystack.includes(term)
    })
  }, [peopleUsers, peopleSearch, peopleRoleFilter, peopleCompanyFilter, peopleTenantFilter, defaultTenantId])

  const filteredMachineUsers = useMemo(() => {
    const term = machineSearch.trim().toLowerCase()
    return machineUsers.filter((user) => {
      const persona = (user.machinePersona ?? "unassigned").toLowerCase()
      if (machinePersonaFilter !== "all") {
        if (machinePersonaFilter === "unassigned" && persona !== "unassigned") return false
        if (machinePersonaFilter !== "unassigned" && persona !== machinePersonaFilter) return false
      }
      if (!term) return true
      return (
        (user.name ?? "").toLowerCase().includes(term) ||
        user.email.toLowerCase().includes(term) ||
        persona.includes(term) ||
        (extractMachineId(user.email) ?? "").toLowerCase().includes(term)
      )
    })
  }, [machineUsers, machinePersonaFilter, machineSearch])

  const combinedBaseUsers = useMemo(() => {
    if (usersTypeFilter === "people") return peopleUsers
    if (usersTypeFilter === "machines") return machineUsers
    return [...peopleUsers, ...machineUsers]
  }, [peopleUsers, machineUsers, usersTypeFilter])

  const filteredCombinedUsers = useMemo(() => {
    const term = usersSearch.trim().toLowerCase()
    return combinedBaseUsers.filter((user) => {
      if (usersCompanyFilter !== "all" && user.companyId !== usersCompanyFilter) return false
      if (usersTenantFilter !== "all" && (user.tenantId ?? defaultTenantId) !== usersTenantFilter) return false
      if (!term) return true
      const persona = (user.machinePersona ?? "").toLowerCase()
      const machineId = extractMachineId(user.email) ?? ""
      const haystack = [
        user.name ?? "",
        user.email ?? "",
        user.companyName ?? "",
        formatRole(user.role),
        persona,
        machineId,
      ]
        .join(" ")
        .toLowerCase()
      return haystack.includes(term)
    })
  }, [combinedBaseUsers, usersSearch, usersCompanyFilter, usersTenantFilter, defaultTenantId])

  useEffect(() => {
    void (async () => {
      try {
        const response = await fetch("/api/admin/companies", { credentials: "include" })
        const json = (await response.json()) as { companies?: CompanyOption[] }
        const mapped = (json.companies ?? []).map((company) => ({ id: company.id, name: company.name }))
        setCompanies(mapped)
        if (mapped.length > 0 && !linkCompanyId) {
          setLinkCompanyId(mapped[0].id)
        }
      } catch (error) {
        console.error("Falha ao carregar empresas", error)
      }
    })()
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [])

  useEffect(() => {
    if (!editUser) {
      setEditForm({ name: "", email: "", role: "agent", tenantId: defaultTenantId, companyId: "" })
      setPasswordPreview(null)
      return
    }

    setEditForm({
      name: editUser.name || "",
      email: editUser.email,
      role: coerceRole(editUser.role),
      tenantId: editUser.tenantId || defaultTenantId,
      companyId: editUser.companyId ?? "",
    })
    setPasswordPreview(null)
  }, [editUser, defaultTenantId])
  useEffect(() => {
    setCreateForm((prev) => ({
      ...prev,
      role: defaultCreateRole,
      tenantId: defaultTenantId,
    }))
  }, [defaultCreateRole, defaultTenantId])


  async function handleInviteSubmit(event: React.FormEvent<HTMLFormElement>) {
    event.preventDefault()
    const normalizedEmail = email.trim().toLowerCase()
    if (!normalizedEmail || !normalizedEmail.includes("@")) {
      toast.error("Informe um e-mail válido")
      return
    }

    const payload = {
      email: normalizedEmail,
      name: name.trim(),
      role,
      tenantId,
      expiresInDays: Number.parseInt(expiresInDays, 10),
    }

    startTransition(async () => {
      try {
        const response = await fetch("/api/admin/invites", {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify(payload),
        })

        if (!response.ok) {
          const data = await response.json().catch(() => ({}))
          throw new Error(data.error ?? "Não foi possível gerar o convite")
        }

        const data = (await response.json()) as { invite: AdminInvite }
        const nextInvite = sanitizeInvite(data.invite)
        setInvites((previous) => [nextInvite, ...previous.filter((item) => item.id !== nextInvite.id)])
        setEmail("")
        setName("")
        setRole("agent")
        setTenantId(defaultTenantId)
        setExpiresInDays("7")
        setLastInviteLink(nextInvite.inviteUrl)
        toast.success("Convite criado com sucesso")
      } catch (error) {
        const message = error instanceof Error ? error.message : "Falha ao criar convite"
        toast.error(message)
      }
    })
  }

  function handleCopy(link: string) {
    navigator.clipboard
      .writeText(link)
      .then(() => toast.success("Link de convite copiado"))
      .catch(() => toast.error("Não foi possível copiar o link"))
  }

  async function handleRevokeConfirmed() {
    if (!revokeCandidate || revokeCandidate.status !== "pending") {
      setRevokeDialogInviteId(null)
      return
    }

    if (!canManageInvite(revokeCandidate.role)) {
      toast.error("Você não pode revogar convites deste papel")
      setRevokeDialogInviteId(null)
      return
    }

    setRevokingId(revokeCandidate.id)
    try {
      const response = await fetch(`/api/admin/invites/${revokeCandidate.id}`, {
        method: "PATCH",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ reason: "Revogado manualmente" }),
      })

      if (!response.ok) {
        const data = await response.json().catch(() => ({}))
        throw new Error(data.error ?? "Falha ao revogar convite")
      }

      const data = (await response.json()) as { invite: AdminInvite }
      const updated = sanitizeInvite(data.invite)
      setInvites((previous) => previous.map((item) => (item.id === updated.id ? updated : item)))
      toast.success("Convite revogado")
    } catch (error) {
      const message = error instanceof Error ? error.message : "Erro ao revogar convite"
      toast.error(message)
    } finally {
      setRevokingId(null)
      setRevokeDialogInviteId(null)
    }
  }

  async function handleReactivate(invite: AdminInvite) {
    if (!canReactivateInvitePolicy(invite)) return
    if (!canManageInvite(invite.role)) {
      toast.error("Você não pode reativar convites deste papel")
      return
    }
    setReactivatingId(invite.id)
    try {
      const response = await fetch(`/api/admin/invites/${invite.id}`, {
        method: "PATCH",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ action: "reactivate" }),
      })
      if (!response.ok) {
        const data = await response.json().catch(() => ({}))
        throw new Error(data.error ?? "Falha ao reativar convite")
      }
      const data = (await response.json()) as { invite: AdminInvite }
      const normalized = sanitizeInvite(data.invite)
      setInvites((previous) => previous.map((item) => (item.id === normalized.id ? normalized : item)))
      toast.success("Convite reativado")
    } catch (error) {
      const message = error instanceof Error ? error.message : "Não foi possível reativar"
      toast.error(message)
    } finally {
      setReactivatingId(null)
    }
  }

  async function handleAssignCompany(event: React.FormEvent<HTMLFormElement>) {
    event.preventDefault()
    const normalizedEmail = linkEmail.trim().toLowerCase()
    if (!normalizedEmail || !normalizedEmail.includes("@")) {
      toast.error("Informe um e-mail válido para vincular")
      return
    }
    if (!linkCompanyId) {
      toast.error("Selecione a empresa para vincular")
      return
    }

    setAssigningCompany(true)
    toast.loading("Vinculando colaborador...", { id: "assign-company" })
    try {
      const response = await fetch("/api/admin/users/assign-company", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ email: normalizedEmail, companyId: linkCompanyId }),
        credentials: "include",
      })
      if (!response.ok) {
        const data = await response.json().catch(() => ({}))
        throw new Error(data.error ?? "Falha ao vincular")
      }
      toast.success("Colaborador vinculado com sucesso", { id: "assign-company" })
      setLinkEmail("")
      setLinkCompanyId("")
    } catch (error) {
      const message = error instanceof Error ? error.message : "Não foi possível vincular"
      toast.error(message, { id: "assign-company" })
    } finally {
      setAssigningCompany(false)
    }
  }

  const resetCreateForm = useCallback(() => {
    setCreateForm({
      name: "",
      email: "",
      role: defaultCreateRole,
      tenantId: defaultTenantId,
      companyId: NO_COMPANY_ID,
    })
    setCreatePassword(null)
  }, [defaultCreateRole, defaultTenantId])

  const handleOpenCreateUser = useCallback(() => {
    resetCreateForm()
    setCreateDialogOpen(true)
  }, [resetCreateForm])

  const handleCloseCreateDialog = useCallback(() => {
    resetCreateForm()
    setCreateDialogOpen(false)
  }, [resetCreateForm])

  async function handleCreateUser(event: React.FormEvent<HTMLFormElement>) {
    event.preventDefault()

    const payload = {
      name: createForm.name.trim(),
      email: createForm.email.trim().toLowerCase(),
      role: createForm.role,
      tenantId: createForm.tenantId.trim() || defaultTenantId,
    }

    if (!payload.name) {
      toast.error("Informe o nome do usuário")
      return
    }
    if (!payload.email || !payload.email.includes("@")) {
      toast.error("Informe um e-mail válido")
      return
    }

    setIsCreatingUser(true)
    setCreatePassword(null)
    try {
      const response = await fetch("/api/admin/users", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        credentials: "include",
        body: JSON.stringify(payload),
      })

      if (!response.ok) {
        const data = await response.json().catch(() => ({}))
        throw new Error(data.error ?? "Não foi possível criar o usuário")
      }

      const data = (await response.json()) as { user: { id: string; email: string; name: string | null; role: string; tenantId: string | null; createdAt: string }; temporaryPassword: string }
      const normalizedRole = coerceRole(data.user.role)
      const normalizedUser: AdminUser = {
        id: data.user.id,
        email: data.user.email,
        name: data.user.name ?? data.user.email,
        role: normalizedRole,
        tenantId: data.user.tenantId ?? defaultTenantId,
        createdAt: data.user.createdAt,
        updatedAt: null,
        companyId: null,
        companyName: null,
        machinePersona: null,
      }

      if (createForm.companyId && createForm.companyId !== NO_COMPANY_ID) {
        try {
          const assignResponse = await fetch("/api/admin/users/assign-company", {
            method: "POST",
            headers: { "Content-Type": "application/json" },
            credentials: "include",
            body: JSON.stringify({ email: normalizedUser.email, companyId: createForm.companyId }),
          })
          if (assignResponse.ok) {
            const company = companies.find((company) => company.id === createForm.companyId)
            normalizedUser.companyId = createForm.companyId
            normalizedUser.companyName = company?.name ?? null
          } else {
            const assignData = await assignResponse.json().catch(() => ({}))
            toast.error(assignData.error ?? "Não foi possível vincular a empresa")
          }
        } catch (error) {
          const message = error instanceof Error ? error.message : "Falha ao vincular empresa"
          toast.error(message)
        }
      }

      setUsers((previous) => [normalizedUser, ...previous])
      setCreatePassword(data.temporaryPassword)
      toast.success("Usuário criado com sucesso")
      setCreateForm((prev) => ({
        ...prev,
        name: "",
        email: "",
        companyId: NO_COMPANY_ID,
      }))
    } catch (error) {
      const message = error instanceof Error ? error.message : "Erro ao criar usuário"
      toast.error(message)
    } finally {
      setIsCreatingUser(false)
    }
  }

  // Bulk selection helpers
  const selectedTeamUsers = useMemo(() => filteredTeamUsers.filter((u) => teamSelection.has(u.id)), [filteredTeamUsers, teamSelection])
  const allTeamSelected = selectedTeamUsers.length > 0 && selectedTeamUsers.length === filteredTeamUsers.length
  const someTeamSelected = selectedTeamUsers.length > 0 && !allTeamSelected

  const selectedPeopleUsers = useMemo(() => filteredPeopleUsers.filter((u) => peopleSelection.has(u.id)), [filteredPeopleUsers, peopleSelection])
  const allPeopleSelected = selectedPeopleUsers.length > 0 && selectedPeopleUsers.length === filteredPeopleUsers.length
  const somePeopleSelected = selectedPeopleUsers.length > 0 && !allPeopleSelected

  const selectedMachineUsers = useMemo(() => filteredMachineUsers.filter((u) => machineSelection.has(u.id)), [filteredMachineUsers, machineSelection])

  const [inviteSelection, setInviteSelection] = useState<Set<string>>(new Set())
  const selectedInvites = useMemo(() => invites.filter((i) => inviteSelection.has(i.id)), [invites, inviteSelection])
  const allInvitesSelected = selectedInvites.length > 0 && selectedInvites.length === invites.length
  const someInvitesSelected = selectedInvites.length > 0 && !allInvitesSelected
  const [isBulkRevokingInvites, setIsBulkRevokingInvites] = useState(false)
  const [bulkRevokeInvitesOpen, setBulkRevokeInvitesOpen] = useState(false)

  function toggleTeamSelectAll(checked: boolean) {
    setTeamSelection(checked ? new Set(filteredTeamUsers.map((u) => u.id)) : new Set())
  }
  function togglePeopleSelectAll(checked: boolean) {
    setPeopleSelection(checked ? new Set(filteredPeopleUsers.map((u) => u.id)) : new Set())
  }
  function toggleMachinesSelectAll(checked: boolean) {
    setMachineSelection(checked ? new Set(filteredMachineUsers.map((u) => u.id)) : new Set())
  }
  function toggleInvitesSelectAll(checked: boolean) {
    setInviteSelection(checked ? new Set(invites.map((i) => i.id)) : new Set())
  }

  function toggleUsersCombinedSelectAll(checked: boolean) {
    setUsersSelection(checked ? new Set(filteredCombinedUsers.map((u) => u.id)) : new Set())
  }

  async function performBulkDeleteUsers(ids: string[]) {
    if (ids.length === 0) return
    const tasks = ids.map(async (id) => {
      const user = users.find((u) => u.id === id)
      if (!user) return
      if (!canManageUser(user.role)) return
      const response = await fetch(`/api/admin/users/${id}`, { method: "DELETE", credentials: "include" })
      if (!response.ok) {
        const data = await response.json().catch(() => ({}))
        throw new Error(data.error ?? `Falha ao remover ${user.email}`)
      }
    })
    await Promise.allSettled(tasks)
    setUsers((prev) => prev.filter((u) => !ids.includes(u.id)))
  }

  async function performBulkDeleteMachines(ids: string[]) {
    if (ids.length === 0) return
    const tasks = ids.map(async (id) => {
      const user = users.find((u) => u.id === id)
      if (!user) return
      const machineId = extractMachineId(user.email)
      if (!machineId) return
      const response = await fetch(`/api/admin/machines/delete`, {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        credentials: "include",
        body: JSON.stringify({ machineId }),
      })
      if (!response.ok) {
        const data = await response.json().catch(() => ({}))
        throw new Error(data.error ?? `Falha ao remover agente ${user.email}`)
      }
    })
    await Promise.allSettled(tasks)
    setUsers((prev) => prev.filter((u) => !ids.includes(u.id)))
  }

  async function performBulkRevokeInvites(ids: string[]) {
    if (ids.length === 0) return
    const tasks = ids.map(async (id) => {
      const invite = invites.find((i) => i.id === id)
      if (!invite) return
      if (!canManageInvite(invite.role)) return
      const response = await fetch(`/api/admin/invites/${id}`, {
        method: "PATCH",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ reason: "Revogado em massa" }),
      })
      if (!response.ok) {
        const data = await response.json().catch(() => ({}))
        throw new Error(data.error ?? `Falha ao revogar ${invite.email}`)
      }
    })
    await Promise.allSettled(tasks)
    setInvites((prev) => prev.map((i) => (ids.includes(i.id) && i.status === "pending" ? { ...i, status: "revoked", revokedAt: new Date().toISOString() } : i)))
  }

  async function performBulkDeleteUsersCombined(ids: string[]) {
    if (ids.length === 0) return
    const machineIds: string[] = []
    const humanIds: string[] = []
    ids.forEach((id) => {
      const u = users.find((x) => x.id === id)
      if (!u) return
      if (u.role === "machine") machineIds.push(id)
      else humanIds.push(id)
    })
    await Promise.allSettled([
      performBulkDeleteMachines(machineIds),
      performBulkDeleteUsers(humanIds),
    ])
  }

  async function handleSaveUser(event: React.FormEvent<HTMLFormElement>) {
    event.preventDefault()
    if (!editUser) return

    const payload = {
      name: editForm.name.trim(),
      email: editForm.email.trim().toLowerCase(),
      role: editForm.role,
      tenantId: editForm.tenantId.trim() || defaultTenantId,
      companyId: editForm.companyId || null,
    }

    if (!payload.name) {
      toast.error("Informe o nome do usuário")
      return
    }
    if (!payload.email || !payload.email.includes("@")) {
      toast.error("Informe um e-mail válido")
      return
    }

    setIsSavingUser(true)
    try {
      const response = await fetch(`/api/admin/users/${editUser.id}`, {
        method: "PATCH",
        headers: { "Content-Type": "application/json" },
        credentials: "include",
        body: JSON.stringify(payload),
      })

      if (!response.ok) {
        const data = await response.json().catch(() => ({}))
        throw new Error(data.error ?? "Não foi possível atualizar o usuário")
      }

      const data = (await response.json()) as { user: AdminUser }
      setUsers((previous) => previous.map((item) => (item.id === data.user.id ? data.user : item)))
      toast.success("Usuário atualizado com sucesso")
      setEditUserId(null)
    } catch (error) {
      const message = error instanceof Error ? error.message : "Erro ao salvar alterações"
      toast.error(message)
    } finally {
      setIsSavingUser(false)
    }
  }

  async function handleResetPassword() {
    if (!editUser) return
    if (!canManageUser(editUser.role)) {
      toast.error("Você não pode gerar senha para este usuário")
      return
    }
    setIsResettingPassword(true)
    toast.loading("Gerando nova senha...", { id: "reset-password" })
    try {
      const response = await fetch(`/api/admin/users/${editUser.id}/reset-password`, {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        credentials: "include",
      })
      if (!response.ok) {
        const data = await response.json().catch(() => ({}))
        throw new Error(data.error ?? "Falha ao gerar nova senha")
      }
      const data = (await response.json()) as { temporaryPassword: string }
      setPasswordPreview(data.temporaryPassword)
      toast.success("Senha temporária criada", { id: "reset-password" })
    } catch (error) {
      const message = error instanceof Error ? error.message : "Erro ao gerar senha"
      toast.error(message, { id: "reset-password" })
    } finally {
      setIsResettingPassword(false)
    }
  }

  const isMachineEditing = editUser?.role === "machine"
  const editingRestricted = editUser ? !canManageUser(editUser.role) : false
  const companyOptions = useMemo(
    () => [{ id: NO_COMPANY_ID, name: "Sem empresa vinculada" }, ...companies],
    [companies]
  )
async function handleDeleteUser() {
    if (!deleteTarget) return
    if (!canManageUser(deleteTarget.role)) {
      toast.error("Você não pode remover esse usuário")
      setDeleteUserId(null)
      return
    }
    setIsDeletingUser(true)
    const isMachine = deleteTarget.role === "machine"

    try {
      if (isMachine) {
        const machineId = extractMachineId(deleteTarget.email)
        if (!machineId) {
          throw new Error("Não foi possível identificar a máquina associada.")
        }
        const response = await fetch("/api/admin/machines/delete", {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify({ machineId }),
          credentials: "include",
        })
        if (!response.ok) {
          const data = await response.json().catch(() => ({}))
          throw new Error(data.error ?? "Falha ao remover agente de máquina")
        }
        toast.success("Agente de máquina removido")
      } else {
        const response = await fetch(`/api/admin/users/${deleteTarget.id}`, {
          method: "DELETE",
          credentials: "include",
        })
        if (!response.ok) {
          const data = await response.json().catch(() => ({}))
          throw new Error(data.error ?? "Falha ao remover colaborador")
        }
        toast.success("Colaborador removido")
      }

      setUsers((previous) => previous.filter((user) => user.id !== deleteTarget.id))
      if (editUserId === deleteTarget.id) {
        setEditUserId(null)
      }
    } catch (error) {
      const message = error instanceof Error ? error.message : "Não foi possível remover o usuário"
      toast.error(message)
    } finally {
      setIsDeletingUser(false)
      setDeleteUserId(null)
    }
  }

  return (
    <>
      <Tabs defaultValue="team" className="w-full">
        <TabsList className="h-12 w-full justify-start rounded-xl bg-slate-100 p-1">
          <TabsTrigger value="team" className="rounded-lg">Equipe</TabsTrigger>
          <TabsTrigger value="users" className="rounded-lg">Usuários</TabsTrigger>
          <TabsTrigger value="invites" className="rounded-lg">Convites</TabsTrigger>
        </TabsList>

        <TabsContent value="team" className="mt-6 space-y-6">
          <div className="flex flex-col gap-4 rounded-xl border border-slate-200 bg-white p-4 shadow-sm sm:flex-row sm:items-center sm:justify-between">
            <div className="space-y-1">
              <p className="text-sm font-semibold text-neutral-900">Equipe cadastrada</p>
              <p className="text-xs text-neutral-500">{filteredTeamUsers.length} {filteredTeamUsers.length === 1 ? "membro" : "membros"}</p>
            </div>
            <Button onClick={handleOpenCreateUser} size="sm" className="gap-2 self-start sm:self-auto">
              <IconUserPlus className="size-4" />
              Novo usuário
            </Button>
          </div>
          <div className="rounded-xl border border-slate-200 bg-white p-4 shadow-sm md:grid md:grid-cols-[minmax(0,1fr)_auto_auto_auto_auto] md:items-center md:gap-3">
            <div className="relative w-full md:max-w-sm">
              <IconSearch className="text-muted-foreground pointer-events-none absolute left-3 top-1/2 size-4 -translate-y-1/2" />
              <Input
                value={teamSearch}
                onChange={(event) => setTeamSearch(event.target.value)}
                placeholder="Buscar por nome, e-mail ou empresa..."
                className="h-9 pl-9"
              />
            </div>
            <div className="mt-3 flex flex-wrap items-center gap-3 md:mt-0">
              <Select value={teamRoleFilter} onValueChange={(value) => setTeamRoleFilter(value as "all" | RoleOption)}>
                <SelectTrigger className="h-9 w-full sm:w-48">
                  <SelectValue placeholder="Todos os papéis" />
                </SelectTrigger>
                <SelectContent>
                  <SelectItem value="all">Todos os papéis</SelectItem>
                  {selectableRoles.filter((option) => ["admin", "agent"].includes(option)).map((option) => (
                    <SelectItem key={`team-filter-${option}`} value={option}>{formatRole(option)}</SelectItem>
                  ))}
                </SelectContent>
              </Select>
              <Select value={teamCompanyFilter} onValueChange={setTeamCompanyFilter}>
                <SelectTrigger className="h-9 w-full sm:w-56">
                  <SelectValue placeholder="Empresa" />
                </SelectTrigger>
                <SelectContent>
                  <SelectItem value="all">Todas as empresas</SelectItem>
                  {companies.map((company) => (
                    <SelectItem key={`team-company-${company.id}`} value={company.id}>{company.name}</SelectItem>
                  ))}
                </SelectContent>
              </Select>
              <Select value={teamTenantFilter} onValueChange={setTeamTenantFilter}>
                <SelectTrigger className="h-9 w-full sm:w-40">
                  <SelectValue placeholder="Espaço" />
                </SelectTrigger>
                <SelectContent>
                  <SelectItem value="all">Todos os espaços</SelectItem>
                  {tenantOptions.map((t) => (
                    <SelectItem key={`team-tenant-${t}`} value={t}>{formatTenantLabel(t, defaultTenantId)}</SelectItem>
                  ))}
                </SelectContent>
              </Select>
              {(teamSearch.trim().length > 0 || teamRoleFilter !== "all") ? (
                <Button
                  variant="ghost"
                  size="sm"
                  onClick={() => {
                    setTeamSearch("")
                    setTeamRoleFilter("all")
                    setTeamCompanyFilter("all")
                    setTeamTenantFilter("all")
                  }}
                >
                  Limpar filtros
                </Button>
              ) : null}
              <Button
                variant="outline"
                size="sm"
                className="gap-2 border-rose-200 text-rose-600 hover:bg-rose-50 hover:text-rose-700 disabled:text-rose-300 disabled:border-rose-100"
                disabled={selectedTeamUsers.length === 0 || isBulkDeletingTeam}
                onClick={() => setBulkDeleteTeamOpen(true)}
              >
                <IconTrash className="size-4" /> Excluir selecionados
              </Button>
            </div>
          </div>
          <Card>
            <CardHeader>
              <CardTitle>Equipe cadastrada</CardTitle>
              <CardDescription>Usuários com acesso ao sistema. Edite papéis, dados pessoais ou gere uma nova senha.</CardDescription>
            </CardHeader>
            <CardContent className="overflow-x-auto">
              <table className="min-w-full table-fixed divide-y divide-slate-200 text-sm">
                <thead>
                  <tr className="text-left text-xs uppercase tracking-wide text-neutral-500">
                    <th className="w-10 py-3 pr-2 font-medium">
                      <div className="flex items-center justify-center">
                        <Checkbox
                          checked={allTeamSelected || (someTeamSelected && "indeterminate")}
                          onCheckedChange={(value) => toggleTeamSelectAll(!!value)}
                          aria-label="Selecionar todos"
                        />
                      </div>
                    </th>
                    <th className="py-3 pr-4 font-medium">Nome</th>
                    <th className="py-3 pr-4 font-medium">E-mail</th>
                    <th className="py-3 pr-4 font-medium">Papel</th>
                    <th className="py-3 pr-4 font-medium">Empresa</th>
                    <th className="py-3 pr-4 font-medium">Espaço</th>
                    <th className="py-3 pr-4 font-medium">Criado em</th>
                    <th className="py-3 font-medium">Ações</th>
                  </tr>
                </thead>
                <tbody className="divide-y divide-slate-100">
                  {filteredTeamUsers.map((user) => (
                    <tr key={user.id} className="hover:bg-slate-50">
                      <td className="py-3 pr-2">
                        <div className="flex items-center justify-center">
                          <Checkbox
                            checked={teamSelection.has(user.id)}
                            onCheckedChange={(checked) => {
                              setTeamSelection((prev) => {
                                const next = new Set(prev)
                                if (checked) next.add(user.id)
                                else next.delete(user.id)
                                return next
                              })
                            }}
                            aria-label="Selecionar linha"
                          />
                        </div>
                      </td>
                      <td className="py-3 pr-4 font-medium text-neutral-800">{user.name || "—"}</td>
                      <td className="py-3 pr-4 text-neutral-600">{user.email}</td>
                      <td className="py-3 pr-4 text-neutral-600">{formatRole(user.role)}</td>
                      <td className="py-3 pr-4 text-neutral-600">{user.companyName ?? "—"}</td>
                      <td className="py-3 pr-4 text-neutral-600">{formatTenantLabel(user.tenantId, defaultTenantId)}</td>
                      <td className="py-3 pr-4 text-neutral-500">{formatDate(user.createdAt)}</td>
                      <td className="py-3">
                        <div className="flex flex-wrap gap-2">
                          <Button
                            variant="outline"
                            size="sm"
                            disabled={!canManageUser(user.role)}
                            onClick={() => {
                              if (!canManageUser(user.role)) return
                              setEditUserId(user.id)
                            }}
                          >
                            Editar
                          </Button>
                          <Button
                            variant="outline"
                            size="sm"
                            className="border-rose-200 text-rose-600 hover:bg-rose-50 hover:text-rose-700"
                            disabled={!canManageUser(user.role)}
                            onClick={() => {
                              if (!canManageUser(user.role)) return
                              setDeleteUserId(user.id)
                            }}
                          >
                            Remover
                          </Button>
                        </div>
                      </td>
                    </tr>
                  ))}
                  {filteredTeamUsers.length === 0 ? (
                    <tr>
                      <td colSpan={8} className="py-6 text-center text-neutral-500">
                        {teamUsers.length === 0
                          ? "Nenhum usuário cadastrado até o momento."
                          : "Nenhum usuário corresponde aos filtros atuais."}
                      </td>
                    </tr>
                  ) : null}
                </tbody>
              </table>
            </CardContent>
          </Card>

          <Card>
            <CardHeader>
              <CardTitle>Vincular usuário a empresa</CardTitle>
              <CardDescription>Associe colaboradores existentes a uma empresa para liberar painéis de gestores e filtros específicos.</CardDescription>
            </CardHeader>
            <CardContent>
              <form onSubmit={handleAssignCompany} className="grid gap-4 lg:grid-cols-[minmax(0,2fr)_minmax(0,2fr)_auto]">
                <div className="grid gap-2">
                  <Label>E-mail do usuário</Label>
                  <Input
                    value={linkEmail}
                    onChange={(event) => setLinkEmail(event.target.value)}
                    placeholder="colaborador@empresa.com"
                    type="email"
                    required
                  />
                </div>
                <div className="grid gap-2">
                  <Label>Empresa</Label>
                  <Select value={linkCompanyId} onValueChange={setLinkCompanyId}>
                    <SelectTrigger>
                      <SelectValue placeholder="Selecionar" />
                    </SelectTrigger>
                    <SelectContent>
                      {companies.map((company) => (
                        <SelectItem key={company.id} value={company.id}>
                          {company.name}
                        </SelectItem>
                      ))}
                    </SelectContent>
                  </Select>
                </div>
                <div className="flex items-end">
                  <Button type="submit" disabled={assigningCompany || companies.length === 0}>
                    {assigningCompany ? "Vinculando..." : "Vincular"}
                  </Button>
                </div>
              </form>
              <p className="mt-2 text-xs text-neutral-500">Caso a empresa ainda não exista, cadastre-a em <Link href="/admin/companies" className="underline underline-offset-4">Admin ▸ Empresas &amp; clientes</Link>.</p>
            </CardContent>
          </Card>
        </TabsContent>

        <TabsContent value="users" className="mt-6 space-y-6">
          <div className="flex flex-col gap-4 rounded-xl border border-slate-200 bg-white p-4 shadow-sm sm:flex-row sm:items-center sm:justify-between">
            <div className="space-y-1">
              <p className="text-sm font-semibold text-neutral-900">Usuários</p>
              <p className="text-xs text-neutral-500">{filteredCombinedUsers.length} {filteredCombinedUsers.length === 1 ? "usuário" : "usuários"}</p>
            </div>
            <Button onClick={handleOpenCreateUser} size="sm" className="gap-2 self-start sm:self-auto">
              <IconUserPlus className="size-4" />
              Novo usuário
            </Button>
          </div>
          <div className="rounded-xl border border-slate-200 bg-white p-4 shadow-sm md:grid md:grid-cols-[minmax(0,1fr)_auto_auto_auto_auto] md:items-center md:gap-3">
            <div className="relative w-full md:max-w-sm">
              <IconSearch className="text-muted-foreground pointer-events-none absolute left-3 top-1/2 size-4 -translate-y-1/2" />
              <Input
                value={usersSearch}
                onChange={(event) => setUsersSearch(event.target.value)}
                placeholder="Buscar por nome, e-mail, empresa ou máquina..."
                className="h-9 pl-9"
              />
            </div>
            <div className="mt-3 flex flex-wrap items-center gap-3 md:mt-0">
              <Select value={usersTypeFilter} onValueChange={(v) => setUsersTypeFilter(v as typeof usersTypeFilter)}>
                <SelectTrigger className="h-9 w-full sm:w-40">
                  <SelectValue placeholder="Tipo" />
                </SelectTrigger>
                <SelectContent>
                  <SelectItem value="all">Todos</SelectItem>
                  <SelectItem value="people">Pessoas</SelectItem>
                  <SelectItem value="machines">Máquinas</SelectItem>
                </SelectContent>
              </Select>
              <Select value={usersCompanyFilter} onValueChange={setUsersCompanyFilter}>
                <SelectTrigger className="h-9 w-full sm:w-56">
                  <SelectValue placeholder="Empresa" />
                </SelectTrigger>
                <SelectContent>
                  <SelectItem value="all">Todas as empresas</SelectItem>
                  {companies.map((company) => (
                    <SelectItem key={`users-company-${company.id}`} value={company.id}>{company.name}</SelectItem>
                  ))}
                </SelectContent>
              </Select>
              <Select value={usersTenantFilter} onValueChange={setUsersTenantFilter}>
                <SelectTrigger className="h-9 w-full sm:w-40">
                  <SelectValue placeholder="Espaço" />
                </SelectTrigger>
                <SelectContent>
                  <SelectItem value="all">Todos os espaços</SelectItem>
                  {tenantOptions.map((t) => (
                    <SelectItem key={`users-tenant-${t}`} value={t}>{formatTenantLabel(t, defaultTenantId)}</SelectItem>
                  ))}
                </SelectContent>
              </Select>
              {(usersSearch.trim().length > 0 || usersTypeFilter !== "all" || usersCompanyFilter !== "all" || usersTenantFilter !== "all") ? (
                <Button
                  variant="ghost"
                  size="sm"
                  onClick={() => {
                    setUsersSearch("")
                    setUsersTypeFilter("all")
                    setUsersCompanyFilter("all")
                    setUsersTenantFilter("all")
                  }}
                >
                  Limpar filtros
                </Button>
              ) : null}
              <Button
                variant="outline"
                size="sm"
                className="gap-2 border-rose-200 text-rose-600 hover:bg-rose-50 hover:text-rose-700 disabled:text-rose-300 disabled:border-rose-100"
                disabled={usersSelection.size === 0 || isBulkDeletingUsersCombined}
                onClick={() => setBulkDeleteUsersCombinedOpen(true)}
              >
                <IconTrash className="size-4" /> Excluir selecionados
              </Button>
            </div>
          </div>
          <Card>
            <CardHeader>
              <CardTitle>Usuários</CardTitle>
              <CardDescription>Pessoas e máquinas com acesso ao sistema.</CardDescription>
            </CardHeader>
            <CardContent className="overflow-x-auto">
              <table className="min-w-full table-fixed divide-y divide-slate-200 text-sm">
                <thead>
                  <tr className="text-left text-xs uppercase tracking-wide text-neutral-500">
                    <th className="w-10 py-3 pr-2 font-medium">
                      <div className="flex items-center justify-center">
                        <Checkbox
                          checked={usersSelection.size > 0 && usersSelection.size === filteredCombinedUsers.length || (usersSelection.size > 0 && usersSelection.size < filteredCombinedUsers.length && "indeterminate")}
                          onCheckedChange={(value) => toggleUsersCombinedSelectAll(!!value)}
                          aria-label="Selecionar todos"
                        />
                      </div>
                    </th>
                    <th className="py-3 pr-4 font-medium">Nome</th>
                    <th className="py-3 pr-4 font-medium">E-mail</th>
                    <th className="py-3 pr-4 font-medium">Tipo</th>
                    <th className="py-3 pr-4 font-medium">Perfil</th>
                    <th className="py-3 pr-4 font-medium">Empresa</th>
                    <th className="py-3 pr-4 font-medium">Espaço</th>
                    <th className="py-3 pr-4 font-medium">Criado em</th>
                    <th className="py-3 font-medium">Ações</th>
                  </tr>
                </thead>
                <tbody className="divide-y divide-slate-100">
                  {filteredCombinedUsers.map((user) => (
                    <tr key={user.id} className="hover:bg-slate-50">
                      <td className="py-3 pr-2">
                        <div className="flex items-center justify-center">
                          <Checkbox
                            checked={usersSelection.has(user.id)}
                            onCheckedChange={(checked) => {
                              setUsersSelection((prev) => {
                                const next = new Set(prev)
                                if (checked) next.add(user.id)
                                else next.delete(user.id)
                                return next
                              })
                            }}
                            aria-label="Selecionar linha"
                          />
                        </div>
                      </td>
                      <td className="py-3 pr-4 font-medium text-neutral-800">{user.name || (user.role === "machine" ? "Máquina" : "—")}</td>
                      <td className="py-3 pr-4 text-neutral-600">{user.email}</td>
                      <td className="py-3 pr-4 text-neutral-600">{user.role === "machine" ? "Máquina" : "Pessoa"}</td>
                      <td className="py-3 pr-4 text-neutral-600">
                        {user.role === "machine" ? (
                          user.machinePersona ? (
                            <Badge variant={machinePersonaBadgeVariant(user.machinePersona)} className="rounded-full px-3 py-1 text-xs font-medium">
                              {formatMachinePersona(user.machinePersona)}
                            </Badge>
                          ) : (
                            <span className="text-neutral-500">Sem persona</span>
                          )
                        ) : (
                          formatRole(user.role)
                        )}
                      </td>
                      <td className="py-3 pr-4 text-neutral-600">{user.companyName ?? "—"}</td>
                      <td className="py-3 pr-4 text-neutral-600">{formatTenantLabel(user.tenantId, defaultTenantId)}</td>
                      <td className="py-3 pr-4 text-neutral-500">{formatDate(user.createdAt)}</td>
                      <td className="py-3">
                        <div className="flex flex-wrap gap-2">
                          <Button
                            variant="outline"
                            size="sm"
                            disabled={!canManageUser(user.role)}
                            onClick={() => {
                              if (!canManageUser(user.role)) return
                              setEditUserId(user.id)
                            }}
                          >
                            Editar
                          </Button>
                          {user.role === "machine" ? (
                            <Button variant="ghost" size="sm" asChild>
                              <Link href={(extractMachineId(user.email) ? `/admin/machines/${extractMachineId(user.email)}` : "/admin/machines")}>Detalhes da máquina</Link>
                            </Button>
                          ) : null}
                          <Button
                            variant="outline"
                            size="sm"
                            className="border-rose-200 text-rose-600 hover:bg-rose-50 hover:text-rose-700"
                            disabled={!canManageUser(user.role)}
                            onClick={() => {
                              if (!canManageUser(user.role)) return
                              setDeleteUserId(user.id)
                            }}
                          >
                            Remover
                          </Button>
                        </div>
                      </td>
                    </tr>
                  ))}
                  {filteredCombinedUsers.length === 0 ? (
                    <tr>
                      <td colSpan={9} className="py-6 text-center text-neutral-500">
                        {combinedBaseUsers.length === 0
                          ? "Nenhum usuário cadastrado até o momento."
                          : "Nenhum usuário corresponde aos filtros atuais."}
                      </td>
                    </tr>
                  ) : null}
                </tbody>
              </table>
            </CardContent>
          </Card>
        </TabsContent>

        <TabsContent value="invites" className="mt-6 space-y-6">
          <Card>
            <CardHeader>
              <CardTitle>Gerar convite</CardTitle>
              <CardDescription>Envie convites personalizados com validade controlada e acompanhe o status em tempo real.</CardDescription>
            </CardHeader>
            <CardContent>
              <form
                onSubmit={handleInviteSubmit}
                className="grid gap-4 md:grid-cols-2 xl:grid-cols-[minmax(0,2.4fr)_minmax(0,2fr)_minmax(0,1.2fr)_minmax(0,1.2fr)_auto]"
              >
                <div className="grid gap-2 md:col-span-2 xl:col-auto">
                  <Label htmlFor="invite-email">E-mail corporativo</Label>
                  <Input
                    id="invite-email"
                    type="email"
                    inputMode="email"
                    placeholder="nome@suaempresa.com"
                    value={email}
                    onChange={(event) => setEmail(event.target.value)}
                    required
                    autoComplete="off"
                  />
                </div>
                <div className="grid gap-2 md:col-span-2 xl:col-auto">
                  <Label htmlFor="invite-name">Nome</Label>
                  <Input
                    id="invite-name"
                    placeholder="Nome completo"
                    value={name}
                    onChange={(event) => setName(event.target.value)}
                    autoComplete="off"
                  />
                </div>
                <div className="grid gap-2 md:col-span-1 xl:col-auto">
                  <Label>Papel</Label>
                  <Select value={role} onValueChange={(value) => setRole(value as RoleOption)}>
                    <SelectTrigger id="invite-role" className="h-9 w-full">
                      <SelectValue placeholder="Selecione" />
                    </SelectTrigger>
                    <SelectContent>
                      {selectableRoles.map((option) => (
                        <SelectItem key={option} value={option}>
                          {formatRole(option)}
                        </SelectItem>
                      ))}
                    </SelectContent>
                  </Select>
                </div>
                <div className="grid gap-2 md:col-span-1 xl:col-auto">
                  <Label>Expira em</Label>
                  <Select value={expiresInDays} onValueChange={setExpiresInDays}>
                    <SelectTrigger id="invite-expiration" className="w-full">
                      <SelectValue placeholder="7 dias" />
                    </SelectTrigger>
                    <SelectContent>
                      <SelectItem value="7">7 dias</SelectItem>
                      <SelectItem value="14">14 dias</SelectItem>
                      <SelectItem value="30">30 dias</SelectItem>
                    </SelectContent>
                  </Select>
                </div>
                <div className="flex items-end md:col-span-2 xl:col-auto xl:justify-end">
                  <Button type="submit" disabled={isPending} className="w-full">
                    {isPending ? "Gerando..." : "Gerar convite"}
                  </Button>
                </div>
              </form>
              {lastInviteLink ? (
                <div className="mt-4 flex flex-col gap-2 rounded-lg border border-slate-200 bg-slate-50 p-4 text-sm text-neutral-700 lg:flex-row lg:items-center lg:justify-between">
                  <div>
                    <p className="font-medium text-neutral-900">Link de convite pronto</p>
                    <p className="text-neutral-600">Compartilhe com o convidado. O link expira automaticamente no prazo selecionado.</p>
                    <code className="mt-2 block rounded bg-white px-3 py-1 text-xs text-neutral-700">{lastInviteLink}</code>
                  </div>
                  <Button variant="outline" onClick={() => handleCopy(lastInviteLink)}>Copiar link</Button>
                </div>
              ) : null}
            </CardContent>
          </Card>

          <Card>
            <CardHeader>
              <CardTitle>Convites emitidos</CardTitle>
              <CardDescription>Histórico e status atual de todos os convites enviados para o workspace.</CardDescription>
            </CardHeader>
            <CardContent className="overflow-x-auto">
              <table className="min-w-full table-fixed divide-y divide-slate-200 text-sm">
                <thead>
                  <tr className="text-left text-xs uppercase tracking-wide text-neutral-500">
                    <th className="w-10 py-3 pr-2 font-medium">
                      <div className="flex items-center justify-center">
                        <Checkbox
                          checked={allInvitesSelected || (someInvitesSelected && "indeterminate")}
                          onCheckedChange={(value) => toggleInvitesSelectAll(!!value)}
                          aria-label="Selecionar todos"
                        />
                      </div>
                    </th>
                    <th className="py-3 pr-4 font-medium">Colaborador</th>
                    <th className="py-3 pr-4 font-medium">Papel</th>
                    <th className="py-3 pr-4 font-medium">Espaço</th>
                    <th className="py-3 pr-4 font-medium">Expira em</th>
                    <th className="py-3 pr-4 font-medium">Status</th>
                    <th className="py-3 font-medium">Ações</th>
                  </tr>
                </thead>
                <tbody className="divide-y divide-slate-100">
                  {invites.map((invite) => (
                    <tr key={invite.id} className="hover:bg-slate-50">
                      <td className="py-3 pr-2">
                        <div className="flex items-center justify-center">
                          <Checkbox
                            checked={inviteSelection.has(invite.id)}
                            onCheckedChange={(checked) => {
                              setInviteSelection((prev) => {
                                const next = new Set(prev)
                                if (checked) next.add(invite.id)
                                else next.delete(invite.id)
                                return next
                              })
                            }}
                            aria-label="Selecionar linha"
                          />
                        </div>
                      </td>
                      <td className="py-3 pr-4">
                        <div className="flex flex-col">
                          <span className="font-medium text-neutral-800">{invite.name || invite.email}</span>
                          <span className="text-xs text-neutral-500">{invite.email}</span>
                        </div>
                      </td>
                      <td className="py-3 pr-4 text-neutral-600">{formatRole(invite.role)}</td>
                      <td className="py-3 pr-4 text-neutral-600">{formatTenantLabel(invite.tenantId, defaultTenantId)}</td>
                      <td className="py-3 pr-4 text-neutral-600">{formatDate(invite.expiresAt)}</td>
                      <td className="py-3 pr-4">
                        <Badge
                          variant={inviteStatusVariant(invite.status)}
                          className="rounded-full px-3 py-1 text-xs font-medium"
                        >
                          {formatStatus(invite.status)}
                        </Badge>
                      </td>
                      <td className="py-3">
                        <div className="flex flex-wrap gap-2">
                          <Button variant="outline" size="sm" onClick={() => handleCopy(invite.inviteUrl)}>
                            Copiar link
                          </Button>
                          {invite.status === "pending" && canManageInvite(invite.role) ? (
                            <Button
                              variant="ghost"
                              size="sm"
                              className="text-red-600 transition-colors hover:bg-red-500/10"
                              onClick={() => setRevokeDialogInviteId(invite.id)}
                              disabled={revokingId === invite.id}
                            >
                              {revokingId === invite.id ? "Revogando..." : "Revogar"}
                            </Button>
                          ) : null}
                          {invite.status === "revoked" && canReactivateInvitePolicy(invite) && canManageInvite(invite.role) ? (
                            <Button
                              variant="outline"
                              size="sm"
                              className="border-amber-400 text-amber-600 hover:bg-amber-50"
                              onClick={() => handleReactivate(invite)}
                              disabled={reactivatingId === invite.id}
                            >
                              {reactivatingId === invite.id ? "Reativando..." : "Reativar"}
                            </Button>
                          ) : null}
                        </div>
                      </td>
                    </tr>
                  ))}
                  {invites.length === 0 ? (
                    <tr>
                      <td colSpan={7} className="py-6 text-center text-neutral-500">
                        Nenhum convite emitido até o momento.
                      </td>
                    </tr>
                  ) : null}
                </tbody>
              </table>
              <div className="mt-3 flex items-center justify-end">
                <Button
                  variant="outline"
                  size="sm"
                  className="gap-2 border-rose-200 text-rose-600 hover:bg-rose-50 hover:text-rose-700 disabled:text-rose-300 disabled:border-rose-100"
                  disabled={selectedInvites.length === 0 || isBulkRevokingInvites}
                  onClick={() => setBulkRevokeInvitesOpen(true)}
                >
                  <IconTrash className="size-4" /> Revogar selecionados
                </Button>
              </div>
            </CardContent>
          </Card>
        </TabsContent>
      </Tabs>
      <Dialog
        open={createDialogOpen}
        onOpenChange={(open) => {
          if (open) {
            setCreateDialogOpen(true)
          } else {
            handleCloseCreateDialog()
          }
        }}
      >
        <DialogContent className="max-w-lg space-y-4">
          <DialogHeader>
            <DialogTitle>Novo usuário</DialogTitle>
            <DialogDescription>Crie uma conta para membros da equipe com acesso imediato ao sistema.</DialogDescription>
          </DialogHeader>
          <form onSubmit={handleCreateUser} className="space-y-5">
            <div className="grid gap-2">
              <Label htmlFor="create-name">Nome</Label>
              <Input
                id="create-name"
                placeholder="Nome completo"
                value={createForm.name}
                onChange={(event) => setCreateForm((prev) => ({ ...prev, name: event.target.value }))}
                required
                autoComplete="off"
              />
            </div>
            <div className="grid gap-2">
              <Label htmlFor="create-email">E-mail</Label>
              <Input
                id="create-email"
                type="email"
                inputMode="email"
                placeholder="nome@suaempresa.com"
                value={createForm.email}
                onChange={(event) => setCreateForm((prev) => ({ ...prev, email: event.target.value }))}
                required
                autoComplete="off"
              />
            </div>
            <div className="grid gap-2">
              <Label htmlFor="create-role">Papel</Label>
              <Select
                value={createForm.role}
                onValueChange={(value) => setCreateForm((prev) => ({ ...prev, role: value as RoleOption }))}
              >
                <SelectTrigger id="create-role" className="h-9">
                  <SelectValue placeholder="Selecione" />
                </SelectTrigger>
                <SelectContent>
                  {selectableRoles.map((option) => (
                    <SelectItem key={`create-role-${option}`} value={option}>
                      {formatRole(option)}
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>
            </div>
            <div className="grid gap-2">
              <Label htmlFor="create-tenant">Espaço (tenant)</Label>
              <Input
                id="create-tenant"
                placeholder="tenant-atlas"
                value={createForm.tenantId}
                onChange={(event) => setCreateForm((prev) => ({ ...prev, tenantId: event.target.value }))}
              />
            </div>
            <div className="grid gap-2">
              <Label htmlFor="create-company">Empresa vinculada</Label>
              <Select
                value={createForm.companyId}
                onValueChange={(value) => setCreateForm((prev) => ({ ...prev, companyId: value }))}
              >
                <SelectTrigger id="create-company" className="h-9">
                  <SelectValue placeholder="Sem vínculo" />
                </SelectTrigger>
                <SelectContent>
                  {companyOptions.map((company) => (
                    <SelectItem key={`create-company-${company.id}`} value={company.id}>
                      {company.name}
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>
            </div>
            {createPassword ? (
              <div className="rounded-lg border border-slate-300 bg-slate-50 p-3">
                <p className="text-xs text-neutral-600">Senha temporária gerada:</p>
                <div className="mt-2 flex flex-wrap items-center gap-3">
                  <code className="text-sm font-semibold text-neutral-900">{createPassword}</code>
                  <Button
                    type="button"
                    variant="ghost"
                    size="sm"
                    onClick={() => navigator.clipboard.writeText(createPassword).then(() => toast.success("Senha copiada"))}
                  >
                    Copiar
                  </Button>
                </div>
              </div>
            ) : null}
            <DialogFooter className="flex flex-col gap-2 sm:flex-row sm:justify-end">
              <Button type="button" variant="outline" onClick={handleCloseCreateDialog} disabled={isCreatingUser}>
                Cancelar
              </Button>
              <Button type="submit" disabled={isCreatingUser}>
                {isCreatingUser ? "Criando..." : "Criar usuário"}
              </Button>
            </DialogFooter>
          </form>
        </DialogContent>
      </Dialog>

      <Dialog open={bulkDeleteUsersCombinedOpen} onOpenChange={setBulkDeleteUsersCombinedOpen}>
        <DialogContent>
          <DialogHeader>
            <DialogTitle>Remover usuários selecionados</DialogTitle>
            <DialogDescription>Pessoas perderão o acesso e máquinas serão desconectadas.</DialogDescription>
          </DialogHeader>
          <div className="max-h-64 space-y-2 overflow-auto">
            {Array.from(usersSelection).slice(0, 5).map((id) => {
              const u = users.find((x) => x.id === id)
              if (!u) return null
              return (
                <div key={`users-del-${id}`} className="rounded-md bg-slate-100 px-3 py-2 text-sm">
                  {(u.name || u.email)} <span className="text-neutral-500">— {u.email}</span>
                </div>
              )
            })}
            {usersSelection.size > 5 ? (
              <div className="px-3 text-xs text-neutral-500">+ {usersSelection.size - 5} outros</div>
            ) : null}
          </div>
          <DialogFooter>
            <Button variant="outline" onClick={() => setBulkDeleteUsersCombinedOpen(false)} disabled={isBulkDeletingUsersCombined}>
              Cancelar
            </Button>
            <Button
              variant="destructive"
              disabled={isBulkDeletingUsersCombined}
              onClick={async () => {
                setIsBulkDeletingUsersCombined(true)
                try {
                  await performBulkDeleteUsersCombined(Array.from(usersSelection))
                  setUsersSelection(new Set())
                  setBulkDeleteUsersCombinedOpen(false)
                  toast.success("Remoção concluída")
                } catch (error) {
                  const message = error instanceof Error ? error.message : "Falha ao excluir selecionados"
                  toast.error(message)
                } finally {
                  setIsBulkDeletingUsersCombined(false)
                }
              }}
            >
              Excluir selecionados
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>


      <Sheet open={Boolean(editUser)} onOpenChange={(open) => (!open ? setEditUserId(null) : null)}>
        <SheetContent side="right" className="space-y-6 overflow-y-auto px-6 pb-10 sm:max-w-2xl">
          <SheetHeader className="px-0 pt-6">
            <SheetTitle>Editar usuário</SheetTitle>
            <SheetDescription>Atualize os dados cadastrais, papel e vínculo do colaborador.</SheetDescription>
          </SheetHeader>

          {editUser ? (
            <form onSubmit={handleSaveUser} className="space-y-6">
              {editingRestricted ? (
                <div className="rounded-md border border-amber-200 bg-amber-50 p-3 text-sm text-amber-700">
                  Você pode visualizar este perfil, mas apenas administradores podem alterá-lo.
                </div>
              ) : null}
              <div className="grid gap-4">
                <div className="grid gap-2">
                  <Label>Nome</Label>
                  <Input
                    value={editForm.name}
                    onChange={(event) => setEditForm((prev) => ({ ...prev, name: event.target.value }))}
                    placeholder="Nome completo"
                    disabled={isSavingUser || isMachineEditing || editingRestricted}
                    required
                  />
                </div>
                <div className="grid gap-2">
                  <Label>E-mail</Label>
                  <Input
                    value={editForm.email}
                    onChange={(event) => setEditForm((prev) => ({ ...prev, email: event.target.value }))}
                    type="email"
                    disabled={isSavingUser || isMachineEditing || editingRestricted}
                    required
                  />
                </div>
                <div className="grid gap-2">
                  <Label>Papel</Label>
                  <Select
                    value={editForm.role}
                    onValueChange={(value) => setEditForm((prev) => ({ ...prev, role: value as RoleOption }))}
                    disabled={isSavingUser || isMachineEditing || editingRestricted}
                  >
                    <SelectTrigger>
                      <SelectValue placeholder="Selecione" />
                    </SelectTrigger>
                    <SelectContent>
                      {selectableRoles.map((option) => (
                        <SelectItem key={option} value={option}>
                          {formatRole(option)}
                        </SelectItem>
                      ))}
                    </SelectContent>
                  </Select>
                </div>
                <div className="grid gap-2">
                  <Label>Espaço (tenant)</Label>
                  <Input
                    value={editForm.tenantId}
                    onChange={(event) => setEditForm((prev) => ({ ...prev, tenantId: event.target.value }))}
                    placeholder="tenant-atlas"
                    disabled={isSavingUser || isMachineEditing || editingRestricted}
                  />
                </div>
                <div className="grid gap-2">
                  <Label>Empresa vinculada</Label>
                  <Select
                    value={editForm.companyId ? editForm.companyId : NO_COMPANY_ID}
                    onValueChange={(value) =>
                      setEditForm((prev) => ({ ...prev, companyId: value === NO_COMPANY_ID ? "" : value }))
                    }
                    disabled={isSavingUser || editingRestricted}
                  >
                    <SelectTrigger>
                      <SelectValue placeholder="Selecione" />
                    </SelectTrigger>
                    <SelectContent>
                      {companyOptions.map((company) => (
                        <SelectItem key={company.id} value={company.id}>
                          {company.name}
                        </SelectItem>
                      ))}
                    </SelectContent>
                  </Select>
                  <p className="text-xs text-neutral-500">Essa seleção substitui o vínculo atual no portal do cliente.</p>
                </div>
                {isMachineEditing ? (
                  <div className="rounded-lg border border-dashed border-slate-300 bg-slate-50 p-3 text-sm text-neutral-600">
                    Os ajustes detalhados de agentes de máquina são feitos em <Link href="/admin/machines" className="underline underline-offset-4">Admin ▸ Máquinas</Link>.
                  </div>
                ) : (
                  <div className="rounded-lg border border-slate-200 bg-slate-50 p-4 text-sm text-neutral-700">
                    <div className="flex flex-wrap items-center justify-between gap-3">
                      <div>
                        <p className="font-medium text-neutral-900">Gerar nova senha</p>
                        <p className="text-xs text-neutral-500">Uma senha temporária será exibida abaixo. Compartilhe com o usuário e peça para trocá-la no primeiro acesso.</p>
                      </div>
                    <Button type="button" variant="outline" onClick={handleResetPassword} disabled={isResettingPassword}>
                      {isResettingPassword ? "Gerando..." : "Gerar senha"}
                    </Button>
                  </div>
                  {passwordPreview ? (
                      <div className="mt-3 flex flex-wrap items-center gap-3 rounded-md border border-slate-300 bg-white px-3 py-2">
                        <code className="text-sm font-semibold text-neutral-900">{passwordPreview}</code>
                        <Button
                          type="button"
                          variant="ghost"
                          size="sm"
                          onClick={() => navigator.clipboard.writeText(passwordPreview).then(() => toast.success("Senha copiada"))}
                        >
                          Copiar
                        </Button>
                      </div>
                    ) : null}
                  </div>
                )}
              </div>

              <SheetFooter className="flex flex-col gap-2 sm:flex-row sm:gap-3">
                <Button type="button" variant="outline" onClick={() => setEditUserId(null)} disabled={isSavingUser}>
                  Cancelar
                </Button>
                <Button type="submit" disabled={isSavingUser || isMachineEditing || editingRestricted} className="sm:ml-auto">
                  {isSavingUser ? "Salvando..." : "Salvar alterações"}
                </Button>
              </SheetFooter>
            </form>
          ) : null}
        </SheetContent>
      </Sheet>

      <Dialog
        open={deleteUserId !== null}
        onOpenChange={(open) => {
          if (!open) {
            setDeleteUserId(null)
          }
        }}
      >
        <DialogContent>
          <DialogHeader>
            <DialogTitle>
              {deleteTarget?.role === "machine" ? "Remover agente de máquina" : "Remover colaborador"}
            </DialogTitle>
            <DialogDescription>
              {deleteTarget?.role === "machine"
                ? "Revogar o acesso desconecta o aplicativo desktop e exige novo provisionamento."
                : "A remoção impede novos acessos, mas não afeta registros históricos de tickets."}
            </DialogDescription>
          </DialogHeader>
          <div className="space-y-2 text-sm text-neutral-600">
            <p>
              Confirme a exclusão de <span className="font-medium text-neutral-900">{deleteTarget?.name || deleteTarget?.email}</span>.
            </p>
            {deleteTarget?.role === "machine" ? (
              <p>
                A máquina correspondente perderá imediatamente o token ativo e voltará para a tela de provisionamento.
              </p>
            ) : (
              <p>Esse usuário não poderá mais acessar o painel até receber um novo convite.</p>
            )}
          </div>
          <DialogFooter>
            <Button variant="outline" onClick={() => setDeleteUserId(null)} disabled={isDeletingUser}>
              Cancelar
            </Button>
            <Button variant="destructive" onClick={handleDeleteUser} disabled={isDeletingUser}>
              {isDeletingUser
                ? deleteTarget?.role === "machine"
                  ? "Removendo agente..."
                  : "Removendo..."
                : deleteTarget?.role === "machine"
                  ? "Remover agente"
                  : "Remover"}
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>

      <Dialog
        open={revokeDialogInviteId !== null}
        onOpenChange={(open) => {
          if (!open) {
            setRevokeDialogInviteId(null)
            setRevokingId(null)
          }
        }}
      >
        <DialogContent>
          <DialogHeader>
            <DialogTitle>Revogar convite</DialogTitle>
            <DialogDescription>
              O link atual será invalidado imediatamente. Você pode gerar um novo convite a qualquer momento.
            </DialogDescription>
          </DialogHeader>
          <div className="space-y-2 text-sm text-neutral-600">
            <p>
              Deseja revogar o convite enviado para
              {" "}
              <span className="font-medium text-neutral-900">{revokeCandidate?.email}</span>?
            </p>
            <p className="text-xs text-neutral-500">Ação irreversível — o convidado verá o link expirado.</p>
          </div>
          <DialogFooter>
            <Button variant="outline" onClick={() => setRevokeDialogInviteId(null)} disabled={revokingId !== null}>
              Manter convite
            </Button>
            <Button
              variant="destructive"
              onClick={handleRevokeConfirmed}
              disabled={revokingId === revokeCandidate?.id}
            >
              {revokingId === revokeCandidate?.id ? "Revogando..." : "Revogar convite"}
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>

      {/* Bulk actions */}
      <Dialog open={bulkDeleteTeamOpen} onOpenChange={setBulkDeleteTeamOpen}>
        <DialogContent>
          <DialogHeader>
            <DialogTitle>Remover membros selecionados</DialogTitle>
            <DialogDescription>Revoga o acesso imediatamente. Registros históricos permanecem.</DialogDescription>
          </DialogHeader>
          <div className="max-h-64 space-y-2 overflow-auto">
            {selectedTeamUsers.slice(0, 5).map((u) => (
              <div key={`team-del-${u.id}`} className="rounded-md bg-slate-100 px-3 py-2 text-sm">
                {u.name || u.email} <span className="text-neutral-500">— {u.email}</span>
              </div>
            ))}
            {selectedTeamUsers.length > 5 ? (
              <div className="px-3 text-xs text-neutral-500">+ {selectedTeamUsers.length - 5} outros</div>
            ) : null}
          </div>
          <DialogFooter>
            <Button variant="outline" onClick={() => setBulkDeleteTeamOpen(false)} disabled={isBulkDeletingTeam}>
              Cancelar
            </Button>
            <Button
              variant="destructive"
              disabled={isBulkDeletingTeam}
              onClick={async () => {
                setIsBulkDeletingTeam(true)
                try {
                  await performBulkDeleteUsers(selectedTeamUsers.map((u) => u.id))
                  setTeamSelection(new Set())
                  setBulkDeleteTeamOpen(false)
                  toast.success("Remoção concluída")
                } catch (error) {
                  const message = error instanceof Error ? error.message : "Falha ao excluir selecionados"
                  toast.error(message)
                } finally {
                  setIsBulkDeletingTeam(false)
                }
              }}
            >
              Excluir selecionados
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>

      <Dialog open={bulkDeletePeopleOpen} onOpenChange={setBulkDeletePeopleOpen}>
        <DialogContent>
          <DialogHeader>
            <DialogTitle>Remover usuários selecionados</DialogTitle>
            <DialogDescription>Os usuários perderão o acesso imediatamente.</DialogDescription>
          </DialogHeader>
          <div className="max-h-64 space-y-2 overflow-auto">
            {selectedPeopleUsers.slice(0, 5).map((u) => (
              <div key={`people-del-${u.id}`} className="rounded-md bg-slate-100 px-3 py-2 text-sm">
                {u.name || u.email} <span className="text-neutral-500">— {u.email}</span>
              </div>
            ))}
            {selectedPeopleUsers.length > 5 ? (
              <div className="px-3 text-xs text-neutral-500">+ {selectedPeopleUsers.length - 5} outros</div>
            ) : null}
          </div>
          <DialogFooter>
            <Button variant="outline" onClick={() => setBulkDeletePeopleOpen(false)} disabled={isBulkDeletingPeople}>
              Cancelar
            </Button>
            <Button
              variant="destructive"
              disabled={isBulkDeletingPeople}
              onClick={async () => {
                setIsBulkDeletingPeople(true)
                try {
                  await performBulkDeleteUsers(selectedPeopleUsers.map((u) => u.id))
                  setPeopleSelection(new Set())
                  setBulkDeletePeopleOpen(false)
                  toast.success("Remoção concluída")
                } catch (error) {
                  const message = error instanceof Error ? error.message : "Falha ao excluir selecionados"
                  toast.error(message)
                } finally {
                  setIsBulkDeletingPeople(false)
                }
              }}
            >
              Excluir selecionados
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>

      <Dialog open={bulkDeleteMachinesOpen} onOpenChange={setBulkDeleteMachinesOpen}>
        <DialogContent>
          <DialogHeader>
            <DialogTitle>Remover agentes selecionados</DialogTitle>
            <DialogDescription>As máquinas serão desconectadas e precisarão de novo provisionamento.</DialogDescription>
          </DialogHeader>
          <div className="max-h-64 space-y-2 overflow-auto">
            {selectedMachineUsers.slice(0, 5).map((u) => (
              <div key={`machine-del-${u.id}`} className="rounded-md bg-slate-100 px-3 py-2 text-sm">
                {u.name || u.email} <span className="text-neutral-500">— {u.email}</span>
              </div>
            ))}
            {selectedMachineUsers.length > 5 ? (
              <div className="px-3 text-xs text-neutral-500">+ {selectedMachineUsers.length - 5} outros</div>
            ) : null}
          </div>
          <DialogFooter>
            <Button variant="outline" onClick={() => setBulkDeleteMachinesOpen(false)} disabled={isBulkDeletingMachines}>
              Cancelar
            </Button>
            <Button
              variant="destructive"
              disabled={isBulkDeletingMachines}
              onClick={async () => {
                setIsBulkDeletingMachines(true)
                try {
                  await performBulkDeleteMachines(selectedMachineUsers.map((u) => u.id))
                  setMachineSelection(new Set())
                  setBulkDeleteMachinesOpen(false)
                  toast.success("Agentes removidos")
                } catch (error) {
                  const message = error instanceof Error ? error.message : "Falha ao excluir selecionados"
                  toast.error(message)
                } finally {
                  setIsBulkDeletingMachines(false)
                }
              }}
            >
              Remover selecionados
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>

      <Dialog open={bulkRevokeInvitesOpen} onOpenChange={setBulkRevokeInvitesOpen}>
        <DialogContent>
          <DialogHeader>
            <DialogTitle>Revogar convites selecionados</DialogTitle>
            <DialogDescription>Os links serão invalidados imediatamente.</DialogDescription>
          </DialogHeader>
          <div className="max-h-64 space-y-2 overflow-auto">
            {selectedInvites.slice(0, 5).map((i) => (
              <div key={`invite-revoke-${i.id}`} className="rounded-md bg-slate-100 px-3 py-2 text-sm">
                {i.email} <span className="text-neutral-500">— {formatRole(i.role)}</span>
              </div>
            ))}
            {selectedInvites.length > 5 ? (
              <div className="px-3 text-xs text-neutral-500">+ {selectedInvites.length - 5} outros</div>
            ) : null}
          </div>
          <DialogFooter>
            <Button variant="outline" onClick={() => setBulkRevokeInvitesOpen(false)} disabled={isBulkRevokingInvites}>
              Cancelar
            </Button>
            <Button
              variant="destructive"
              disabled={isBulkRevokingInvites}
              onClick={async () => {
                setIsBulkRevokingInvites(true)
                try {
                  const ids = selectedInvites.filter((i) => i.status === "pending").map((i) => i.id)
                  await performBulkRevokeInvites(ids)
                  setInviteSelection(new Set())
                  setBulkRevokeInvitesOpen(false)
                  toast.success("Convites revogados")
                } catch (error) {
                  const message = error instanceof Error ? error.message : "Falha ao revogar convites"
                  toast.error(message)
                } finally {
                  setIsBulkRevokingInvites(false)
                }
              }}
            >
              Revogar selecionados
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>
    </>
  )
}
