"use client"

import Link from "next/link"
import { useRouter } from "next/navigation"
import { useCallback, useEffect, useMemo, useRef, useState } from "react"
import { format, formatDistanceToNow, parseISO } from "date-fns"
import { ptBR } from "date-fns/locale"
import { IconClock, IconDownload, IconLink, IconPlayerPause, IconPlayerPlay, IconPencil } from "@tabler/icons-react"
import { useMutation, useQuery } from "convex/react"
import { toast } from "sonner"
import { api } from "@/convex/_generated/api"

import { useAuth } from "@/lib/auth-client"
import type { Doc, Id } from "@/convex/_generated/dataModel"
import type { TicketWithDetails, TicketQueueSummary, TicketStatus } from "@/lib/schemas/ticket"
import { Badge } from "@/components/ui/badge"
import { Separator } from "@/components/ui/separator"
import { PrioritySelect } from "@/components/tickets/priority-select"
import { DeleteTicketDialog } from "@/components/tickets/delete-ticket-dialog"
import { StatusSelect } from "@/components/tickets/status-select"
import { CloseTicketDialog, type AdjustWorkSummaryResult } from "@/components/tickets/close-ticket-dialog"
import { TicketCustomFieldsSection } from "@/components/tickets/ticket-custom-fields"
import { Calendar as CalendarIcon, CheckCircle2, MessageCircle, MonitorSmartphone, RotateCcw, WifiOff } from "lucide-react"
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"
import { Button } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from "@/components/ui/dialog"
import { Textarea } from "@/components/ui/textarea"
import { Spinner } from "@/components/ui/spinner"
import { useTicketCategories } from "@/hooks/use-ticket-categories"
import { useDefaultQueues } from "@/hooks/use-default-queues"
import { useTicketRemoteAccess } from "@/hooks/use-ticket-remote-access"
import { VISIT_KEYWORDS } from "@/lib/ticket-matchers"
import { cn } from "@/lib/utils"
import { getDeviceStatusIndicator } from "@/lib/device-status"
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu"
import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip"
import {
  deriveServerOffset,
  reconcileLocalSessionStart,
  toServerTimestamp,
  type SessionStartOrigin,
} from "./ticket-timer.utils"
import { SearchableCombobox, type SearchableComboboxOption } from "@/components/ui/searchable-combobox"
import { Calendar } from "@/components/ui/calendar"
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover"
import { TimePicker } from "@/components/ui/time-picker"

interface TicketHeaderProps {
  ticket: TicketWithDetails
}

type AgentWorkTotalSnapshot = {
  agentId: string
  agentName: string | null
  agentEmail: string | null
  avatarUrl: string | null
  totalWorkedMs: number
  internalWorkedMs: number
  externalWorkedMs: number
}

type WorkSummarySnapshot = {
  ticketId: Id<"tickets">
  totalWorkedMs: number
  internalWorkedMs: number
  externalWorkedMs: number
  serverNow?: number | null
  activeSession: {
    id: Id<"ticketWorkSessions">
    agentId: string
    startedAt: number
    workType?: string
  } | null
  perAgentTotals: AgentWorkTotalSnapshot[]
}

const cardClass = "relative space-y-4 rounded-2xl border border-slate-200 bg-white p-6 shadow-sm"
const referenceBadgeClass = "inline-flex h-9 items-center gap-2 rounded-full border border-slate-200 bg-white px-3 text-sm font-semibold text-neutral-700"
const startButtonClass =
  "inline-flex items-center gap-1 rounded-lg border border-black bg-black px-3 py-1.5 text-sm font-semibold text-white transition hover:bg-[#18181b]/85 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-black/30"
const pauseButtonClass =
  "inline-flex items-center gap-1 rounded-lg border border-black bg-black px-3 py-1.5 text-sm font-semibold text-white transition hover:bg-[#18181b]/85 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[#18181b]/30"
const playButtonEnabledClass =
  "inline-flex items-center justify-center rounded-lg border border-black bg-black text-white transition hover:bg-[#18181b]/85 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[#18181b]/30"
const playButtonDisabledClass =
  "inline-flex items-center justify-center rounded-lg border border-slate-300 bg-slate-100 text-neutral-400 cursor-not-allowed"
const pauseButtonEnabledClass =
  "inline-flex items-center justify-center rounded-lg border border-black bg-black text-white transition hover:bg-[#18181b]/85 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[#18181b]/30"
const pauseButtonDisabledClass =
  "inline-flex items-center justify-center rounded-lg border border-slate-300 bg-slate-100 text-neutral-400 cursor-not-allowed"
const selectTriggerClass = "h-8 w-full rounded-lg border border-slate-300 bg-white px-3 text-left text-sm font-medium text-neutral-800 shadow-sm focus:ring-0 data-[state=open]:border-[#00d6eb]"
const smallSelectTriggerClass = "h-8 w-full rounded-lg border border-slate-300 bg-white px-3 text-left text-sm font-medium text-neutral-800 shadow-sm focus:ring-0 data-[state=open]:border-[#00d6eb]"
const sectionLabelClass = "text-xs font-semibold uppercase tracking-wide text-neutral-500"
const sectionValueClass = "font-medium text-neutral-900"
const subtleBadgeClass =
  "inline-flex items-center rounded-full border border-slate-200 bg-slate-50 px-2.5 py-0.5 text-[11px] font-medium text-neutral-600"

const EMPTY_CATEGORY_VALUE = "__none__"
const EMPTY_SUBCATEGORY_VALUE = "__none__"
const PAUSE_REASONS = [
  { value: "NO_CONTACT", label: "Falta de contato" },
  { value: "WAITING_THIRD_PARTY", label: "Aguardando terceiro" },
  { value: "IN_PROCEDURE", label: "Em procedimento" },
  { value: "LUNCH_BREAK", label: "Intervalo de almoço" },
]
const VISIT_STATUS_LABELS: Record<string, string> = {
  scheduled: "Agendada",
  en_route: "Em deslocamento",
  in_service: "Em atendimento",
  done: "Concluída",
  no_show: "No-show",
  canceled: "Cancelada",
}
const VISIT_STATUS_TONES: Record<string, string> = {
  scheduled: "bg-slate-100 text-neutral-700 border-slate-200",
  en_route: "bg-sky-100 text-sky-800 border-sky-200",
  in_service: "bg-amber-100 text-amber-800 border-amber-200",
  done: "bg-emerald-100 text-emerald-800 border-emerald-200",
  no_show: "bg-rose-100 text-rose-800 border-rose-200",
  canceled: "bg-slate-100 text-neutral-600 border-slate-200",
}

type CustomerOption = {
  id: string
  name: string
  email: string
  role: string
  companyId: string | null
  companyName: string | null
  companyIsAvulso: boolean
  avatarUrl: string | null
}

const NO_COMPANY_VALUE = "__no_company__"
const NO_REQUESTER_VALUE = "__no_requester__"

function formatDuration(durationMs: number) {
  if (durationMs <= 0) return "0s"
  const totalSeconds = Math.floor(durationMs / 1000)
  const hours = Math.floor(totalSeconds / 3600)
  const minutes = Math.floor((totalSeconds % 3600) / 60)
  const seconds = totalSeconds % 60
  if (hours > 0) {
    return `${hours}h ${minutes.toString().padStart(2, "0")}m`
  }
  if (minutes > 0) {
    return `${minutes}m ${seconds.toString().padStart(2, "0")}s`
  }
  return `${seconds}s`
}

export function TicketSummaryHeader({ ticket }: TicketHeaderProps) {
  const { convexUserId, role, isStaff, session, machineContext } = useAuth()
  const router = useRouter()
  const normalizedRole = (role ?? "").toLowerCase()
  const isManager = normalizedRole === "manager"
  const isAdmin = normalizedRole === "admin"
  const canAdjustWork = isAdmin || normalizedRole === "agent"
  const sessionName = session?.user?.name?.trim()
  const machineAssignedName = machineContext?.assignedUserName?.trim()
  const agentName =
    sessionName && sessionName.length > 0
      ? sessionName
      : machineAssignedName && machineAssignedName.length > 0
        ? machineAssignedName
        : null
  const viewerId = convexUserId ?? null
  const viewerRole = (role ?? "").toLowerCase()
  const viewerEmailRaw = session?.user?.email ?? machineContext?.assignedUserEmail ?? null
  const viewerEmail = (viewerEmailRaw ?? "").trim().toLowerCase()
  const [status, setStatus] = useState<TicketStatus>(ticket.status)
  const checklistRequiredPending = useMemo(() => {
    const list = ticket.checklist ?? []
    return list.filter((item) => (item.required ?? true) && !item.done).length
  }, [ticket.checklist])
  const [visitStatusLoading, setVisitStatusLoading] = useState(false)
  const rawReopenDeadline = ticket.reopenDeadline ?? null
  const fallbackClosedMs = ticket.closedAt?.getTime() ?? ticket.resolvedAt?.getTime() ?? null
  const DEFAULT_REOPEN_DAYS = 7
  const inferredDeadline = rawReopenDeadline
    ? rawReopenDeadline
    : fallbackClosedMs
      ? fallbackClosedMs + DEFAULT_REOPEN_DAYS * 24 * 60 * 60 * 1000
      : null
  const isRequesterById = Boolean(ticket.requester?.id && viewerId && ticket.requester.id === viewerId)
  const isRequesterByEmail = Boolean(
    viewerEmail && ticket.requester?.email && viewerEmail === ticket.requester.email.trim().toLowerCase(),
  )
  const isRequester = isRequesterById || isRequesterByEmail
  const reopenWindowActive = inferredDeadline ? inferredDeadline > Date.now() : true
  const canReopenTicket =
    status === "RESOLVED" && reopenWindowActive && (isStaff || viewerRole === "manager" || isRequester)
  const reopenDeadlineLabel = useMemo(() => {
    const deadline = inferredDeadline ?? rawReopenDeadline
    if (!deadline) return null
    try {
      return new Date(deadline).toLocaleString("pt-BR")
    } catch {
      return null
    }
  }, [inferredDeadline, rawReopenDeadline])
  const viewerAvatar = session?.user?.avatarUrl ?? null
  const viewerAgentMeta = useMemo(
    () => {
      if (!convexUserId) return null
      return {
        id: String(convexUserId),
        name: agentName ?? viewerEmailRaw ?? null,
        email: viewerEmailRaw,
        avatarUrl: viewerAvatar,
      }
    },
    [convexUserId, agentName, viewerEmailRaw, viewerAvatar]
  )
  useDefaultQueues(ticket.tenantId)
  const {
    canShowRemoteAccess: canShowRemoteShortcut,
    primaryRemoteAccess: remoteShortcutAccess,
    connect: handleRemoteShortcutConnect,
    hostname: remoteShortcutHostname,
    statusKey: remoteShortcutStatusKey,
    statusLabel: remoteShortcutStatusLabel,
  } = useTicketRemoteAccess(ticket)
  const remoteShortcutIndicator = getDeviceStatusIndicator(remoteShortcutStatusKey)
  const showRemoteShortcut = canShowRemoteShortcut && Boolean(remoteShortcutAccess)
  const changeAssignee = useMutation(api.tickets.changeAssignee)
  const changeQueue = useMutation(api.tickets.changeQueue)
  const changeRequester = useMutation(api.tickets.changeRequester)
  const updateSubject = useMutation(api.tickets.updateSubject)
  const startWork = useMutation(api.tickets.startWork)
  const pauseWork = useMutation(api.tickets.pauseWork)
  const updateCategories = useMutation(api.tickets.updateCategories)
  const reopenTicket = useMutation(api.tickets.reopenTicket)
  const updateVisitSchedule = useMutation(api.tickets.updateVisitSchedule)
  const updateVisitStatus = useMutation(api.tickets.updateVisitStatus)
  const agents = (useQuery(api.users.listAgents, { tenantId: ticket.tenantId }) as Doc<"users">[] | undefined) ?? []
  const normalizedTicketQueue = useMemo(() => (ticket.queue ?? "").toLowerCase(), [ticket.queue])
  const isVisitQueueTicket = useMemo(
    () => VISIT_KEYWORDS.some((keyword) => normalizedTicketQueue.includes(keyword)),
    [normalizedTicketQueue],
  )
  const initialVisitDateValue = useMemo(
    () => (ticket.dueAt ? format(ticket.dueAt, "yyyy-MM-dd") : null),
    [ticket.dueAt],
  )
  const initialVisitTimeValue = useMemo(
    () => (ticket.dueAt ? format(ticket.dueAt, "HH:mm") : null),
    [ticket.dueAt],
  )
  const [visitDateInput, setVisitDateInput] = useState<string | null>(initialVisitDateValue)
  const [visitTimeInput, setVisitTimeInput] = useState<string | null>(initialVisitTimeValue)
  const [visitDatePickerOpen, setVisitDatePickerOpen] = useState(false)
  const [visitError, setVisitError] = useState<string | null>(null)
  const queuesEnabled = Boolean(isStaff && convexUserId)
  const companiesRemote = useQuery(
    api.companies.list,
    convexUserId ? { tenantId: ticket.tenantId, viewerId: convexUserId as Id<"users"> } : "skip"
  )
  const companies = useMemo(
    () =>
      (Array.isArray(companiesRemote) ? companiesRemote : []).map((company) => ({
        id: String(company.id),
        name: company.name,
        slug: company.slug ?? null,
      })),
    [companiesRemote]
  )

  const customersRemote = useQuery(
    api.users.listCustomers,
    convexUserId ? { tenantId: ticket.tenantId, viewerId: convexUserId as Id<"users"> } : "skip"
  )
  const customers = useMemo(
    () => (Array.isArray(customersRemote) ? (customersRemote as CustomerOption[]) : []),
    [customersRemote]
  )

  const queuesResult = useQuery(
    api.queues.summary,
    queuesEnabled ? { tenantId: ticket.tenantId, viewerId: convexUserId as Id<"users"> } : "skip"
  )
  const queues: TicketQueueSummary[] = Array.isArray(queuesResult) ? queuesResult : []
  const { categories, isLoading: categoriesLoading } = useTicketCategories(ticket.tenantId)
  const workSummaryRemote = useQuery(
    api.tickets.workSummary,
    convexUserId
      ? { ticketId: ticket.id as Id<"tickets">, viewerId: convexUserId as Id<"users"> }
      : "skip"
  ) as
    | {
        ticketId: Id<"tickets">
        totalWorkedMs: number
        internalWorkedMs?: number
        externalWorkedMs?: number
        serverNow?: number
        activeSession: {
          id: Id<"ticketWorkSessions">
          agentId: string
          startedAt: number
          workType?: string
        } | null
        perAgentTotals?: Array<{
          agentId: string
          agentName?: string | null
          agentEmail?: string | null
          avatarUrl?: string | null
          totalWorkedMs: number
          internalWorkedMs?: number
          externalWorkedMs?: number
        }>
      }
    | null
    | undefined

  // Live Chat
  const ticketMachineId = ticket.machine?.id ?? null
  const liveChatSession = useQuery(
    api.liveChat.getTicketSession,
    convexUserId && ticketMachineId
      ? { ticketId: ticket.id as Id<"tickets">, viewerId: convexUserId as Id<"users"> }
      : "skip"
  ) as {
    sessionId: Id<"liveChatSessions"> | null
    agentId: Id<"users"> | null
    agentName: string | null
    startedAt: number | null
    lastActivityAt: number | null
    unreadByAgent: number
    machineOnline: boolean
  } | null | undefined

  const startLiveChat = useMutation(api.liveChat.startSession)
  const [isStartingChat, setIsStartingChat] = useState(false)

  // Verificar se máquina está online (para tickets com machineId)
  const hasMachine = Boolean(ticketMachineId)
  const machineOnline = liveChatSession?.machineOnline ?? false
  const hasActiveSession = Boolean(liveChatSession?.sessionId)
  const ticketHasAssignee = Boolean(ticket.assignee)
  // Permitir iniciar chat mesmo sem responsavel - vai atribuir automaticamente
  const canStartChat = hasMachine && !hasActiveSession && isStaff

  const handleStartLiveChat = async () => {
    if (!convexUserId || !ticket.id || isStartingChat) return
    setIsStartingChat(true)
    toast.dismiss("live-chat")

    try {
      // Se nao ha responsavel, atribuir o usuario logado automaticamente
      if (!ticketHasAssignee) {
        toast.loading("Atribuindo responsavel...", { id: "live-chat" })
        await changeAssignee({
          ticketId: ticket.id as Id<"tickets">,
          assigneeId: convexUserId as Id<"users">,
          actorId: convexUserId as Id<"users">,
          reason: "Atribuido automaticamente ao iniciar chat ao vivo",
        })
        // Atualizar estado local
        const agent = agents.find((a) => String(a._id) === convexUserId)
        if (agent) {
          setAssigneeState({
            id: String(agent._id),
            name: agent.name,
            email: agent.email,
            avatarUrl: agent.avatarUrl ?? undefined,
            teams: Array.isArray(agent.teams) ? agent.teams.filter((t): t is string => typeof t === "string") : [],
          })
        }
      }

      toast.loading("Iniciando chat ao vivo...", { id: "live-chat" })
      const result = await startLiveChat({
        ticketId: ticket.id as Id<"tickets">,
        actorId: convexUserId as Id<"users">,
      })
      if (result.isNew) {
        toast.success("Chat ao vivo iniciado", { id: "live-chat" })
      } else {
        toast.info("Ja existe uma sessao de chat ativa", { id: "live-chat" })
      }
    } catch (error: unknown) {
      console.error("[LiveChat] Erro ao iniciar chat:", error)
      // Extrair mensagem amigável do erro do Convex
      let message = "Nao foi possivel iniciar o chat"
      if (error instanceof Error) {
        const errorMsg = error.message.toLowerCase()
        if (errorMsg.includes("offline")) {
          message = "Maquina offline. Aguarde a maquina ficar online para iniciar o chat."
        } else if (errorMsg.includes("nao encontrad") || errorMsg.includes("not found")) {
          message = "Maquina nao encontrada"
        }
      }
      toast.error(message, { id: "live-chat" })
    } finally {
      setIsStartingChat(false)
    }
  }

  const [assigneeState, setAssigneeState] = useState(ticket.assignee ?? null)
  const [editing, setEditing] = useState(false)
  const [subject, setSubject] = useState(ticket.subject)
  const [categorySelection, setCategorySelection] = useState<{ categoryId: string; subcategoryId: string }>(
    {
      categoryId: ticket.category?.id ?? "",
      subcategoryId: ticket.subcategory?.id ?? "",
    }
  )
  const currentAssigneeId = assigneeState?.id ?? ""
  const [assigneeSelection, setAssigneeSelection] = useState(currentAssigneeId)
  const [saving, setSaving] = useState(false)
  const [pauseDialogOpen, setPauseDialogOpen] = useState(false)
  const [isReopening, setIsReopening] = useState(false)
  const [pauseReason, setPauseReason] = useState<string>(PAUSE_REASONS[0]?.value ?? "NO_CONTACT")
  const [pauseNote, setPauseNote] = useState("")
  const [pausing, setPausing] = useState(false)
  const [exportingPdf, setExportingPdf] = useState(false)
  const [closeOpen, setCloseOpen] = useState(false)
  const [assigneeChangeReason, setAssigneeChangeReason] = useState("")
  const [assigneeReasonError, setAssigneeReasonError] = useState<string | null>(null)
  const [companySelection, setCompanySelection] = useState<string>(NO_COMPANY_VALUE)
  const [requesterSelection, setRequesterSelection] = useState<string | null>(ticket.requester.id)
  const [requesterError, setRequesterError] = useState<string | null>(null)
  const [customersInitialized, setCustomersInitialized] = useState(false)
  const visitDatePickerValue = useMemo(() => {
    if (!visitDateInput) return null
    try {
      return parseISO(`${visitDateInput}T00:00:00`)
    } catch {
      return null
    }
  }, [visitDateInput])
  const selectedCategoryId = categorySelection.categoryId
  const selectedSubcategoryId = categorySelection.subcategoryId
  const dirty = useMemo(() => subject !== ticket.subject, [subject, ticket.subject])
  const currentCategoryId = ticket.category?.id ?? ""
  const currentSubcategoryId = ticket.subcategory?.id ?? ""
  const categoryDirty = useMemo(() => {
    return selectedCategoryId !== currentCategoryId || selectedSubcategoryId !== currentSubcategoryId
  }, [selectedCategoryId, selectedSubcategoryId, currentCategoryId, currentSubcategoryId])
  const currentQueueName = ticket.queue ?? ""
  const isAvulso = Boolean(((ticket.company ?? null) as { isAvulso?: boolean } | null)?.isAvulso ?? false)
  const hasSlaMetadata = Boolean(ticket.slaSnapshot || ticket.slaSolutionDueAt)
  const resolvedWithSummary = useMemo(() => {
    if (!ticket.resolvedWithTicketId) return null
    const linkedId = String(ticket.resolvedWithTicketId)
    let reference: string | null = null
    let subject: string | null = null
    for (const event of ticket.timeline ?? []) {
      if (!event || event.type !== "TICKET_LINKED") continue
      const payload = (event.payload ?? {}) as {
        linkedTicketId?: unknown
        linkedReference?: unknown
        linkedSubject?: unknown
      }
      if (String(payload.linkedTicketId ?? "") !== linkedId) continue
      if (reference === null) {
        const rawReference = payload.linkedReference
        if (typeof rawReference === "number") {
          reference = rawReference.toString()
        } else if (typeof rawReference === "string" && rawReference.trim().length > 0) {
          reference = rawReference.trim()
        }
      }
      if (subject === null) {
        const rawSubject = payload.linkedSubject
        if (typeof rawSubject === "string" && rawSubject.trim().length > 0) {
          subject = rawSubject.trim()
        }
      }
      if (reference !== null && subject !== null) {
        break
      }
    }
    return { id: linkedId, reference, subject }
  }, [ticket.resolvedWithTicketId, ticket.timeline])
  const [queueSelection, setQueueSelection] = useState(currentQueueName)
  const queueDirty = useMemo(() => queueSelection !== currentQueueName, [queueSelection, currentQueueName])
  const normalizedQueueSelection = useMemo(() => (queueSelection ?? "").toLowerCase(), [queueSelection])
  const isVisitQueueSelected = useMemo(
    () => VISIT_KEYWORDS.some((keyword) => normalizedQueueSelection.includes(keyword)),
    [normalizedQueueSelection],
  )
  const visitSectionEnabled = editing ? isVisitQueueSelected : isVisitQueueTicket
  const visitStatusValue = (ticket.visitStatus as string | null) ?? (ticket.dueAt ? "scheduled" : null)
  const visitPerformedAt = ticket.visitPerformedAt ?? null
  const visitDirty = useMemo(() => {
    if (!visitSectionEnabled) {
      return false
    }
    if (!isVisitQueueTicket && isVisitQueueSelected) {
      return true
    }
    return visitDateInput !== initialVisitDateValue || visitTimeInput !== initialVisitTimeValue
  }, [
    visitSectionEnabled,
    isVisitQueueTicket,
    isVisitQueueSelected,
    visitDateInput,
    initialVisitDateValue,
    visitTimeInput,
    initialVisitTimeValue,
  ])
  const previousVisitSelectionRef = useRef(isVisitQueueSelected)
  const currentRequesterRecord = useMemo(
    () => customers.find((customer) => customer.id === ticket.requester.id) ?? null,
    [customers, ticket.requester.id]
  )
  const currentCompanySelection = useMemo(() => {
    if (currentRequesterRecord?.companyId) return currentRequesterRecord.companyId
    if (ticket.company?.id) return String(ticket.company.id)
    return NO_COMPANY_VALUE
  }, [currentRequesterRecord, ticket.company?.id])
  const companyMeta = useMemo(() => {
    const map = new Map<string, { name: string; isAvulso?: boolean; keywords: string[] }>()
    companies.forEach((company) => {
      const trimmedName = company.name.trim()
      const slugFallback = company.slug?.trim()
      const label =
        trimmedName.length > 0
          ? trimmedName
          : slugFallback && slugFallback.length > 0
            ? slugFallback
            : `Empresa ${company.id.slice(0, 8)}`
      const keywords = slugFallback ? [slugFallback] : []
      map.set(company.id, { name: label, isAvulso: false, keywords })
    })
    customers.forEach((customer) => {
      if (customer.companyId && !map.has(customer.companyId)) {
        const trimmedName = customer.companyName?.trim() ?? ""
        const label =
          trimmedName.length > 0 ? trimmedName : `Empresa ${customer.companyId.slice(0, 8)}`
        map.set(customer.companyId, {
          name: label,
          isAvulso: customer.companyIsAvulso,
          keywords: [],
        })
      }
    })
    return map
  }, [companies, customers])

  const companyComboboxOptions = useMemo<SearchableComboboxOption[]>(() => {
    const entries = Array.from(companyMeta.entries())
      .map(([id, meta]) => ({
        value: id,
        label: meta.name,
        keywords: meta.keywords,
      }))
      .sort((a, b) => a.label.localeCompare(b.label, "pt-BR"))
    return [{ value: NO_COMPANY_VALUE, label: "Sem empresa", keywords: ["sem empresa", "nenhuma"] }, ...entries]
  }, [companyMeta])

  const filteredCustomers = useMemo(() => {
    if (companySelection === NO_COMPANY_VALUE) {
      return customers.filter((customer) => !customer.companyId)
    }
    return customers.filter((customer) => customer.companyId === companySelection)
  }, [companySelection, customers])
  const assigneeDirty = useMemo(() => assigneeSelection !== currentAssigneeId, [assigneeSelection, currentAssigneeId])
  const requesterDirty = useMemo(() => requesterSelection !== ticket.requester.id, [requesterSelection, ticket.requester.id])
  const visitHasInvalid =
    visitSectionEnabled && (!visitDateInput || !visitTimeInput || Boolean(visitError))
  const visitInlineError =
    visitError ??
    (editing && visitSectionEnabled && (!visitDateInput || !visitTimeInput)
      ? "Informe a data e o horário da visita para prosseguir."
      : null)
  const shouldHighlightVisitFields = Boolean(visitInlineError && editing && visitSectionEnabled)
  const slaDueDate = !visitSectionEnabled && hasSlaMetadata ? ticket.dueAt : null
  const visitDateMissing = !visitDateInput
  const visitTimeMissing = !visitTimeInput
  const formDirty = dirty || categoryDirty || queueDirty || assigneeDirty || requesterDirty || visitDirty
  const normalizedAssigneeReason = assigneeChangeReason.trim()
  const assigneeReasonValid = normalizedAssigneeReason.length === 0 || normalizedAssigneeReason.length >= 5
  const saveDisabled = !formDirty || saving || !assigneeReasonValid || visitHasInvalid
  const handleVisitStatusChange = useCallback(
    async (nextStatus: string) => {
      if (!visitSectionEnabled) return
      if (!viewerId) {
        toast.error("É necessário estar autenticado para atualizar a visita.")
        return
      }
      const normalizedStatus = nextStatus.toLowerCase()
      setVisitStatusLoading(true)
      const toastId = "visit-status"
      toast.loading("Atualizando status da visita...", { id: toastId })
      try {
        await updateVisitStatus({
          ticketId: ticket.id as Id<"tickets">,
          actorId: viewerId as Id<"users">,
          status: normalizedStatus,
          performedAt: Date.now(),
        })
        toast.success("Visita atualizada com sucesso.", { id: toastId })
        router.refresh()
      } catch (error) {
        console.error(error)
        toast.error("Não foi possível atualizar o status da visita.", { id: toastId })
      } finally {
        setVisitStatusLoading(false)
      }
    },
    [router, ticket.id, updateVisitStatus, viewerId, visitSectionEnabled],
  )
  const companyLabel = useMemo(() => {
    if (ticket.company?.name) return ticket.company.name
    if (isAvulso) return "Cliente avulso"
    return "Sem empresa vinculada"
  }, [ticket.company?.name, isAvulso])

  const activeCategory = useMemo(
    () => categories.find((category) => category.id === selectedCategoryId) ?? null,
    [categories, selectedCategoryId]
  )
  const secondaryOptions = useMemo(() => activeCategory?.secondary ?? [], [activeCategory])
  const hasAssignee = Boolean(currentAssigneeId)
  const isCurrentResponsible = hasAssignee && convexUserId ? currentAssigneeId === convexUserId : false
  const isResolved = status === "RESOLVED"
  // Permitir Play mesmo sem responsavel - vai atribuir automaticamente
  const canControlWork = !isResolved && isStaff
  const canPauseWork = !isResolved && (isAdmin || isCurrentResponsible)
  const pauseDisabled = !canPauseWork
  const startDisabled = !canControlWork
  const startDisabledReason = useMemo(() => {
    if (isResolved) {
      return "Este chamado está encerrado. Reabra o ticket para iniciar um novo atendimento."
    }
    if (!isStaff) {
      return "Apenas a equipe interna pode iniciar este atendimento."
    }
    return "Não é possível iniciar o atendimento neste momento."
  }, [isResolved, isStaff])

  useEffect(() => {
    if (!customersInitialized) {
      if (customers.length > 0) {
        setRequesterSelection(ticket.requester.id)
        setCompanySelection(currentCompanySelection)
        setCustomersInitialized(true)
      }
      return
    }
    if (!editing) {
      setRequesterSelection(ticket.requester.id)
      setCompanySelection(currentCompanySelection)
    }
  }, [customersInitialized, customers, currentCompanySelection, ticket.requester.id, editing])

  useEffect(() => {
    if (!editing) return
    const available = filteredCustomers
    if (available.length === 0) {
      if (requesterSelection !== null) {
        setRequesterSelection(null)
      }
      return
    }
    if (!requesterSelection || !available.some((customer) => customer.id === requesterSelection)) {
      setRequesterSelection(available[0].id)
    }
  }, [editing, filteredCustomers, requesterSelection])

  useEffect(() => {
    if (requesterSelection && requesterError) {
      setRequesterError(null)
    }
  }, [requesterSelection, requesterError])


  useEffect(() => {
    setStatus(ticket.status)
  }, [ticket.status])

  useEffect(() => {
    setAssigneeState(ticket.assignee ?? null)
  }, [ticket.assignee])

  async function handleSave() {
    if (!convexUserId || !formDirty) {
      setEditing(false)
      return
    }

    setSaving(true)

    try {
      if (categoryDirty && !isManager) {
        toast.loading("Atualizando categoria...", { id: "ticket-category" })
        try {
          await updateCategories({
            ticketId: ticket.id as Id<"tickets">,
            categoryId: selectedCategoryId ? (selectedCategoryId as Id<"ticketCategories">) : null,
            subcategoryId: selectedSubcategoryId ? (selectedSubcategoryId as Id<"ticketSubcategories">) : null,
            actorId: convexUserId as Id<"users">,
          })
          toast.success("Categoria atualizada!", { id: "ticket-category" })
        } catch (categoryError) {
          toast.error("Não foi possível atualizar a categoria.", { id: "ticket-category" })
          setCategorySelection({
            categoryId: currentCategoryId,
            subcategoryId: currentSubcategoryId,
          })
          throw categoryError
        }
      } else if (categoryDirty && isManager) {
        setCategorySelection({
          categoryId: currentCategoryId,
          subcategoryId: currentSubcategoryId,
        })
      }

      if (queueDirty && !isManager) {
        const queue = queues.find((item) => item.name === queueSelection)
        if (!queue) {
          toast.error("Fila selecionada não está disponível.")
          setQueueSelection(currentQueueName)
          throw new Error("Fila inválida")
        }
        toast.loading("Atualizando fila...", { id: "queue" })
        try {
          await changeQueue({
            ticketId: ticket.id as Id<"tickets">,
            queueId: queue.id as Id<"queues">,
            actorId: convexUserId as Id<"users">,
          })
          toast.success("Fila atualizada!", { id: "queue" })
        } catch (queueError) {
          toast.error("Não foi possível atualizar a fila.", { id: "queue" })
          setQueueSelection(currentQueueName)
          throw queueError
        }
      } else if (queueDirty && isManager) {
        setQueueSelection(currentQueueName)
      }

      if (visitSectionEnabled && visitDirty && !isManager) {
        if (!visitDateInput || !visitTimeInput) {
          setVisitError("Informe a data e o horário da visita.")
          throw new Error("invalid-visit-schedule")
        }
        try {
          const timeSegment = visitTimeInput.length === 5 ? `${visitTimeInput}:00` : visitTimeInput
          const isoString = `${visitDateInput}T${timeSegment}`
          const parsed = parseISO(isoString)
          const timestamp = parsed.getTime()
          if (!Number.isFinite(timestamp)) {
            setVisitError("Data ou horário da visita inválido.")
            throw new Error("invalid-visit-schedule")
          }
          setVisitError(null)
          toast.loading("Atualizando data da visita...", { id: "visit-date" })
          await updateVisitSchedule({
            ticketId: ticket.id as Id<"tickets">,
            actorId: convexUserId as Id<"users">,
            visitDate: timestamp,
          })
          toast.success("Data da visita atualizada!", { id: "visit-date" })
        } catch (visitScheduleError) {
          if (!(visitScheduleError instanceof Error && visitScheduleError.message === "invalid-visit-schedule")) {
            toast.error("Não foi possível atualizar a data da visita.", { id: "visit-date" })
          }
          throw visitScheduleError
        }
      } else if (visitSectionEnabled && visitDirty && isManager) {
        setVisitDateInput(initialVisitDateValue)
        setVisitTimeInput(initialVisitTimeValue)
      }

      if (requesterDirty && !isManager) {
        if (!requesterSelection) {
          setRequesterError("Selecione um solicitante.")
          toast.error("Selecione um solicitante válido.", { id: "requester" })
          throw new Error("invalid-requester")
        }
        toast.loading("Atualizando solicitante...", { id: "requester" })
        try {
          await changeRequester({
            ticketId: ticket.id as Id<"tickets">,
            requesterId: requesterSelection as Id<"users">,
            actorId: convexUserId as Id<"users">,
          })
          toast.success("Solicitante atualizado!", { id: "requester" })
        } catch (requesterError) {
          console.error(requesterError)
          toast.error("Não foi possível atualizar o solicitante.", { id: "requester" })
          setRequesterSelection(ticket.requester.id)
          setCompanySelection(currentCompanySelection)
          throw requesterError
        }
      } else if (requesterDirty && isManager) {
        setRequesterSelection(ticket.requester.id)
        setCompanySelection(currentCompanySelection)
      }

      if (assigneeDirty && !isManager) {
        if (!assigneeSelection) {
          toast.error("Selecione um responsável válido.", { id: "assignee" })
          setAssigneeSelection(currentAssigneeId)
          throw new Error("invalid-assignee")
        } else {
          const reasonValue = assigneeChangeReason.trim()
          if (reasonValue.length > 0 && reasonValue.length < 5) {
            setAssigneeReasonError("Descreva o motivo com pelo menos 5 caracteres ou deixe em branco.")
            toast.error("Informe ao menos 5 caracteres no motivo ou deixe o campo vazio.", { id: "assignee" })
            return
          }
          if (reasonValue.length > 1000) {
            setAssigneeReasonError("Use no máximo 1.000 caracteres.")
            toast.error("Reduza o motivo para até 1.000 caracteres.", { id: "assignee" })
            return
          }
          setAssigneeReasonError(null)
          toast.loading("Atualizando responsável...", { id: "assignee" })
          try {
            await changeAssignee({
              ticketId: ticket.id as Id<"tickets">,
              assigneeId: assigneeSelection as Id<"users">,
              actorId: convexUserId as Id<"users">,
              reason: reasonValue.length > 0 ? reasonValue : undefined,
            })
            toast.success("Responsável atualizado!", { id: "assignee" })
            if (assigneeSelection) {
              const next = agents.find((agent) => String(agent._id) === assigneeSelection)
              if (next) {
                setAssigneeState({
                  id: String(next._id),
                  name: next.name,
                  email: next.email,
                  avatarUrl: next.avatarUrl ?? undefined,
                  teams: Array.isArray(next.teams) ? next.teams.filter((team): team is string => typeof team === "string") : [],
                })
              }
            }
            setAssigneeChangeReason("")
          } catch (error) {
            console.error(error)
            toast.error("Não foi possível atualizar o responsável.", { id: "assignee" })
            setAssigneeSelection(currentAssigneeId)
            throw error
          }
        }
      } else if (assigneeDirty && isManager) {
        setAssigneeSelection(currentAssigneeId)
      }

      if (dirty) {
        toast.loading("Salvando alterações...", { id: "save-header" })
        if (subject !== ticket.subject) {
          await updateSubject({
            ticketId: ticket.id as Id<"tickets">,
            subject: subject.trim(),
            actorId: convexUserId as Id<"users">,
          })
        }
        toast.success("Cabeçalho atualizado!", { id: "save-header" })
      }
      setEditing(false)
    } catch {
      toast.error("Não foi possível salvar.", { id: "save-header" })
    } finally {
      setSaving(false)
    }
  }

  function handleCancel() {
    setSubject(ticket.subject)
    setCategorySelection({
      categoryId: currentCategoryId,
      subcategoryId: currentSubcategoryId,
    })
    setQueueSelection(currentQueueName)
    setRequesterSelection(ticket.requester.id)
    setCompanySelection(currentCompanySelection)
    setRequesterError(null)
    setAssigneeSelection(currentAssigneeId)
    setAssigneeChangeReason("")
    setAssigneeReasonError(null)
    setVisitDateInput(initialVisitDateValue)
    setVisitTimeInput(initialVisitTimeValue)
    setVisitError(null)
    setEditing(false)
  }

  useEffect(() => {
    if (editing) return
    setAssigneeChangeReason("")
    setAssigneeReasonError(null)
    setCategorySelection({
      categoryId: ticket.category?.id ?? "",
      subcategoryId: ticket.subcategory?.id ?? "",
    })
    setQueueSelection(ticket.queue ?? "")
    setAssigneeSelection(currentAssigneeId)
    setRequesterSelection(ticket.requester.id)
    setCompanySelection(currentCompanySelection)
  }, [editing, ticket.category?.id, ticket.subcategory?.id, ticket.queue, currentAssigneeId, ticket.requester.id, currentCompanySelection])

  useEffect(() => {
    if (editing) return
    setVisitDateInput(initialVisitDateValue)
    setVisitTimeInput(initialVisitTimeValue)
    setVisitError(null)
  }, [editing, initialVisitDateValue, initialVisitTimeValue])

  useEffect(() => {
    if (!editing) {
      previousVisitSelectionRef.current = isVisitQueueSelected
      return
    }
    if (isVisitQueueSelected && !previousVisitSelectionRef.current && !isVisitQueueTicket) {
      setVisitDateInput(null)
      setVisitTimeInput(null)
      setVisitError(null)
    }
    previousVisitSelectionRef.current = isVisitQueueSelected
  }, [editing, isVisitQueueSelected, isVisitQueueTicket])

  useEffect(() => {
    if (!editing) {
      setVisitDatePickerOpen(false)
    }
  }, [editing])

  useEffect(() => {
    if (!visitSectionEnabled) {
      setVisitDatePickerOpen(false)
    }
  }, [visitSectionEnabled])

  useEffect(() => {
    if (visitError && visitDateInput && visitTimeInput) {
      setVisitError(null)
    }
  }, [visitError, visitDateInput, visitTimeInput])

  useEffect(() => {
    if (!editing) return
    if (!selectedCategoryId) {
      if (selectedSubcategoryId) {
        setCategorySelection((prev) => ({ ...prev, subcategoryId: "" }))
      }
      return
    }

    const stillValid = secondaryOptions.some((option) => option.id === selectedSubcategoryId)
    if (!stillValid && selectedSubcategoryId) {
      setCategorySelection((prev) => ({ ...prev, subcategoryId: "" }))
    }
  }, [editing, secondaryOptions, selectedCategoryId, selectedSubcategoryId])

  const ticketActiveSession = ticket.workSummary?.activeSession ?? null
  const ticketActiveSessionStartedAtMs = ticketActiveSession ? ticketActiveSession.startedAt.getTime() : undefined
  const ticketActiveSessionWorkType = (ticketActiveSession as { workType?: string } | null)?.workType

  const initialWorkSummary = useMemo<WorkSummarySnapshot | null>(() => {
    if (!ticket.workSummary) return null
    return {
      ticketId: ticket.id as Id<"tickets">,
      totalWorkedMs: ticket.workSummary.totalWorkedMs ?? 0,
      internalWorkedMs: ticket.workSummary.internalWorkedMs ?? 0,
      externalWorkedMs: ticket.workSummary.externalWorkedMs ?? 0,
      serverNow: typeof ticket.workSummary.serverNow === "number" ? ticket.workSummary.serverNow : null,
      activeSession: ticketActiveSession
        ? {
            id: ticketActiveSession.id as Id<"ticketWorkSessions">,
            agentId: String(ticketActiveSession.agentId),
            startedAt: ticketActiveSessionStartedAtMs ?? ticketActiveSession.startedAt.getTime(),
            workType: (ticketActiveSessionWorkType ?? "INTERNAL").toString().toUpperCase(),
          }
        : null,
      perAgentTotals: (ticket.workSummary.perAgentTotals ?? []).map((item) => ({
        agentId: String(item.agentId),
        agentName: item.agentName ?? null,
        agentEmail: item.agentEmail ?? null,
        avatarUrl: item.avatarUrl ?? null,
        totalWorkedMs: item.totalWorkedMs ?? 0,
        internalWorkedMs: item.internalWorkedMs ?? 0,
        externalWorkedMs: item.externalWorkedMs ?? 0,
      })),
    }
  }, [
    ticket.id,
    ticket.workSummary,
    ticketActiveSession,
    ticketActiveSessionStartedAtMs,
    ticketActiveSessionWorkType,
  ])

  const [workSummary, setWorkSummary] = useState<WorkSummarySnapshot | null>(initialWorkSummary)
  const effectiveWorkSummary = workSummary ?? initialWorkSummary
  const serverOffsetRef = useRef<number>(0)

  const calibrateServerOffset = useCallback(
    (serverNow?: number | Date | null) => {
      if (serverNow === undefined || serverNow === null) return
      const serverMs =
        serverNow instanceof Date ? serverNow.getTime() : Number(serverNow)
      if (!Number.isFinite(serverMs)) return
      serverOffsetRef.current = deriveServerOffset({
        currentOffset: serverOffsetRef.current,
        localNow: Date.now(),
        serverNow: serverMs,
      })
    },
    []
  )

  const getServerNow = useCallback(() => toServerTimestamp(Date.now(), serverOffsetRef.current), [])

  useEffect(() => {
    if (initialWorkSummary?.serverNow) {
      calibrateServerOffset(initialWorkSummary.serverNow)
    }
    setWorkSummary(initialWorkSummary)
  }, [initialWorkSummary, calibrateServerOffset])

  useEffect(() => {
    if (workSummaryRemote === undefined) return
    if (workSummaryRemote === null) {
      setWorkSummary(null)
      return
    }
    if (typeof workSummaryRemote.serverNow === "number") {
      calibrateServerOffset(workSummaryRemote.serverNow)
    }
    setWorkSummary({
      ticketId: workSummaryRemote.ticketId,
      totalWorkedMs: workSummaryRemote.totalWorkedMs ?? 0,
      internalWorkedMs: workSummaryRemote.internalWorkedMs ?? 0,
      externalWorkedMs: workSummaryRemote.externalWorkedMs ?? 0,
      serverNow: typeof workSummaryRemote.serverNow === "number" ? workSummaryRemote.serverNow : null,
      activeSession: workSummaryRemote.activeSession
        ? {
            id: workSummaryRemote.activeSession.id,
            agentId: workSummaryRemote.activeSession.agentId,
            startedAt: workSummaryRemote.activeSession.startedAt,
            workType: (workSummaryRemote.activeSession.workType ?? "INTERNAL").toString().toUpperCase(),
          }
        : null,
      perAgentTotals: (workSummaryRemote.perAgentTotals ?? []).map((item) => ({
        agentId: String(item.agentId),
        agentName: item.agentName ?? null,
        agentEmail: item.agentEmail ?? null,
        avatarUrl: item.avatarUrl ?? null,
        totalWorkedMs: item.totalWorkedMs ?? 0,
        internalWorkedMs: item.internalWorkedMs ?? 0,
        externalWorkedMs: item.externalWorkedMs ?? 0,
      })),
    })
  }, [workSummaryRemote, calibrateServerOffset])

  const activeSessionId = workSummary?.activeSession?.id ?? null
  const activeSessionStartedAt = workSummary?.activeSession?.startedAt ?? null
  const isPlaying = Boolean(activeSessionId)
  const [now, setNow] = useState(() => Date.now())
  // Guarda um marcador local do início da sessão atual para evitar inflar tempo com
  // timestamps defasados vindos da rede. Escolhemos o MAIOR entre (remoto, local).
  const localStartAtRef = useRef<number>(0)
  const localStartOriginRef = useRef<SessionStartOrigin>("unknown")

  useEffect(() => {
    if (!activeSessionId) return
    const interval = setInterval(() => {
      setNow(Date.now())
    }, 1000)
    return () => clearInterval(interval)
  }, [activeSessionId])

  // Sempre que a sessão ativa (id) mudar, sincroniza o ponteiro local
  useEffect(() => {
    if (!activeSessionId) {
      localStartAtRef.current = 0
      localStartOriginRef.current = "unknown"
      return
    }
    const { localStart, origin } = reconcileLocalSessionStart({
      remoteStart: Number(activeSessionStartedAt) || 0,
      localStart: localStartAtRef.current,
      origin: localStartOriginRef.current,
    })
    localStartAtRef.current = localStart
    localStartOriginRef.current = origin
  }, [activeSessionId, activeSessionStartedAt])

  useEffect(() => {
    if (!pauseDialogOpen) {
      setPauseReason(PAUSE_REASONS[0]?.value ?? "NO_CONTACT")
      setPauseNote("")
      setPausing(false)
    }
  }, [pauseDialogOpen])

  const currentSessionMs = workSummary?.activeSession
    ? (() => {
        const remoteStart = Number(workSummary.activeSession.startedAt) || 0
        const effectiveStart = Math.max(remoteStart, localStartAtRef.current || 0)
        const alignedNow = toServerTimestamp(now, serverOffsetRef.current)
        return Math.max(0, alignedNow - effectiveStart)
      })()
    : 0
  const totalWorkedMs = workSummary ? workSummary.totalWorkedMs + currentSessionMs : 0
  const internalWorkedMs = workSummary
    ? workSummary.internalWorkedMs + (workSummary.activeSession?.workType === "INTERNAL" ? currentSessionMs : 0)
    : 0
  const externalWorkedMs = workSummary
    ? workSummary.externalWorkedMs + (workSummary.activeSession?.workType === "EXTERNAL" ? currentSessionMs : 0)
    : 0

  const formattedTotalWorked = useMemo(() => formatDuration(totalWorkedMs), [totalWorkedMs])
  const updatedRelative = useMemo(
    () => formatDistanceToNow(ticket.updatedAt, { addSuffix: true, locale: ptBR }),
    [ticket.updatedAt]
  )

  const handleStartWork = async (workType: "INTERNAL" | "EXTERNAL") => {
    if (!convexUserId) return

    // Se nao ha responsavel, atribuir o usuario logado automaticamente
    if (!assigneeState?.id) {
      toast.loading("Atribuindo responsavel e iniciando...", { id: "work" })
      try {
        await changeAssignee({
          ticketId: ticket.id as Id<"tickets">,
          assigneeId: convexUserId as Id<"users">,
          actorId: convexUserId as Id<"users">,
          reason: "Atribuido automaticamente ao iniciar atendimento",
        })
        // Atualizar estado local
        const agent = agents.find((a) => String(a._id) === convexUserId)
        if (agent) {
          setAssigneeState({
            id: String(agent._id),
            name: agent.name,
            email: agent.email,
            avatarUrl: agent.avatarUrl ?? undefined,
            teams: Array.isArray(agent.teams) ? agent.teams.filter((t): t is string => typeof t === "string") : [],
          })
        }
      } catch (err) {
        toast.error("Nao foi possivel atribuir responsavel.", { id: "work" })
        return
      }
    }

    toast.dismiss("work")
    toast.loading("Iniciando atendimento...", { id: "work" })
    try {
      const result = await startWork({
        ticketId: ticket.id as Id<"tickets">,
        actorId: convexUserId as Id<"users">,
        workType,
      })
      const resultMeta = result as {
        status?: string
        startedAt?: number
        sessionId?: Id<"ticketWorkSessions">
        serverNow?: number
      }
      const startStatus = resultMeta?.status ?? "started"
      if (startStatus === "already_started") {
        toast.info("O atendimento já estava em andamento", { id: "work" })
      } else {
        toast.success("Atendimento iniciado", { id: "work" })
      }
      // Otimização local: garantir startedAt correto imediatamente
      calibrateServerOffset(resultMeta?.serverNow ?? null)
      const startedAtMsRaw = resultMeta?.startedAt
      const startedAtMs =
        typeof startedAtMsRaw === "number" && Number.isFinite(startedAtMsRaw) ? startedAtMsRaw : getServerNow()
      if (typeof startedAtMsRaw === "number") {
        localStartOriginRef.current = "remote"
      } else if (startStatus === "already_started") {
        localStartOriginRef.current = "already-running-fallback"
      } else {
        localStartOriginRef.current = "fresh-local"
      }
      localStartAtRef.current = startedAtMs
      const sessionId = resultMeta?.sessionId
      setWorkSummary((prev) => {
        const base: WorkSummarySnapshot = prev ?? {
          ticketId: ticket.id as Id<"tickets">,
          totalWorkedMs: 0,
          internalWorkedMs: 0,
          externalWorkedMs: 0,
          serverNow: null,
          activeSession: null,
          perAgentTotals: [],
        }
        const sessionAgentId = assigneeState?.id ? String(assigneeState.id) : ""
        if (!sessionAgentId) {
          return base
        }
        const existingTotals = base.perAgentTotals ?? []
        const hasAgentEntry = existingTotals.some((item) => item.agentId === sessionAgentId)
        const updatedTotals = hasAgentEntry
          ? existingTotals
          : [
              ...existingTotals,
              {
                agentId: sessionAgentId,
                agentName: assigneeState?.name ?? viewerAgentMeta?.name ?? null,
                agentEmail: assigneeState?.email ?? viewerAgentMeta?.email ?? null,
                avatarUrl: assigneeState?.avatarUrl ?? viewerAgentMeta?.avatarUrl ?? null,
                totalWorkedMs: 0,
                internalWorkedMs: 0,
                externalWorkedMs: 0,
              },
            ]
        return {
          ...base,
          serverNow: typeof resultMeta?.serverNow === "number" ? resultMeta.serverNow : getServerNow(),
          activeSession: {
            id: (sessionId as Id<"ticketWorkSessions">) ?? (base.activeSession?.id as Id<"ticketWorkSessions">),
            agentId: sessionAgentId,
            startedAt: startedAtMs,
            workType,
          },
          perAgentTotals: updatedTotals,
        }
      })

      setStatus("AWAITING_ATTENDANCE")
    } catch (error) {
      const message = error instanceof Error ? error.message : "Não foi possível atualizar o atendimento"
      toast.error(message, { id: "work" })
    }
  }

  const handlePauseConfirm = async () => {
    if (!convexUserId) return
    toast.dismiss("work")
    toast.loading("Pausando atendimento...", { id: "work" })
    setPausing(true)
    try {
      const result = await pauseWork({
        ticketId: ticket.id as Id<"tickets">,
        actorId: convexUserId as Id<"users">,
        reason: pauseReason,
        note: pauseNote.trim() ? pauseNote.trim() : undefined,
      })
      const resultMeta = result as { status?: string; durationMs?: number; serverNow?: number }
      if (resultMeta?.status === "already_paused") {
        toast.info("O atendimento já estava pausado", { id: "work" })
      } else {
        toast.success("Atendimento pausado", { id: "work" })
      }
      setPauseDialogOpen(false)
      // Otimização local: aplicar duração retornada no total e limpar sessão ativa
      calibrateServerOffset(resultMeta?.serverNow ?? null)
      const delta = typeof resultMeta?.durationMs === "number" ? resultMeta.durationMs : 0
      localStartAtRef.current = 0
      localStartOriginRef.current = "unknown"
      setWorkSummary((prev) => {
        if (!prev) return prev
        const workType = prev.activeSession?.workType ?? "INTERNAL"
        const sessionAgentId = prev.activeSession?.agentId ?? (viewerAgentMeta?.id ?? "")
        const internalDelta = workType === "INTERNAL" ? delta : 0
        const externalDelta = workType === "EXTERNAL" ? delta : 0
        const updatedTotals = (() => {
          if (!sessionAgentId) return prev.perAgentTotals
          let found = false
          const mapped = prev.perAgentTotals.map((item) => {
            if (item.agentId !== sessionAgentId) return item
            found = true
            return {
              ...item,
              totalWorkedMs: item.totalWorkedMs + delta,
              internalWorkedMs: item.internalWorkedMs + internalDelta,
              externalWorkedMs: item.externalWorkedMs + externalDelta,
            }
          })
          if (found || delta <= 0) {
            return mapped
          }
          return [
            ...mapped,
            {
              agentId: sessionAgentId,
              agentName: viewerAgentMeta?.name ?? null,
              agentEmail: viewerAgentMeta?.email ?? null,
              avatarUrl: viewerAgentMeta?.avatarUrl ?? null,
              totalWorkedMs: delta,
              internalWorkedMs: internalDelta,
              externalWorkedMs: externalDelta,
            },
          ]
        })()
        return {
          ...prev,
          totalWorkedMs: prev.totalWorkedMs + delta,
          internalWorkedMs: prev.internalWorkedMs + internalDelta,
          externalWorkedMs: prev.externalWorkedMs + externalDelta,
          serverNow: typeof resultMeta?.serverNow === "number" ? resultMeta.serverNow : getServerNow(),
          activeSession: null,
          perAgentTotals: updatedTotals,
        }
      })
      setStatus("PAUSED")
    } catch (error) {
      const message = error instanceof Error ? error.message : "Não foi possível atualizar o atendimento"
      toast.error(message, { id: "work" })
    } finally {
      setPausing(false)
    }
  }

  const handleWorkSummaryAdjusted = useCallback(
    (result: AdjustWorkSummaryResult) => {
      calibrateServerOffset(result?.serverNow ?? null)
      setWorkSummary((prev) => {
        const fallback: WorkSummarySnapshot = {
          ticketId: ticket.id as Id<"tickets">,
          totalWorkedMs: 0,
          internalWorkedMs: 0,
          externalWorkedMs: 0,
          serverNow: result?.serverNow ?? null,
          activeSession: null,
          perAgentTotals: [],
        }
        const base = prev ?? fallback
        return {
          ...base,
          totalWorkedMs: result?.totalWorkedMs ?? base.totalWorkedMs,
          internalWorkedMs: result?.internalWorkedMs ?? base.internalWorkedMs,
          externalWorkedMs: result?.externalWorkedMs ?? base.externalWorkedMs,
          serverNow: result?.serverNow ?? base.serverNow,
          perAgentTotals: result?.perAgentTotals
            ? result.perAgentTotals.map((item) => ({
                agentId: item.agentId,
                agentName: item.agentName ?? null,
                agentEmail: item.agentEmail ?? null,
                avatarUrl: item.avatarUrl ?? null,
                totalWorkedMs: item.totalWorkedMs,
                internalWorkedMs: item.internalWorkedMs,
                externalWorkedMs: item.externalWorkedMs,
              }))
            : base.perAgentTotals,
        }
      })
    },
    [calibrateServerOffset, ticket.id],
  )

  const handleExportPdf = useCallback(async () => {
    try {
      setExportingPdf(true)
      toast.dismiss("ticket-export")
      toast.loading("Gerando PDF...", { id: "ticket-export" })
      const response = await fetch(`/api/tickets/${ticket.id}/export/pdf`, { credentials: "include" })
      if (!response.ok) {
        throw new Error(`failed: ${response.status}`)
      }
      const blob = await response.blob()
      const url = URL.createObjectURL(blob)
      const link = document.createElement("a")
      link.href = url
      link.download = `ticket-${ticket.reference}.pdf`
      document.body.appendChild(link)
      link.click()
      document.body.removeChild(link)
      URL.revokeObjectURL(url)
      toast.success("PDF exportado com sucesso!", { id: "ticket-export" })
    } catch (error) {
      console.error(error)
      toast.error("Não foi possível exportar o PDF.", { id: "ticket-export" })
    } finally {
      setExportingPdf(false)
    }
  }, [ticket.id, ticket.reference])

  const handleReopenTicket = useCallback(async () => {
    if (!viewerId) {
      toast.error("Não foi possível identificar o usuário atual.")
      return
    }
    toast.dismiss("ticket-reopen")
    setIsReopening(true)
    toast.loading("Reabrindo ticket...", { id: "ticket-reopen" })
    try {
      await reopenTicket({ ticketId: ticket.id as Id<"tickets">, actorId: viewerId as Id<"users"> })
      toast.success("Ticket reaberto com sucesso!", { id: "ticket-reopen" })
      setStatus("AWAITING_ATTENDANCE")
    } catch (error) {
      console.error(error)
      toast.error("Não foi possível reabrir o ticket.", { id: "ticket-reopen" })
    } finally {
      setIsReopening(false)
    }
  }, [reopenTicket, ticket.id, viewerId])

  return (
    <div id="ticket-summary-header" className={cardClass}>
      <div className="absolute right-6 top-6 flex flex-col items-end gap-1">
        <div className="flex items-center gap-3">
          {status !== "RESOLVED" ? (
            checklistRequiredPending > 0 ? (
              <Tooltip>
                <TooltipTrigger asChild>
                  <span>
                    <Button
                      type="button"
                      disabled
                      className="inline-flex items-center gap-2 rounded-lg border border-sidebar-border bg-sidebar-accent px-3 py-1.5 text-sm font-semibold text-sidebar-accent-foreground opacity-70"
                    >
                      <CheckCircle2 className="size-4" /> Encerrar
                    </Button>
                  </span>
                </TooltipTrigger>
                <TooltipContent className="rounded-lg border border-slate-200 bg-white px-3 py-2 text-xs font-medium text-neutral-700 shadow-lg">
                  Conclua o checklist antes de encerrar ({checklistRequiredPending} pendente
                  {checklistRequiredPending === 1 ? "" : "s"}).
                </TooltipContent>
              </Tooltip>
            ) : (
              <Button
                type="button"
                className="inline-flex items-center gap-2 rounded-lg border border-sidebar-border bg-sidebar-accent px-3 py-1.5 text-sm font-semibold text-sidebar-accent-foreground transition-all duration-200 ease-out hover:-translate-y-0.5 hover:border-sidebar-ring hover:bg-sidebar-accent focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--sidebar-ring)]/30 active:translate-y-0 active:border-sidebar-ring"
                onClick={() => setCloseOpen(true)}
              >
                <CheckCircle2 className="size-4" /> Encerrar
              </Button>
            )
          ) : canReopenTicket ? (
            <Button
              type="button"
              className="inline-flex items-center gap-2 rounded-lg border border-sidebar-border bg-white px-3 py-1.5 text-sm font-semibold text-neutral-800 transition-all duration-200 ease-out hover:-translate-y-0.5 hover:border-sidebar-ring hover:bg-slate-50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--sidebar-ring)]/30 active:translate-y-0 active:border-sidebar-ring"
              onClick={handleReopenTicket}
              disabled={isReopening}
            >
              {isReopening ? <Spinner className="size-4 text-neutral-600" /> : <RotateCcw className="size-4" />}
              Reabrir
            </Button>
          ) : null}
          {workSummary ? (
            <Tooltip>
              <TooltipTrigger asChild>
                <Badge
                  className="inline-flex h-9 cursor-help items-center gap-2 rounded-full border border-slate-200 bg-white px-3 text-sm font-semibold text-neutral-700 [&>svg]:size-5"
                >
                  <IconClock className="size-5 text-neutral-700" /> {formattedTotalWorked}
                </Badge>
              </TooltipTrigger>
              <TooltipContent className="rounded-lg border border-slate-200 bg-white px-3 py-2 text-xs font-medium text-neutral-700 shadow-lg">
                <div className="flex flex-col gap-1">
                  <span>Horas internas: {formatDuration(internalWorkedMs)}</span>
                  <span>Horas externas: {formatDuration(externalWorkedMs)}</span>
                </div>
              </TooltipContent>
            </Tooltip>
          ) : null}
          {!editing ? (
            <Button
              size="icon"
              aria-label="Editar"
              className="inline-flex items-center justify-center rounded-lg border border-slate-200 bg-white text-neutral-800 hover:bg-slate-50"
              onClick={() => setEditing(true)}
              title="Editar"
            >
              <IconPencil className="size-5" />
            </Button>
          ) : null}
          <Button
            size="icon"
            variant="outline"
            aria-label="Exportar PDF"
            className="inline-flex items-center justify-center rounded-lg border border-slate-200 bg-white text-neutral-800 hover:bg-slate-50"
            onClick={handleExportPdf}
            disabled={exportingPdf}
            title="Exportar PDF"
          >
            {exportingPdf ? <Spinner className="size-4 text-neutral-700" /> : <IconDownload className="size-5" />}
          </Button>
          {showRemoteShortcut ? (
            <Tooltip>
              <TooltipTrigger asChild>
                <Button
                  size="icon"
                  variant="outline"
                  aria-label="Conectar remotamente"
                  className="inline-flex items-center justify-center rounded-lg border border-slate-200 bg-white text-neutral-800 hover:bg-slate-50"
                  onClick={handleRemoteShortcutConnect}
                >
                  <span className="relative inline-flex items-center justify-center">
                    <MonitorSmartphone className="size-5" />
                    <span className="pointer-events-none absolute -right-0.5 -top-0.5 inline-flex">
                      <span className="relative inline-flex">
                        {remoteShortcutIndicator.isPinging ? (
                          <span
                            className={cn(
                              "absolute left-1/2 top-1/2 size-4 -translate-x-1/2 -translate-y-1/2 rounded-full animate-ping",
                              remoteShortcutIndicator.ringClass
                            )}
                          />
                        ) : null}
                        <span
                          className={cn(
                            "inline-flex size-2 rounded-full border border-white",
                            remoteShortcutIndicator.dotClass
                          )}
                        />
                      </span>
                    </span>
                  </span>
                </Button>
              </TooltipTrigger>
              <TooltipContent className="max-w-xs space-y-1 rounded-xl border border-slate-200 bg-white px-3 py-2 text-left text-xs text-neutral-900 shadow-lg">
                <p className="text-sm font-semibold text-neutral-900">Acesso remoto</p>
                {remoteShortcutHostname ? (
                  <p className="text-xs text-neutral-700">
                    <span className="font-semibold text-neutral-900">Host:</span> {remoteShortcutHostname}
                  </p>
                ) : null}
                {remoteShortcutAccess?.identifier ? (
                  <p className="text-xs text-neutral-700">
                    <span className="font-semibold text-neutral-900">ID RustDesk:</span> {remoteShortcutAccess.identifier}
                  </p>
                ) : null}
                <p className="text-xs text-neutral-700">
                  <span className="font-semibold text-neutral-900">Status:</span> {remoteShortcutStatusLabel}
                </p>
              </TooltipContent>
            </Tooltip>
          ) : null}
          {hasMachine && !hasActiveSession && isStaff ? (
            <Tooltip>
              <TooltipTrigger asChild>
                <Button
                  size="icon"
                  variant="outline"
                  aria-label="Iniciar chat ao vivo"
                  className={cn(
                    "inline-flex items-center justify-center rounded-lg border border-slate-200 bg-white text-neutral-800 hover:bg-slate-50",
                    (!machineOnline || !ticketHasAssignee) && "cursor-not-allowed opacity-50"
                  )}
                  onClick={handleStartLiveChat}
                  disabled={isStartingChat || !machineOnline || !ticketHasAssignee}
                >
                  <span className="relative inline-flex items-center justify-center">
                    <MessageCircle className="size-5" />
                    <span className="pointer-events-none absolute -right-0.5 -top-0.5 inline-flex">
                      <span className="relative inline-flex">
                        <span
                          className={cn(
                            "inline-flex size-2 rounded-full border border-white",
                            machineOnline ? "bg-green-500" : "bg-slate-400"
                          )}
                        />
                      </span>
                    </span>
                  </span>
                </Button>
              </TooltipTrigger>
              <TooltipContent className="max-w-xs space-y-1 rounded-xl border border-slate-200 bg-white px-3 py-2 text-left text-xs text-neutral-900 shadow-lg">
                <p className="text-sm font-semibold text-neutral-900">Iniciar chat ao vivo</p>
                <p className="text-xs text-neutral-700">
                  <span className="font-semibold text-neutral-900">Status:</span>{" "}
                  {machineOnline ? "Máquina online" : "Máquina offline"}
                </p>
                {!ticketHasAssignee && (
                  <p className="text-xs text-amber-600">
                    Atribua um responsável ao ticket para iniciar o chat.
                  </p>
                )}
                {ticketHasAssignee && !machineOnline && (
                  <p className="text-xs text-amber-600">
                    A máquina precisa estar online para iniciar o chat.
                  </p>
                )}
              </TooltipContent>
            </Tooltip>
          ) : hasMachine && hasActiveSession ? (
            <Tooltip>
              <TooltipTrigger asChild>
                <Button
                  size="icon"
                  variant="outline"
                  aria-label="Chat ativo"
                  className="inline-flex items-center justify-center rounded-lg border border-green-200 bg-green-50 text-green-700 hover:bg-green-100"
                  onClick={() => {
                    // Não faz nada - sessão já ativa (widget flutuante mostra)
                  }}
                >
                  <span className="relative inline-flex items-center justify-center">
                    <MessageCircle className="size-5" />
                    <span className="pointer-events-none absolute -right-0.5 -top-0.5 inline-flex">
                      <span className="relative inline-flex">
                        <span className="absolute left-1/2 top-1/2 size-4 -translate-x-1/2 -translate-y-1/2 rounded-full bg-green-400 animate-ping" />
                        <span className="inline-flex size-2 rounded-full border border-white bg-green-500" />
                      </span>
                    </span>
                  </span>
                </Button>
              </TooltipTrigger>
              <TooltipContent className="max-w-xs space-y-1 rounded-xl border border-slate-200 bg-white px-3 py-2 text-left text-xs text-neutral-900 shadow-lg">
                <p className="text-sm font-semibold text-green-700">Chat em andamento</p>
                <p className="text-xs text-neutral-700">
                  Use o widget flutuante no canto inferior direito para continuar a conversa.
                </p>
              </TooltipContent>
            </Tooltip>
          ) : null}
          <DeleteTicketDialog ticketId={ticket.id as Id<"tickets">} />
        </div>
        {status === "RESOLVED" && canReopenTicket && reopenDeadlineLabel ? (
          <p className="mt-1 text-xs text-neutral-500">Prazo para reabrir: {reopenDeadlineLabel}</p>
        ) : null}
      </div>
      <CloseTicketDialog
        open={closeOpen}
        onOpenChange={setCloseOpen}
        ticketId={ticket.id as unknown as string}
        tenantId={ticket.tenantId}
        actorId={convexUserId as Id<"users"> | null}
        ticketReference={ticket.reference ?? null}
        requesterName={ticket.requester?.name ?? ticket.requester?.email ?? null}
        agentName={agentName}
        workSummary={
          effectiveWorkSummary
            ? {
                totalWorkedMs: effectiveWorkSummary.totalWorkedMs,
                internalWorkedMs: effectiveWorkSummary.internalWorkedMs,
                externalWorkedMs: effectiveWorkSummary.externalWorkedMs,
              }
            : null
        }
        canAdjustTime={canAdjustWork && Boolean(effectiveWorkSummary)}
        onWorkSummaryAdjusted={handleWorkSummaryAdjusted}
        onSuccess={() => setStatus("RESOLVED")}
      />
      <div className="flex flex-wrap items-start justify-between gap-3">
        <div className="space-y-3">
      <div className="flex flex-wrap items-center gap-3">
        <Badge className={referenceBadgeClass}>#{ticket.reference}</Badge>
        {isAvulso ? (
          <Badge className="inline-flex h-9 items-center gap-2 rounded-full border border-rose-200 bg-rose-50 px-3 text-sm font-semibold text-rose-700">
            Cliente avulso
          </Badge>
        ) : null}
        <PrioritySelect ticketId={ticket.id} value={ticket.priority} />
        <StatusSelect
          ticketId={ticket.id}
          value={status}
          tenantId={ticket.tenantId}
          requesterName={ticket.requester?.name ?? ticket.requester?.email ?? null}
          ticketReference={ticket.reference ?? null}
          showCloseButton={false}
          onStatusChange={setStatus}
        />
        {resolvedWithSummary ? (
          <Link
            href={`/tickets/${resolvedWithSummary.id}`}
            className="flex items-center gap-3 rounded-2xl border border-primary/20 bg-primary/5 px-4 py-3 text-sm font-semibold text-primary-700 transition hover:border-primary hover:bg-primary/10 hover:text-primary-800"
          >
            <span className="flex size-9 items-center justify-center rounded-full border border-primary/30 bg-white text-primary">
              <IconLink className="size-5" strokeWidth={1.7} />
            </span>
            <span className="flex flex-col">
              <span className="text-xs font-semibold uppercase tracking-wide text-primary/70">Chamado vinculado</span>
              <span className="text-sm font-semibold text-neutral-900">
                {resolvedWithSummary.reference ? `#${resolvedWithSummary.reference}` : "Ver ticket"}
                {resolvedWithSummary.subject ? ` · ${resolvedWithSummary.subject}` : ""}
              </span>
            </span>
          </Link>
        ) : null}
            {isPlaying ? (
              <Tooltip>
                <TooltipTrigger asChild>
                  <span className="inline-flex">
                    <Button
                      size="icon"
                      aria-label="Pausar atendimento"
                      className={pauseDisabled ? pauseButtonDisabledClass : pauseButtonEnabledClass}
                      onClick={() => {
                        if (!convexUserId || pauseDisabled) return
                        setPauseDialogOpen(true)
                      }}
                      disabled={pauseDisabled}
                      title="Pausar"
                    >
                      <IconPlayerPause className={pauseDisabled ? "size-4 text-neutral-500" : "size-4 text-white"} />
                    </Button>
                  </span>
                </TooltipTrigger>
                {pauseDisabled ? (
                  <TooltipContent className="rounded-lg border border-slate-200 bg-white px-3 py-2 text-xs font-medium text-neutral-700 shadow-lg">
                    Apenas o responsável atual ou um administrador pode pausar o atendimento.
                  </TooltipContent>
                ) : null}
              </Tooltip>
            ) : startDisabled ? (
              <Tooltip>
                <TooltipTrigger asChild>
                  <span className="inline-flex">
                    <Button
                      size="icon"
                      aria-label="Iniciar atendimento"
                      className={playButtonDisabledClass}
                      disabled
                      title="Iniciar"
                    >
                      <IconPlayerPlay className="size-4 text-neutral-500" />
                    </Button>
                  </span>
                </TooltipTrigger>
                <TooltipContent className="rounded-lg border border-slate-200 bg-white px-3 py-2 text-xs font-medium text-neutral-700 shadow-lg">
                  {startDisabledReason}
                </TooltipContent>
              </Tooltip>
            ) : (
              <DropdownMenu>
                <DropdownMenuTrigger asChild>
                  <Button
                    size="icon"
                    aria-label="Iniciar atendimento"
                    className={playButtonEnabledClass}
                    title="Iniciar"
                  >
                    <IconPlayerPlay className="size-4 text-white" />
                  </Button>
                </DropdownMenuTrigger>
                <DropdownMenuContent align="start" className="rounded-lg border border-slate-200 bg-white text-neutral-800 shadow-sm">
                  <DropdownMenuItem onSelect={() => void handleStartWork("INTERNAL")}>Iniciar (interno)</DropdownMenuItem>
                  <DropdownMenuItem onSelect={() => void handleStartWork("EXTERNAL")}>Iniciar (externo)</DropdownMenuItem>
                </DropdownMenuContent>
              </DropdownMenu>
            )}
          </div>
          {editing ? (
            <div className="space-y-2">
              <Input
                value={subject}
                onChange={(e) => setSubject(e.target.value)}
                className="h-10 rounded-lg border border-slate-300 text-lg font-semibold text-neutral-900"
              />
            </div>
          ) : (
            <div className="space-y-1">
              <div className="flex flex-wrap items-center gap-2">
                <h1 className="break-words text-2xl font-semibold text-neutral-900">{subject}</h1>
                {ticket.formTemplateLabel || ticket.formTemplate ? (
                  <span className="inline-flex items-center rounded-full border border-sky-200 bg-sky-50 px-2.5 py-0.5 text-xs font-semibold text-sky-700">
                    {ticket.formTemplateLabel ?? ticket.formTemplate}
                  </span>
                ) : null}
              </div>
            </div>
          )}
        </div>
      </div>
      <Separator className="bg-slate-200" />
      <div className="grid gap-4 text-sm text-neutral-600 sm:grid-cols-2 lg:grid-cols-3">
        <div className="flex flex-col gap-1">
          <span className={sectionLabelClass}>Categoria primária</span>
          {editing ? (
            <Select
              disabled={saving || categoriesLoading || isManager}
              value={selectedCategoryId ? selectedCategoryId : EMPTY_CATEGORY_VALUE}
              onValueChange={(value) => {
                if (isManager) return
                if (value === EMPTY_CATEGORY_VALUE) {
                  setCategorySelection({ categoryId: "", subcategoryId: "" })
                  return
                }
                const category = categories.find((item) => item.id === value)
                setCategorySelection({
                  categoryId: value,
                  subcategoryId: category?.secondary.find((option) => option.id === selectedSubcategoryId)?.id ?? "",
                })
              }}
            >
              <SelectTrigger className={selectTriggerClass}>
                <SelectValue placeholder={categoriesLoading ? "Carregando..." : "Sem categoria"} />
              </SelectTrigger>
              <SelectContent className="rounded-lg border border-slate-200 bg-white text-neutral-800 shadow-sm">
                <SelectItem value={EMPTY_CATEGORY_VALUE}>Sem categoria</SelectItem>
                {categories.map((category) => (
                  <SelectItem key={category.id} value={category.id}>
                    {category.name}
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>
          ) : (
            <span className={sectionValueClass}>{ticket.category?.name ?? "Sem categoria"}</span>
          )}
        </div>
        <div className="flex flex-col gap-1">
          <span className={sectionLabelClass}>Categoria secundária</span>
          {editing ? (
            <Select
              disabled={
                saving || categoriesLoading || !selectedCategoryId || isManager
              }
              value={selectedSubcategoryId ? selectedSubcategoryId : EMPTY_SUBCATEGORY_VALUE}
              onValueChange={(value) => {
                if (isManager) return
                if (value === EMPTY_SUBCATEGORY_VALUE) {
                  setCategorySelection((prev) => ({ ...prev, subcategoryId: "" }))
                  return
                }
                setCategorySelection((prev) => ({ ...prev, subcategoryId: value }))
              }}
            >
              <SelectTrigger className={selectTriggerClass}>
                <SelectValue
                  placeholder={
                    !selectedCategoryId
                      ? "Selecione uma primária"
                      : secondaryOptions.length === 0
                        ? "Sem subcategoria"
                        : "Selecionar"
                  }
                />
              </SelectTrigger>
              <SelectContent className="rounded-lg border border-slate-200 bg-white text-neutral-800 shadow-sm">
                <SelectItem value={EMPTY_SUBCATEGORY_VALUE}>Sem subcategoria</SelectItem>
                {secondaryOptions.map((option) => (
                  <SelectItem key={option.id} value={option.id}>
                    {option.name}
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>
          ) : (
            <span className={sectionValueClass}>{ticket.subcategory?.name ?? "Sem subcategoria"}</span>
          )}
        </div>
        <div className="flex flex-col gap-1">
          <span className={sectionLabelClass}>Fila</span>
          {editing ? (
            <Select
              disabled={isManager}
              value={queueSelection}
              onValueChange={(value) => {
                if (isManager) return
                setQueueSelection(value)
              }}
            >
              <SelectTrigger className={smallSelectTriggerClass}>
                <SelectValue placeholder="Selecionar" />
              </SelectTrigger>
              <SelectContent className="rounded-lg border border-slate-200 bg-white text-neutral-800 shadow-sm">
                {queues.map((queue) => (
                  <SelectItem key={queue.id} value={queue.name}>
                    {queue.name}
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>
          ) : (
            <span className={sectionValueClass}>{ticket.queue ?? "Sem fila"}</span>
          )}
        </div>
        <div className="flex flex-col gap-1">
          <span className={sectionLabelClass}>Empresa</span>
          {editing && !isManager ? (
            <SearchableCombobox
              value={companySelection}
              onValueChange={(value) => {
                setCompanySelection(value ?? NO_COMPANY_VALUE)
              }}
              options={companyComboboxOptions}
              placeholder="Selecionar empresa"
              disabled={isManager}
              renderValue={(option) =>
                option ? (
                  <span className="truncate">{option.label}</span>
                ) : (
                  <span className="text-muted-foreground">Selecionar empresa</span>
                )
              }
              renderOption={(option) => {
                const meta = companyMeta.get(option.value)
                return (
                  <div className="flex items-center justify-between gap-3">
                    <span className="font-medium text-foreground">{option.label}</span>
                    {meta?.isAvulso ? (
                      <Badge variant="outline" className="rounded-full px-2 py-0.5 text-[10px] uppercase tracking-wide">
                        Avulsa
                      </Badge>
                    ) : null}
                  </div>
                )
              }}
            />
          ) : (
            <span className={sectionValueClass}>{companyLabel}</span>
          )}
        </div>
        <div className="flex flex-col gap-1">
          <span className={sectionLabelClass}>Solicitante</span>
          {editing && !isManager ? (
            <div className="space-y-1.5">
              <Select
                value={requesterSelection ?? NO_REQUESTER_VALUE}
                onValueChange={(value) => {
                  if (value === NO_REQUESTER_VALUE) {
                    setRequesterSelection(null)
                  } else {
                    setRequesterSelection(value)
                  }
                }}
                disabled={filteredCustomers.length === 0}
              >
                <SelectTrigger className={selectTriggerClass}>
                  <SelectValue
                    placeholder={filteredCustomers.length === 0 ? "Nenhum usuário disponível" : "Selecionar solicitante"}
                  />
                </SelectTrigger>
                <SelectContent className="max-h-64 rounded-lg border border-slate-200 bg-white text-neutral-800 shadow-sm">
                  {filteredCustomers.length === 0 ? (
                    <SelectItem value={NO_REQUESTER_VALUE} disabled>
                      Nenhum usuário disponível
                    </SelectItem>
                  ) : (
                    filteredCustomers.map((customer) => (
                      <SelectItem key={customer.id} value={customer.id}>
                        <div className="flex flex-col">
                          <span className="font-medium">{customer.name}</span>
                          <span className="text-xs text-neutral-500">{customer.email}</span>
                        </div>
                      </SelectItem>
                    ))
                  )}
                </SelectContent>
              </Select>
              {filteredCustomers.length === 0 ? (
                <span className="text-xs text-neutral-500">Nenhum colaborador disponível para a empresa selecionada.</span>
              ) : null}
              {requesterError ? <span className="text-xs font-semibold text-rose-600">{requesterError}</span> : null}
            </div>
          ) : (
            <span className={sectionValueClass}>{ticket.requester.name}</span>
          )}
        </div>
        <div className="flex flex-col gap-1">
          <span className={sectionLabelClass}>Responsável</span>
          {editing ? (
            <Select
              disabled={isManager}
              value={assigneeSelection}
              onValueChange={(value) => {
                if (isManager) return
                setAssigneeSelection(value)
              }}
            >
              <SelectTrigger className={selectTriggerClass}>
                <SelectValue placeholder="Selecionar" />
              </SelectTrigger>
              <SelectContent className="rounded-lg border border-slate-200 bg-white text-neutral-800 shadow-sm">
                {agents.map((agent) => (
                  <SelectItem key={agent._id} value={agent._id}>
                    {agent.name}
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>
          ) : (
            <span className={sectionValueClass}>{assigneeState?.name ?? "Não atribuído"}</span>
          )}
        </div>
        {editing && assigneeDirty ? (
          <div className="flex flex-col gap-2 sm:col-span-2 lg:col-span-3">
            <span className={sectionLabelClass}>Motivo da troca</span>
            <Textarea
              value={assigneeChangeReason}
              onChange={(event) => {
                setAssigneeChangeReason(event.target.value)
                if (assigneeReasonError) {
                  setAssigneeReasonError(null)
                }
              }}
              placeholder="Explique brevemente por que o chamado será reatribuído..."
              className="min-h-[96px]"
            />
            <p className="text-xs text-neutral-500">
              O motivo é registrado como comentário interno visível para administradores e agentes.
            </p>
            {assigneeReasonError ? (
              <p className="text-xs font-semibold text-rose-600">{assigneeReasonError}</p>
            ) : normalizedAssigneeReason.length > 0 && normalizedAssigneeReason.length < 5 ? (
              <p className="text-xs font-semibold text-rose-600">Descreva o motivo com pelo menos 5 caracteres ou deixe em branco.</p>
            ) : null}
          </div>
        ) : null}
        <div className="flex flex-col gap-1">
          <span className={sectionLabelClass}>Criado em</span>
          <span className={sectionValueClass}>{format(ticket.createdAt, "dd/MM/yyyy HH:mm", { locale: ptBR })}</span>
        </div>
        <div className="flex flex-col gap-1">
          <span className={sectionLabelClass}>Atualizado em</span>
          <div className="flex items-center gap-2">
            <span className={sectionValueClass}>{format(ticket.updatedAt, "dd/MM/yyyy HH:mm", { locale: ptBR })}</span>
            <span className={subtleBadgeClass}>{updatedRelative}</span>
          </div>
        </div>
        {visitSectionEnabled ? (
          <div
            className={`flex flex-col gap-1 ${
              shouldHighlightVisitFields ? "rounded-2xl border border-rose-200 bg-rose-50/70 p-3" : ""
            }`}
          >
            <span className={`${sectionLabelClass} ${shouldHighlightVisitFields ? "text-rose-700" : ""}`}>
              Data da visita
            </span>
            {editing && !isManager ? (
              <div className="space-y-2">
                <div className="grid gap-2 sm:grid-cols-[minmax(0,1fr)_160px]">
                  <Popover open={visitDatePickerOpen} onOpenChange={setVisitDatePickerOpen}>
                    <PopoverTrigger asChild>
                      <button
                        type="button"
                        className={`flex h-9 w-full items-center justify-between rounded-lg border bg-white px-3 text-left text-sm shadow-sm hover:bg-slate-50 ${
                          visitDateMissing
                            ? "border-rose-400 text-rose-700"
                            : visitDateInput
                              ? "border-slate-300 text-neutral-800"
                              : "border-slate-300 text-muted-foreground"
                        }`}
                      >
                        {visitDatePickerValue
                          ? format(visitDatePickerValue, "dd/MM/yyyy", { locale: ptBR })
                          : "Selecionar data"}
                        <CalendarIcon className={`ml-2 size-4 ${visitDateMissing ? "text-rose-600" : "text-neutral-500"}`} />
                      </button>
                    </PopoverTrigger>
                    <PopoverContent className="w-auto p-0" align="start">
                      <Calendar
                        mode="single"
                        selected={visitDatePickerValue ?? undefined}
                        onSelect={(date) => {
                          if (!date) {
                            setVisitDateInput(null)
                            setVisitTimeInput(null)
                            return
                          }
                          const iso = date.toISOString().slice(0, 10)
                          setVisitDateInput(iso)
                          setVisitError(null)
                          setVisitDatePickerOpen(false)
                        }}
                        initialFocus
                      />
                    </PopoverContent>
                  </Popover>
                  <TimePicker
                    value={visitTimeInput ?? ""}
                    onChange={(value) => {
                      setVisitTimeInput(value || null)
                      if (value) {
                        setVisitError(null)
                      }
                    }}
                    stepMinutes={5}
                    className={`h-9 rounded-lg border bg-white text-sm font-medium shadow-sm ${
                      visitTimeMissing ? "border-rose-400 text-rose-700" : "border-slate-300 text-neutral-800"
                    }`}
                  />
                </div>
                {visitInlineError ? (
                  <p className="text-xs font-semibold text-rose-600">{visitInlineError}</p>
                ) : null}
              </div>
            ) : (
              <div className="flex flex-col gap-1">
                <span className={sectionValueClass}>
                  {ticket.dueAt ? format(ticket.dueAt, "dd/MM/yyyy HH:mm", { locale: ptBR }) : "Sem data definida"}
                </span>
                <div className="flex flex-wrap items-center gap-2">
                  {visitStatusValue ? (
                    <Badge
                      variant="outline"
                      className={cn(
                        "rounded-full border px-2.5 py-1 text-[11px] font-semibold",
                        VISIT_STATUS_TONES[visitStatusValue] ?? "bg-slate-100 text-neutral-700 border-slate-200",
                      )}
                    >
                      {VISIT_STATUS_LABELS[visitStatusValue] ?? visitStatusValue}
                    </Badge>
                  ) : null}
                  {!isManager && visitStatusValue !== "done" ? (
                    <Button
                      size="sm"
                      variant="outline"
                      onClick={() => handleVisitStatusChange("done")}
                      disabled={visitStatusLoading}
                    >
                      Marcar visita realizada
                    </Button>
                  ) : null}
                  {!isManager && visitStatusValue && visitStatusValue !== "scheduled" && visitStatusValue !== "in_service" ? (
                    <Button
                      size="sm"
                      variant="ghost"
                      onClick={() => handleVisitStatusChange("scheduled")}
                      disabled={visitStatusLoading}
                    >
                      Reabrir visita
                    </Button>
                  ) : null}
                </div>
                {visitStatusValue === "done" && visitPerformedAt ? (
                  <span className="text-xs text-muted-foreground">
                    Concluída em {format(visitPerformedAt, "dd/MM/yyyy HH:mm", { locale: ptBR })}
                  </span>
                ) : null}
              </div>
            )}
          </div>
        ) : slaDueDate ? (
          <div className="flex flex-col gap-1">
            <span className={sectionLabelClass}>SLA até</span>
            <span className={sectionValueClass}>{format(slaDueDate, "dd/MM/yyyy HH:mm", { locale: ptBR })}</span>
          </div>
        ) : null}
        {ticket.slaSnapshot ? (
          <div className="flex flex-col gap-1">
            <span className={sectionLabelClass}>Política</span>
            <span className={sectionValueClass}>{ticket.slaSnapshot.categoryName ?? "Configuração personalizada"}</span>
          </div>
        ) : null}
        <TicketCustomFieldsSection ticket={ticket} variant="inline" className="sm:col-span-2 lg:col-span-3" />
        {editing ? (
          <div className="flex items-center justify-end gap-2 sm:col-span-2 lg:col-span-3">
            <Button variant="ghost" size="sm" className="text-sm font-semibold text-neutral-700" onClick={handleCancel}>
              Cancelar
            </Button>
            <Button size="sm" className={startButtonClass} onClick={handleSave} disabled={saveDisabled}>
              Salvar
            </Button>
          </div>
        ) : null}
      </div>
      <Dialog open={pauseDialogOpen} onOpenChange={setPauseDialogOpen}>
        <DialogContent>
          <DialogHeader>
            <DialogTitle>Registrar pausa</DialogTitle>
            <DialogDescription>Informe o motivo da pausa para registrar no histórico do chamado.</DialogDescription>
          </DialogHeader>
          <div className="space-y-4">
            <div className="space-y-1.5">
              <span className="text-xs font-semibold uppercase tracking-wide text-neutral-500">Motivo</span>
              <Select value={pauseReason} onValueChange={setPauseReason}>
                <SelectTrigger className={selectTriggerClass}>
                  <SelectValue placeholder="Selecione" />
                </SelectTrigger>
                <SelectContent className="rounded-lg border border-slate-200 bg-white text-neutral-800 shadow-sm">
                  {PAUSE_REASONS.map((reason) => (
                    <SelectItem key={reason.value} value={reason.value}>
                      {reason.label}
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>
            </div>
            <div className="space-y-1.5">
              <span className="text-xs font-semibold uppercase tracking-wide text-neutral-500">Observações</span>
              <Textarea
                value={pauseNote}
                onChange={(event) => setPauseNote(event.target.value)}
                rows={3}
                placeholder="Adicione detalhes opcionais (visível apenas internamente)."
                className="min-h-[96px]"
              />
            </div>
          </div>
          <DialogFooter>
            <Button variant="outline" onClick={() => setPauseDialogOpen(false)} disabled={pausing}>
              Cancelar
            </Button>
            <Button
              className={pauseButtonClass}
              onClick={handlePauseConfirm}
              disabled={pausing || !pauseReason}
            >
              {pausing ? <Spinner className="size-4 text-white" /> : "Registrar pausa"}
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>
    </div>
  )
}
